【问题标题】:HTML checkbox elements are only submitted if they're checked?HTML复选框元素仅在选中后才提交?
【发布时间】:2011-05-11 19:32:34
【问题描述】:

我正在尝试在现有网站上工作,但我发现了一个错误,但我不确定它为什么是一个错误或如何解决它。

该网站基本上列出了在一个城市出租的一些商业物业。有一个类从数据库中获取列表并从每个列表中创建一个对象。每个对象中都有一个与该属性相关联的图像数组。

当用户编辑列表时,他们会得到一个编辑页面,其中包含图像列表,以及旁边的“删除”复选框。复选框都具有相同的名称,因此当它们被提交回服务器时,应用程序会获取要删除的图像数组。

应该发生的是,应用程序有这个开/关值数组(其中 on = delete),并且数组中每个值的索引对应于列表对象中图像的索引 - 当其中一个值为“on”,对应于“on”值的图像数组中的文件名从文件系统中删除,并且该图像从数据库中删除。

但是,当提交表单时,应用程序会获得一个仅包含选中复选框的 0 索引数组。因此,如果我设置三个任意图像进行删除,应用程序会得到

大批 { [0] =>“开”, [1] =>“开”, [2] =>“开” }

这显然不起作用,列表中的前 3 张图像将被删除,无论设置了哪些复选框。

我该如何解决这个问题?我想避免命名每个复选框(delete_1delete_2delete_3 等),因为系统已经构建为可以使用所有具有相同名称的复选框。有没有一种方法可以强制所有复选框以“on”或“off”的形式提交?

【问题讨论】:

    标签: php html checkbox


    【解决方案1】:

    没有办法强制,但您可以在复选框之前添加一个隐藏的名称和所需值:

    <input type="hidden" name="delete[42]" value="off" />
    <input type="checkbox" name="delete[42]" value="on" />
    

    【讨论】:

    • 抱歉,我试图避免为每个复选框使用不同的名称。目前它们都被命名为delete,应用程序将它们作为数组接收。我不认为这种技术适用于所有具有相同名称的人
    • @Carson Myers:正如我所说,您可以将 same name 赋予复选框。不清楚你有什么名字&lt;input type="hidden" name="delete[1]" value="off" /&gt;。好点了吗?
    • @Carson Myers:“我认为这种技术行不通”——你为什么不试试呢? ;-)
    • 啊,我误会你了。现在他们都只有name="delete",我以前从未在他们中使用过下标。这也可以
    • +1 这是最简单、最优雅的解决方案。这也是一些框架在其 HTML 助手中使用的解决方案。 (如 CakePHP)。事实上,我会将它们全部命名为name="delete[id]",其中id 是图像索引,这将为您的后端提供一个已经格式化的数组
    【解决方案2】:

    不,您不能强制提交未选中的复选框,但您可以为它们赋予唯一值(而不是全部“打开”)以确定哪些复选框被选中而不更改名称。

    【讨论】:

    • 太棒了,不知道你能做到。非常感谢(允许时接受)
    • @Steve 我想避免以不同的方式命名它们,因为这将不得不改变后端的行为。我没有意识到您可以提交除“on”或“off”以外的值 - 这需要最少的更改
    • @Fred Nurk:他问:“有没有一种方法可以强制所有复选框以“on”或“off”的形式提交?这个答案没有回答这个问题,但我的答案。
    • @zerkms 你能解释一下为什么这是一个糟糕的答案吗?如果有任何失败,我想知道失败
    • @fred @zerk 我确实要求强制他们“打开”或“关闭”,而 zerkms 确实回答了这个问题,所以我支持他。碰巧这更好地解决了我的问题,并且总体上似乎是一种更好的方法。
    【解决方案3】:

    如果你真的想返回一个开和关的数组,那么你需要将一个函数附加到表单提交中,该函数将扫描所有具有给定名称的复选框,并将它们的值放入数组中。

    在 jQuery 中,这看起来像...

    $('#yourForm').submit(function(){
        var array = new Array();
        $('input[name="nameOfCheckboxes"]').each(function(index){
            array[index] = $(this).value();
        }
        var r = $.param(array);
        $('#someHiddenFieldInForm').value(r);
     }
    

    (当然,代码未经测试)

    【讨论】:

    • +1 表示有效的解决方案,但 javascript 似乎对这个问题有点矫枉过正
    • 你真的没有什么比抱怨更好了吗? Carson 要求提供不需要更改现有“功能”的解决方案。他的问题不清楚他愿意改变多少,并且使用 JavaScript 不需要更改现有代码。
    【解决方案4】:

    您可以通过添加以下 jQuery 来解决此问题:

    $(function () {
      $("#myform").submit(function(){
        $("input[name='delete']:not(:checked)").attr("checked","checked").val("off");  
      });
    }); 
    

    myform 是表单的 ID,delete 是复选框的名称。

    【讨论】:

    • 我曾短暂地考虑过使用 javascript,但在这种情况下似乎有点矫枉过正。这个问题的公认答案涉及将foreach($listing['delete'] as $index =&gt; $state) 更改为foreach($listing['delete'] as $index),我认为这对我来说是理想的解决方案。 +1 为有效的解决方案虽然
    • 格特,比我更喜欢你的。 +1
    • Javascript 是一种黑客解决方案。
    【解决方案5】:

    Fred Nurk 的解决方案很好,我赞成。就我个人而言,当我遇到这种情况时,我总是给这些字段起不同的名字。我使用一个通用前缀,后跟一个下划线以便于识别,然后是某种 id。我通常会创建一组具有相同模式的字段,例如“name_1”、“amount_1”、“foobar_1”、“name_2”、“amount_2”等。遍历字段并获取这些名称相当容易分开。 (在 Java 中,只需 indexOf('_')。)

    【讨论】:

      【解决方案6】:

      解决此问题的另一种方法是接受 HTML 表单的奇怪之处,并使用在声明期间使用 ternary operators 的局部变量来捕获它。

      例如,给定一个复选框

      <input type="checkbox" name="notify_users" id="notify_cb">
      

      无论是否包含复选框值,您都可以像这样处理帖子:

      // normal boolean value    
      $notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on' );    
      // explicitly set a 1 or 0
      $notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on' )? 1 : 0);
      // explicitly set 'yes' or 'no'
      $notify_users = ((!empty($_POST['notify_users']) and $_POST['notify_users'] == 'on' )? 'yes' : 'no');
      

      在我看来,这比向客户端添加额外的 Javascript 更可取,因为它维护起来稍微少了一点(并且可以说让继任者/其他开发人员更清楚地了解正在发生的事情)

      【讨论】:

        猜你喜欢
        • 2021-10-29
        • 1970-01-01
        • 2021-12-18
        • 2021-09-22
        • 1970-01-01
        • 1970-01-01
        • 2015-11-21
        相关资源
        最近更新 更多