简体   繁体   English

你如何处理 jQuery 中的表单更改?

[英]How do you handle a form change in jQuery?

In jQuery, is there a simple way to test if any of a form's elements have changed?在 jQuery 中,是否有一种简单的方法来测试表单的任何元素是否已更改?

Say I have a form and I have a button with the following click() event:假设我有一个表单,并且有一个带有以下click()事件的按钮:

$('#mybutton').click(function() {
  // Here is where is need to test
  if(/* FORM has changed */) {
     // Do something
  }
});

How would I test if the form has changed since it was loaded?我将如何测试表单自加载以来是否已更改?

You can do this:你可以这样做:

$("form :input").change(function() {
  $(this).closest('form').data('changed', true);
});
$('#mybutton').click(function() {
  if($(this).closest('form').data('changed')) {
     //do something
  }
});

This rigs a change event handler to inputs in the form, if any of them change it uses .data() to set a changed value to true , then we just check for that value on the click, this assumes that #mybutton is inside the form (if not just replace $(this).closest('form') with $('#myForm') ), but you could make it even more generic, like this:这将change事件处理程序绑定到表单中的输入,如果其中任何一个更改它使用.data()changed值设置为true ,然后我们只需在单击时检查该值,这假设#mybutton在表单(如果不只是将$(this).closest('form')替换$('#myForm') ),但您可以使其更加通用,如下所示:

$('.checkChangedbutton').click(function() {
  if($(this).closest('form').data('changed')) {
     //do something
  }
});

References: Updated参考:更新

According to jQuery this is a filter to select all form controls.根据 jQuery,这是一个选择所有表单控件的过滤器。

http://api.jquery.com/input-selector/ http://api.jquery.com/input-selector/

The :input selector basically selects all form controls. :input 选择器基本上选择所有表单控件。

If you want to check if the form data, as it is going to be sent to the server, have changed, you can serialize the form data on page load and compare it to the current form data:如果要检查将要发送到服务器的表单数据是否已更改,您可以在页面加载时序列化表单数据并将其与当前表单数据进行比较:

$(function() {

    var form_original_data = $("#myform").serialize(); 

    $("#mybutton").click(function() {
        if ($("#myform").serialize() != form_original_data) {
            // Something changed
        }
    });

});

A real time and simple solution:一个实时且简单的解决方案:

$('form').on('keyup change paste', 'input, select, textarea', function(){
    console.log('Form changed!');
});

You can use multiple selectors to attach a callback to the change event for any form element.您可以使用多个选择器将回调附加到任何表单元素的更改事件。

$("input, select").change(function(){
    // Something changed
});

EDIT编辑

Since you mentioned you only need this for a click, you can simply modify my original code to this:既然你提到你只需要点击一下,你可以简单地将我的原始代码修改为:

$("input, select").click(function(){
    // A form element was clicked
});

EDIT #2编辑#2

Ok, you can set a global that is set once something has been changed like this:好的,您可以设置一个全局设置,一旦某些内容发生更改,则设置如下:

var FORM_HAS_CHANGED = false;

$('#mybutton').click(function() {
    if (FORM_HAS_CHANGED) {
        // The form has changed
    }
});

$("input, select").change(function(){
    FORM_HAS_CHANGED = true;
});

Looking at the updated question try something like查看更新的问题尝试类似

$('input, textarea, select').each(function(){
    $(this).data("val", $(this).val());
});
$('#button').click(function() {
    $('input, textarea, select').each(function(){
        if($(this).data("val")!==$(this).val()) alert("Things Changed");
    });
});

For the original question use something like对于原始问题,请使用类似

$('input').change(function() {
    alert("Things have changed!");
});

Here is an elegant solution.这是一个优雅的解决方案。

There is hidden property for each input element on the form that you can use to determine whether or not the value was changed.表单上的每个输入元素都有一个隐藏属性,您可以使用它来确定值是否已更改。 Each type of input has it's own property name.每种类型的输入都有自己的属性名称。 For example例如

  • for text/textarea it's defaultValue对于text/textarea它是defaultValue
  • for select it's defaultSelect select它是defaultSelect
  • for checkbox/radio it's defaultChecked对于checkbox/radio它是defaultChecked

Here is the example.这是示例。

function bindFormChange($form) {

  function touchButtons() {
    var
      changed_objects = [],
      $observable_buttons = $form.find('input[type="submit"], button[type="submit"], button[data-object="reset-form"]');

    changed_objects = $('input:text, input:checkbox, input:radio, textarea, select', $form).map(function () {
      var
        $input = $(this),
        changed = false;

      if ($input.is('input:text') || $input.is('textarea') ) {
        changed = (($input).prop('defaultValue') != $input.val());
      }
      if (!changed && $input.is('select') ) {
        changed = !$('option:selected', $input).prop('defaultSelected');
      }
      if (!changed && $input.is('input:checkbox') || $input.is('input:radio') ) {
        changed = (($input).prop('defaultChecked') != $input.is(':checked'));
      }
      if (changed) {
        return $input.attr('id');
      }

    }).toArray();

    if (changed_objects.length) {
      $observable_buttons.removeAttr('disabled')   
    } else {
      $observable_buttons.attr('disabled', 'disabled');
    }
  };
  touchButtons();

  $('input, textarea, select', $form).each(function () {
    var $input = $(this);

    $input.on('keyup change', function () {
      touchButtons();
    });
  });

};

Now just loop thru the forms on the page and you should see submit buttons disabled by default and they will be activated ONLY if you indeed will change some input value on the form.现在只需循环浏览页面上的表单,您应该会看到默认情况下禁用提交按钮,并且只有当您确实要更改表单上的某些输入值时,它们才会被激活。

$('form').each(function () {
    bindFormChange($(this));
});

Implementation as a jQuery plugin is here https://github.com/kulbida/jmodifiable作为jQuery插件的实现在这里https://github.com/kulbida/jmodifiable

$('form :input').change(function() {
    // Something has changed
});
var formStr = JSON.stringify($("#form").serializeArray());
...
function Submit(){
   var newformStr = JSON.stringify($("#form").serializeArray());
   if (formStr != newformStr){
      ...
         formChangedfunct();
      ...
   }
   else {
      ...
         formUnchangedfunct();
      ...
   }
}

Extending Udi's answer, this only checks on form submission, not on every input change.扩展 Udi 的答案,这只检查表单提交,而不是每次输入更改。

$(document).ready( function () {
  var form_data = $('#myform').serialize();
  $('#myform').submit(function () {
      if ( form_data == $(this).serialize() ) {
        alert('no change');
      } else {
        alert('change');
      }
   });
});

You need jQuery Form Observe plugin.你需要jQuery Form Observe插件。 That's what you are looking for.这就是你要找的。

 $('form[name="your_form_name"] input, form[name="your_form_name"] select').click(function() { $("#result").html($(this).val()); });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <h2>Form "your_form_name"</h2> <form name="your_form_name"> <input type="text" name="one_a" id="one_a" value="AAAAAAAA" /> <input type="text" name="one_b" id="one_b" value="BBBBBBBB" /> <input type="text" name="one_c" id="one_c" value="CCCCCCCC" /> <select name="one_d"> <option value="111111">111111</option> <option value="222222">222222</option> <option value="333333">333333</option> </select> </form> <hr/> <h2>Form "your_other_form_name"</h2> <form name="your_other_form_name"> <input type="text" name="two_a" id="two_a" value="DDDDDDDD" /> <input type="text" name="two_b" id="two_b" value="EEEEEEEE" /> <input type="text" name="two_c" id="two_c" value="FFFFFFFF" /> <input type="text" name="two_d" id="two_d" value="GGGGGGGG" /> <input type="text" name="two_e" id="two_f" value="HHHHHHHH" /> <input type="text" name="two_f" id="two_e" value="IIIIIIII" /> <select name="two_g"> <option value="444444">444444</option> <option value="555555">555555</option> <option value="666666">666666</option> </select> </form> <h2>Result</h2> <div id="result"> <h2>Click on a field..</h2> </div>

In addition to above @JoeD's answer.除了以上@JoeD 的回答。

If you want to target fields in a particular form (assuming there are more than one forms) than just fields, you can use the following code:如果您想针对特定表单中的字段(假设有多个表单)而不仅仅是字段,您可以使用以下代码:

$('form[name="your_form_name"] input, form[name="your_form_name"] select').click(function() {
    // A form element was clicked
});

Try this:尝试这个:

<script>
var form_original_data = $("form").serialize(); 
var form_submit=false;
$('[type="submit"]').click(function() {
    form_submit=true;
});
window.onbeforeunload = function() {
    //console.log($("form").submit());
    if ($("form").serialize() != form_original_data && form_submit==false) {
        return "Do you really want to leave without saving?";
    }
};
</script>

First, I'd add a hidden input to your form to track the state of the form.首先,我会在您的表单中添加一个隐藏输入来跟踪表单的状态。 Then, I'd use this jQuery snippet to set the value of the hidden input when something on the form changes:然后,当表单上的某些内容发生更改时,我将使用此 jQuery 代码段来设置隐藏输入的值:

    $("form")
    .find("input")
    .change(function(){
        if ($("#hdnFormChanged").val() == "no")
        {
            $("#hdnFormChanged").val("yes");
        }
    });

When your button is clicked, you can check the state of your hidden input:单击按钮时,您可以检查隐藏输入的状态:

$("#Button").click(function(){
    if($("#hdnFormChanged").val() == "yes")
    {
        // handler code here...
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM