Dva selecty, ajax a ztracejici se hodnota
- musa
- Člen | 28
Ahoj,
mam ve formulari dva selecty, jednim vyberu spolecnost a na jeho onchange vymenim druhy za select s uzivateli patricimi k dane spolecnosti.
Problem: pokud po vymene toho druheho selectu s uzivateli udelam submit formulare jsou hodnoty tech vymenenych selectu NULL. Kdyz se podivam po vymene do html tak skutecne chybi atribut selected. Ikdyz ho pridam rucne v prohlizeci a pak submitnu tak nepomuze. Formular je vytvareny v tovarnicce. V debuggeru u toho controlu po vymene a naslednem submitu pole value skutecne neni.
Nenapada vas kde muze byt zakopany pes?
Formular:
<?php
$form->addSelect('managing_user_company_id', '_Manažer');
$form->addSelect('managing_user_id');
$form['managing_user_company_id']->getControlPrototype()
->onchange("loadUsers(this.value, '".$form['managing_user_id']->getHtmlId()."')");
?>
Javascript:
<script>
function loadUsers(value, selectId) {
$select = $('#'+selectId);
link = {$control->link('loadUsers', array('company_id'=>'_TOKEN_VALUE_1', 'select_name'=>'_TOKEN_VALUE_2'))};
link = link.replace('_TOKEN_VALUE_1', value);
link = link.replace('_TOKEN_VALUE_2', $select.attr('name'));
$.get(link, null, function(data) {
$select.parent().html(data.html);
});
}
</script>
Handler:
<?php
public function handleLoadUsers($company_id, $select_name) {
$users = UsersModel::getUsersByCompany($company_id);
$form = $this['form'];
$element = $form[$select_name];
$element->setItems($users);
$keys = array_keys($users); // pokus vnuceni hodnoty
$element->setValue($keys[0]);
$this->presenter->payload->html = $element->getControl()->render();
$this->presenter->sendPayload();
}
?>
- musa
- Člen | 28
Ty hodnoty jsou v postu, takže jako nejkratší workaround na který jsem přišel mám jednoduché doplnění těch hodnot právě z POSTu. Bohužel tím pádem nejspíš přicházím o ověření hodnot těch selectů:
<?php
private function getFixedValues($values) {
$form = $this['form'];
$items = $form['approving_user_id']->getItems();
$postValues = $this->presenter->getRequest()->getPost();
$values['approving_user_id'] = $postValues['approving_user_id'];
$values['managing_user_id'] = $postValues['managing_user_id'];
$values['implementing_user_id'] = $postValues['implementing_user_id'];
return $values;
}
?>
Nakonec sem ale šel tedy trochu jinou cestou. Přidám si submit tlačítko s handlerem, který vyplní select boxy podle aktuálního výběru, s tím že formulář jsem již před tím nechal zajaxovatět, tlačitko pak kliknu na onchange toho selectu:
<?php
$form->addSubmit('changeSelect', 'Změn firmu')
->setValidationScope(false)
->onClick[] = array($this, 'handleLoadUsers');
$form['approving_user_company_id']->getControlPrototype()
->onchange("$('#".$form['changeSelect']->getHtmlId()."').click();");
?>
Obsah selectu si uložím do pole innerSnippets (nechtěl sem zasahovat do snippetu nette):
<?php
public function handleLoadUsers() {
$form = $this['form'];
$values = $form->getValues();
$form['approving_user_id']->setItems(UsersModel::getUsersByCompany($values['approving_user_company_id']));
$form['managing_user_id']->setItems(UsersModel::getUsersByCompany($values['managing_user_company_id']));
$form['implementing_user_id']->setItems(UsersModel::getUsersByCompany($values['implementing_user_company_id']));
$this->session->saveValues($values, AuctionSession::STEP_1);
if ($this->presenter->isAjax()) {
$this->presenter->payload->innerSnippets[$form['approving_user_id']->getHtmlId()] = $form['approving_user_id']->getControl()->render();
$this->presenter->sendPayload();
} else {
$this->redirect('this');
}
}
?>
Aby se mi select vykreslil doplnil sem ještě v podstatě kopii snippet driveru s tím rozdílem, že se nahrazuje přes rodiče:
<script>
nette: {
updateSnippet: function (id, html) {
$("#" + id).html(html);
},
updateInnerSnippet: function (id, html) {
$("#" + id).parent().html(html);
},
success: function (payload) {
// redirect
if (payload.redirect) {
window.location.href = payload.redirect;
return;
}
// snippets
if (payload.snippets) {
for (var i in payload.snippets) {
jQuery.nette.updateSnippet(i, payload.snippets[i]);
}
}
// inner snippets
if (payload.innerSnippets) {
for (var i in payload.innerSnippets) {
jQuery.nette.updateInnerSnippet(i, payload.innerSnippets[i]);
}
}
}
}
</script>
Takové selecty jak je i vidět z kódu tam mám tři, submity tedy budou ke každému zvlášť a samotná tlačítka schovám.
Vidíte v tom někdo nějakou zásadní krpu která mi utekla?