sortable menu do databáze

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

Ahoj,
myslím že se to tu nedávno řešilo (nevím jestli vyřešilo) ale nemůžu najít to vlákno takže se omlouvám za případnou duplicitu.

S nette právě začínám a narazil jsem na problém jak z AJAXU (??) vytáhnout data.
Takže: mám jQuery sortable

.latte

{snippet}
	<ul id="sortable" class="sortable">
		<li n:foreach="$titles as $ord => $title" class="ui-state-default">
			<img src="{$basePath}/images/updo.png" alt="move" class="handle" id="{$ord}"/>{$title}
		</li>
	</ul>
{/snippet}

 <script>
    $(function() {
        $("#sortable").sortable({
            revert: true,
            handle: '.handle',
            update : function () {
                $.get({link saveOrder!}, {'order': $("#sortable").sortable("toArray")});
            }
        });
    });
</script>

presenter

public function handleSaveOrder()
{
		$data = $this->getParameter('order');		// Vytáhnu data ?? - nejsem si jist google nepomohl
		$this->context->menu->updateMenu($data);  // Předám modelu pro zpracování s parametrem $data
}

model

	public function updateMenu($data){
		foreach ($data as $position => $name){
			$this->database->table('menu')->where("name", $name)->update(array('position', $position)); // UPDATE 'menu' SET `position` = $position WHERE `name` = $name
		}
	}

tuším že nedokážu vytáhnout data, ale TRACY mi nevyhodí chybu takže ani netuším v čem je zakopaný pes.

Díky všem za rady milda

japlavaren
Člen | 404
+
0
-

v debuggeri prehliadacu (F12) mas zalozku NET – otvor a mozes dabugovat:

  • ak ti po zoradeni pribudne dalsia polozka (request), mozes debuggovat vystup php (response, prip. si tam echovat daco)
  • ak ti nepribudne mas chybu v js . otvor console tab v prehliadaci a pozri chybu

ku kodu:

  • snippet je zbytocny (nepotrebujes prekreslovat nieco, co si zoradil)
  • pouzi data-sortable attribut na ul a mozes odseparovat js kod
  • pouzi $.nette.ajax namiesto $.get (ak sa to neulozilo, pouzijest redirect a nette.ajaxt ti to spravne redirectne)
  • pouzi handleSaveOrder(array $order) namiesto vytahovania z parametru (btw. order je nevhodny nazov premennej – order je objednavka. pouzi position alebo neico podobne)
  • nepoiuzivaj contexu ale injectuj sluzby
  • skus prepisat ten dotaz na databazu a tipujem, ze chyba je v nom… kedtak napis, helpnem znovu

Editoval japlavaren (15. 9. 2014 21:54)

milda404
Člen | 27
+
0
-

Ahoj,
tak jsem si otevřel konzoli a tam jsem zjistil, že mi to odesílá bez těch dat

...?do=saveOrder&order%5B%5D=&order%5B%5D=   // ?do=saveOrder&order[]=&order[]=

a jak by jsi jinak napsal ten dotaz?

$order přejmenuju a s těmi dalšími body se zkusím poprat

japlavaren
Člen | 404
+
0
-

myslim, ze to id musis mat na li (standartne berie sortable potomka seba cize ul > li). osobne preferujem data-id pretoze id by malo byt na stranke unikatne (a pri viac sortable to byt nemusi):

<ul class="sortable" data-sortable="{link sort!}>
	<li n:foreach="$titles as $ord => $title" class="ui-state-default" data-id="{$ord}">
		<img src="{$basePath}/images/updo.png" alt="move" class="handle"/>{$title}
	</li>
</ul>

<script>
$('.sortable').sortable({
	delay: 200,
	stop: function () {
		var el = $(this);
		$.nette.ajax({
			url: el.data('sortable'),
			data: { ids: el.sortable('toArray', { attribute: 'data-id' }) }
		});
	}
});
</script>

k somu ukladaniu do db:

<?php

public function sort(array $ids)
{
	if (!$ids) throw new \InvalidArgumentException("Empty \$ids");

	$orderBy = 'FIELD(id, ' . implode(',', array_map('intval', $ids)) . ')';
	$result = $this->getTable()->where('id', $ids)->order($orderBy);

	$position = 1;
	foreach ($result as $row) {
		if ($row->position != $position) {
			$row->update(array('position' => $position));
		}
		++$position;
	}
}

?>
milda404
Člen | 27
+
0
-

Ahoj,
tak právě jsem to rozchodil ale asi nebudeš šťastnej v jakým stavu.

latte

    <ul id="sortable" class="sortable">
        <li n:foreach="$titles as $ord => $title" class="ui-state-default" id="{$title}">
            <img src="{$basePath}/images/arrow.png" alt="move" class="handle" />{$title}
        </li>
    </ul>


 <script>
    $(function() {
        $("#sortable").sortable({
            revert: true,
            handle: '.handle',
            update : function () {
                $.get({link menuPosition!}, {'positions': $("#sortable").sortable("toArray")});
            }
        });
    });
</script>

presenter

public function handleMenuPosition(array $positions)
{
    if (!$positions) throw new \InvalidArgumentException("Empty \$positions");

	foreach($positions as $position => $title) {
		$this->database->table('menu')->where('title', $title)->update(array('ord' => $position));
	}
}

ještě se budu snažit poupravit ten <script>, abych používal $.nette.ajax než $.get a zápis do db aby mi nedělal presenter ale model

Pozn.: ten tvůj kód mi neudělal žádnou akci proto jsem se držel toho svýho

Editoval milda404 (16. 9. 2014 18:06)

japlavaren
Člen | 404
+
0
-

samotne nette.ajax nespravi nic. treba si odchytit exception pri ukladani a nasledne presmerovat (to sa dostane do nette ajax a to dokaze presmerovat)

milda404
Člen | 27
+
0
-

takže nette.ajax tam je jen pro zachytávání výjímek???

japlavaren
Člen | 404
+
0
-

nette ajax nevie odchytit vynimku. vie zabezpecit to, ze jed idchytis vynimku a spravis presmerovanie, presmeruje to za teba :) (resp. sa nemusis o to starat)