欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Custom beforeSubmit for AHAH elements

(sorry for my english)

I'd like to offer to implement ability to call custom beforeSubmit handlers.

Hack:

form.inc - form_expand_ahah()

      'button'   => isset($element['#executes_submit_callback']) ? array($element['#name'] => $element['#value']) : FALSE,
//new - begin
      //'before'   => empty($element['#ahah']['before_submit']) ? array() : (is_scalar($element['#ahah']['before_submit']) ? array($element['#ahah']['before_submit']) : $element['#ahah']['before_submit']),
      'before'   => empty($element['#ahah']['before_submit']) ? array() : $element['#ahah']['before_submit'], // for better extensibility
//new - end
    );

ahah.js - "Drupal.ahah = function(base, element_settings) {...}"

  this.button = element_settings.button || { };
//new - begin
  this.before = element_settings.before;
//new - end

ahah.js - "Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) {...}"

Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) {
//new - begin
  for( var i in this.before )
    if( eval(this.before[i] + '(form_values, element, options)') == false )
      return false;
//new - end

Use example:

A form builder function

//...
      'delete' => array(
        '#type' => 'submit',
        '#value' => t('Delete'),
        '#ahah' => array(
          'path' => '.../delete/'.$id,
          'wrapper' => 'content',
          'method' => 'replace',
          'effect' => 'fade',
          'before_submit' => array('our_custom_delete_before_submit_handler'),
        ),
      ),
//...

our JS function our_custom_delete_before_submit_handler()

function our_custom_delete_before_submit_handler(form_values, element, options)
{
  return confirm('The whole content will be unrecoverably deleted! Are you sure?');
}

Comments

liquixis’s picture

 

Update:

Hack

form.inc - form_expand_ahah()

      'button'   => isset($element['#executes_submit_callback']) ? array($element['#name'] => $element['#value']) : FALSE,
    );

//[new]
    // Store callbacks
    foreach( array('before_submit', 'after_submit', 'before_success', 'after_success') as $callback_name )
      $ahah_binding[$callback_name] = empty($element['#ahah'][$callback_name]) ? NULL : $element['#ahah'][$callback_name];

    // Prepare callbacks
    // Moved to "ahah.js" for purpose to move cpu load from server to client
    /*foreach( array('before', 'after') as $kind_name )
      foreach( $ahah_binding[$kind_name] as $key => &$value )
        if( is_scalar($value) )
          $value = array('type' => 'function', 'callback' => $value, 'params' => array());
        else if( is_array($value) )
        {
          if( !isset($value['type']) )
            $value['type'] = 'function'; //'code';

          if( !isset($value['params']) )
            $value['params'] = array();
        }*/
//[/new]

    // Convert a simple #ahah[progress] type string into an array.

ahah.js - "Drupal.ahah = function(base, element_settings) {...}"

  this.button = element_settings.button || { };

//[new]
  // Prepare callbacks
  var callback_kinds = ['before_submit', 'after_submit', 'before_success', 'after_success'];
  for( var i in callback_kinds)
  {
    var callback_kind = callback_kinds[i];

    this[callback_kind] = element_settings[callback_kind];

    var callbacks = this[callback_kind];

    for( var j in callbacks )
    {
      var callback = callbacks[j];

      if( typeof callback == 'string' )
        callbacks[j] = {'type' : 'function', 'callback' : callback, 'params' : []};
      else if( typeof callback == 'object' )
      {
        if( !callback['type'] )
          callback['type'] = 'function';

        if( !callback['params'] )
          callback['params'] = {};
      }
    }
  }
//[/new]

  if (this.effect == 'none') {

ahah.js - new function - before "Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) {...}"

//[new]
/**
 * Callback caller.
 */
Drupal.ahah.prototype.call_callbacks = function (callbacks, args, breakable)
{
  breakable = (typeof breakable == 'undefined') ? false : breakable;

  for( var i in callbacks )
  {
    var callback = callbacks[i];

    var params = callback['params'];

    var eval_code;
    switch( callback['type'] )
    {
    case 'function':
      eval_code = callback['callback'] + '(args, params)';
      break;
    case 'code':
      eval_code = 'function callback(args, params) {' + callback['callback'] + '}; callback(args, params)';
      break;
    case 'expression':
      eval_code = 'function callback(args, params) { return ' + callback['callback'] + '; }; callback(args, params)';
      break;
    default:
      return true;
    }

    var result = eval(eval_code);

    if( breakable && (result == false) )
      return false;
  }
}
//[/new]

ahah.js - "Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) {...}"

Drupal.ahah.prototype.beforeSubmit = function (form_values, element, options) {
//[new]
  // Call before_submit callbacks
  if( this.call_callbacks(this.before_submit, {'form_values' : form_values, 'element' : element, 'options' : options}, true) == false )
    return false;
//[/new]

//...

//[new]
  // Call after_submit callbacks
  this.call_callbacks(this.after_submit, {'form_values' : form_values, 'element' : element, 'options' : options});
//[/new]
};

ahah.js - "Drupal.ahah.prototype.success = function (response, status) {...}"

Drupal.ahah.prototype.success = function (response, status) {
//[new]
  // Call before_success callbacks
  this.call_callbacks(this.before_success, {'response' : response, 'status' : status});
//[/new]

//...

//[new]
  // Call after_success callbacks
  this.call_callbacks(this.after_success, {'response' : response, 'status' : status});
//[/new]
};
Documentation

There are four types of callbacks:
before_submit - Executes before AHAH submit (if callback returns FALSE then the operation interrupt: next callbacks and AHAH submit are not executed )
after_submit - Executes immediately after AHAH submit
before_success - Executes immediately after successful AHAH submit and before it's default Drupal processing
after_success - Executes after successful AHAH submit and after it's default Drupal processing

Each callback has next arguments:
"args" (object) - AHAH data.
- in case of "before_submit" and "after_submit" this will be (in JS): {'form_values' : form_values, 'element' : element, 'options' : options}
- in case of "before_success" and "after_success" this will be (in JS): {'response' : response, 'status' : status}
"params" (object) - params defined in callback definition ( #ahah['<callback_type>'][<callback_index>]['params'] )

In all callbacks you can set (override) "args" object items values to your values.
This will be useful in case of overriding successful AHAH submit result in "before_success" callback, e.g.:
function mymodule_submit_button_before_success(args, params) { args['response']['data'] = '<div class="my-content-wrapper">' + args['response']['data'] + '</div>'; }

Examples
// Function callbacks (they are all same)
'before_submit' => array('mymodule_delete_button_before_submit'),
'before_submit' => array(array('callback' => 'mymodule_delete_button_before_submit')),
'before_submit' => array(array('type' => 'function', 'callback' => 'mymodule_delete_button_before_submit')),
'before_submit' => array(array('type' => 'function', 'callback' => 'mymodule_delete_button_before_submit', 'params' => array())),

// Function callbacks using params (they are all same)
'before_submit' => array(array('callback' => 'mymodule_delete_button_before_submit', 'params' => array('message' => 'Are you sure?'))),
'before_submit' => array(array('type' => 'function', 'callback' => 'mymodule_delete_button_before_submit', 'params' => array('message' => 'Are you sure?'))),

// Code callbacks
'before_submit' => array(array('type' => 'code', 'callback' => 'return confirm("Are you sure?");')),

// Code callbacks using params
'before_submit' => array(array('type' => 'code', 'callback' => 'if( params.message ) return confirm(params.message); else return confirm("Are you definitely sure?");', 'params' => array('message' => t('Are you sure?')))),

// Code callbacks using args
'after_success' => array(array('type' => 'code', 'callback' => 'alert(args["response"]["message"]);')),

// Expression callbacks
'before_submit' => array(array('type' => 'expression', 'callback' => 'confirm("Are you sure?")')),

// Expression callbacks using params
'before_submit' => array(array('type' => 'expression', 'callback' => 'params.message ? confirm(params.message) : confirm("Are you definitely sure?")', 'params' => array('message' => t('Are you sure?')))),

// Expression callbacks using args
'after_success' => array(array('type' => 'expression', 'callback' => 'alert(args["response"]["message"])')),
neochief’s picture

 

Status:Needs review» Needs work

You'd better make patch for 7.x for this, while there's a time left.

liquixis’s picture

 

Is anyone working on this currently ?
Thanks

dpearcefl’s picture

 

Priority:Critical» Normal
Status:Needs work» Closed (won't fix)

Doesn't look like it. No interest shown.

liquixis’s picture

 

I m in. This post is really helpful for me. I have CKEditor integrated in my custom form. I am using AHAH to submit my form but in AHAH submit i m not getting value of editor in $_POST variable.

So i am thinking to disable editor before ahah call & then re-enable after completion.

I tried above code for before_submit and it worked for me.

But still i think it is not better idea to hack in core

Thanks for that.


来自  https://www.drupal.org/node/461206
普通分类: