Vypnutí řazení ve formulářích u addSelect()
- Webster.K
- Člen | 209
Zdravím všechny, mám takovou zapeklitost se kterou si už nevím rady. Jde o řazení prvků které dávám do formuláře do selectu.
Ve formuláři mám následující:
$form->addSelect('motor', 'Motorizace:')
->setHtmlAttribute('data-depends', $model->getHtmlName())
->setHtmlAttribute('data-url', $this->link('Car:motory', '#'))
->setHtmlAttribute('class', 'form-control form-control-sm')
->setPrompt('Nevybráno')
->setRequired('Vyberte motorizaci');
A o kus dál pak:
$form->onAnchor[] = fn() =>
$motor->setItems($model->getValue() ? $this->database->table('motorizace')->select('id, CONCAT(kw,"kw / ",hp,"hp / ",ccm,"ccm") AS motor')->where('model_id', $model->getValue())->order('kw ASC')->fetchPairs('id', 'motor') : []);
O hodně řádků je pak volána action která načítá obsah do tohoto
pole a odesílá to jako JSON. Vše voláno přes Ajax. Jde o formulář který
má asi 12 závislých prvků které se různě volají a doplňují. To co
řeším je to, že z DB se mi vrátí vše seřazeno ve formátu
[1=>‚hodnota‘,4=>‚druhá hodnota‘,2=>‚treti hodnota‘]. Což
je to čeho potřebuji dosáhnout, ale Nette mi to přehází.
Nemá někdo nápad jak toho docílit, aby Nette neřadilo prvky a nechalo je
tak, jak jdou z DB?
Editoval Webster.K (10. 11. 19:21)
- Webster.K
- Člen | 209
Ok, tak po čem jít, action ve stejném presenteru vypadá takto:
public function actionMotory($model): void {
$motor = array('Nevybráno');
$motor += $this->database->table('motorizace')->select('id, CONCAT(kw,"kw / ",hp,"hp / ",ccm,"ccm"," (",kod_motoru,")") AS motor')->where('model_id', $model)->order('hp ASC')->fetchPairs('id', 'motor');
$this->sendJson($motor);
}
a v šabloně pak script, ktery to tam sype
<script>
// najdeme na stránce všechny podřízené selectboxy
document.querySelectorAll('select[data-depends]').forEach((childSelect) => {
let parentSelect = childSelect.form[childSelect.dataset.depends]; // nadřízený <select>
let url = childSelect.dataset.url; // atribut data-url
let items = JSON.parse(childSelect.dataset.items || 'null'); // atribut data-items
// když uživatel změní vybranou položku v nadřízeném selectu...
parentSelect.addEventListener('change', () => {
// pokud existuje atribut data-items...
if (items) {
// nahrajeme rovnou do podřízeného selectboxu nové položky
updateSelectbox(childSelect, items[parentSelect.value]);
}
// pokud existuje atribut data-url...
if (url) {
// uděláme AJAXový požadavek na endpoint s vybranou položkou místo placeholderu
fetch(url.replace(encodeURIComponent('#'), encodeURIComponent(parentSelect.value)))
.then((response) => response.json())
// a nahrajeme do podřízeného selectboxu nové položky
.then((data) => updateSelectbox(childSelect, data));
}
});
});
// přepíše <options> v <select>
function updateSelectbox(select, items)
{
select.innerHTML = ''; // odstraníme vše
for (let id in items) { // vložíme nové
let el = document.createElement('option');
el.setAttribute('value', id);
el.innerText = items[id];
select.appendChild(el);
}
}
</script>
- Kamil Valenta
- Člen | 815
A není to jen tím, že používáš na dvou místech různý order()?
Ono by bylo nejlepší, kdyby to dodávala jedna modelová metoda…
$form->onAnchor[] = fn() => $motor->setItems($model->getValue() ? $this->database->table('motorizace')->select('...')->where(...)->order('kw ASC')->fetchPairs('id', 'motor') : []);
public function actionMotory($model): void { $motor = array('Nevybráno'); $motor += $this->database->table('motorizace')->select('...')->where(...)->order('hp ASC')->fetchPairs('id', 'motor'); $this->sendJson($motor); }