diff options
author | Gábor Hojtsy <gabor@hojtsy.hu> | 2007-10-15 19:33:27 +0000 |
---|---|---|
committer | Gábor Hojtsy <gabor@hojtsy.hu> | 2007-10-15 19:33:27 +0000 |
commit | 59150295800f9a918c26da25855e41dba78eb5b8 (patch) | |
tree | 255e14eaf09e027f568e53f93087dd6a1fd2a3b1 /modules | |
parent | 0a61aff2518f149cf3317ef47b9eb1cc7347f78e (diff) | |
download | brdo-59150295800f9a918c26da25855e41dba78eb5b8.tar.gz brdo-59150295800f9a918c26da25855e41dba78eb5b8.tar.bz2 |
#181125 by quicksketch and dmitrig01: AHAH usability improvements for book module
- book outline form reordering in real-time
- better context sensitive book parent editing
Diffstat (limited to 'modules')
-rw-r--r-- | modules/book/book.admin.inc | 137 | ||||
-rw-r--r-- | modules/book/book.css | 19 | ||||
-rw-r--r-- | modules/book/book.module | 22 | ||||
-rw-r--r-- | modules/book/book.pages.inc | 19 |
4 files changed, 165 insertions, 32 deletions
diff --git a/modules/book/book.admin.inc b/modules/book/book.admin.inc index a57bc074e..4fd1e6815 100644 --- a/modules/book/book.admin.inc +++ b/modules/book/book.admin.inc @@ -69,16 +69,26 @@ function book_admin_settings_validate($form, &$form_state) { * @ingroup forms. */ function book_admin_edit($form_state, $node) { - - drupal_set_title(check_plain($node->title)); - $form = array(); - - $form['#node'] = $node; - $form['table'] = _book_admin_table($node); - $form['save'] = array( - '#type' => 'submit', - '#value' => t('Save book pages'), - ); + drupal_set_title(check_plain($node->title)); + $form = array( + '#cache' => TRUE, + '#prefix' => '<div id="book-admin-edit-wrapper">', + '#suffix' => '</div>', + ); + + $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; } @@ -139,8 +149,8 @@ function _book_admin_table($node) { * @see book_admin_edit() */ function _book_admin_table_tree($tree, &$form) { - foreach ($tree as $data) { - $form[] = array( + foreach ($tree as $key => $data) { + $form[$key] = array( 'nid' => array('#type' => 'value', '#value' => $data['link']['nid']), 'depth' => array('#type' => 'value', '#value' => $data['link']['depth']), 'href' => array('#type' => 'value', '#value' => $data['link']['href']), @@ -169,7 +179,6 @@ function _book_admin_table_tree($tree, &$form) { * @ingroup themeable */ function theme_book_admin_table($form) { - $header = array(t('Title'), t('Weight'), array('data' => t('Operations'), 'colspan' => '3')); $rows = array(); @@ -178,14 +187,110 @@ function theme_book_admin_table($form) { foreach (element_children($form) as $key) { $nid = $form[$key]['nid']['#value']; $href = $form[$key]['href']['#value']; - $rows[] = array( - '<div style="padding-left: '. (25 * $form[$key]['depth']['#value']) .'px;">'. drupal_render($form[$key]['title']) .'</div>', + $asterisk = (isset($form[$key]['#attributes']['class']) && strpos($form[$key]['#attributes']['class'], 'book-changed') !== FALSE) ? '<span class="warning">*</span>' : ''; + $data = array( + '<div style="padding-left: '. (25 * $form[$key]['depth']['#value']) .'px;">'. drupal_render($form[$key]['title']) . $asterisk .'</div>', drupal_render($form[$key]['weight']), l(t('view'), $href), $access ? l(t('edit'), 'node/'. $nid .'/edit', array('query' => $destination)) : ' ', $access ? l(t('delete'), 'node/'. $nid .'/delete', array('query' => $destination) ) : ' ', ); + $row = array('data' => $data); + if (isset($form[$key]['#attributes'])) { + $row = array_merge($row, $form[$key]['#attributes']); + } + $rows[] = $row; } - return theme('table', $header, $rows); + 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']); + } + } +} + +/** + * Recursive helper to sort each layer of a book tree by weight. + */ +function _book_admin_sort_tree(&$tree) { + uasort($tree, '_book_admin_compare'); + foreach($tree as $key => $subtree) { + if (!empty($tree[$key]['below'])) { + _book_admin_sort_tree($tree[$key]['below']); + } + } +} + +/** + * Used by uasort() in _book_admin_sort_tree() to compare items in a book tree. + */ +function _book_admin_compare($a, $b) { + $weight = $a['link']['weight'] - $b['link']['weight']; + if ($weight) { + return $weight; + } + return strncmp($a['link']['title'], $b['link']['title']); } diff --git a/modules/book/book.css b/modules/book/book.css index 187a5c852..6e9a6912d 100644 --- a/modules/book/book.css +++ b/modules/book/book.css @@ -28,3 +28,22 @@ display: block; float: right; } +.book-outline-form .form-item { + margin-top: 0; + margin-bottom: 0; +} +#edit-book-bid-wrapper .description { + clear: both; +} +#book-admin-edit select { + margin-right: 24px; +} +#book-admin-edit select.progress-disabled { + margin-right: 0; +} +#book-admin-edit tr.ahah-new-content { + background-color: #ffd; +} +#book-admin-edit .form-item { + float: left; +}
\ No newline at end of file diff --git a/modules/book/book.module b/modules/book/book.module index 3fb34a486..da000663d 100644 --- a/modules/book/book.module +++ b/modules/book/book.module @@ -131,13 +131,19 @@ function book_menu() { 'type' => MENU_CALLBACK, 'file' => 'book.pages.inc', ); - $items['book-form-update/%/%'] = array( + $items['book/js/form'] = array( 'page callback' => 'book_form_update', - 'page arguments' => array(1, 2), 'access arguments' => array('access content'), '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; } @@ -366,14 +372,9 @@ function _book_parent_select($book_link) { * Build the common elements of the book form for the node and outline forms. */ function _book_add_form_elements(&$form, $node) { - $settings['book']['formCallback'] = url('book-form-update' , array()); - $settings['book']['formId'] = $form['#id']; - drupal_add_js($settings, 'setting'); - drupal_add_js(drupal_get_path('module', 'book') .'/book.js'); - drupal_add_js('misc/progress.js'); - // Need this for AJAX. $form['#cache'] = TRUE; + drupal_add_js("if (Drupal.jsEnabled) { $(document).ready(function() { $('#edit-book-pick-book').css('display', 'none'); }); }", 'inline'); $form['book'] = array( '#type' => 'fieldset', @@ -433,6 +434,11 @@ function _book_add_form_elements(&$form, $node) { '#description' => t('Your page will be a part of the selected book.'), '#weight' => -5, '#attributes' => array('class' => 'book-title-select'), + '#ahah' => array( + 'path' => 'book/js/form', + 'wrapper' => 'edit-book-plid-wrapper', + 'effect' => 'slide', + ), ); } diff --git a/modules/book/book.pages.inc b/modules/book/book.pages.inc index ac640141f..15dd553a3 100644 --- a/modules/book/book.pages.inc +++ b/modules/book/book.pages.inc @@ -258,9 +258,9 @@ function book_remove_form_submit($form, &$form_state) { * @return * Prints the replacement HTML in JSON format. */ -function book_form_update($build_id, $bid) { - - $cid = 'form_'. $build_id; +function book_form_update() { + $cid = 'form_'. $_POST['form_build_id']; + $bid = $_POST['book']['bid']; $cache = cache_get($cid, 'cache_form'); if ($cache) { $form = $cache->data; @@ -271,18 +271,21 @@ function book_form_update($build_id, $bid) { $book_link['bid'] = $bid; // Get the new options and update the cache. $form['book']['plid'] = _book_parent_select($book_link); - // We set an updated expiration time for the cached form using the same - // formula as used originally in function drupal_get_form() - $expire = max(ini_get('session.cookie_lifetime'), 86400); - cache_set($cid, $form, 'cache_form', $expire); + cache_set($cid, $form, 'cache_form', $cache->expire); // Build and render the new select element, then return it in JSON format. $form_state = array(); $form['#post'] = array(); $form = form_builder($form['form_id']['#value'] , $form, $form_state); $output = drupal_render($form['book']['plid']); - drupal_json(array('book' => $output)); + drupal_json(array('status' => TRUE, 'data' => $output)); + } + else { + drupal_json(array('status' => FALSE, 'data' => '')); } } + else { + drupal_json(array('status' => FALSE, 'data' => '')); + } exit(); } |