Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
58852d4b
Commit
58852d4b
authored
Nov 26, 2007
by
Dries Buytaert
Browse files
- Patch
#192736
by quicksketch et al: drag and drop for book module.
parent
a960d4d6
Changes
8
Hide whitespace changes
Inline
Side-by-side
includes/cache.inc
View file @
58852d4b
...
...
@@ -133,8 +133,8 @@ function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
global
$user
;
if
(
!
isset
(
$cid
)
&&
!
isset
(
$table
))
{
// Clear the block cache first, so stale data will
// not end up in the page cache.
// Clear the block cache first, so stale data will
// not end up in the page cache.
cache_clear_all
(
NULL
,
'cache_block'
);
cache_clear_all
(
NULL
,
'cache_page'
);
return
;
...
...
includes/common.inc
View file @
58852d4b
...
...
@@ -2028,10 +2028,12 @@ function drupal_get_js($scope = 'header', $javascript = NULL) {
* (optional) The column containing the field elements may be entirely hidden
* from view dynamically when the JavaScript is loaded. Set to FALSE if the
* column should not be hidden.
* @param $limit
* (optional) Limit the maximum amount of parenting in this table.
* @see block-admin-display-form.tpl.php
* @see theme_menu_overview_form()
*/
function
drupal_add_tabledrag
(
$table_id
,
$action
,
$relationship
,
$group
,
$subgroup
=
NULL
,
$source
=
NULL
,
$hidden
=
TRUE
)
{
function
drupal_add_tabledrag
(
$table_id
,
$action
,
$relationship
,
$group
,
$subgroup
=
NULL
,
$source
=
NULL
,
$hidden
=
TRUE
,
$limit
=
0
)
{
static
$js_added
=
FALSE
;
if
(
!
$js_added
)
{
drupal_add_js
(
'misc/tabledrag.js'
,
'core'
);
...
...
@@ -2047,6 +2049,7 @@ function drupal_add_tabledrag($table_id, $action, $relationship, $group, $subgro
'relationship'
=>
$relationship
,
'action'
=>
$action
,
'hidden'
=>
$hidden
,
'limit'
=>
$limit
,
);
drupal_add_js
(
$settings
,
'setting'
);
}
...
...
includes/menu.inc
View file @
58852d4b
...
...
@@ -1788,7 +1788,7 @@ function menu_link_save(&$item) {
function
_menu_clear_page_cache
()
{
static
$cache_cleared
=
0
;
// Clear the page and block caches, but at most twice, including at
// Clear the page and block caches, but at most twice, including at
// the end of the page load when there are multple links saved or deleted.
if
(
empty
(
$cache_cleared
))
{
cache_clear_all
();
...
...
@@ -1805,7 +1805,7 @@ function _menu_clear_page_cache() {
}
/**
* Helper function to update a list of menus with expanded items
* Helper function to update a list of menus with expanded items
*/
function
_menu_set_expanded_menus
()
{
$names
=
array
();
...
...
misc/tabledrag.js
View file @
58852d4b
...
...
@@ -46,6 +46,7 @@ Drupal.tableDrag = function(table, tableSettings) {
this
.
oldRowElement
=
null
;
// Remember the previous element.
this
.
oldY
=
0
;
// Used to determine up or down direction from last mouse move.
this
.
changed
=
false
;
// Whether anything in the entire table has changed.
this
.
maxDepth
=
0
// Maximum amount of allowed parenting.
// Configure the scroll settings.
this
.
scrollSettings
=
{
amount
:
4
,
interval
:
50
,
trigger
:
70
};
...
...
@@ -62,6 +63,9 @@ Drupal.tableDrag = function(table, tableSettings) {
if
(
tableSettings
[
group
][
n
][
'
relationship
'
]
==
'
parent
'
)
{
this
.
indentEnabled
=
true
;
}
if
(
tableSettings
[
group
][
n
][
'
limit
'
]
>
0
)
{
this
.
maxDepth
=
tableSettings
[
group
][
n
][
'
limit
'
];
}
}
}
if
(
this
.
indentEnabled
)
{
...
...
@@ -190,7 +194,7 @@ Drupal.tableDrag.prototype.makeDraggable = function(item) {
}
// Create a new rowObject for manipulation of this row.
self
.
rowObject
=
new
self
.
row
(
item
,
'
mouse
'
,
self
.
indentEnabled
,
true
);
self
.
rowObject
=
new
self
.
row
(
item
,
'
mouse
'
,
self
.
indentEnabled
,
self
.
maxDepth
,
true
);
// Save the position of the table.
self
.
table
.
topY
=
self
.
getPosition
(
self
.
table
).
y
;
...
...
@@ -244,7 +248,7 @@ Drupal.tableDrag.prototype.makeDraggable = function(item) {
handle
.
keydown
(
function
(
event
)
{
// If a rowObject doesn't yet exist and this isn't the tab key.
if
(
event
.
keyCode
!=
9
&&
!
self
.
rowObject
)
{
self
.
rowObject
=
new
self
.
row
(
item
,
'
keyboard
'
,
self
.
indentEnabled
,
true
);
self
.
rowObject
=
new
self
.
row
(
item
,
'
keyboard
'
,
self
.
indentEnabled
,
self
.
maxDepth
,
true
);
}
var
keyChange
=
false
;
...
...
@@ -753,10 +757,12 @@ Drupal.tableDrag.prototype.onDrop = function() {
* The method in which this row is being moved. Either 'keyboard' or 'mouse'.
* @param indentEnabled
* Whether the containing table uses indentations. Used for optimizations.
* @param maxDepth
* The maximum amount of indentations this row may contain.
* @param addClasses
* Whether we want to add classes to this row to indicate child relationships.
*/
Drupal
.
tableDrag
.
prototype
.
row
=
function
(
tableRow
,
method
,
indentEnabled
,
addClasses
)
{
Drupal
.
tableDrag
.
prototype
.
row
=
function
(
tableRow
,
method
,
indentEnabled
,
maxDepth
,
addClasses
)
{
this
.
element
=
tableRow
;
this
.
method
=
method
;
this
.
group
=
new
Array
(
tableRow
);
...
...
@@ -764,6 +770,7 @@ Drupal.tableDrag.prototype.row = function(tableRow, method, indentEnabled, addCl
this
.
changed
=
false
;
this
.
table
=
$
(
tableRow
).
parents
(
'
table:first
'
).
get
(
0
);
this
.
indentEnabled
=
indentEnabled
;
this
.
maxDepth
=
maxDepth
;
this
.
direction
=
''
;
// Direction the row is being moved.
if
(
this
.
indentEnabled
)
{
...
...
@@ -901,8 +908,8 @@ Drupal.tableDrag.prototype.row.prototype.indent = function(indentDiff) {
indentDiff
=
Math
.
max
(
nextIndent
-
this
.
indents
,
indentDiff
);
}
// Never allow indentation greater th
an 8 parents (menu system
limit
)
.
if
(
indentDiff
+
this
.
groupDepth
>
8
)
{
// Never allow indentation greater th
e set
limit.
if
(
this
.
maxDepth
&&
indentDiff
+
this
.
groupDepth
>
this
.
maxDepth
)
{
indentDiff
=
0
;
}
...
...
modules/book/book.admin.inc
View file @
58852d4b
...
...
@@ -70,24 +70,12 @@ function book_admin_settings_validate($form, &$form_state) {
*/
function
book_admin_edit
(
$form_state
,
$node
)
{
drupal_set_title
(
check_plain
(
$node
->
title
));
$form
=
array
(
'#cache'
=>
TRUE
,
'#prefix'
=>
'<div id="book-admin-edit-wrapper">'
,
'#suffix'
=>
'</div>'
,
);
$form
=
array
();
$form
[
'#node'
]
=
$node
;
$form
[
'table'
]
=
_book_admin_table
(
$node
);
$form
[
'save'
]
=
array
(
'#type'
=>
'submit'
,
'#value'
=>
t
(
'Save book pages'
),
'#ahah'
=>
array
(
'path'
=>
'book/js/admin/'
.
$node
->
nid
,
'selector'
=>
'#book-admin-edit select'
,
'wrapper'
=>
'book-admin-edit-wrapper'
,
'event'
=>
'change'
,
'effect'
=>
'fade'
,
),
);
return
$form
;
}
...
...
@@ -95,36 +83,44 @@ function book_admin_edit($form_state, $node) {
/**
* Handle submission of the book administrative page form.
*
* This function takes care to save parent menu items before their children.
* Saving menu items in the incorrect order can break the menu tree.
*
* @see book_admin_edit()
* @see menu_overview_form_submit()
*/
function
book_admin_edit_submit
(
$form
,
&
$form_state
)
{
foreach
(
$form_state
[
'values'
][
'table'
]
as
$row
)
{
$node
=
node_load
(
$row
[
'nid'
],
FALSE
);
if
(
$row
[
'title'
]
!=
$node
->
title
||
$row
[
'weight'
]
!=
$node
->
book
[
'weight'
])
{
// Record changes in node's log message.
$log_messages
=
array
();
if
(
$row
[
'title'
]
!=
$node
->
title
)
{
$log_messages
[]
=
t
(
'Title changed from %original to %current.'
,
array
(
'%original'
=>
$node
->
title
,
'%current'
=>
$row
[
'title'
]));
// Save elements in the same order as defined in post rather than the form.
// This ensures parents are updated before their children, preventing orphans.
$order
=
array_flip
(
array_keys
(
$form
[
'#post'
][
'table'
]));
$form
[
'table'
]
=
array_merge
(
$order
,
$form
[
'table'
]);
foreach
(
element_children
(
$form
[
'table'
])
as
$key
)
{
if
(
$form
[
'table'
][
$key
][
'#item'
])
{
$row
=
$form
[
'table'
][
$key
];
$values
=
$form_state
[
'values'
][
'table'
][
$key
];
// Update menu item if moved.
if
(
$row
[
'plid'
][
'#default_value'
]
!=
$values
[
'plid'
]
||
$row
[
'weight'
][
'#default_value'
]
!=
$values
[
'weight'
])
{
$row
[
'#item'
][
'plid'
]
=
$values
[
'plid'
];
$row
[
'#item'
][
'weight'
]
=
$values
[
'weight'
];
menu_link_save
(
$row
[
'#item'
]);
}
if
(
$row
[
'weight'
]
!=
$node
->
book
[
'weight'
])
{
$log_messages
[]
=
t
(
'Weight changed from %original to %current.'
,
array
(
'%original'
=>
$node
->
book
[
'weight'
],
'%current'
=>
$row
[
'weight'
]));
}
$node
->
title
=
$row
[
'title'
];
$node
->
book
[
'link_title'
]
=
$row
[
'title'
];
$node
->
book
[
'weight'
]
=
$row
[
'weight'
];
$node
->
revision
=
1
;
$node
->
log
=
implode
(
' '
,
$log_messages
);
node_save
(
$node
);
watchdog
(
'content'
,
'book: updated %title.'
,
array
(
'%title'
=>
$node
->
title
),
WATCHDOG_NOTICE
,
l
(
t
(
'view'
),
'node/'
.
$node
->
nid
));
// Update the title if changed.
if
(
$row
[
'title'
][
'#default_value'
]
!=
$values
[
'title'
])
{
$node
=
node_load
(
$values
[
'nid'
],
FALSE
);
$node
->
title
=
$values
[
'title'
];
$node
->
book
[
'link_title'
]
=
$values
[
'title'
];
$node
->
revision
=
1
;
$node
->
log
=
t
(
'Title changed from %original to %current.'
,
array
(
'%original'
=>
$node
->
title
,
'%current'
=>
$values
[
'title'
]));
node_save
(
$node
);
watchdog
(
'content'
,
'book: updated %title.'
,
array
(
'%title'
=>
$node
->
title
),
WATCHDOG_NOTICE
,
l
(
t
(
'view'
),
'node/'
.
$node
->
nid
));
}
}
}
// Insure we have the current title - it may have been changed in the form.
$title
=
db_result
(
db_query
(
"SELECT title FROM
{
node
}
WHERE nid = %d"
,
$form
[
'#node'
]
->
nid
));
drupal_set_message
(
t
(
'Updated book %title.'
,
array
(
'%title'
=>
$title
)));
drupal_set_message
(
t
(
'Updated book %title.'
,
array
(
'%title'
=>
$form
[
'#node'
]
->
title
)));
}
/**
...
...
@@ -139,7 +135,10 @@ function _book_admin_table($node) {
);
$tree
=
book_menu_subtree_data
(
$node
->
book
);
_book_admin_table_tree
(
$tree
,
$form
);
$tree
=
array_shift
(
$tree
);
// Do not include the book item itself.
if
(
$tree
[
'below'
])
{
_book_admin_table_tree
(
$tree
[
'below'
],
$form
);
}
return
$form
;
}
...
...
@@ -151,6 +150,7 @@ function _book_admin_table($node) {
function
_book_admin_table_tree
(
$tree
,
&
$form
)
{
foreach
(
$tree
as
$key
=>
$data
)
{
$form
[
$key
]
=
array
(
'#item'
=>
$data
[
'link'
],
'nid'
=>
array
(
'#type'
=>
'value'
,
'#value'
=>
$data
[
'link'
][
'nid'
]),
'depth'
=>
array
(
'#type'
=>
'value'
,
'#value'
=>
$data
[
'link'
][
'depth'
]),
'href'
=>
array
(
'#type'
=>
'value'
,
'#value'
=>
$data
[
'link'
][
'href'
]),
...
...
@@ -158,12 +158,22 @@ function _book_admin_table_tree($tree, &$form) {
'#type'
=>
'textfield'
,
'#default_value'
=>
$data
[
'link'
][
'link_title'
],
'#maxlength'
=>
255
,
'#size'
=>
40
,
),
'weight'
=>
array
(
'#type'
=>
'weight'
,
'#default_value'
=>
$data
[
'link'
][
'weight'
],
'#delta'
=>
15
,
),
'plid'
=>
array
(
'#type'
=>
'textfield'
,
'#default_value'
=>
$data
[
'link'
][
'plid'
],
'#size'
=>
6
,
),
'mlid'
=>
array
(
'#type'
=>
'hidden'
,
'#default_value'
=>
$data
[
'link'
][
'mlid'
],
),
);
if
(
$data
[
'below'
])
{
_book_admin_table_tree
(
$data
[
'below'
],
$form
);
...
...
@@ -177,9 +187,13 @@ function _book_admin_table_tree($tree, &$form) {
* Theme function for the book administration page form.
*
* @ingroup themeable
* @see book_admin_table().
*/
function
theme_book_admin_table
(
$form
)
{
$header
=
array
(
t
(
'Title'
),
t
(
'Weight'
),
array
(
'data'
=>
t
(
'Operations'
),
'colspan'
=>
'3'
));
drupal_add_tabledrag
(
'book-outline'
,
'match'
,
'parent'
,
'book-plid'
,
'book-plid'
,
'book-mlid'
,
TRUE
,
MENU_MAX_DEPTH
-
2
);
drupal_add_tabledrag
(
'book-outline'
,
'order'
,
'sibling'
,
'book-weight'
);
$header
=
array
(
t
(
'Title'
),
t
(
'Weight'
),
t
(
'Parent'
),
array
(
'data'
=>
t
(
'Operations'
),
'colspan'
=>
'3'
));
$rows
=
array
();
$destination
=
drupal_get_destination
();
...
...
@@ -187,10 +201,16 @@ function theme_book_admin_table($form) {
foreach
(
element_children
(
$form
)
as
$key
)
{
$nid
=
$form
[
$key
][
'nid'
][
'#value'
];
$href
=
$form
[
$key
][
'href'
][
'#value'
];
$asterisk
=
(
isset
(
$form
[
$key
][
'#attributes'
][
'class'
])
&&
strpos
(
$form
[
$key
][
'#attributes'
][
'class'
],
'book-changed'
)
!==
FALSE
)
?
'<span class="warning">*</span>'
:
''
;
// Add special classes to be used with tabledrag.js.
$form
[
$key
][
'plid'
][
'#attributes'
][
'class'
]
=
'book-plid'
;
$form
[
$key
][
'mlid'
][
'#attributes'
][
'class'
]
=
'book-mlid'
;
$form
[
$key
][
'weight'
][
'#attributes'
][
'class'
]
=
'book-weight'
;
$data
=
array
(
'<div style="padding-left: '
.
(
25
*
$form
[
$key
][
'depth'
][
'#value'
]
)
.
'px;">'
.
drupal_render
(
$form
[
$key
][
'title'
])
.
$asterisk
.
'</div>'
,
theme
(
'indentation'
,
$form
[
$key
][
'depth'
][
'#value'
]
-
2
)
.
drupal_render
(
$form
[
$key
][
'title'
]),
drupal_render
(
$form
[
$key
][
'weight'
]),
drupal_render
(
$form
[
$key
][
'plid'
])
.
drupal_render
(
$form
[
$key
][
'mlid'
]),
l
(
t
(
'view'
),
$href
),
$access
?
l
(
t
(
'edit'
),
'node/'
.
$nid
.
'/edit'
,
array
(
'query'
=>
$destination
))
:
' '
,
$access
?
l
(
t
(
'delete'
),
'node/'
.
$nid
.
'/delete'
,
array
(
'query'
=>
$destination
)
)
:
' '
,
...
...
@@ -199,77 +219,11 @@ function theme_book_admin_table($form) {
if
(
isset
(
$form
[
$key
][
'#attributes'
]))
{
$row
=
array_merge
(
$row
,
$form
[
$key
][
'#attributes'
]);
}
$row
[
'class'
]
=
empty
(
$row
[
'class'
])
?
'draggable'
:
$row
[
'class'
]
.
' draggable'
;
$rows
[]
=
$row
;
}
return
theme
(
'status_messages'
)
.
theme
(
'table'
,
$header
,
$rows
);
}
/**
* Menu callback for updating the book outline form.
*/
function
book_admin_js_update
()
{
$cid
=
'form_'
.
$_POST
[
'form_build_id'
];
$cache
=
cache_get
(
$cid
,
'cache_form'
);
if
(
$cache
)
{
$form
=
$cache
->
data
;
$tree
=
book_menu_subtree_data
(
$form
[
'#node'
]
->
book
);
_book_admin_js_update_tree
(
$tree
);
_book_admin_sort_tree
(
$tree
);
// Create the form in the new order.
$table_form
=
array
();
_book_admin_table_tree
(
$tree
,
$table_form
);
// Find the changed element on this request and save the current classes.
foreach
(
element_children
(
$form
[
'table'
])
as
$key
)
{
if
(
isset
(
$form
[
'table'
][
$key
][
'#attributes'
]))
{
$table_form
[
$key
][
'#attributes'
]
=
$form
[
'table'
][
$key
][
'#attributes'
];
}
if
(
$form
[
'table'
][
$key
][
'weight'
][
'#default_value'
]
!=
$_POST
[
'table'
][
$key
][
'weight'
])
{
$changed_key
=
$key
;
}
}
// Preserve the order of the new form while merging the previous data.
$form_order
=
array_flip
(
array_keys
(
$table_form
));
// Save the form order.
$form
[
'table'
]
=
array_merge
(
$form
[
'table'
],
$table_form
);
// Merge the data.
$form
[
'table'
]
=
array_merge
(
$form_order
,
$form
[
'table'
]);
// Put back into the correct order.
$form
[
'table'
][
$changed_key
][
'#attributes'
][
'class'
]
=
'book-changed'
;
cache_set
(
$cid
,
$form
,
'cache_form'
,
$cache
->
expire
);
// Add the special AHAH class for new content.
$form
[
'table'
][
$changed_key
][
'#attributes'
][
'class'
]
=
isset
(
$form
[
'table'
][
$changed_key
][
'#attributes'
][
'class'
])
?
$form
[
'table'
][
$changed_key
][
'#attributes'
][
'class'
]
.
' ahah-new-content'
:
'ahah-new-content'
;
// Set a message for the user to save the form.
drupal_set_message
(
t
(
'Your changes will not be saved until you click the <em>Save book pages</em> button.'
),
'warning'
);
// Prevent duplicate wrappers.
unset
(
$form
[
'#prefix'
],
$form
[
'#suffix'
]);
// Render the form.
$form
[
'#post'
]
=
$_POST
;
$form_state
=
array
(
'submitted'
=>
FALSE
);
$form
=
form_builder
(
'book_admin_edit'
,
$form
,
$form_state
);
$output
=
drupal_render
(
$form
);
drupal_json
(
array
(
'status'
=>
TRUE
,
'data'
=>
$output
));
}
}
/**
* Recursive helper to set new form weights to the tree.
*/
function
_book_admin_js_update_tree
(
&
$tree
)
{
foreach
(
$tree
as
$key
=>
$subtree
)
{
$tree
[
$key
][
'link'
][
'weight'
]
=
$_POST
[
'table'
][
$key
][
'weight'
];
$tree
[
$key
][
'link'
][
'title'
]
=
$_POST
[
'table'
][
$key
][
'title'
];
if
(
!
empty
(
$subtree
[
'below'
]))
{
_book_admin_js_update_tree
(
$tree
[
$key
][
'below'
]);
}
}
return
theme
(
'table'
,
$header
,
$rows
,
array
(
'id'
=>
'book-outline'
));
}
/**
...
...
modules/book/book.css
View file @
58852d4b
...
...
@@ -28,6 +28,9 @@
display
:
block
;
float
:
right
;
}
#book-outline
{
min-width
:
56em
;
}
.book-outline-form
.form-item
{
margin-top
:
0
;
margin-bottom
:
0
;
...
...
modules/book/book.module
View file @
58852d4b
...
...
@@ -143,13 +143,6 @@ function book_menu() {
'type'
=>
MENU_CALLBACK
,
'file'
=>
'book.pages.inc'
,
);
$items
[
'book/js/admin/%node'
]
=
array
(
'page callback'
=>
'book_admin_js_update'
,
'access callback'
=>
'_book_outline_access'
,
'access arguments'
=>
array
(
3
),
'type'
=>
MENU_CALLBACK
,
'file'
=>
'book.admin.inc'
,
);
return
$items
;
}
...
...
modules/menu/menu.admin.inc
View file @
58852d4b
...
...
@@ -165,7 +165,7 @@ function menu_overview_form_submit($form, &$form_state) {
* Theme the menu overview form into a table.
*/
function
theme_menu_overview_form
(
$form
)
{
drupal_add_tabledrag
(
'menu-overview'
,
'match'
,
'parent'
,
'menu-plid'
,
'menu-plid'
,
'menu-mlid'
);
drupal_add_tabledrag
(
'menu-overview'
,
'match'
,
'parent'
,
'menu-plid'
,
'menu-plid'
,
'menu-mlid'
,
TRUE
,
MENU_MAX_DEPTH
-
1
);
drupal_add_tabledrag
(
'menu-overview'
,
'order'
,
'sibling'
,
'menu-weight'
);
$header
=
array
(
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment