【问题标题】:Disable submit button unless original form data has changed除非原始表单数据已更改,否则禁用提交按钮
【发布时间】:2013-05-16 16:53:10
【问题描述】:

这是我正在使用的代码:

$('form').bind('keyup change', function(){

默认情况下,提交按钮设置为禁用,如果输入文本字段、单选按钮检查状态或下拉选择值发生更改,则必须通过删除禁用属性将按钮设置为启用。

我的最终目标:

编辑:如果将任何内容更改回其默认值,则提交按钮应通过 prop('disabled', true); 设置为禁用; - 需要一些方法来跟踪每一个变化。

================================================ =====

示例: 转到 Twitter,然后登录,从下拉菜单中选择设置。在帐户页面中,更改您的用户名(只需添加一个额外的字符),然后向下滚动,将复选框设置为选中,然后更改您的国家/地区选择。

底部的按钮会启用,返回并取消之前勾选的复选框,底部的按钮将保持启用状态,

滚动到顶部将您的用户名更改回原来的样子,向下滚动按钮以保存更改仍将启用,转到国家列表并将其更改回您以前的名称,现在终于向下滚动:保存更改按钮将被禁用。

================================================ =====

编辑:这看起来很相似,What is the best way to track changes in a form via javascript?

引用:“您可以默认禁用它,并让 JavaScript 处理程序监视更改事件的输入以启用它。也许渲染一些隐藏字段或直接渲染 JavaScript 值以存储“原始”,并且在这些更改事件上,对照原始值检查当前值,以确定是否应启用或禁用该按钮。- David Jan 18 日 15:14" (Enable 'submit' button only if a value in the form has been changed)。

【问题讨论】:

  • 您想使用carljohnson 之类的默认值吗?占位符怎么样?
  • @PSL:这里不是默认值,方法如下:名字:Erik,更改为其他名称,然后按钮设置为启用,但如果用户返回并将名字更改为 Erik - 从一开始按钮就应该被禁用,因为他从未做过任何改变。只是为了演示而添加了默认值。
  • 默认值实际上可以是任何值,因为它们是从数据库加载的......
  • 如何拥有一个保存默认值的 data-default 属性 - 然后检查输入的更改/keyup 是否有任何当前值已更改?
  • @JohnSmith 我只需要做同样的事情。只需几行代码即可实现。 stackoverflow.com/a/24790754/1850421

标签: jquery html css


【解决方案1】:

我知道这是一个迟到的答案,但这种方法使用的代码比接受的答案少得多,不需要字段上的 ID,也不需要存储全局数组。

只需使用.serialize() 存储数据并检查每次更改是否匹配。

http://jsfiddle.net/Pug3H/2/

$('form')
    .each(function(){
        $(this).data('serialized', $(this).serialize())
    })
    .on('change input', function(){
        $(this)             
            .find('input:submit, button:submit')
                .prop('disabled', $(this).serialize() == $(this).data('serialized'))
        ;
     })
    .find('input:submit, button:submit')
        .prop('disabled', true)
;

【讨论】:

  • 很棒,聪明的解决方案
  • 作为目前接受答案的人,我同意,这个解决方案是最好的。
  • 仅供参考,这有一个缺点:如果您有将 JSON 数据放在隐藏字段中的自定义小部件,则您可以对 JSON 数据进行字符串比较。所以{"foo": "bar"}{"foo":"bar"} 是不同的字符串,即使它们的值相同。
  • 你好。如果我只想检查
  • 输入[type="image"] 也可以添加到执行提交的选择器列表中。 w3schools.com/tags/att_input_type_image.asp
【解决方案2】:

您只需要保存原始值,然后在每次更改后检查它们。

示例:http://jsfiddle.net/justincook/42EYq/15/

JavaScript:

// Store original values
var orig = [];             
$("form :input").each(function () {
    var type = $(this).getType();
    var tmp = {'type': type, 'value': $(this).val()};
    if (type == 'radio') { tmp.checked = $(this).is(':checked'); }
    orig[$(this).attr('id')] = tmp;
});

// Check values on change
$('form').bind('change keyup', function () {
    var disable = true;
    $("form :input").each(function () {
        var type = $(this).getType();
        var id = $(this).attr('id');    
        if (type == 'text' || type == 'select') {
            disable = (orig[id].value == $(this).val());
        } else if (type == 'radio') {
            disable = (orig[id].checked == $(this).is(':checked'));
        }    
        if (!disable) { return false; } // break out of loop
    });

    $('#submit-data').prop('disabled', disable); // update button
});

// Get form element type
$.fn.getType = function () { 
    if(this[0].tagName == "INPUT")
        return $(this[0]).attr("type").toLowerCase() 
    else
        return this[0].tagName.toLowerCase();        
}

HTML:

<form id="" action="" method="post">
    <input type="text" value="Carl" name="firstname" id="firstname" />
    <input type="text" value="Johnson" name="lastname" id="lasttname" />
    <input id="radio_1" type="radio" value="female" name="sex" />Female
    <input id="radio_2" type="radio" value="male" name="sex" />Male
    <select id="country-list" name="countries">
        <option value="xx" selected="">Worldwide</option>
        <option value="in">India</option>
        <option value="us">United States</option>
    </select>
    <button id="submit-data" disabled="" type="submit">Save changes</button>
</form>

【讨论】:

  • 在我的代码 HTML 文件中,我刚刚粘贴到您的解决方案中,但正如我所期望的那样,它并不能完美地工作,但在小提琴中它确实如此。 :(
  • 我对您的 HTML 所做的唯一更改是在您的单选字段中添加一个 ID。如果您还没有添加它们。如果仍然无法正常工作,请查看 JavaScript 控制台中是否出现错误(Chrome 中为 ctrl+shift+j)。
  • 如果您使用的是php,您可以在ID字段中输入&lt;?php echo uniqid() ?&gt;
  • 使用序列化有一个更简单的方法
  • 是的,我喜欢下面的序列化方法,因为它不需要额外的工作来获取输入类型。非常聪明。
【解决方案3】:

@Nigel Angel 的改进版回答:

/* Disable the forms submissions until they have changed */
$(window).on('load', function (e) {
    $('form').each(function(){
        $(this).data('serialized', $(this).serialize())
    })
    .on('change input', function(){
        $(this).find(':submit, input[type="image"]')
            .prop('disabled', $(this).serialize() == $(this).data('serialized'));

        /* Check if input with type files has changed */
        var changedFiles = $( ":file" ).filter(function( index ) {
            return this.value != this.defaultValue;
        }).length;

        if ( changedFiles > 0) {
            $(this).find(':submit, input[type="image"]')
                .prop('disabled', false);
        }
    })
    .find(':submit, input[type="image"]').prop('disabled', true);
});
  • input[type="image"] 添加到执行的选择器列表中 提交。
  • 添加了对文件类型的输入更改的检查。
  • 还缩短了使用 :submit 的答案以涵盖两者 按钮和输入的情况。

【讨论】:

    【解决方案4】:

    您可以添加一个数据属性来保存默认值 - 对于选中的类型,您可以使用 0 表示未选中和 1 表示选中

    <form id="" action="" method="post">
        <input type="text" data-default="Carl" value="Carl" name="firstname" id="firstname" />
        <input type="text" data-default="Johnson" value="Johnson" name="lastname" id="lasttname" />
        <br />
        <br />
        <input id="female" type="radio" value="female" name="sex" data-default="0" />Female
        <br />
        <input id="male" type="radio" value="male" name="sex" data-default="0" />Male
        <br />
        <br />
        <select id="country-list" name="countries" data-default="xx">
            <option value="xx" selected="">Worldwide</option>
            <option value="in">India</option>
            <option value="il">Israel</option>
            <option value="ru">Russia</option>
            <option value="us">United States</option>
        </select>
        <br />
        <br />
        <button id="submit-data" disabled="" type="submit">Save changes</button>
    </form>
    

    然后在您的 jquery 中使用过滤器来获取更改的那些

    var button = $('#submit-data');
    $('form :input').not(button).bind('keyup change', function () {
        // get all that inputs that has changed
        var changed = $('form :input').not(button).filter(function () {
            if (this.type == 'radio' || this.type == 'checkbox') {
                return this.checked != $(this).data('default');
            } else {
                return this.value != $(this).data('default');
            }
        });
        // disable if none have changed - else enable if at least one has changed
        $('#submit-data').prop('disabled', !changed.length);
    });
    

    FIDDLE

    【讨论】:

      猜你喜欢
      • 2018-09-12
      • 1970-01-01
      • 2017-03-10
      • 1970-01-01
      • 2019-07-19
      • 2020-04-23
      • 1970-01-01
      • 2016-04-03
      • 2012-06-19
      相关资源
      最近更新 更多