Manejar expresamente body-parser checkbox arrays en formularios

Tengo un formulario HTML con una serie de casillas de verificación (usando [] nombrar). Necesito poder procesar esto con expreso . Estoy usando body-parser .

El problema es que las casillas de verificación no seleccionadas no envían un valor y, al mismo tiempo, el analizador del cuerpo parece eliminar “agujeros” en las matrices simplemente agrupando los valores en una matriz en orden de índices, pero ignorando los índices en sí mismos. (Actualización: en realidad parece qs es el culpable ).

Considere este ejemplo completo, que muestra un formulario y responde con un volcado JSON de los datos enviados:

Instalar:

 npm install express body-parser 

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:

      



En ese ejemplo, si tuviera que marcar solo la option[1] , verifico que el índice está configurado correctamente al inspeccionar la solicitud en Chrome, el cuerpo es:

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

Sin embargo, body-parser colapsa la matriz de option y produce lo siguiente en req.body :

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

Como puede ver, el text tiene los tres, pero la option tiene solo un elemento. De manera similar, si tuviera que marcar la option[0] y la option[2] , el cuerpo de la solicitud sería:

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

Pero sería analizado a:

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

Perdí toda la información sobre qué checkbox estaba marcada.

Mi pregunta es, ¿cómo hago esto? Lo que quiero que suceda es, por ejemplo:

  • Con la checkbox[1] marcada:

     {"option":[null,"1",null],"text":["","",""]} 
  • Con la checkbox[0] y la checkbox[2] marcadas:

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

En realidad no estoy casado con null y "1" , solo necesito falsey y sincero.

Además, es importante que no pierda información sobre cuántas casillas de verificación debería haber en la matriz . Por ejemplo, si le diera a cada checkbox un valor único, supongo que podría traducir "option":["0","1"] en una matriz de valores booleanos, excepto que perdería el conocimiento de que la matriz es de tamaño 3 (con el 3er valor falso en ese caso) – aunque creo que podría agregar, por ejemplo, una entrada oculta como numberOfCheckboxes=3 , pero … este tipo de mapeo es engorroso y me gustaría evitarlo si es posible.

Mi enfoque no requiere javascript en el lado del cliente. Agregue campos ocultos tantos como sus casillas de verificación con los mismos nombres

el analizador de cuerpo analizará los elementos marcados como una matriz y otros de cadena

me refería

       

Si su opción [1] está marcada, el analizador de cuerpo lo analizará como

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

Y aquí está el modificador.

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

así que ahora el cuerpo será

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

La solución más simple (no la mejor) es que puede agregar entradas ocultas con diferentes ID y luego marcarlas cuando las casillas de verificación de la página no están marcadas.

       

Y antes de enviar:

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

Y luego, en función de eso, puedes averiguar cuáles no están marcadas.

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