【问题标题】:jquery: how to remove blank fields from a form before submitting?jquery:如何在提交之前从表单中删除空白字段?
【发布时间】:2011-08-19 18:03:57
【问题描述】:

我有一个页面,上面有一组表单,用于 API 测试。由于不值得解释的原因,我通常不想在提交给服务器的文件中包含空字段。如何在提交前从数据中删除空字段?

例如,如果我有一个包含两个字段 foo 和 bar 的表单,并且用户将 bar 留空,我希望服务器看到提交时就好像唯一的字段是 foo。

我的第一次尝试涉及使用 jquery 循环遍历字段

$("form").submit(function() {
    $(this).children(':input').each(...)
}

并删除该字段。但是 a) 不起作用,并且 b) 似乎它会从页面上的可见表单中删除该字段,这不是我想要的。

另一种方法可能是遍历字段并使用具有“”以外的值的字段手动构造提交字符串。那会奏效吗?有更好的想法吗?

【问题讨论】:

    标签: jquery form-submit


    【解决方案1】:

    一种方法是在这些字段上设置“禁用”属性,以防止它们的值被序列化并发送到服务器:

    $(function()
    {
        $("form").submit(function()
        {
            $(this).children(':input[value=""]').attr("disabled", "disabled");
    
            return true; // ensure form still submits
        });
    });
    

    如果您有客户端验证,您还需要在验证失败时重新启用这些字段:

    $(':input').removeAttr("disabled");
    

    编辑:修复错误

    【讨论】:

    • 这真的很优雅......只是它似乎不起作用。我错过了什么?特别是,在通过 http get 提交时,我可以看到发生了什么,我仍然看到类似 'api/userattributes/?action=read_by_user&name=&value=' 的内容,其中名称和值留空,但仍显示为提交变量。
    • 在进一步调查中,':input[value=""]' 没有找到任何东西。在我通过 each() 将 attr() 调用拆分到另一行之后,使用调试器进行显示它永远不会到达那里,因此永远不会设置 disabled。
    • @Dave:我怀疑如果你将 $(this).children 更改为 $(this).find,它在任何一个地方都可以工作。
    • @FelipeTadeo:应该,因为它不使用“输入”选择器,而是使用“:输入”,这是一种针对输入、文本区域、选择等的特定于 jQuery 的方式。但是,选择器的 [value=""] 部分可能不适用于 textarea。最好的方法可能是使用过滤函数,类似于: .children(':input').filter(function(item){ return !!$(item).val(); /* untested */ })
    • 最新版本的 jQuery 包含 prop 方法。他们建议使用该方法而不是 attr 方法来设置禁用属性,因此应将 @LukeDennis 代码更新为 $(this).children(':input[value=""]').prop('disabled', true);
    【解决方案2】:

    结合这里的答案,与this question regarding finding empty input 我得出了这个解决方案。

    $(function() {
       $("form").submit(function() {
          $(this).find(":input").filter(function(){ return !this.value; }).attr("disabled", "disabled");
          return true; // ensure form still submits
        });
    });
    

    所以从@Luke 的解决方案开始,添加他使用 find 而不是 children 的建议(我的表单在表格中),然后使用 @gdoron 的过滤技术来隔离空元素。

    【讨论】:

    • 不 - 我认为它们是过度想象力的虚构。
    • 这应该是公认的答案。接受的答案基本上在最初呈现时检查输入值(可能会改变),这个答案在提交时检查实时输入值。
    • 这对我来说非常有用,一个干净优雅的解决方案@ReggieB +1
    【解决方案3】:

    我通常会同意@Luke,但是下面的解决方案应该处理任何空值,无论它是否是输入标签,只要记住在所有表单子元素上添加一个 name 属性,如果你想要它们进行序列化;

    HTML:

    <form action="yourUrl.php" name="myForm" id="myForm">
    input1: <input type="text" name="field1" /><br /><br />
    input2: <input type="text" name="field2" /><br /><br />
    input3: <input type="text" name="field3" /><br /><br />
    input4: <input type="text" name="field4" /><br /><br />
    select: <select name="selectField">
        <option value="">empty value</option>
        <option value="option2">option2</option>
        <option value="option3">option3</option>
    </select><br /><br />
    <input type="submit" name="submit" value="submit" />
    </form>    
    

    jQuery:

    $("#myForm").submit (function (e) {
        e.preventDefault();
        var _form = $(this);
        var data = {};
        var formData = _form.serializeArray();
        $.each(formData, function (index, value) {
            var data_name = formData[index].name;
            var data_value = formData[index].value;
            if (data_value !== "") {
                data[data_name] = data_value;
            }
        });
        // now with ajax you can send the sanitize data object
        $.post(_form.attr("action"), data, function(res, textStatus, jqXHR) {
            // do something
        });
    });
    

    【讨论】:

      【解决方案4】:

      投票最多的答案对我不起作用。我认为选择器不够具体。这对我有用:

      $(function() {
        $("#myForm").submit(function() {
          $("#myForm *").filter(":input").each(function(){
            if ($(this).val() == '')
              $(this).prop("disabled", true);
          });
      
          return true; // ensure form still submits
        });
      });

      【讨论】:

        【解决方案5】:

        在提交时删除空字段

        $(function() {
            $('form').submit(function () {
                var $empty_fields = $(this).find(':input').filter(function () { 
                    return $(this).val() === '';
                });
                $empty_fields.prop('disabled', true);
                return true;
            });
        });
        

        结合多种特征和主观风格,尤其是:

        • .find()deeper.children()
        • .val() === '' 适用于 textareachanged 属性,[value=""] 不适用。
        • .prop()over.attr().

        【讨论】:

          【解决方案6】:

          也许不是最好的解决方案,但这应该是实现您所追求的快速简便的方法

          $("form").submit(function() {
              $(this).children('input[value=""]').each(function(){
                  // Rename the name attribute to something else if the value is "" to it isn't submitted
                  $(this).attr('blank', $(this).attr('name'));
                  $(this).removeAttr('name');
          
              });
          }
          

          那么如果你使用vlient端验证或者通过ajax发帖,那么你需要重新设置name属性,这样下一次提交才能正常工作...

          $(this).attr('name', $(this).attr('blank'));
          $(this).removeAttr('blank');
          

          【讨论】:

          • @Luke 以几乎相同的答案击败了我,我更喜欢 Luke 的解决方案。 :)
          【解决方案7】:

          添加到卢克丹尼斯接受的答案。如果有人使用 Python/Django 框架,如果您使用 django-filters 应用程序,此脚本可能会有所帮助。在这个例子中,我有多个过滤器,它们有一个输入和选择器 html 元素。但是,该脚本也适用于单输入过滤器以及多项选择过滤器。

          $(function()
          {
              var form = $( 'form' )[0];
              $( form ).submit(function() 
              { 
                  $('input, select').each(function()
                  {
                      if ($(this).val().length === 0) 
                      {
                          $(this).prop('disabled', true);
                          $(this).next().prop('disabled', true);
                      }
                  });
              });
          });
          

          【讨论】:

            猜你喜欢
            • 2011-01-25
            • 2012-02-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多