Skip to content

Commit d68d74d

Browse files
committed
CheckboxList: compact transmission mode in form name=val1,val2,val3
Must be enabled via <form data-nette-compact>
1 parent af22a26 commit d68d74d

File tree

3 files changed

+88
-11
lines changed

3 files changed

+88
-11
lines changed

src/Forms/Controls/CheckboxList.php

+15
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,21 @@ public function __construct($label = null, array $items = null)
4646
}
4747

4848

49+
public function loadHttpData(): void
50+
{
51+
$data = $this->getForm()->getHttpData(Nette\Forms\Form::DATA_TEXT, substr($this->getHtmlName(), 0, -2));
52+
if ($data === null) {
53+
$data = $this->getHttpData(Nette\Forms\Form::DATA_TEXT);
54+
} else {
55+
$data = explode(',', $data);
56+
}
57+
$this->value = array_keys(array_flip($data));
58+
if (is_array($this->disabled)) {
59+
$this->value = array_diff($this->value, array_keys($this->disabled));
60+
}
61+
}
62+
63+
4964
public function getControl(): Html
5065
{
5166
$input = parent::getControl();

src/assets/netteForms.js

+58-9
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
}
8989
return values;
9090

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

@@ -665,16 +665,71 @@
665665
};
666666

667667

668+
/**
669+
* Compact checkboxes
670+
*/
671+
Nette.compactCheckboxes = function(form) {
672+
var name, i, elem, values = {};
673+
674+
for (i = 0; i < form.elements.length; i++) {
675+
elem = form.elements[i];
676+
if (elem.tagName
677+
&& elem.tagName.toLowerCase() === 'input'
678+
&& elem.type === 'checkbox'
679+
) {
680+
if (elem.name
681+
&& elem.name.substr(-2) === '[]'
682+
) {
683+
name = elem.name.substr(0, elem.name.length - 2);
684+
elem.removeAttribute('name');
685+
elem.setAttribute('data-nette-name', name);
686+
}
687+
688+
if (name = elem.getAttribute('data-nette-name')) { // eslint-disable-line no-cond-assign
689+
values[name] = values[name] || [];
690+
if (elem.checked && !elem.disabled) {
691+
values[name].push(elem.value);
692+
}
693+
}
694+
}
695+
}
696+
697+
for (name in values) {
698+
if (form.elements[name] === undefined) {
699+
elem = document.createElement('input');
700+
elem.setAttribute('name', name);
701+
elem.setAttribute('type', 'hidden');
702+
form.appendChild(elem);
703+
}
704+
form.elements[name].value = values[name].join(',');
705+
}
706+
};
707+
708+
668709
/**
669710
* Setup handlers.
670711
*/
671712
Nette.initForm = function(form) {
713+
if (form.method === 'get' && form.hasAttribute('data-nette-compact')) {
714+
form.addEventListener('submit', function() {
715+
Nette.compactCheckboxes(form);
716+
});
717+
}
718+
719+
check: {
720+
for (var i = 0; i < form.elements.length; i++) {
721+
if (form.elements[i].getAttribute('data-nette-rules')) {
722+
break check;
723+
}
724+
}
725+
return;
726+
}
727+
672728
Nette.toggleForm(form);
673729

674730
if (form.noValidate) {
675731
return;
676732
}
677-
678733
form.noValidate = true;
679734

680735
form.addEventListener('submit', function(e) {
@@ -692,13 +747,7 @@
692747
Nette.initOnLoad = function() {
693748
Nette.onDocumentReady(function() {
694749
for (var i = 0; i < document.forms.length; i++) {
695-
var form = document.forms[i];
696-
for (var j = 0; j < form.elements.length; j++) {
697-
if (form.elements[j].getAttribute('data-nette-rules')) {
698-
Nette.initForm(form);
699-
break;
700-
}
701-
}
750+
Nette.initForm(document.forms[i]);
702751
}
703752

704753
document.body.addEventListener('click', function(e) {

tests/Forms/Controls.CheckboxList.loadData.phpt

+15-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ $series = [
2929
];
3030

3131

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

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

4444

45+
test(function () use ($series) { // compact mode
46+
$_POST = ['list' => 'red-dwarf,0'];
47+
48+
$form = new Form;
49+
$input = $form->addCheckboxList('list', null, $series);
50+
51+
Assert::true($form->isValid());
52+
Assert::same(['red-dwarf', 0], $input->getValue());
53+
Assert::same(['red-dwarf' => 'Red Dwarf', 0 => 'South Park'], $input->getSelectedItems());
54+
Assert::true($input->isFilled());
55+
});
56+
57+
4558
test(function () use ($series) { // multiple selected items, zero item
4659
$_POST = ['multi' => ['red-dwarf', 'unknown', 0]];
4760

0 commit comments

Comments
 (0)