Skip to content

Commit

Permalink
wrong format multiple select? #20
Browse files Browse the repository at this point in the history
  • Loading branch information
serbanghita committed Dec 14, 2023
1 parent e1a6a00 commit cfda0b3
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 18 deletions.
35 changes: 34 additions & 1 deletion build/bundle/formToObject.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions build/src/FormToObject.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ export declare class FormToObject {
settings: {
includeEmptyValuedElements: boolean;
w3cSuccessfulControlsOnly: boolean;
/**
* In case of a multiple select, e.g. <select name="multiple[]" multiple>
* If true, we're going to mimic PHP POST payload behaviour,
* then the <select>'s value will be:
* ```
* {
* "multiple": [111,222]
* }
* ```
*
* If false, then the <select>'s value will be:
*
* ```
* {
* "multiple": [
* 0: [111, 222]
* ]
* }
* ```
*/
phpStyleMultipleSelects: boolean;
debug: boolean;
};
constructor(selector: string | HTMLFormElement, options?: IFormToObjectOptions);
Expand Down
5 changes: 3 additions & 2 deletions build/src/dom.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HTMLFormField } from "./types";
/**
* Check to see if the object is an HTML node.
*
Expand All @@ -10,8 +11,8 @@ export declare function isRadio($domNode: HTMLInputElement): boolean;
export declare function isCheckbox($domNode: HTMLInputElement): boolean;
export declare function isFileField($domNode: HTMLInputElement): boolean;
export declare function isTextarea($domNode: HTMLTextAreaElement): boolean;
export declare function isSelectSimple($domNode: HTMLSelectElement): boolean;
export declare function isSelectMultiple($domNode: HTMLSelectElement): boolean;
export declare function isSelectSimple($domNode: HTMLFormField): boolean;
export declare function isSelectMultiple($domNode: HTMLFormField): boolean;
export declare function isSubmitButton($domNode: HTMLButtonElement): boolean;
export declare function isChecked($domNode: HTMLInputElement): boolean;
export declare function isFileList($domNode: HTMLInputElement): boolean;
48 changes: 35 additions & 13 deletions src/FormToObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,27 @@ export class FormToObject {
public settings = {
includeEmptyValuedElements: false,
w3cSuccessfulControlsOnly: false,
/**
* In case of a multiple select, e.g. <select name="multiple[]" multiple>
* If true, we're going to mimic PHP POST payload behaviour,
* then the <select>'s value will be:
* ```
* {
* "multiple": [111,222]
* }
* ```
*
* If false, then the <select>'s value will be:
*
* ```
* {
* "multiple": [
* 0: [111, 222]
* ]
* }
* ```
*/
phpStyleMultipleSelects: true,
debug: true
};

Expand Down Expand Up @@ -106,21 +127,18 @@ export class FormToObject {
objKeyNames = $domNode.name.match(FormToObject.keyRegex);

if (objKeyNames && objKeyNames.length === 1) {
this.processSingleLevelNode(
$domNode,
objKeyNames,
(domNodeValue ? domNodeValue : ''),
result
);
this.processSingleLevelNode($domNode, objKeyNames, (domNodeValue ? domNodeValue : ''), result);
}

if (objKeyNames && objKeyNames.length > 1) {
this.processMultiLevelNode(
$domNode,
objKeyNames,
(domNodeValue ? domNodeValue : ''),
result
);
if (isSelectMultiple($domNode) && this.settings.phpStyleMultipleSelects) {
// Check for name in this format <select --> name="multiple[]" <--- multiple>
// Keep the name as "multiple" so it matches the PHP style POST payload format.
if (objKeyNames.length === 2 && objKeyNames[1] === '[]') {
objKeyNames = [objKeyNames[0]];
}
}
this.processMultiLevelNode($domNode, objKeyNames, (domNodeValue ? domNodeValue : ''), result);
}

}
Expand Down Expand Up @@ -313,7 +331,11 @@ export class FormToObject {
result[keyName]
);
} else {
result[keyName] = Object.create(null);
if (isSelectMultiple($domNode) && arr.length >= 2 && arr[1] === '[]') {
result[keyName] = [];
} else {
result[keyName] = Object.create(null);
}
}

return this.processMultiLevelNode($domNode, arr.splice(1, arr.length), value, result[keyName]);
Expand Down
6 changes: 4 additions & 2 deletions src/dom.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {HTMLFormField} from "./types";

/**
* Check to see if the object is an HTML node.
*
Expand Down Expand Up @@ -28,11 +30,11 @@ export function isTextarea($domNode: HTMLTextAreaElement) {
return $domNode.nodeName === 'TEXTAREA';
}

export function isSelectSimple($domNode: HTMLSelectElement) {
export function isSelectSimple($domNode: HTMLFormField) {
return $domNode.nodeName === 'SELECT' && $domNode.type === 'select-one';
}

export function isSelectMultiple($domNode: HTMLSelectElement) {
export function isSelectMultiple($domNode: HTMLFormField) {
return $domNode.nodeName === 'SELECT' && $domNode.type === 'select-multiple';
}

Expand Down
62 changes: 62 additions & 0 deletions test/unit/settings.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {FormToObject} from "../../src/FormToObject";

describe('settings', () => {
describe('phpStyleMultipleSelects', () => {
it('when true, should return "multiple" key and array as value', () => {
const $formEl = document.createElement('form');
const $formInner = document.createElement('div');
$formInner.innerHTML = `
<select name="multiple[]" multiple>
<option value="a" selected>a</option>
<option value="b" selected>b</option>
</select>
`;
$formEl.appendChild($formInner);

const formToObject = new FormToObject($formEl, { phpStyleMultipleSelects: true });
const result = formToObject.convertToObj();

expect(result).toEqual({"multiple": ["a", "b"]});
});

it('when false, should return "multiple" key and multi-array as value', () => {
const $formEl = document.createElement('form');
const $formInner = document.createElement('div');
$formInner.innerHTML = `
<select name="multiple[]" multiple>
<option value="a" selected>a</option>
<option value="b" selected>b</option>
</select>
`;
$formEl.appendChild($formInner);

const formToObject = new FormToObject($formEl, { phpStyleMultipleSelects: false });
const result = formToObject.convertToObj();

expect(result).toEqual({"multiple": [["a", "b"]]});
});

// Note: this is a forced example.
it('when false, should return "multiple" key and multi-arrays as value', () => {
const $formEl = document.createElement('form');
const $formInner = document.createElement('div');
$formInner.innerHTML = `
<select name="multiple[]" multiple>
<option value="a" selected>a</option>
<option value="b" selected>b</option>
</select>
<select name="multiple[]" multiple>
<option value="c" selected>c</option>
<option value="d" selected>d</option>
</select>
`;
$formEl.appendChild($formInner);

const formToObject = new FormToObject($formEl, { phpStyleMultipleSelects: false });
const result = formToObject.convertToObj();

expect(result).toEqual({"multiple": [["a", "b"], ["c", "d"]]});
});

});
});

0 comments on commit cfda0b3

Please sign in to comment.