Skip to content

Commit

Permalink
CheckboxList: compact transmission mode in form name=val1,val2,val3
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed May 15, 2020
1 parent 5297f35 commit 458607d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 11 deletions.
15 changes: 15 additions & 0 deletions src/Forms/Controls/CheckboxList.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ public function __construct($label = null, array $items = null)
}


public function loadHttpData(): void
{
$data = $this->getForm()->getHttpData(Nette\Forms\Form::DATA_TEXT, substr($this->getHtmlName(), 0, -2));
if ($data === null) {
$data = $this->getHttpData(Nette\Forms\Form::DATA_TEXT);
} else {
$data = explode(',', $data);
}
$this->value = array_keys(array_flip($data));
if (is_array($this->disabled)) {
$this->value = array_diff($this->value, array_keys($this->disabled));
}
}


public function getControl(): Html
{
$input = parent::getControl();
Expand Down
67 changes: 58 additions & 9 deletions src/assets/netteForms.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
}
return values;

} else if (elem.name && elem.name.match(/\[\]$/)) { // multiple elements []
} else if (elem.name && elem.name.substr(-2) === '[]') { // multiple elements []
elements = elem.form.elements[elem.name].tagName ? [elem] : elem.form.elements[elem.name];
values = [];

Expand Down Expand Up @@ -660,16 +660,71 @@
};


/**
* Compact checkboxes
*/
Nette.compactCheckboxes = function(form) {
var name, i, elem, values = {};

for (i = 0; i < form.elements.length; i++) {
elem = form.elements[i];
if (elem.tagName
&& elem.tagName.toLowerCase() === 'input'
&& elem.type === 'checkbox'
) {
if (elem.name
&& elem.name.substr(-2) === '[]'
) {
name = elem.name.substr(0, elem.name.length - 2);
elem.removeAttribute('name');
elem.setAttribute('data-nette-name', name);
}

if (name = elem.getAttribute('data-nette-name')) { // eslint-disable-line no-cond-assign
values[name] = values[name] || [];
if (elem.checked && !elem.disabled) {
values[name].push(elem.value);
}
}
}
}

for (name in values) {
if (form.elements[name] === undefined) {
elem = document.createElement('input');
elem.setAttribute('name', name);
elem.setAttribute('type', 'hidden');
form.appendChild(elem);
}
form.elements[name].value = values[name].join(',');
}
};


/**
* Setup handlers.
*/
Nette.initForm = function(form) {
if (form.method === 'get') {
form.addEventListener('submit', function() {
Nette.compactCheckboxes(form);
});
}

check: {
for (var i = 0; i < form.elements.length; i++) {
if (form.elements[i].getAttribute('data-nette-rules')) {
break check;
}
}
return;
}

Nette.toggleForm(form);

if (form.noValidate) {
return;
}

form.noValidate = true;

form.addEventListener('submit', function(e) {
Expand All @@ -687,13 +742,7 @@
Nette.initOnLoad = function() {
Nette.onDocumentReady(function() {
for (var i = 0; i < document.forms.length; i++) {
var form = document.forms[i];
for (var j = 0; j < form.elements.length; j++) {
if (form.elements[j].getAttribute('data-nette-rules')) {
Nette.initForm(form);
break;
}
}
Nette.initForm(document.forms[i]);
}

document.body.addEventListener('click', function(e) {
Expand Down
17 changes: 15 additions & 2 deletions tests/Forms/Controls.CheckboxList.loadData.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ $series = [
];


test(function () use ($series) { // invalid input
$_POST = ['list' => 'red-dwarf'];
test(function () use ($series) { // empty input
$_POST = [];

$form = new Form;
$input = $form->addCheckboxList('list', null, $series);
Expand All @@ -42,6 +42,19 @@ test(function () use ($series) { // invalid input
});


test(function () use ($series) { // compact mode
$_POST = ['list' => 'red-dwarf,0'];

$form = new Form;
$input = $form->addCheckboxList('list', null, $series);

Assert::true($form->isValid());
Assert::same(['red-dwarf', 0], $input->getValue());
Assert::same(['red-dwarf' => 'Red Dwarf', 0 => 'South Park'], $input->getSelectedItems());
Assert::true($input->isFilled());
});


test(function () use ($series) { // multiple selected items, zero item
$_POST = ['multi' => ['red-dwarf', 'unknown', 0]];

Expand Down

0 comments on commit 458607d

Please sign in to comment.