AJAX 表单验证并提交

Posted

技术标签:

【中文标题】AJAX 表单验证并提交【英文标题】:AJAX form validate and submit 【发布时间】:2011-12-15 17:28:00 【问题描述】:

我在 Drupal 7 中创建了一个表单并想使用 AJAX。我将此添加到提交按钮数组中:

"#ajax" => array(
  "callback" => "my_callback",
  "wrapper" => "details-container",
  "effect" => "fade"
)

这可行,但整个验证功能被忽略。如何在调用 my_callback() 之前验证表单?以及如何在 AJAX 表单上显示状态或错误消息?

【问题讨论】:

您的肯定验证是否被忽略?我已经这样做了几十次,并且验证从未被忽略(除非我明确告诉 Drupal 使用 #limit_validation_errors 忽略它们)。此外,默认情况下,错误消息会自动加载到wrapper 元素中,因此一旦您修复了第一个位,它应该就位。你能发布更多你的代码吗? @Clive 我刚刚制作了另一个测试表,结果相同。表格如下: function dr_search_test_form($form, &$fstate) $form["wrapper"] = array( "#markup" => "" ); $form["name"] = array("#type" => "textfield", "#required" => true, "#title" => "Name"); $form["submit"] = array("#type" => "submit", "#value" => "Send", "#ajax" => array("callback" => "dr_search_test_form_callback", "wrapper" => "test-ajax", "效果" => "fade" ) );返回$表格; 函数 dr_search_test_form_callback($form, &$fstate) return "sadsadas"; function dr_search_test_form_validate($form, &$fstate) form_set_error("name", "Some error to display."); 我只看到来自回调函数“sadsadas”的文本,但没有进行验证...... 【参考方案1】:

好的,我想通了。显然你应该在你的 ajax 回调函数上返回一个数组,而不仅仅是一条短信......

类似这样的:

return array("#markup" => "<div id='wrapper'></div>");

【讨论】:

【参考方案2】:

这个问题和答案帮助我找到了正确的解决方案,但并不十分清楚。让我们这样吧。

需要非常注意的事情:

    验证错误消息将放置在指定为 #ajax['wrapper'] 的任何内容中 密切注意Drupal Forms API documentation of the ajax wrapper 所说的“替换具有此ID 的整个元素,而不仅仅是元素的内容”。 由于该元素已被替换,您最好再次提供它。 是 Marius Ilie 的答案有效的原因 - 不是因为数组和 #markup,而是因为他包含了带有包装器 ID 集的 div。

根据 Marius 在上述评论中的内容,这是对我有用的代码:

function dr_search_test_form($form, &$fstate) 
  $form["wrapper"] = array("#markup" => "<div id='test-ajax'></div>");

  $form["name"] = array(
    "#type" => "textfield",
    "#required" => true,
    "#title" => "Name"
  );

  $form["submit"] = array(
    "#type" => "submit",
    "#value" => t("Send"),
    "#ajax" => array(
      "callback" => "dr_search_test_form_callback",
      "wrapper" => "test-ajax",
      "effect" => "fade",
    ),
  );
  return $form;


function dr_search_test_form_callback($form, &$fstate) 
  return "<div id='test-ajax'>Wrapper Div</div>";


function dr_search_test_form_validate($form, &$fstate) 
  form_set_error("name", "Some error to display.");

【讨论】:

+1 用于在问题结束后分享您的经验;这是真正的社区问答。 工作正常。提交后如何清除表单值?【参考方案3】:

这些都不适合我。表单提交的ajax函数仍然只是直接调用回调函数,绕过验证,提交,也使得按钮不能被多次点击。不会显示验证消息。我从字面上复制并粘贴了 Joshua Stewardson 代码,但它不起作用。

这个用例如此困难且没有记录的事实令人非常沮丧。对我来说,这似乎是对 AJAX 表单 API 的最基本请求。好的,我的挫败感说完,就解决问题了。

这就是我最终为使其正常工作所做的工作。感觉很笨拙和迟钝。如果单个页面上有多个表单实例,它也会中断,但这是我能做的最好的。如果有人可以阐明这一点,请做!

基本上,您必须在回调中将整个表单替换为自身,并手动将任何设置的消息添加到表单对象。通过将包装器声明为表单的 id 来做到这一点(如果单个页面上有多个表单实例,它将中断,因为 ID 将被更新)。

function productsearchbar_savesearch_form($form, &$form_state) 

  $form["wrapper"] = array("#markup" => "<div class='inline-messages'></div>");

  $form["name"] = array(
    "#type" => "textfield", 
    "#required" => true,
    "#title" => "Name"
  );

  $form["submit"] = array(
    "#type" => "submit", 
    "#value" => "Send", 
    "#ajax" => array(
      "callback" => "productsearchbar_savesearch_form_callback", 
      "wrapper" => "productsearchbar-savesearch-form", 
      "effect" => "fade"
    )
  );

  return $form;


function productsearchbar_savesearch_form_callback($form, &$form_state) 
  $messages = theme('status_messages');

  if($messages)
    $form["wrapper"] = array("#markup" => "<div class='inline-messages'>$messages</div>");
  
  return $form;


function productsearchbar_savesearch_form_validate($form, &$form_state) 
  if ($form_state['values']['name'] == '') 
   form_set_error('', t('Name field is empty!'));
  


function productsearchbar_savesearch_form_submit($form, &$form_state) 
  drupal_set_message(t('Your form has been saved.'));

【讨论】:

我遇到了相反的情况,触发了 Ajax 回调,然后调用表单提交函数,提交处理程序中的消息返回 Ajax 响应,说它已保存。这不是我想要发生的。由于这会触发批处理操作。如果重要的话,这就是 Drupal 7。【参考方案4】:

//可以使用jquery表单验证

jQuery('#button-id').mousedown(function() 
  var textval = $("#get-text-val").val();
  if (textval == '') 
    $("#apend-error-msg").append('<div id="add-text-error" class="add-text-error">error msg</div>');
   return false;
  
  else 
    return true;
  
  return false;
 );

【讨论】:

当您想要检查的不仅仅是字符串长度时,在 Drupal 之外进行验证可能会出现问题。【参考方案5】:

我找到了一个很好的解决这个问题的方法。

感谢这个人的博客:

http://saw.tl/validate-form-ajax-submit-callback

他提出的解决方案如下:

// when creating or altering the form..

  $form['#prefix'] = '<div id="formwrapper">';
  $form['#suffix'] = '</div>';
  // the submit button
  $form['save']['#ajax'] = array(
    'callback' => 'mymodule_form_ajax_submit',
    'wrapper' => 'formwrapper',
    'method' => 'replace',
    'effect' => 'fade',
  );
 // ...


function mymodule_from_ajax_submit($form, &$form_state) 
  // validate the form
  drupal_validate_form('mymodule_form_id', $form, $form_state);
  // if there are errors, return the form to display the error messages
  if (form_get_errors()) 
    $form_state['rebuild'] = TRUE;
    return $form;
  
  // process the form
  mymodule_form_id_submit($form, $form_state);
  $output = array(
    '#markup' => 'Form submitted.'
  );
  // return the confirmation message
  return $output;

【讨论】:

$form['#prefix'] 和 $form['#suffix'] 在我的 _form_alter 挂钩中不起作用。 @AlxVallejo 它应该适用于表单的任何元素,包括表单本身。查看Form API Reference【参考方案6】:

我花了好几个小时寻找正确执行此操作的方法。不幸的是,这些解决方案中的大多数仍然依赖 Drupal 的服务器端验证来确定是否应该将 ajax 结果或客户端错误消息放在包装器中。依赖服务器结果比客户端验证要慢,客户端验证应该几乎是即时的。此外,将表单...替换为表单...错误消息对于我的偏好来说有点太混乱了。

使用 jquery 验证的方法通过 javascript 触发器触发 ajax 事件:

// Prevent form submission when there are client-side errors, trigger ajax event when it is valid
(function ($) 
    Drupal.behaviors.submitForm =  
        attach: function (context) 
            var $form = $("form#validated_form", context);
            var $submitButton = $('input[type="submit"]', $form);

            $form
                .once('submitForm')
                .off('submit')
                .on('submit', function(e)

                    // Prevent normal form submission
                    e.preventDefault();
                    var $form = $(this);

                    // The trigger value should match what you have in your $form['submit'] array's ajax array
                    //if the form is valid, trigger the ajax event
                    if($form.valid()) 
                        $submitButton.trigger('submit_form');
                    
            );

        
    ;
)(jQuery);

引用 javascript 触发器作为您要监听的 ajax 事件:

$form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
    '#ajax' => array(
      'event' => 'submit_form',
      'callback' => 'callback_function_for_when_form_is_valid',
      'wrapper' => 'validated_form'
    )
);

现在,只要点击提交按钮就会触发验证,服务器端验证只有在有效时才会发生!

【讨论】:

以上是关于AJAX 表单验证并提交的主要内容,如果未能解决你的问题,请参考以下文章

jQuery在使用ajax验证后提交表单

使用Ajax验证并提交Django表单(django-crispy-forms)

bootstrap 表单验证FormValidation ajax提交后怎么恢复初始状态

如何在 ajax 调用中提交表单之前调用 javascript 验证函数

使用 ajax 验证 jquery / 标准 javascript 提交表单

验证表单输入,然后单击启动 ajax 请求