Unobtrusive ExtJS vďaka Nette

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

Vytvoril som novú komopnentu pre Nette, využívajúcu ExtJS pre unobtrusive javascriptové stránky. Tvorba stránok pomocou rôznych javascriptových frameworkov a používaním ajaxu apod. často znemožňuje ich prehliadanie pomocou programov, ktoré javascript buď nepodporujú alebo nie na dostatočnej úrovni (vyhľadávacie roboty alebo staršie prehliadače). Preto je potrebné poskytovať aj html verziu, čo môže viesť k ťažko udržateľným dualitám (javascriptová stránka vs stránka bez javascriptu). Riešenie je myšlienkovo jednoduché, ale zložitejšie na implementáciu. Príklad: stránkovadlo článkov. V html treba vygenerovať jednotlivé články čo patria pre danú stránku a ešte samotné stránkovadlo. Nad tým by bola javascriptová nadstavba, čo rozparsuje jednotlivé články a stránkovadlo a vytvorí niečo takéto: http://extjs.com/…/paging.html Pomocou ajaxu by sa prenášali neskôr už iba samotné ďalšie články.

Ako to vyzerá pre už spomenuté stránkovadlo?

<?php

class DefaultPresenter extends Ext::Presenter
{
	function actionDefault()
	{
		$store = new Ext::grid::Store(array(
			"proxy" => array($this, "getArticles"), // one day may be replaced by closures
			"reader" => new Ext::data::JsonReader(array(
				"root" => "articles",
				"totalProperty" => "total",
				"fields" => array(
					"title",
					"text"
				)
			))
		));
		$store->setDefaultSort("title", "asc");
		$store->load(array("params" => array("start" => 0, "limit" => 20)));

		$grid = new Ext::grid::GridPanel(array(
			"width" => 700,
			"height" => 500,
			"title" => "Paging example",
			"store" => $store,
			"sm" => new Ext::grid::RowSelectionModel(),
			"cm" => new Ext::grid::ColumnModel(array(
				array("header" => "Title", "dataIndex" => "title", "sortable" => true),
				array("header" => "Text", "dataIndex" => "text")
			)),
			"bbar" => new Ext::PagingToolbar(array(
				"store" => $store
				"displayInfo" => true,
				"pageSize" => 20,
				"displayMsg" => 'Displaying articles {0} - {1} of {2}',
			))
		));

		$this->template->grid = $grid;
	}

	function getArticles($limit, $offset, $orderBy, $direction)
	{
		return dibi::query( ... )->fetchAll();
	}
}

?>

Template:

<html>
<head>
{$presenter->renderExt()}
</head>
<body>
{$grid->render()}
</body>

Ako vyzerá vygenerovaný html kód?

<html>
<head>
... extjs subory, Ext.onReady transformujuca tabulky na grid ...
</head>
<body>
<table id="nette-ext-1" width="700" height="500">
<caption>Paging example</caption>
<thead>
	<tr><th><a href="... sort link ...">Title</a></th><th>Text</th></tr>
</thead>
<tbody>
	<tr><td>titulok</td><td>text</td></tr>
	...
</tbody>
<tfoot>
	<td collapse="2">
		<a href="..." title="First"><img ...></a>
		<a href="..." title="Previous"><img ...></a>
		Page <form ...><input value="1" ...></form> of 10
		<a href="..." title="Next"><img ...></a>
		<a href="..." title="Last"><img ...></a>
	</td>
</tfoot>
</table>
</body>
</html>

So zapnutým javascriptom to vyzerá podobne ako už spomenuté http://extjs.com/…/paging.html. V metóde beforeRender sa zistí či sa jedná o ajaxový požiadavok. Ak áno, tak sa vygenereje len zmena, ak nie tak celá stránka.

Pre eventy sa zatiaľ musí vypisovať čistý javascript (to sa asi príliš nezmení, pokiaľ neprídem na niečo geniálne), takže to vyzerá asi takto:

new Ext::grid::RowSelectionModel(array(
	"listeners" => array(
		"rowselect" => "function(sm, index, record) { alert('You selected row ' + index + ' with title ' + record.get('title')) }"
	)
));

Celkom pekné, nie? ;) Kód zatiaľ nie je k dispozícií, testujem to a implementujem najrôznejšie Ext komponenty. Ocením feedback.

Editoval fiso (25. 7. 2008 17:37)

David Grudl
Nette Core | 8218
+
0
-

To vypadá velmi dobře!

Pro zápis JavaScriptu by se možná dala použít třída, kterou jsem spíš z hecu zkusil napsat – mrkni do tests/Web.JavaScript.

Koukám, že už používáš PHP 5.3, to bys mohl rovnou používat i closures, ne?

fiso
Člen | 32
+
0
-

David Grudl napsal(a):
Koukám, že už používáš PHP 5.3, to bys mohl rovnou používat i closures, ne?

Hej, už by sa dali, ale keď som si inštaloval raný build 5.3 na server tak v ňom podpora pre closures ešte nebola.

washo
Člen | 88
+
0
-

To je presne to co se mi nechce psat znova a znova stale dokola. Bude nekdy ten kod k dispozici?
Diky

Chtelo by to vlanko zde na foru (mozna ze by si to zaslouzilo i vetsi prostor) pro hotove znovu pouzitelne komponenty. Jiste jich mate spousty! Nebo jsem to jenom nenasel?
Sorry za trochu OT.

Ne ze by se mi nechtelo nic psat, ale precejen, nette studuju asi tyden a rad bych trochu nabyl predstavy jak to vlasnte delat – psat ty komponenty. A zase proc porad dokola psat menu, datagridy, …

Editoval washo (30. 10. 2008 19:56)