Client and server side validation of checkbox array in container using own validator or onValidate method

Notice: This thread is very old.

5 years ago

fronty
Member | 16
+
0
-

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?

5 years ago

japlavaren
Backer | 412
+
0
-

Hi,

use CheckboxList and setRequired().

5 years ago

fronty
Member | 16
+
0
-

Well, I was blind. Thank's a lot!

5 years ago

japlavaren
Backer | 412
+
0
-

fronty wrote:

Well, I was blind. Thank's a lot!

;)