how to use callback class?
- thcom
- Backer | 94
hi i try to use DependentSelectBox in my project,
i dont like this structure, it is not pretty to read and to understand for me :(
<?php
$form->addDSelect('select2', 'Select 2', $form['select1'], function($form) {
$v = $form['select1']->getValue();
return array("$v 1" => "$v 1", "$v 2" => "$v 2", "$v 3" => "$v 3");
});
?>
i prefer something like
<?php
public function MyCbFunc($form) {
$v = $form['select1']->getValue();
return array("$v 1" => "$v 1", "$v 2" => "$v 2", "$v 3" => "$v 3");
}
$myCallBack = new Nette\Callback(array($this, '$this->getData', $form)); // not right code
$form->addDSelect('select2', 'Select 2', $form['select1'], $myCallBack);
?>
but i have problem how to righct declare the function MyCbFunc anfd how to right create a callback :(
i try many variants, but nothing was working well
thx
Tomas
Last edited by thcom (2013-05-22 14:33)
- Majkl578
- Moderator | 1364
In this case, it's being passed automatically in Form using an event (array of
callbacks), see Form::fireEvents().
In other cases, you pass it when you invoke the callback, as in my example
above, which presumes method
having one argument.
- thcom
- Backer | 94
yes!, i understand, but what to do, when i need my own parameter in callback function
when i use this :
<?php
$form->addDSelect('zbozi', 'Zbozi:', $form['kategorie'], $myCallBack(1));
?>
the $form parameter is replaced by constant 1
when i use
<?php
$form->addDSelect('zbozi', 'Zbozi:', $form['kategorie'], $myCallBack($form, 1));
?>
the parameters are given right, but i get error callback is not callable :(
Last edited by thcom (2013-05-23 21:37)
- Majkl578
- Moderator | 1364
Not sure what you're trying to do, but you can't set some parameters before you actually call the callback. The only way would be to wrap it in e.g. closure. In your latest code, you invoke the callback instead of just passing it (what seems to be your intention). Be more specific about your goal, we don't know what you're trying to do nor what addDSelect is.
- thcom
- Backer | 94
addDSelect is a part of dependentselectbox library, see my first post
now, one pair of dependent selectboxes is working, thanks to you advices
but i need a set of them, so i need index them like
<?php
$form->addDSelect('zbozi_01', ...
$form->addDSelect('zbozi_02', ...
$form->addDSelect('zbozi_03', ...
?>
this code i can create, but problem is, that in callback function (which loads data in second selectbox) i need a parametr – link to parent select box
<?php
public function MyCbFunc($form) {
$v = $form['select1']->getValue();
return array("$v 1" => "$v 1", "$v 2" => "$v 2", "$v 3" => "$v 3");
}
?>
there i need replace select1 with zbozi01, 02 … 03, so i need another parametr
i hope, i explain it well
- Majkl578
- Moderator | 1364
but i need a set of them
If you need a set of something repeating, you should use container, not add
index into name. So say we want zbozi
three times, it'd look
like this:
$zboziContainer = $form->addContainer('zbozi');
for ($i = 1; $i <= 3; $i++) {
$zboziContainer->addDSelect($i, 'Zbozi' . $i . ':', $form['kategorie'], $myCallBack);
}
And then you can access the control's instance like
$form['zbozi'][1]
.
problem is, that in callback function (which loads data in second selectbox) i need a parametr – link to parent select box
According to source, you receive an instance of DependentSelectBox itself as second argument. So your callback should look like this:
public function MyCbFunc(Container $container, DependentSelectBox $dSelectBox) {
$v = $dSelectBox->getValue();
return array("$v 1" => "$v 1", "$v 2" => "$v 2", "$v 3" => "$v 3");
}
(Note that container is acutally an instance of form, but this way it's more generic.)
But to answer your original question, if it was not possible to the above way, you would have to do it other, smelly way, here is one option – wrap your callback into another one:
$zboziContainer = $form->addContainer('zbozi');
for ($i = 1; $i <= 3; $i++) {
$zboziContainer->addDSelect($i, 'Zbozi:', $form['kategorie'], function (Container $container) use ($myCallBack, $i) {
$myCallBack($container, $i); // note how we're passing $i through closure to our own callback
});
}
// ...
public function MyCbFunc(Container $container, $dIndex) {
$v = $containerdSelectBox['zbozi'][$dIndex]->getValue();
return array("$v 1" => "$v 1", "$v 2" => "$v 2", "$v 3" => "$v 3");
}
No doubt there are other ways, but this was just to imagine.
- thcom
- Backer | 94
many thanks, containers looks very good
but i have last(i hope) problem
i need both selects in this container, for example 5 rows and on every row is kategorie select and zbozi dselect
<?php
$kategData = $this->getKategData(); // load data for select
$zboziContainer = $form->addContainer('zbozi');
for ($i = 1; $i <= 5; $i++) {
$zboziContainer->addSelect($i, 'Kategorie' . $i . ':', $kategData);
$zboziContainer->addDSelect($i, 'Zbozi' . $i . ':', $form['kategorie'], $myCallBack);
}
?>
problem is how to link dselect to master select, the third param in AddDSelect < $form[‘kategorie’] >
- Majkl578
- Moderator | 1364
Your example wouldn't work since there can't be two components (select and dselect here) with same name. So we need to go deeper ™ and a) add one more nested container or b) name each select uniquely. I'd prefer a) variant since it's much cleaner, so here it is:
$kategData = $this->getKategData(); // load data for select
$zboziContainer = $form->addContainer('zbozi'); // first level - container for repeated content
for ($i = 1; $i <= 5; $i++) { // second level - we'll add a container of two selects 5 times
$zboziItemContainer = $zboziContainer->addContainer($i); // third level - just because we have more than one repeated element
$zboziItemContainer->addSelect('category' 'Kategorie' . $i . ':', $kategData);
$zboziItemContainer->addDSelect(
'item',
'Zbozi' . $i . ':',
$zboziItemContainer['category'], // equivalent to $form['zbozi'][$i]['category']
$myCallBack
);
}
At first, it might look strange, but it has a logical reason. Because of this nesting, the resulting structure makes clear sense, it will look like this:
form
-zbozi
--1
---category
---item
--2
---category
---item
...
In the above code, note I also answered your question:
problem is how to link dselect to master select, the third param in AddDSelect < $form[‘kategorie’] >
Hope it solves your problem. :)