- Patch #154398 by quicksketch et al: add dynamic AHAH submission properties to Forms API. This patch was ready for a long time and is somewhat of a usability improvement (enabler).
parent
4b3efeffca
commit
2ceae6ad58
|
@ -1382,6 +1382,48 @@ function expand_radios($element) {
|
||||||
return $element;
|
return $element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add AHAH information about a form element to the page to communicate with
|
||||||
|
* javascript. If #ahah_path is set on an element, this additional javascript is
|
||||||
|
* added to the page header to attach the AHAH behaviors. See ahah.js for more
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* @param $element
|
||||||
|
* An associative array containing the properties of the element.
|
||||||
|
* Properties used: ahah_event, ahah_path, ahah_wrapper, ahah_parameters,
|
||||||
|
* ahah_effect.
|
||||||
|
* @return
|
||||||
|
* None. Additional code is added to the header of the page using
|
||||||
|
* drupal_add_js.
|
||||||
|
*/
|
||||||
|
function form_expand_ahah($element) {
|
||||||
|
static $js_added = array();
|
||||||
|
|
||||||
|
// Adding the same javascript settings twice will cause a recursion error,
|
||||||
|
// we avoid the problem by checking if the javascript has already been added.
|
||||||
|
if (!isset($js_added[$element['#id']]) && isset($element['#ahah_event']) && isset($element['#ahah_path'])) {
|
||||||
|
drupal_add_js('misc/ahah.js');
|
||||||
|
drupal_add_js('misc/progress.js');
|
||||||
|
|
||||||
|
$ahah_binding = array(
|
||||||
|
'id' => $element['#id'],
|
||||||
|
'uri' => url($element['#ahah_path']),
|
||||||
|
'event' => $element['#ahah_event'],
|
||||||
|
'effect' => empty($element['#ahah_effect']) ? 'none' : $element['#ahah_effect'],
|
||||||
|
'method' => empty($element['#ahah_method']) ? 'replace' : $element['#ahah_method'],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!empty($element['#ahah_wrapper'])) {
|
||||||
|
$ahah_binding['wrapper'] = $element['#ahah_wrapper'];
|
||||||
|
}
|
||||||
|
|
||||||
|
drupal_add_js(array('ahah' => array($element['#id'] => $ahah_binding)), 'setting');
|
||||||
|
|
||||||
|
$js_added[$element['#id']] = TRUE;
|
||||||
|
}
|
||||||
|
return $element;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a form item.
|
* Format a form item.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
// $Id$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides AJAX-like page updating via AHAH (Asynchronous HTML and HTTP).
|
||||||
|
*
|
||||||
|
* AHAH is a method of making a request via Javascript while viewing an HTML
|
||||||
|
* page. The request returns a small chunk of HTML, which is then directly
|
||||||
|
* injected into the page.
|
||||||
|
*
|
||||||
|
* Drupal uses this file to enhance form elements with #ahah_path and
|
||||||
|
* #ahah_wrapper properties. If set, this file will automatically be included
|
||||||
|
* to provide AHAH capabilities.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches the ahah behaviour to each ahah form element.
|
||||||
|
*/
|
||||||
|
Drupal.behaviors.ahah = function(context) {
|
||||||
|
for (var base in Drupal.settings.ahah) {
|
||||||
|
if (!$('#'+ base + '.ahah-processed').size()) {
|
||||||
|
var element = Drupal.settings.ahah[base];
|
||||||
|
var ahah = new Drupal.ahah(base, element);
|
||||||
|
$('#'+ base).addClass('ahah-processed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AHAH object.
|
||||||
|
*/
|
||||||
|
Drupal.ahah = function(base, element) {
|
||||||
|
// Set the properties for this object.
|
||||||
|
this.id = '#' + base;
|
||||||
|
this.event = element.event;
|
||||||
|
this.uri = element.uri;
|
||||||
|
this.wrapper = '#'+ element.wrapper;
|
||||||
|
this.effect = element.effect;
|
||||||
|
this.method = element.method;
|
||||||
|
if (this.effect == 'none') {
|
||||||
|
this.showEffect = 'show';
|
||||||
|
this.hideEffect = 'hide';
|
||||||
|
}
|
||||||
|
else if (this.effect == 'fade') {
|
||||||
|
this.showEffect = 'fadeIn';
|
||||||
|
this.hideEffect = 'fadeOut';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.showEffect = this.effect + 'Toggle';
|
||||||
|
this.hideEffect = this.effect + 'Toggle';
|
||||||
|
}
|
||||||
|
Drupal.redirectFormButton(this.uri, $(this.id).get(0), this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for the form redirection submission.
|
||||||
|
*/
|
||||||
|
Drupal.ahah.prototype.onsubmit = function () {
|
||||||
|
// Insert progressbar and stretch to take the same space.
|
||||||
|
this.progress = new Drupal.progressBar('ahah_progress');
|
||||||
|
this.progress.setProgress(-1, Drupal.t('Please wait...'));
|
||||||
|
|
||||||
|
var wrapper = $(this.wrapper);
|
||||||
|
var button = $(this.id);
|
||||||
|
var progress_element = $(this.progress.element);
|
||||||
|
|
||||||
|
progress_element.css('float', 'left').css({
|
||||||
|
display: 'none',
|
||||||
|
width: '10em',
|
||||||
|
margin: '0 0 0 20px'
|
||||||
|
});
|
||||||
|
button.css('float', 'left').attr('disabled', true).after(progress_element);
|
||||||
|
eval('progress_element.' + this.showEffect + '()');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for the form redirection completion.
|
||||||
|
*/
|
||||||
|
Drupal.ahah.prototype.oncomplete = function (data) {
|
||||||
|
var wrapper = $(this.wrapper);
|
||||||
|
var button = $(this.id);
|
||||||
|
var progress_element = $(this.progress.element);
|
||||||
|
var new_content = $('<div>' + data + '</div>');
|
||||||
|
|
||||||
|
Drupal.freezeHeight();
|
||||||
|
|
||||||
|
// Remove the progress element.
|
||||||
|
progress_element.remove();
|
||||||
|
|
||||||
|
// Hide the new content before adding to page.
|
||||||
|
new_content.hide();
|
||||||
|
|
||||||
|
// Add the form and re-attach behavior.
|
||||||
|
if (this.method == 'replace') {
|
||||||
|
wrapper.empty().append(new_content);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
eval('wrapper.' + this.method + '(new_content)');
|
||||||
|
}
|
||||||
|
eval('new_content.' + this.showEffect + '()');
|
||||||
|
button.css('float', 'none').attr('disabled', false);
|
||||||
|
|
||||||
|
Drupal.attachBehaviors(new_content);
|
||||||
|
Drupal.unfreezeHeight();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for the form redirection error.
|
||||||
|
*/
|
||||||
|
Drupal.ahah.prototype.onerror = function (error) {
|
||||||
|
alert(Drupal.t('An error occurred:\n\n@error', { '@error': error }));
|
||||||
|
// Remove progressbar.
|
||||||
|
$(this.progress.element).remove();
|
||||||
|
this.progress = null;
|
||||||
|
// Undo hide.
|
||||||
|
$(this.wrapper).show();
|
||||||
|
// Re-enable the element.
|
||||||
|
$(this.id).css('float', 'none').attr('disabled', false);
|
||||||
|
};
|
|
@ -103,9 +103,8 @@ function system_elements() {
|
||||||
$type['form'] = array('#method' => 'post', '#action' => request_uri());
|
$type['form'] = array('#method' => 'post', '#action' => request_uri());
|
||||||
|
|
||||||
// Inputs
|
// Inputs
|
||||||
$type['checkbox'] = array('#input' => TRUE, '#return_value' => 1);
|
$type['submit'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => TRUE, '#ahah_event' => 'submit', '#process' => array('form_expand_ahah'));
|
||||||
$type['submit'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => TRUE);
|
$type['button'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => FALSE, '#ahah_event' => 'submit', '#process' => array('form_expand_ahah'));
|
||||||
$type['button'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => FALSE);
|
|
||||||
$type['textfield'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#autocomplete_path' => FALSE);
|
$type['textfield'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#autocomplete_path' => FALSE);
|
||||||
$type['password'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128);
|
$type['password'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128);
|
||||||
$type['password_confirm'] = array('#input' => TRUE, '#process' => array('expand_password_confirm'));
|
$type['password_confirm'] = array('#input' => TRUE, '#process' => array('expand_password_confirm'));
|
||||||
|
@ -113,6 +112,7 @@ function system_elements() {
|
||||||
$type['radios'] = array('#input' => TRUE, '#process' => array('expand_radios'));
|
$type['radios'] = array('#input' => TRUE, '#process' => array('expand_radios'));
|
||||||
$type['radio'] = array('#input' => TRUE, '#default_value' => NULL);
|
$type['radio'] = array('#input' => TRUE, '#default_value' => NULL);
|
||||||
$type['checkboxes'] = array('#input' => TRUE, '#process' => array('expand_checkboxes'), '#tree' => TRUE);
|
$type['checkboxes'] = array('#input' => TRUE, '#process' => array('expand_checkboxes'), '#tree' => TRUE);
|
||||||
|
$type['checkbox'] = array('#input' => TRUE, '#return_value' => 1);
|
||||||
$type['select'] = array('#input' => TRUE, '#size' => 0, '#multiple' => FALSE);
|
$type['select'] = array('#input' => TRUE, '#size' => 0, '#multiple' => FALSE);
|
||||||
$type['weight'] = array('#input' => TRUE, '#delta' => 10, '#default_value' => 0, '#process' => array('process_weight'));
|
$type['weight'] = array('#input' => TRUE, '#delta' => 10, '#default_value' => 0, '#process' => array('process_weight'));
|
||||||
$type['date'] = array('#input' => TRUE, '#process' => array('expand_date' => array()), '#element_validate' => array('date_validate'));
|
$type['date'] = array('#input' => TRUE, '#process' => array('expand_date' => array()), '#element_validate' => array('date_validate'));
|
||||||
|
|
|
@ -368,9 +368,6 @@ function upload_form_alter(&$form, $form_state, $form_id) {
|
||||||
if (isset($form['type']) && isset($form['#node'])) {
|
if (isset($form['type']) && isset($form['#node'])) {
|
||||||
$node = $form['#node'];
|
$node = $form['#node'];
|
||||||
if ($form['type']['#value'] .'_node_form' == $form_id && variable_get("upload_$node->type", TRUE)) {
|
if ($form['type']['#value'] .'_node_form' == $form_id && variable_get("upload_$node->type", TRUE)) {
|
||||||
drupal_add_js('misc/progress.js');
|
|
||||||
drupal_add_js('misc/upload.js');
|
|
||||||
|
|
||||||
// Attachments fieldset
|
// Attachments fieldset
|
||||||
$form['attachments'] = array(
|
$form['attachments'] = array(
|
||||||
'#type' => 'fieldset',
|
'#type' => 'fieldset',
|
||||||
|
@ -384,7 +381,7 @@ function upload_form_alter(&$form, $form_state, $form_id) {
|
||||||
'#weight' => 30,
|
'#weight' => 30,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Wrapper for fieldset contents (used by upload JS).
|
// Wrapper for fieldset contents (used by ahah.js).
|
||||||
$form['attachments']['wrapper'] = array(
|
$form['attachments']['wrapper'] = array(
|
||||||
'#prefix' => '<div id="attach-wrapper">',
|
'#prefix' => '<div id="attach-wrapper">',
|
||||||
'#suffix' => '</div>',
|
'#suffix' => '</div>',
|
||||||
|
@ -633,12 +630,6 @@ function _upload_form($node) {
|
||||||
|
|
||||||
if (user_access('upload files')) {
|
if (user_access('upload files')) {
|
||||||
$limits = _upload_file_limits($user);
|
$limits = _upload_file_limits($user);
|
||||||
|
|
||||||
// This div is hidden when the user uploads through JS.
|
|
||||||
$form['new'] = array(
|
|
||||||
'#prefix' => '<div id="attach-hide">',
|
|
||||||
'#suffix' => '</div>',
|
|
||||||
);
|
|
||||||
$form['new']['upload'] = array(
|
$form['new']['upload'] = array(
|
||||||
'#type' => 'file',
|
'#type' => 'file',
|
||||||
'#title' => t('Attach new file'),
|
'#title' => t('Attach new file'),
|
||||||
|
@ -649,14 +640,13 @@ function _upload_form($node) {
|
||||||
'#type' => 'submit',
|
'#type' => 'submit',
|
||||||
'#value' => t('Attach'),
|
'#value' => t('Attach'),
|
||||||
'#name' => 'attach',
|
'#name' => 'attach',
|
||||||
'#id' => 'attach-button',
|
'#ahah_path' => 'upload/js',
|
||||||
|
'#ahah_wrapper' => 'attach-wrapper',
|
||||||
'#submit' => array(),
|
'#submit' => array(),
|
||||||
);
|
);
|
||||||
// The class triggers the js upload behaviour.
|
|
||||||
$form['attach-url'] = array('#type' => 'hidden', '#value' => url('upload/js', array('absolute' => TRUE)), '#attributes' => array('class' => 'upload'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needed for JS.
|
// This value is used in upload_js().
|
||||||
$form['current']['vid'] = array('#type' => 'hidden', '#value' => isset($node->vid) ? $node->vid : 0);
|
$form['current']['vid'] = array('#type' => 'hidden', '#value' => isset($node->vid) ? $node->vid : 0);
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
@ -708,6 +698,7 @@ function upload_load($node) {
|
||||||
function upload_js() {
|
function upload_js() {
|
||||||
// We only do the upload.module part of the node validation process.
|
// We only do the upload.module part of the node validation process.
|
||||||
$node = (object)$_POST;
|
$node = (object)$_POST;
|
||||||
|
$files = isset($_POST['files']) ? $_POST['files'] : array();
|
||||||
|
|
||||||
// Load existing node files.
|
// Load existing node files.
|
||||||
$node->files = upload_load($node);
|
$node->files = upload_load($node);
|
||||||
|
@ -725,8 +716,13 @@ function upload_js() {
|
||||||
drupal_alter('form', $form, array(), 'upload_js');
|
drupal_alter('form', $form, array(), 'upload_js');
|
||||||
$form_state = array('submitted' => FALSE);
|
$form_state = array('submitted' => FALSE);
|
||||||
$form = form_builder('upload_js', $form, $form_state);
|
$form = form_builder('upload_js', $form, $form_state);
|
||||||
// @todo: Put status messages inside wrapper, instead of above so they do not
|
|
||||||
// persist across ajax reloads.
|
// Maintain the list and delete checkboxes values.
|
||||||
|
foreach ($files as $fid => $file) {
|
||||||
|
$form['files'][$fid]['list']['#value'] = isset($file['list']) ? 1 : 0;
|
||||||
|
$form['files'][$fid]['remove']['#value'] = isset($file['remove']) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
$output = theme('status_messages') . drupal_render($form);
|
$output = theme('status_messages') . drupal_render($form);
|
||||||
|
|
||||||
// We send the updated file attachments form.
|
// We send the updated file attachments form.
|
||||||
|
|
Loading…
Reference in New Issue