表示体解析器处理表单上的复选框数组

时间:2022-12-19 07:52:56

I have an HTML form with an array of checkboxes (using [] naming). I need to be able to process this with express. I'm using body-parser.

我有一个带有复选框数组的HTML表单(使用[]命名)。我需要用快递来处理这件事。我用体。

The problem is that unchecked checkboxes don't submit a value, and at the same time, body-parser seems to remove "holes" in arrays by simply packing the values into an array in order of indices, but ignoring the indices themselves. (Update: Actually it looks like qs is the culprit).

问题是,未检查的复选框不会提交一个值,同时,body解析器似乎通过简单地将值打包成一个数组中的索引来删除数组中的“漏洞”,而忽略了索引本身。(更新:实际上,qs是罪魁祸首)。

Consider this full example, which displays a form and responds with a JSON dump of the submitted data:

考虑这个完整的示例,它显示一个表单,并使用提交数据的JSON转储进行响应:

Install:

安装:

npm install express body-parser

index.js:

index.js:

var express = require("express");
var site = express();

site.use(require("body-parser").urlencoded({extended:true}));

site.get("/", function (req, res) {
    res.sendFile(__dirname + "/test.html");
});

site.post("/form", function (req, res) {
    res.json(req.body);
});

site.listen(8081);

test.html:

test.html:

<html>
    <body>
        <form method="post" action="/form">
            <input type="checkbox" name="option[0]" value="1">
            <input type="checkbox" name="option[1]" value="1">
            <input type="checkbox" name="option[2]" value="1"><br>
            <input type="text" name="text[0]"><br>
            <input type="text" name="text[1]"><br>
            <input type="text" name="text[2]"><br>
            <button type="submit">Submit</button>
        </form>
    </body>
</html>

In that example, if I were to check only option[1], I verify that the index is set correctly by inspecting the request in Chrome, body is:

在这个例子中,如果我只检查选项[1],我通过检查Chrome中的请求来验证索引是否设置正确,body是:

option[1]:1
text[0]:
text[1]:
text[2]:

Yet body-parser collapses the option array and produces the following in req.body:

然而body-parser折叠选项数组并在req.body中生成以下内容:

{"option":["1"],"text":["","",""]}

As you can see, text has all three, but option has only one item. Similarly, if I were to check option[0] and option[2], the request body would look like:

如您所见,文本包含这三种,但是选项只有一项。类似地,如果我检查选项[0]和选项[2],请求体将如下所示:

option[0]:1
option[2]:1
text[0]:
text[1]:
text[2]:

But it would be parsed to:

但我们可以把它理解为:

{"option":["1","1"],"text":["","",""]}

I lose all information about which checkbox was checked.

我丢失了有关哪个复选框被选中的所有信息。

My question is, how do I do this? What I want to happen is, e.g.:

我的问题是,我该怎么做?我想要发生的是,例如:

  • With checkbox[1] checked:

    检查复选框[1]:

    {"option":[null,"1",null],"text":["","",""]}
    
  • With checkbox[0] and checkbox[2] checked:

    选择复选框[0]和复选框[2]:

    {"option":["1",null,"1"],"text":["","",""]}
    

I'm not actually married to null and "1", I just need falsey and truthy.

我并没有嫁给零和1,我只是需要福赛和真理。

Also, it is important that I not lose information about how many checkboxes should be in the array. For example, if I were to give each checkbox a unique value, I suppose I could translate "option":["0","1"] into an array of boolean values, except I would lose the knowledge that the array is of size 3 (with the 3rd value false in that case) -- although I guess I could add e.g. a hidden input like numberOfCheckboxes=3, but... this kind of mapping is cumbersome and I'd like to avoid it if possible.

此外,重要的是我不能丢失关于数组中应该有多少复选框的信息。举个例子,如果我给每个复选框一个独特的价值,我想我可以翻译“选项”:(“0”,“1”)成一个布尔值数组,但我将失去的知识的数组大小3(第三值错误在这种情况下),不过我想我可以添加如隐藏输入numberOfCheckboxes = 3,但是……这种映射很麻烦,如果可能的话我想避免它。

2 个解决方案

#1


3  

My approach requires no javascript on client side. Add hidden fields as many as your checkboxes with same names

我的方法在客户端不需要javascript。在复选框中添加相同名称的隐藏字段。

body parser will parse checked items as array and string others

主体解析器将被检查的项解析为数组和字符串

I meant

我的意思是

<input type="hidden" name="option[0]" value="0">
<input type="hidden" name="option[1]" value="0">
<input type="hidden" name="option[2]" value="0">
<input type="checkbox" name="option[0]" value="1">
<input type="checkbox" name="option[1]" value="1">
<input type="checkbox" name="option[2]" value="1">

If your option[1] is checked then body parser will parse it like

如果您的选项[1]被选中,那么body解析器将像这样解析它

{option:['0', ['0', '1'], '0']}

And here is the modifier

这是修饰语

req.body.option = req.body.option.map(item => (Array.isArray(item) && item[1]) || null);

so now body will be

所以现在身体会

{option: [null, '1', null]}

#2


0  

The simplest solution (not the best) is that you can add hidden input's with different ids and then check them when the check-boxes on the page get unchecked.

最简单的解决方案(不是最好的)是,您可以添加不同id的隐藏输入,然后在页面上的复选框未选中时选中它们。

<input type="checkbox" name="option[0]" value="1">
<input type="checkbox" name="option[1]" value="1">
<input type="checkbox" name="option[2]" value="1">

<input type="checkbox" class="hidden" name="hiddenOption[0]" value="1">
<input type="checkbox" class="hidden" name="hiddenOption[1]" value="1">
<input type="checkbox" class="hidden" name="hiddenOption[2]" value="1">

And before submit:

和之前提交:

$('input[name^=option]').each(function () {      
  if(!this.checked) {
    var name = "input[name=\'hiddenOption" + this.name.replace('option', '') + "\']";
    console.log(name);
    $(name).prop('checked', true);
  }
});

And then based on that you can figure out which ones are not ticked.

然后根据它,你可以知道哪些没有被勾选。

https://plnkr.co/edit/mJCbtgQnQudHGrUzAz3A?p=preview

https://plnkr.co/edit/mJCbtgQnQudHGrUzAz3A?p=preview

#1


3  

My approach requires no javascript on client side. Add hidden fields as many as your checkboxes with same names

我的方法在客户端不需要javascript。在复选框中添加相同名称的隐藏字段。

body parser will parse checked items as array and string others

主体解析器将被检查的项解析为数组和字符串

I meant

我的意思是

<input type="hidden" name="option[0]" value="0">
<input type="hidden" name="option[1]" value="0">
<input type="hidden" name="option[2]" value="0">
<input type="checkbox" name="option[0]" value="1">
<input type="checkbox" name="option[1]" value="1">
<input type="checkbox" name="option[2]" value="1">

If your option[1] is checked then body parser will parse it like

如果您的选项[1]被选中,那么body解析器将像这样解析它

{option:['0', ['0', '1'], '0']}

And here is the modifier

这是修饰语

req.body.option = req.body.option.map(item => (Array.isArray(item) && item[1]) || null);

so now body will be

所以现在身体会

{option: [null, '1', null]}

#2


0  

The simplest solution (not the best) is that you can add hidden input's with different ids and then check them when the check-boxes on the page get unchecked.

最简单的解决方案(不是最好的)是,您可以添加不同id的隐藏输入,然后在页面上的复选框未选中时选中它们。

<input type="checkbox" name="option[0]" value="1">
<input type="checkbox" name="option[1]" value="1">
<input type="checkbox" name="option[2]" value="1">

<input type="checkbox" class="hidden" name="hiddenOption[0]" value="1">
<input type="checkbox" class="hidden" name="hiddenOption[1]" value="1">
<input type="checkbox" class="hidden" name="hiddenOption[2]" value="1">

And before submit:

和之前提交:

$('input[name^=option]').each(function () {      
  if(!this.checked) {
    var name = "input[name=\'hiddenOption" + this.name.replace('option', '') + "\']";
    console.log(name);
    $(name).prop('checked', true);
  }
});

And then based on that you can figure out which ones are not ticked.

然后根据它,你可以知道哪些没有被勾选。

https://plnkr.co/edit/mJCbtgQnQudHGrUzAz3A?p=preview

https://plnkr.co/edit/mJCbtgQnQudHGrUzAz3A?p=preview