【问题标题】:Help with ajax callback and drupal_process_form帮助 ajax 回调和 drupal_process_form
【发布时间】:2010-02-02 03:54:47
【问题描述】:

我有一个通过仅在视图模式下显示的 nodeapi 添加的表单。用户可以从选择菜单中选择一个项目,他们的选择将自动保存到数据库中,并在更改时使用 hook_menu 回调。如果用户禁用了 javascript,它将使用表单 api 正常提交。这一切都很好,但现在出于安全原因,我也想通过表单 api 提交 ajax 版本。我的 form_name_submit 很简单:

function mymodule_test_form_submit($form, &$form_state) {
  global $user;
  db_query("INSERT INTO {mymodule} (nid, uid, status, created) VALUES (%d, %d, %d, " . time() . ")", $form['#parameters'][2], $user->uid, $form_state['values']['mymodule_status']);
}

我的 ajax:

$('.mysubmit').css('display', 'none');
$('.myclass').change(function() {
  $.ajax({
    type: 'POST',
    url: Drupal.settings.basePath + 'mymodule/set/' + $nid + '/' + $('.myclass').val(),
    dataType: 'json',
    data: { 'ajax' : true, 'form_build_id' : $('#mymodule-form input[name=form_build_id]').val() }
  });
});

还有我的回调函数:

function mymodule_set($nid, $status) {
  $form_build_id = $_POST['form_build_id'];
  $form_state = array('storage' => NULL, 'submitted' => FALSE);
  $form = form_get_cache($form_build_id, $form_state);
  $args = $form['#parameters'];
  $form_id = array_shift($args);
  $form['#post'] = $_POST;
  $form['#redirect'] = FALSE;
  $form['#programmed'] = FALSE;
  $form_state['post'] = $_POST;
  drupal_process_form($form_id, $form, $form_state);
}

最初我的回调函数和我的提交函数差不多,但现在我也尝试将提交函数与 ajax 一起使用。这是使用 drupal_process_form 的正确方法吗?表单是从缓存中抓取的,如果没有错误,它会被验证并提交?我正在使用本教程中的一些代码来应用我的情况:http://drupal.org/node/331941 似乎没有任何我正在尝试做的示例。我也有 $form['#cache'] = TRUE;在我的表单函数中。

drupal_process_form 如何将提交的值与原始表单进行比较以检查完整性?我是否应该将我的值添加到 form_state 中,因为使用 ajax 时表单状态将为空。卡在这个问题上几天了,希望有人对此有经验。

谢谢。

【问题讨论】:

    标签: ajax drupal forms callback


    【解决方案1】:

    过去我不得不做一些与您类似的事情并阅读您发布的相同教程,不幸的是没有太多关于此的可用信息,让我感到头疼。我不太记得细节了,但我正在查看我编写的代码,这里有一些可能对你有用的建议:

    如果您在节点表单中执行此操作,则在表单更改中添加#ahah 属性可能不起作用,我记得当时看到了一个尚未解决的问题。如果是这种情况,请使用此代码附加 ahah 绑定,您不需要“efect”、“method”或“progress”,因为您只想提交表单,而不是对其进行任何更改:

    function YOURMODULE_form_alter(&$form, $form_state, $form_id) {
      if ('YOURCONTENTTYPE_node_form' == $form_id) {
        //the only way I could make it work for exisiting fields is adding the binding "manually"
        $ahah_binding = array(
          'url'   => url('YOURCALLBACKPATH'), 
          'event' => 'change',
          'wrapper' => 'FIELD-wrapper',
          'selector' => '#FIELD',
          'effect'   => 'fade',
          'method'   => 'replace',
          'progress' => array('type' => 'throbber'),
        );
    
        drupal_add_js('misc/jquery.form.js');
        drupal_add_js('misc/ahah.js');
        drupal_add_js(array('ahah' => array('FIELDd' => $ahah_binding)), 'setting');
    
        //force the form to be cached
        $form['#cache'] = TRUE;
      }
    }
    
    • 这是我的回调函数,请注意它对您发布的教程进行了一些修改:

      function YOURMODULE_js() {
      
        // The form is generated in an include file which we need to include manually.
        include_once 'modules/node/node.pages.inc';
        // We're starting in step #3, preparing for #4.
        //I have to add the 'rebuild' element, if not an empty node was created
        $form_state = array('storage' => NULL, 'submitted' => FALSE, 'rebuild' => TRUE);
        $form_build_id = $_POST['form_build_id'];
        // Step #4.
        $form = form_get_cache($form_build_id, $form_state);
      
        // Preparing for #5.
        $args = $form['#parameters'];
        $form_id = array_shift($args);
        $form_state['post'] = $form['#post'] = $_POST;
        $form['#programmed'] = $form['#redirect'] = FALSE;
      
        // if you want to do any modification to the form values, this is the place 
      
        // Step #5.
        drupal_process_form($form_id, $form, $form_state);
        // Step #6 and #7 and #8.
        $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
      
      
        // Final rendering callback.
        drupal_json(array('status' => TRUE, 'data' => $output));
      }
      

    正如我之前所说,有些细节我已经忘记了,但也许这会对你有所帮助。

    祝你好运。

    【讨论】:

    • 感谢发帖。 nodeapi 正在添加表单,因为我只希望表单显示在节点视图上。我以前没有做过任何 AHAH,所以我会使用您发布的 form_alter 中的相同代码吗?我现在就试试看……
    • 如果表单是节点表单,那么我发布的代码应该进行一些小的修改,我唯一不能 100% 确定的是,如果 drupal_process_form 会自动调用提交函数。
    • 嗯,我看不出和以前有什么不同。 drupal 如何真正知道要比较的值是什么?还是您需要将它们添加到表单状态?如果你不这样做,表单状态不会只是空的,但我已经尝试向 form_state 添加一个值数组,但没有区别。
    • 您是否尝试过以这种方式将值添加到表单状态? $form_state['post']['FIELDNAME'][0]['value'] = '要保存的值';这应该适用于单个值字段,无论如何您应该 print_r 在表单提交中尝试修改的元素,这样您就知道期望什么值以及它是如何形成的。无论如何,我没有尝试向表单添加新值,所以我不确定您是否应该将值添加到 $form_state 或 $form,您可以同时尝试。
    • 如果这一切都失败了并且您想尝试另一种方法,您总是可以使用 drupal_execute (lullabot.com/articles/quick_and_dirty_cck_imports),但这不是一个非常“干净”的实现。很抱歉没有提供太多帮助,但我没有尝试过您需要的确切内容
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    相关资源
    最近更新 更多