jQuery AJAX 表单验证并提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7903073/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 00:25:25  来源:igfitidea点击:

AJAX form validate and submit

jqueryajaxdrupal-7drupal-forms

提问by Marius Ilie

I created a form in Drupal 7 and want to use AJAX. I added this to the submit button array:

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

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

This works but the whole validation function is ignored. How can I validate the form before my_callback()is called? And how can I display the status or error messages on a AJAX form?

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

采纳答案by Marius Ilie

Ok, I figure it out. Apparently you should return an array on your ajax callback function, not just a text message...

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

Something like this:

像这样的东西:

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

回答by Joshua Stewardson

This question and answer helped guide me to the right solution, but it isn't exactly crystal clear. Let's make it so.

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

Things to be veryaware of:

需要非常注意的事项:

  1. Validation error messages will be placed inside whatever is specified as the #ajax['wrapper']
  2. Pay close attention to where the Drupal Forms API documentation of the ajax wrappersays that "the entire element with this ID is replaced, not just the contents of the element."
  3. Because that element is replaced, you had better provide it again. Thatis why Marius Ilie's answer works - not because of the array and #markup, but rather because he is including the div with the wrapper id set.
  1. 验证错误消息将放置在任何指定为 #ajax['wrapper']
  2. 请密切注意ajax 包装器Drupal Forms API 文档说“替换具有此 ID 的整个元素,而不仅仅是元素的内容”。
  3. 因为那个元素被替换了,你最好重新提供它。 就是 Marius Ilie 的答案有效的原因 - 不是因为数组 and #markup,而是因为他将 div 与包装器 id 集一起包含在内。

Here is code that was working for me based off what Marius put in the comment above:

以下是根据 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.");
}

回答by bmunslow

I found an excellent solution to this problem.

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

Credit goes to this guy's blog:

归功于此人的博客:

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

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

The solution he proposes is the following:

他提出的解决方案如下:

// 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;
}

回答by Brent Hartmann

None of this works for me. The form submit's ajax function still just calls the callback function directly, bypassing validation, submit, and also making it so the button cannot be clicked multiple times. The validation messages do NOT get displayed. I literally copied and pasted Joshua Stewardson code and it did not work.

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

The fact that this usage case is so hard and undocumented is very upsetting. To me, this seems like the most basic of requests for an AJAX form API. Okay, done venting my frustration, onto the solution.

这个用例如此困难且没有记录的事实非常令人沮丧。对我来说,这似乎是对 AJAX 表单 API 的最基本请求。好的,我已经把我的挫败感发泄到了解决方案上。

Here's what I ended up doing to get this to work. It feels hacky and retarded. It will also break if there are multiple instances of the form on a single page but it was the best I could do. If anyone can shed light on this PLEASE do!

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

Basically, you have to replace the whole form with itself inside your callback, and manually prepend any set messages to the form object. Do this by declaring the wrapper to be the id of your form (it will break if there are multiple instances of your form on a single page, because the ID will be updated).

基本上,您必须在回调中用自身替换整个表单,并手动将任何设置的消息添加到表单对象中。通过将包装器声明为表单的 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.'));
}

回答by CLL

I searched many hours for a way to do this properly. Unfortunately, most of these solutions still rely on Drupal's server side validation to determine whether the ajax results or the client side error messages should be placed in the wrapper. Relying on the server result is slower than client side validation, which should be virtually instantaneous. Also, replacing the form...with a form...with the error messages is a bit too messy for my preference.

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

Use jquery validation's methods to trigger an ajax event with a javascript trigger:

使用 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);

Reference the javascript trigger as your ajax event that is listened for:

引用 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'
    )
);

Now, the validation is triggered as soon as the submit button is clicked, and the server side validation only happens once it's valid!

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

回答by chathura

//you can use jquery form validation

//你可以使用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;
 });