Index: modules/book/book.module =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.module,v retrieving revision 1.442 diff -u -r1.442 book.module --- modules/book/book.module 11 Sep 2007 17:35:58 -0000 1.442 +++ modules/book/book.module 10 Oct 2007 06:59:04 -0000 @@ -131,13 +131,19 @@ '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 @@ * 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,7 +434,13 @@ '#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', + ), ); + } /** Index: modules/book/book.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.admin.inc,v retrieving revision 1.3 diff -u -r1.3 book.admin.inc --- modules/book/book.admin.inc 28 Sep 2007 15:44:13 -0000 1.3 +++ modules/book/book.admin.inc 10 Oct 2007 06:59:04 -0000 @@ -69,16 +69,26 @@ * @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' => '
', + '#suffix' => '
', + ); + + $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; } @@ -169,7 +179,6 @@ * @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,86 @@ foreach (element_children($form) as $key) { $nid = $form[$key]['nid']['#value']; $href = $form[$key]['href']['#value']; - $rows[] = array( - '
'. drupal_render($form[$key]['title']) .'
', + $asterisk = (isset($form[$key]['#attributes']['class']) && strpos($form[$key]['#attributes']['class'], 'book-changed') !== FALSE) ? '*' : ''; + $data = array( + '
'. drupal_render($form[$key]['title']) . $asterisk .'
', 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('status_messages') . theme('table', $header, $rows); +} + +function book_admin_js_update() { + + $cid = 'form_'. $_POST['form_build_id']; + $cache = cache_get($cid, 'cache_form'); + if ($cache) { + $form = $cache->data; + + // Update title and weight values in the form. + foreach (element_children($form['table']) as $key) { + if ($form['table'][$key]['weight']['#default_value'] != $_POST['table'][$key]['weight']) { + $changed_key = $key; + $form['table'][$key]['#attributes']['class'] = 'book-changed'; + } + $form['table'][$key]['title']['#default_value'] = $_POST['table'][$key]['title']; + $form['table'][$key]['weight']['#default_value'] = $_POST['table'][$key]['weight']; + } + +// $tree = book_menu_subtree_data($form['#node']->book); +// $tree_form = array(); +// _book_admin_table_tree($tree, $tree_form); +// $depths = array(); +// foreach ($tree_form as $key => $value) { +// $depths[$value['weight']['#default_value']][$key] = $value + array('key' => $key); +// } +// +// foreach ($depths as $depth) { +// uasort($depth, '_book_admin_sort'); +// foreach ($depth as $key => $value) { +// $value['title']['#default_value'] = $_POST[$key]['title']; +// $value['weight']['#default_value'] = $_POST[$key]['weight']; +// $final[$key] = $value; +// } +// } + + 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 Save book pages button.'), 'warning'); + + // Render the form. + drupal_alter('form', $form, array(), 'book_admin_edit'); + $form['#post'] = $_POST; + unset($form['#prefix'], $form['#suffix']); // Prevent duplicate wrappers. + $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)); } +} - return theme('table', $header, $rows); +/** + * Function used by uasort in book_admin_sort() to sort book arrays by weight. + */ +function _book_admin_sort($a, $b) { + $a_weight = (is_array($a) && isset($_POST['table'][$a['key']]['weight'])) ? $_POST['table'][$a['key']]['weight'] : 0; + $b_weight = (is_array($b) && isset($_POST['table'][$a['key']]['weight'])) ? $_POST['table'][$b['key']]['weight'] : 0; + if ($a_weight == $b_weight) { + return 0; + } + return ($a_weight < $b_weight) ? -1 : 1; } Index: modules/book/book.css =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.css,v retrieving revision 1.4 diff -u -r1.4 book.css --- modules/book/book.css 27 May 2007 17:57:48 -0000 1.4 +++ modules/book/book.css 10 Oct 2007 06:59:04 -0000 @@ -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 Index: modules/book/book.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/book/book.pages.inc,v retrieving revision 1.1 diff -u -r1.1 book.pages.inc --- modules/book/book.pages.inc 11 Sep 2007 17:35:58 -0000 1.1 +++ modules/book/book.pages.inc 10 Oct 2007 06:59:04 -0000 @@ -258,9 +258,9 @@ * @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 @@ $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(); } Index: modules/book/book.js =================================================================== RCS file: modules/book/book.js diff -N modules/book/book.js --- modules/book/book.js 12 Sep 2007 18:29:32 -0000 1.3 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,35 +0,0 @@ -// $Id: book.js,v 1.3 2007/09/12 18:29:32 goba Exp $ - -Drupal.behaviors.bookSelect = function(context) { - // This behavior attaches by ID, so is only valid once on a page. - if ($('#edit-book-bid.book-select-processed').size()) { - return; - } - // Hide the button in the node form, since it's not needed when JS is enabled. - $('#edit-book-pick-book').css('display', 'none'); - - // Binds a function to the keyup and change actions of the book select to - // retrieve parent options. Mark as processed so this binding is only done once. - $('#edit-book-bid') - .keyup(Drupal.bookFillSelect) - .change(Drupal.bookFillSelect) - .addClass('book-select-processed'); -}; - -// This function passes the form information and the book ID to a Drupal callback -// and retrieves a parent select with changed options to replace the one in the form. -Drupal.bookFillSelect = function() { - // Create a progress bar and substitute it for the parent select. - pb = new Drupal.progressBar('book_progress'); - pb.setProgress(-1, Drupal.t('Updating parents...')); - $('#edit-book-plid-wrapper').html(pb.element); - - $.ajax({ - url: Drupal.settings.book.formCallback +'/'+ $('#'+ Drupal.settings.book.formId +' input[name=form_build_id]').val() +'/'+ $('#edit-book-bid').val(), - dataType: 'json', - success: function(data) { - // Insert the new select, and remove the progress bar. - $('#edit-book-plid-wrapper').after(data['book']).remove(); - } - }); -};