addDynamic přehazuje pořadí prvků při použití ajaxu
- Filip111
- Člen | 244
Ahoj, používám addDynamic pro komplikovanější formulář, kde je
v jednom kontejneru vložen další. Přeloženo: v jednom kontejneru se
zadávají dny,
ve vnořeném kontejneru se definují nějaké požadavky pro tento den,
kterých může být libovolný počet.
Na formuláři jsou tlačítka pro přidání/odebrání dne a
přidání/odebrání požadavků pro tento den.
Přidávání/odebírání dní funguje v pořádku, ale když přidám nový
prvek do požadavků dne (vnořený kontejner), přehodí se pořadí
definovaných dní. (Když pracuji s prvním dnem, tak nic, když pracují
s jiným dnem, vždy se přesune jako první).
A pozor, děje se to pouze pokud jsou tlačítka zajaxována. Při normálním requestu sepořadí dní nezmění. Poradíte? (je to stěžejní formulář celé aplikace a už se s tím peru docela dlouho).
Díky.
ps.: Kódy jsem ořezal na minimum, děje se to stále (u plného i prázdného formuláře).
public function createComponentEditForm() {
$form = new EditForm;
$form->addText('title', 'Název', 80);
$removeEvent = callback($this, 'MyFormRemoveElementClicked');
$step = $this;
$dates = $form->addDynamic('dates', function (\Nette\Forms\Container $date) use($removeEvent, $step) {
$date->addText('date', 'Datum', 10)
->getControlPrototype()->class('datepicker');
$date->addHidden('id');
$requirements = $date->addDynamic('reqs', function (\Nette\Forms\Container $req) use($removeEvent, $step) {
$req->addSelect('job', 'Kvalifikace', $step->context->akce->jobsRepository->catalog());
$req->addText('count', 'Počet', 5);
$req->addSubmit('remove', 'smazat')
->setValidationScope(FALSE) # zakáže validaci
->onClick[] = $removeEvent;
}, 0);
$requirements->addSubmit('add', 'Přidat kvalifikaci')
->setValidationScope(FALSE)
->onClick[] = callback($step, 'MyFormAddElementClicked');
$date->addSubmit('remove', 'Smazat datum')
->setValidationScope(FALSE) # zakáže validaci
->onClick[] = $removeEvent;
}, 1);
$dates->addSubmit('add', 'Přidat datum')
->setValidationScope(FALSE)
->onClick[] = callback($this, 'MyFormAddElementClicked');
$form->addSubmit('save', 'Uložit akci')->setAttribute('class', 'default');
$form->onSuccess[] = callback($this, 'editFormSuccess');
return $form;
}
Template:
{snippet datesForm}
{form editForm}
<div class="tab-content">
<div class="tab-pane" id="header">
<div class="well">
<table>
<tr><td>{label title /}</td><td>{input title}</td></tr>
</table>
</div>
</div>
<div class="tab-pane active" id="dates">
{foreach $form['dates']->containers as $id => $date}
<div class="row-fluid">
<div class="span4">
<div class="control-group">
<table>
<tr><td>{label dates-$id-date /}</td><td>{input dates-$id-date} {input dates-$id-id}</td></tr>
</table>
</div>
</div>
<div class="span3">
<table>
{foreach $date['reqs']->containers as $rid => $req}
<tr>
<td>{label dates-$id-reqs-$rid-job /}</td>
<td>{input dates-$id-reqs-$rid-job}</td>
<td>{input dates-$id-reqs-$rid-count class => 'input-mini ajax'}</td>
<td>{input dates-$id-reqs-$rid-remove, class => 'btn-mini ajax'}</td>
</tr>
{/foreach}
<tr><td></td><td></td><td></td><td>{input dates-$id-reqs-add, class => 'btn-mini btn-info ajax'}</td></tr>
</table>
</div>
</div>
<div class="row-fluid"><div class="span1"></div></div>
<div class="row-fluid">
<div class="span8"></div>
<div class="span2">{input dates-$id-remove, class => 'btn ajax'}</div>
<div class="span1">{input dates-add, class => 'btn btn-success ajax'}</div>
</div>
{/foreach}
</div>{*dates end*}
</div>{* tab-content end *}
<br />
{input cancel, class => 'btn'} {input save, class => 'btn btn-primary'}
{/form}
{/snippet}
U ajaxu nic speciálního nemám, jen inicializaci nového
scriptu nette.ajax.js
$(function () {
$.nette.init();
});
- Filip Procházka
- Moderator | 4668
Něco málo jsem tam předělal, ale nedaří se mi nasimulovat tu tvou chybu. Vyzkoušej tento sandbox. Pokud se ti to povede nasimulovat zde, tak pošli kompletní kód, třeba v zipu, ale na tomhle čistém sandboxu.
Editoval HosipLan (1. 9. 2012 1:52)
- Filip111
- Člen | 244
Bylo to o nervy a postupně jsem rozebíral celý projekt až na kost, ale
dohledal jsem kde je problém – nette.ajax.js
HosipLan má v odkazovaném sandboxu – nějakou jinou verzi scriptu, já
mám aktuální revizi g835c5e4
Je tam změna od řádku 305:
settings.data = this.serializeValues(analyze.form, settings.data);
}
}, {
serializeValues: function ($form, data) {
var values = $form.serializeArray();
for (var i = 0; i < values.length; i++) {
var name = values[i].name;
if (name in data) {
var val = data[name];
if (!(val instanceof Array)) {
val = [val];
}
val.push(values[i].value);
data[name] = val;
} else {
data[name] = values[i].value;
}
}
return data;
}
Nevím přesně co to znamená, ani nevim jak přesně tenhle script funguje (poprvé jsem ho zkusil před dvěma týdny), ale vidím tam něco s formulářem, takže hádám že jsem trefil správně.
Můžete na to někdo kompetentní kouknout, případně navrhnout co s tím?
Díky.
- Filip Procházka
- Moderator | 4668
Jop, to byla ta oprava :) Problém byl celou dobu v ajax scriptu. Javascript totiž náhodně přehazuje prvky v objektu. Asi jsem ti to mohl říct rovnou, že ;D promiň :)
Tady je pull request pro Vojtu.
Editoval HosipLan (4. 9. 2012 15:01)
- Filip111
- Člen | 244
Bezva dík, aspoň že je to vyřešený (zkusim ještě poslední revizi).
Kdyby to bylo bez těch dvou hodin hledání, byla by nuda :c)
(dlouho jsem to hledal v Presenteru a až když jsem zjistil, že PHP kód
vykopírovanej ze sandboxu u mě taky nefunguje, dohrabal jsem se postupně až
k js).