DependentSelectBox for Nette Framework. This dependent select box support dependence for more form controls , not only for select boxes but also dependence for text input, textarea and more.
The best way to install NasExt/DependentSelectBox is using Composer:
$ composer require nasext/dependent-select-box
Initialization in your bootstrap.php
:
NasExt\Forms\DependentExtension::registerControls();
Or enable the extension using your neon config:
extensions:
dependentSelectBox: NasExt\Forms\DependentExtension
Include from client-side folder:
dependentSelectBox.js
Initialize DependentSelectBox:
// @param callback a handler to be called when Ajax requests complete
$('[data-dependentselectbox]').dependentSelectBox(callback);
How to use DependentSelectBox in form:
$form->addDependentSelectBox('name', 'Label', $dependentControl1, $dependentControl2, ...)
->setDependentCallback(function ($values) {
return new \NasExt\Forms\DependentData(items, value, prompt);
})
$country = [
1 => 'Slovakia',
2 => 'Czechia',
3 => 'USA',
];
$citySlovakia = [
1 => 'Bratislaba',
2 => 'Kosice',
3 => 'Zilina',
];
$cityCzechia = [
1 => 'Praha',
2 => 'Brno',
3 => 'Ostrava',
];
$cityUsa = [
1 => 'Toronto',
2 => 'Philadelphia',
3 => 'Boston',
];
$street1 = [
1 => 'street1-1',
2 => 'street1-2',
3 => 'street1-3',
];
$street2 = [
1 => 'street2-1',
2 => 'street2-2',
3 => 'street2-3',
];
$street3 = [
1 => 'street3-1',
2 => 'street3-2',
3 => 'street3-3',
];
$form->addSelect('country', 'Country', $country)
->setPrompt('--- Select ---');
$form->addText('text', 'Text')
->setAttribute('placeholder', 'Text');
$form->addDependentSelectBox('city', 'City', $form['country'])
->setDependentCallback(function ($values) use ($citySlovakia, $cityCzechia, $cityUsa) {
$data = new \NasExt\Forms\DependentData;
if ($values['country'] === 1) {
$data->setItems($citySlovakia)->setPrompt('---');
} elseif ($values['country'] === 2) {
$data->setItems($cityCzechia)->setPrompt('---');
} elseif ($values['country'] === 3) {
$data->setItems($cityUsa)->setPrompt('---');
}
return $data;
})
->setPrompt('--- Select country first ---');
$form->addDependentSelectBox('street', 'Street', $form['city'], $form['text'])
->setDependentCallback(function ($values) use ($street1, $street2, $street3) {
$data = new \NasExt\Forms\DependentData;
if ($values['city'] === 1) {
if (!empty($values['text'])) {
$street1 = array_merge($street1, [10 => 'Value from Text input: ' . $values['text']]);
}
$data->setItems($street1);
} elseif ($values['city'] === 2) {
if (!empty($values['text'])) {
$street2 = array_merge($street2, [10 => 'Value from Text input: ' . $values['text']]);
}
$data->setItems($street2);
} elseif ($values['city'] === 3) {
if (!empty($values['text'])) {
$street3 = array_merge($street3, [10 => 'Value from Text input: ' . $values['text']]);
}
$data->setItems($street3);
return $data;
})
->setPrompt('--- Select ---');
// alternative with callback params
/* set callback params if the control should not be reloaded after change of any parents/params .. e.g. if control is dependant on another control3,
which is dependant on control2 and that is dependant on control1, we should set parent(control3) and params(control1, control2, control3) in this order.
Note, control3 has to be set within `params` as well (the order is important)
If, however, control should reload after change of any depending control, we set all those controls as parents(control1, control2, control3) in this order
order of params matters! as the control values are being set in that order, thus the allowed items for that particular control are being loaded based
on passed params.. otherwise we would have to call `->checkDefaultValue(false)` on those dependent controls
*/
$form->addDependentSelectBox('street', 'Street', $form['city'])
->setDependentCallbackParams([$form['city'], $form['text']])
->setDependentCallback(function ($values) use ($street1, $street2, $street3) {
$data = new \NasExt\Forms\DependentData;
if ($values['city'] === 1 && !empty($values['text'])) {
$data->setItems($street1);
}
return $data;
})
->setPrompt('--- Select ---');
You can set the select box as disabled with setDisabledWhenEmpty(true)
when empty, but remember, a disabled select box does not support validation.
$form->addDependentSelectBox('city', 'City', $form['country'])
->setDependentCallback(function ($values) use ($citySlovakia, $cityCzechia, $cityUsa) {
$data = new \NasExt\Forms\Controls\DependentSelectBoxData;
if ($values['country'] === 1) {
$data->setItems($citySlovakia);
} elseif ($values['country'] === 2) {
$data->setItems($cityCzechia);
} elseif ($values['country'] === 3) {
$data->setItems($cityUsa);
}
return $data;
})
->setDisabledWhenEmpty(true)
->setPrompt('--- Select ---');