Client and server side validation of checkbox array in container using own validator or onValidate method
- fronty
- Member | 16
Hi,
I may be blind, but can't find this anywhere. I would like to validate
array of checkboxes in container, so at least one have to be checked, both
client and server side. I managed to validate them server side, but my form is
in modal window and is submitted without AJAX (thus the modal window is closed),
so primary I need client side validation.
My code in form component currently looks similar to this:
<?php
class MyForm extends \Nette\Application\UI\Form {
public function __construct(\Nette\Database\Table\Selection $items) {
// Add array of checkboxes
$container = $this->addContainer('id_items');
foreach ($items as $item) {
$container->addCheckbox($item->id, $item->name);
}
// Submit and process
$this->addSubmit('send', 'Save');
$this->onSuccess[] = $this->processMyForm;
$this->onValidate[] = $this->validateMyForm;
}
public function validateMyForm(MyForm $form) {
$values = $form->getValues(TRUE);
$items = array_filter($values['id_items']);
if (empty($items)) {
$form->addError('Choose at least one item.');
}
}
public function processMyForm(MyForm $form) {
// ... insert to DB or whatever
}
}
?>
According to this and this I tried to create my own validator so I can create it's client side counterpart like so:
checkboxRules.php
<?php
namespace App\Validators;
use Nette\ComponentModel\IContainer;
class CheckboxRules {
const ONE_CHECKED = 'CheckboxRules::validateOneChecked';
public static function validateOneChecked(IContainer $control, $args) {
// Somehow check at least one selected item (probably from form instance in $args)
}
}
?>
myForm.php
<?php
public function __construct(\Nette\Database\Table\Selection $items) {
$container = $this->addContainer('id_items');
foreach ($items as $item) {
$container->addCheckbox($item->id, $item->name)
->addRule(CheckboxRules::ONE_CHECKED, 'Choose at least one item.');
}
...
}
?>
main.js
<script>
Nette.validators.CheckboxRules_validateOneChecked = function(elem, args, val) {
// console.log(args);
// Somehow validate at least one checked input with the same name
return false;
};
</script>
But I ended very soon with Tracy error
Unknown validator 'CheckboxRules::validateOneChecked' for control '1'.
,
which is very strange, because ONE_CHECKED constant value was output as string
‘CheckboxRules::validateOneChecked’, so the file should be included
correctly. So I changed the callback argument in myForm.php
like so:
<?php
...
$container->addCheckbox($item->id, $item->name)
->addRule(callback(CheckboxRules::ONE_CHECKED), 'Choose at least one item.');
...
?>
With this code I am able to view the form, but after the form is submitted,
I end up with Tracy error
Callback 'CheckboxRules::validateOneChecked' is not callable.
.
I tried to remove arguments from
CheckboxRules::validateOneChecked()
, but the error remained.
What am I doing wrong or how can be this type of validation achieved?