Dva selecty, ajax a ztracejici se hodnota

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
musa
Člen | 28
+
0
-

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();
    }
?>
iguana007
Člen | 970
+
0
-

Možná stejný problém jako tady?
https://forum.nette.org/…eakceptovane?…

musa
Člen | 28
+
0
-

Díky moc, vypadá to na stejný problém. Zkusim si s tím ale ještě chvíli hrát, tam popsanému řešení bych se skutečně rád vyhnul. Zde přítomní nette guru nemají nápad kde by mohl být zakopaný pes?

musa
Člen | 28
+
0
-

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?