diff --git a/src/htmx.js b/src/htmx.js index 485087a62..13b1e0e9a 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -1835,7 +1835,14 @@ var htmx = (() => { for (let option of input.selectedOptions) { formData.append(name, option.value); } - } else { + } else if (Array.isArray(input.value)) { + // Add all array values (e.g. custom elements) + for (let v of input.value) { + if (v != null) { + formData.append(name, v); + } + } + } else if (input.value != null) { formData.append(name, input.value); } } diff --git a/test/tests/unit/__collectFormData.js b/test/tests/unit/__collectFormData.js index 64fb10c39..7f244671f 100644 --- a/test/tests/unit/__collectFormData.js +++ b/test/tests/unit/__collectFormData.js @@ -286,4 +286,34 @@ describe('__collectFormData unit tests', function() { assert.equal(files[0].name, 'file1.txt'); assert.equal(files[1].name, 'file2.txt'); }); + + it('collects element with array value as individual FormData items', function () { + let elt = createProcessedHTML('
'); + Object.defineProperty(elt, 'value', { + value: ['banana', 'apple'], + configurable: true + }); + let formData = htmx.__collectFormData(elt, null, null, false, false); + assert.deepEqual(formData.getAll('fruit'), ['banana', 'apple']); + }); + + it('filters out null or undefined values inside array', function () { + let elt = createProcessedHTML('
'); + Object.defineProperty(elt, 'value', { + value: ['banana', null, 'apple', undefined], + configurable: true + }); + let formData = htmx.__collectFormData(elt, null, null, false, false); + assert.deepEqual(formData.getAll('fruit'), ['banana', 'apple']); + }); + + it('skips element when value is null or undefined', function () { + let elt = createProcessedHTML('
'); + Object.defineProperty(elt, 'value', { + value: null, + configurable: true + }); + let formData = htmx.__collectFormData(elt, null, null, false, false); + assert.equal(formData.get('fruit'), null); + }); }); \ No newline at end of file