diff --git a/css/panopoly-modal.css b/css/panopoly-modal.css index 11bebd7..201f333 100644 --- a/css/panopoly-modal.css +++ b/css/panopoly-modal.css @@ -197,7 +197,7 @@ } #modal-content fieldset.widget-preview-single { - margin-top: 0em; + margin-top: 10px; margin-bottom: 1em; } diff --git a/panopoly-magic.js b/panopoly-magic.js index f52f96b..1c7dff9 100644 --- a/panopoly-magic.js +++ b/panopoly-magic.js @@ -29,9 +29,9 @@ attach: function (context, settings) { // 'this' references the form element function triggerSubmit (e) { - var $this = $(this); - if (!$this.hasClass('ctools-ajaxing')) { - $this.addClass('ctools-ajaxing'); + var $this = $(this), preview_widget = $('.widget-preview', context); + if (!preview_widget.hasClass('panopoly-magic-loading')) { + preview_widget.addClass('panopoly-magic-loading'); $this.find('.ctools-auto-submit-click').click(); } } @@ -70,16 +70,23 @@ // Special handling for link field widgets. This ensures content which is ahah'd in still properly autosubmits. $('.field-widget-link-field input:text', context).addClass('panopoly-textfield-autosubmit').addClass('ctools-auto-submit-exclude'); - // Handle title fields. + // Handle text fields and textareas. var timer; - $('.panopoly-textfield-autosubmit', context) + $('.panopoly-textfield-autosubmit, .panopoly-textarea-autosubmit', context) .once('ctools-auto-submit') - .bind('keyup keydown blur', function (e) { + .bind('keyup blur', function (e) { var $element; $element = $('.widget-preview .pane-title', context); + clearTimeout(timer); + + // Filter out discarded keys. + if (e.type !== 'blur' && $.inArray(e.keyCode, discardKeyCode) > 0) { + return; + } + // Special handling for title elements. - if (($element.length || !$.inArray(e.keycode, discardKeyCode)) && $(e.target).parent().hasClass('form-item-title')) { + if ($element.length && $(e.target).parent().hasClass('form-item-title')) { // If all text was removed, remove the existing title markup from the dom. if (!$(e.target).val().length) { @@ -96,13 +103,11 @@ } // Automatically submit the field on blur. This won't happen if title markup is already present. else if (e.type == 'blur') { - clearTimeout(timer); triggerSubmit.call(e.target.form) } // If all else fails, just trigger a timer to submit the form a second after the last activity. else { - clearTimeout(timer); - timer = setTimeout(function () { triggerSubmit.call(e.target.form); }, 1000) + timer = setTimeout(function () { triggerSubmit.call(e.target.form); }, 1000); } }); @@ -113,22 +118,6 @@ triggerSubmit.call(e.target.form); }); - // Handle textarea fields. - $('.panopoly-textarea-autosubmit', context) - .once('ctools-auto-submit') - .bind('keyup keydown blur', function (e) { - // On blur just autosubmit the form. - if (e.type == 'blur') { - clearTimeout(timer); - triggerSubmit.call(e.target.form) - } - // Otherwise set a 1 second delay on anything that's a valid keypress. - else { - clearTimeout(timer); - timer = setTimeout(function () { triggerSubmit.call(e.target.form); }, 1000) - } - }); - // Prevent ctools auto-submit from firing when changing text formats. $(':input.filter-list').addClass('ctools-auto-submit-exclude'); diff --git a/panopoly_magic.module b/panopoly_magic.module index 70966f9..4bc84a3 100644 --- a/panopoly_magic.module +++ b/panopoly_magic.module @@ -1,5 +1,4 @@ 'AHAH callback', + 'page callback' => 'panopoly_magic_ajax_form_callback', + 'delivery callback' => 'ajax_deliver', + 'access callback' => TRUE, + 'theme callback' => 'ajax_base_page_theme', + 'type' => MENU_CALLBACK, + 'file path' => 'includes', + 'file' => 'form.inc', + ); + return $items; +} + +/** + * Replaces system/ajax for pane configuration preview callback to work with + * ctools multi step form. + */ +function panopoly_magic_ajax_form_callback() { + list($form, $form_state) = ajax_get_form(); + ctools_include('content'); + ctools_include('modal'); + + if (isset($form_state['no_redirect']) && !isset($form_state['form_info'])) { + $form_state += array( + 're_render' => FALSE, + 'no_redirect' => !empty($form_state['ajax']), + ); + $form = drupal_build_form($form_state['build_info']['form_id'], $form_state); + } + else { + // These ensure the class files/form definations are included. + $content_type = ctools_get_content_type($form_state['pane']->type); + $subtype = ctools_content_get_subtype($content_type, $form_state['subtype_name']); + + $form = ctools_content_form($form_state['op'], $form_state['form_info'], $form_state, $form_state['plugin'], $form_state['subtype_name'], $form_state['conf'], $form_state['step']); + } + + if (!empty($form_state['triggering_element'])) { + $callback = $form_state['triggering_element']['#ajax']['callback']; + } + if (!empty($callback) && function_exists($callback)) { + return $callback($form, $form_state); + } +} + +/** * Implements hook_apps_app_info() */ function panopoly_magic_apps_app_info() { @@ -176,7 +225,7 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) { $style = (isset($pane->style['style'])) ? panels_get_style($pane->style['style']) : NULL; } elseif ($form_id == 'panels_edit_style_type_form') { - $style = ($form_state['rebuild'] && $form_id == 'panels_edit_style_type_form') ? panels_get_style($form_state['values']['style']) : panels_get_style($form_state['style']); + $style = ($form_state['rebuild'] && $form_id == 'panels_edit_style_type_form') ? panels_get_style($form_state['input']['style']) : panels_get_style($form_state['style']); } elseif ($form_id == 'panels_edit_style_settings_form') { $style = panels_get_style($form_state['style']); @@ -269,21 +318,21 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) { unset($configuration['image_link']); } } - $content = (empty($preview_subtype)) ? ctools_content_render($pane->type, $pane->subtype, $configuration, $keywords, $args, $context) : ctools_content_render($pane->type, $preview_subtype, $configuration, $keywords, $args, $context); - - // Create the preview fieldset - if ($form_id == 'fieldable_panels_panes_fieldable_panels_pane_content_type_edit_form' || is_object($content)) { - // Create the fieldset with appropriate content - $form['widget_preview'] = array( - '#type' => 'fieldset', - '#title' => t('Preview'), - '#attributes' => array('class' => array('widget-preview', 'widget-preview-single')), - '#collapsible' => FALSE, - '#weight' => -100, - ); - $form['widget_preview']['preview'] = array( - '#markup' => (!empty($style['render pane'])) ? theme($style['render pane'], array('content' => $content, 'pane' => $pane, 'display' => $display, 'style' => $style, 'settings' => $pane->style['settings'])) : theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display)), + // only render preview for Panes and not Regions + if (isset($pane)) { + // Creates preview outside of form itself to fix various bugs, like form + // inside form and double rendering. + $form['#post_render'][] = 'panopoly_magic_form_post_render_preview'; + $form['#panopoly_magic_preview_info'] = array( + 'preview_subtype' => isset($preview_subtype) ? $preview_subtype : NULL, + 'pane' => $pane, + 'configuration' => $configuration, + 'keywords' => $keywords, + 'args' => $args, + 'context' => $context, + 'style' => $style, + 'display' => $display, ); // Remove the clearfix for preview floating @@ -294,7 +343,6 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) { $preview_attributes = array( 'class' => array( 'widget-preview-button', - 'ctools-use-ajax', ), ); @@ -308,17 +356,23 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) { $form['buttons']['preview'] = array( '#type' => 'button', '#value' => t('Update Preview'), - '#wizard type' => 'next', '#attributes' => $preview_attributes, + '#ajax' => array( + 'callback' => 'panopoly_magic_ajax_update_preview', + 'wrapper' => 'panopoly-form-widget-preview', + 'path' => 'system/panopoly-magic', + ), ); // Autosubmit the form ctools_add_js('auto-submit'); $form['#attributes']['class'][] = 'ctools-auto-submit-full-form'; } + // Convert any other #ajax enabled buttons to use system/panopoly-magic. + _panopoly_magic_add_path_to_ajax($form); } - /** + /** * Globally improve the buttons for the Chaos Tools Content Type Settings Forms */ if (strpos($form_id, 'content_type_edit_form') || $form_id == 'ctools_entity_field_content_type_formatter_options') { @@ -326,7 +380,7 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) { if (!empty($form['buttons']['return'])) { $form['buttons']['return']['#value'] = t('Save'); } - $form['buttons']['#weight'] = (!empty($form['widget_preview']['#weight'])) ? ($form['widget_preview']['#weight'] +1 ): -99; + $form['buttons']['#weight'] = -99; } /** @@ -382,6 +436,57 @@ function panopoly_magic_form_alter(&$form, &$form_state, $form_id) { } /** + * Content panes should not use default system/ajax. Use our own for now. + */ +function _panopoly_magic_add_path_to_ajax($element) { + if (!empty($element['#ajax']) && !isset($element['#ajax']['path'])) { + $element['#ajax']['path'] = 'system/panopoly-magic'; + } + foreach (element_children($element) as $key) { + _panopoly_magic_add_path_to_ajax($element[$key]); + } +} + +/** + * Ajax callback that just returns the rendered preview. + */ +function panopoly_magic_ajax_update_preview($form, $form_state) { + if (isset($form_state['values']) && isset($form['#panopoly_magic_preview_info']['configuration'])) { + $form['#panopoly_magic_preview_info']['configuration'] = $form_state['values'] + $form['#panopoly_magic_preview_info']['configuration']; + } + return panopoly_magic_form_post_render_preview('', $form); +} + +/** + * Add the preview to the form output. + * + * It is done here so the form is fully processed. + */ +function panopoly_magic_form_post_render_preview($output, $form) { + extract($form['#panopoly_magic_preview_info']); + $content = (empty($preview_subtype)) ? ctools_content_render($pane->type, $pane->subtype, $configuration, $keywords, $args, $context) : ctools_content_render($pane->type, $preview_subtype, $configuration, $keywords, $args, $context); + + // Create the fieldset with appropriate content + $preview = array( + '#type' => 'fieldset', + '#title' => 'Preview', + '#attributes' => array( + 'id' => 'panopoly-form-widget-preview', + 'class' => array('widget-preview', 'widget-preview-single'), + ), + '#collapsible' => FALSE, + '#weight' => -100, + ); + if (!empty($content)) { + $preview['preview']['#markup'] = (!empty($style['render pane'])) ? theme($style['render pane'], array('content' => $content, 'pane' => $pane, 'display' => $display, 'style' => $style, 'settings' => $pane->style['settings'])) : theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display)); + } + else { + $preview['preview']['#markup'] = t('[no preview]'); + } + return drupal_render($preview) . $output; +} + +/** * Recursively parse form elements to add special autosubmit handling on a per field-type basis. */ function panopoly_magic_autosubmit_configure(&$element) { @@ -709,7 +814,6 @@ function panopoly_magic_form_views_content_views_panes_content_type_edit_form_al // Add a custom submit handler to our preview and submit option $form['#submit'][] = 'panopoly_magic_views_content_type_modal_submit'; - $form['buttons']['preview']['#submit'][] = 'panopoly_magic_views_content_type_modal_submit'; } /**