Nullpointer.cz - RSS odběr Dexempo pro váš kód http://www.nullpointer.cz/ Webová aplikace v Javě od A do Z – Hello world ve Struts2 + zobrazení ve webovém prohlížeči (3.díl) Thu, 19 Sep 2013 12:04:54 GMT http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-hello-world-ve-struts2-zobrazeni-ve-webovem-prohlizeci-3-dil <!-- by Texy2! --> <p>V předchozích dílech tohoto seriálu jsme si připravili v Eclipse java projekt a nakonfigurovali Maven2 pro integraci externích knihoven do našeho projektu. Pro potřeby tohoto dílu budeme potřebovat do našeho projektu připojit <strong>framework Struts2.</strong> V minulém díle jsme tuto závislost do pom.xml již přidávali, přesto pro jistotu ještě jednou:</p> <p><strong>Obsah souboru pom.xml</strong></p> <pre class="html"><code>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;groupId&gt;cz.atax&lt;/groupId&gt; &lt;artifactId&gt;base-maven&lt;/artifactId&gt; &lt;packaging&gt;pom&lt;/packaging&gt; &lt;version&gt;1.0&lt;/version&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.struts&lt;/groupId&gt; &lt;artifactId&gt;struts2-core&lt;/artifactId&gt; &lt;version&gt;2.3.8&lt;/version&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;/project&gt;</code></pre> <h3>Cíl</h3> <p>Zadat do webového prohlížeče konkrétní adresu, např. <strong>localhost:8095/Nu­llpointer/hello­World</strong>, která povede na stránku, kde nebude nic jiného než hláška Hello World.</p> <h3>Postup</h3> <ol> <li>Vytvořit potřebné konfigurační soubory: <p>a. struts.xml</p> <p>b. web.xml</p> </li> <li>Vytvořit potřebné soubory pro vypsání hlášky: <p>a. java třídu HelloWorldActi­on.java</p> <p>b. jsp soubor helloWorld.jsp</p> </li> <li>Zprovoznit lokální server Tomcat a spustit na něm naši aplikaci – to vše přímo v Eclipsech</li> </ol> <h2>Ad 1) a. struts.xml</h2> <p>Nejdříve obsah souboru a posléze vysvětlím, o co tam jde:</p> <p><strong>Obsah souboru struts.xml</strong></p> <pre class="html"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"&gt; &lt;struts&gt; &lt;package name="nullpointer" extends="struts-default"&gt; &lt;action name="helloWorld" method="helloWorldMethod" class="cz.nullpointer.helloWorld.HelloWorldAction"&gt; &lt;result name="success"&gt;helloWorld.jsp&lt;/result&gt; &lt;/action&gt; &lt;/package&gt; &lt;/struts&gt;</code></pre> <p>Soubor uložíme do source folder <strong>src/main/resou­rces</strong> pod jménem <strong>struts.xml.</strong> Tedy pravé tlačítko myši na folder src/main/resources v menu vybereme <strong>New…/Other…/Xml/XML file</strong> a do souboru zkopírujeme obsah uvedený výše. Soubor struts.xml je základ frameworku Struts2 a jeho pochopení je základ, který nám ovšem bude stačit i na mnohem složitější úkoly než Hello World. Důležitý je tento odstaveček:</p> <pre class="html"><code>&lt;action name="helloWorld" method="helloWorldMethod" class="cz.nullpointer.helloWorld.HelloWorldAction"&gt; &lt;result name="success"&gt;helloWorld.jsp&lt;/result&gt; &lt;/action&gt;</code></pre> <p>Takže popořadě:</p> <ul> <li><strong>name=„helloWor­ld“:</strong> pokud bude požadavek v prohlížeči localhost:8095/Nu­llpointer/<strong>hello­World</strong>, bude se používat toto mapování.</li> <li><strong>method=„hello­WorldMethod“ a class=„cz.nullpo­inter.helloWor­ld.HelloWorldAc­tion“&gt;:</strong> pro zpracování požadavku se bude volat metoda helloWorldMethod v java třídě cz.nullpointer­.helloWorld.He­lloWorldAction (zatím nemáme vytvořené, viz níže)</li> <li><strong>&lt;result name=„success“&gt;he­lloWorld.jsp&lt;/re­sult&gt;:</strong> vrátí-li metoda helloWorldMethod řetězec „success“ zobrazí se v prohlížeči jsp soubor helloWorld.jsp (což je v podstatě takové obohacené html, viz níže).</li> </ul> <h2>Ad 1) b. web.xml</h2> <p>Pokud jste správně prošli předchozími kroky tohoto seriálu, měli byste mít již soubor <strong>web.xml</strong> ve vašem projektu, konkrétně ve složce <strong>WEB-INF</strong>. Pokud ne, vytvořte jej. Smažte jeho případný obsah a vložte do něj tento:</p> <p><strong>Obsah souboru web.xml</strong></p> <pre class="html"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&gt; &lt;filter&gt; &lt;filter-name&gt;struts2&lt;/filter-name&gt; &lt;filter-class&gt;org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;struts2&lt;/filter-name&gt; &lt;url-pattern&gt;/*&lt;/url-pattern&gt; &lt;/filter-mapping&gt; &lt;/web-app&gt;</code></pre> <p>V tomto souboru lze provádět spoustu různých užitečných konfigurací, to však není předmětem našeho seriálu. Stručně se dá říct, že jsme zde řekli, ať všechny požadavky v url zpracovává Struts2 (a tím přijdou na řadu struts.xml) a to nám (nejen) pro Hello World bohatě stačí.</p> <h2>Ad 2) a. Java třída HelloWorldActi­on.java</h2> <p>V source folderu <strong>src/main/java</strong> vytvoříme <strong>package cz.nullpointer­.helloWorld</strong> a v něm třídu <strong>HelloWorldActi­on.java.</strong> Do něj zadáme tento obsah :</p> <p><strong>Obsah souboru HelloWorldActi­on.java</strong></p> <pre class="java"><code>package cz.nullpointer.helloWorld; import com.opensymphony.xwork2.ActionSupport; public class HelloWorldAction extends ActionSupport { public String helloWorldMethod() { return SUCCESS; } }</code></pre> <p>Důležitá je metoda:</p> <pre class="java"><code>public String helloWorldMethod() { return SUCCESS; }</code></pre> <p>Tato metoda nedělá nic jiného, než že vrací String konstantu SUCCESS, na kterou máme namapováno naše jsp (ještě není vytvořené, viz níže). Nyní není potřeba, aby se zde dělo cokoliv jiného, ale v běžném vývoji zde samozřejmě probíhá načítání potřebných dat pro zobrazení jsp (stránky), typicky načítání dat z databáze. Asi není třeba dodávat, že tohle je přesně ta třída a metoda (HelloWorldAction a helloWorldMethod), kterou jsme zmiňovali výše v našem struts.xml (viz bod 1) a.)</p> <h2>Ad 2) b. jsp soubor helloWorld.jsp</h2> <p>Než vytvoříme <strong>jsp helloWorld.jsp</strong>, je důležité vědět, kde je root, kam se struts2 defaultně dívá po jsp a kam tedy máme jsp soubor uložit. Možná jste si všimli, že ve struts.xml jsme uvedli pouze helloWorld.jsp, žádnou cestu, žádné složky. To znamená, že se jsp bude hledat v defaultní složce, což je ../WEB-INF (nadřazený WEB-INF, čili jsp musí být ve stejné složce jako je složka WEB-INF). Tam se budou hledat v prvé řadě jsp soubory. V konfiguraci Struts2 lze samozřejmě tuto cestu změnit, ale tím se nyní nebudeme zabývat. Vytovříme tedy soubor helloWorld.jsp s tímto obsahem:</p> <p><strong>Obsah souboru helloWorld.jsp</strong></p> <pre class="html"><code>&lt;%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%&gt; &lt;%@ taglib prefix="s" uri="/struts-tags"%&gt; &lt;h1&gt;Hello World!&lt;/h1&gt;</code></pre> <p>Za komentář zde stojí možná jen &lt;%@ taglib prefix=„s“ uri=„/struts-tags“%&gt;. Tento zápis nám říká, že budeme v našem jsp používat struts2 tagy (některé nejtypičtější si ukážeme v dalším díle našeho seriálu), v současném jsp žádné Struts2 tagy nepoužíváme, vypisujeme jen Hello World v html nadpisu h1, ale radši jsem to uvedl již teď, ať na to pak nezapomeneme.</p> <h2>Ad 3) Zprovoznit lokální server Tomcat a spustit na něm naši aplikaci – to vše přímo v Eclipse</h2> <p>Nejdřív musíme <strong>stáhnout Tomcat na adrese <a href="http://tomcat.apache.org/">http://tomcat.apache.org/</a></strong> je v levé menu sekce download. Stáhněte nejnovější verzi (v tomto článku používám verzi Tomcat 7) a uložte jej na disk. V současné době lze již stáhnout verzi Tomcatu 8, ale zdá se, že jej Eclipse ve verzi jakou používám (viz předchozí díl seriálu) nepodporuje. Nyní přidáme Tomcat do Eclipse. V Eclipse dáme v menu <strong>Window/Show view…/Other/Ser­ver/Servers</strong> a tím si v prostředí trvale zobrazíme záložku Servers (záložka se ve spodní části vývojového prostředí). V ní by mělo být napsáno zhruba následující: <strong>No servers available. Define a new server from the new server wizard…</strong> Klikneme tedy na odkaz new server wizard. Objeví se dialogové okno, kde zvolíme Apache/Tomcat [VERZE] a klikneme na tlačítko Next. Eclipse bude chtít vědět cestu k Tomcatu, zadejte tedy umístění, kam jste Tomcat před chvíli nahráli. Zase Next. Nyní chce Eclipse vědět, které projekty chcete pod server umístit. Ve sloupci Available by měl být pouze jeden, náš projekt, klikněte na něj a pak klikněte na tlačítko Add &gt;. Projekt by se měl přesunout do sloupce Configured. Nyní můžeme dát Finish.</p> <p>V záložce Servers v Eclipse by již nyní měl být vidět přidaný server. Já tam mám označení <strong>Tomcat v7.0 Server at localhost [Stopped, Synchronized]</strong>. Pokud nám nic neběží na portu 8080, můžeme vše nechat při defaultním nastavení, jinak musíme port změnit. Navrhuji v každém případě radši port změnit, abychom se vyhnuli současným a případně i budoucím konfliktům. Klikněte dvakrát na server Tomcat v7.0 Server at localhost… a objeví se konfigurace. Zde nalevo najdeme sekce <strong>Ports</strong>, kde je tabulka používaných portů, kde je mimo jiné i <strong>http/1.1 a port number 8080</strong>. Ten změníme na něco jiného, třeba <strong>8095</strong>, ať to máte stejné jak v tomto příkladu a <strong>uložíme změny pomocí CTRL+S.</strong></p> <p>Dále je velmi důležité nastavit projektu správný <strong>context root.</strong> Nyní už jsme kousek od toho zadat do prohlížeče toto: localhost:8095/Nu­llpointer/hello­World a zobrazit si nadpis Hello World! (tedy naše jsp) v prohlížeči. Považuji za důležité si tuto adresu ještě krátce rozebrat.</p> <ul> <li><strong>localhost:8095</strong> – localhost je default a 8095 je port, který jsme před chvíli nastavovali v Tomcat konfiguraci.</li> <li><strong>Nullpointer</strong> – to jsme zatím nikde nenastavovali, to je právě onen context root. Dejme pravé tlačítko myši na project, zvolme v menu Properties a najděme v levém menu Web project settings a klikněme na tuto položku. Zde nastavíme Context root, můžeme dát Nullpointer, jak používám v tomto příkladě.</li> <li><strong>helloWorld</strong> – máme nastaveno ve struts.xml (viz výše, řádek <em>&lt;action name=„helloWorld“</em>)</li> </ul> <p><strong>Důležité – Deployment Assembly:</strong> nyní je ještě potřeba překontrolovat jednu věc. Klikněte pravým tlačítkem na projekt (v levém sloupečku) a zvolte <strong>Properties/De­ployment Assembly.</strong> V tabulce byste měli mít ve sloupci Source 4 záznamy: <strong>/src/main/java, /src/main/resou­rces, /src/test/java, /WebContent a Maven Dependencies.</strong> Ve sloupci Deploy Path byste měli mít (popořadě) následující: <strong>WEB-INF/classes (3×), /, WEB-INF/lib.</strong> O co tu jde? Tady se říká, do jaké struktury má Eclipse zbuildovat náš projekt. <strong>Nemusíte mít přesně stejnou strukturu, jakou jsem tady nastínil.</strong> Záleží např. na tom, jakou používáte Eclipse perspektivu, jakou máte verzi Eclipse (viz předchozí díly), jak moc důsledně jste dodrželi kroky z předchozích dílů našeho seriálu apod. Každopádně ve <strong>WEB-INF/classes</strong> by měly být <strong>java soubory + struts.xml</strong> (já jej mám v src/main/re­sources), <strong>Maven Dependencies</strong> ve <strong>WEB-INF/lib</strong> a v kořenové složce <strong>/</strong> by měla být složka, kde máme <strong>jsp soubory</strong> (v našem případě jeden jsp soubor helloWorld.jsp) a později třeba javascriptové knihovny a css. Pokud vaši strukturu nemáte v tomto duchu, pomocí tlačítka Add.. doplňte potřebné věci. Hlavně Maven Dependencies zde často chybí.</p> <p>Nyní nezbývá nic jiného, než pustit server a modlit se. Server pustíme tak, že v Eclipse v záložce Servers klikneme pravý tlačítkem myši na <strong>Tomcat v7.0 Server at localhost [Stopped, Synchronized]</strong> a zvolíme v menu <strong>Start</strong> nebo <strong>Debug</strong> (pro tuto chvíli je jedno co). Během pár vteřin by se měl server spustit, což uvidíme v Eclipse v záložce Console. Neměla by se tam objevit žádná chyba (Exception).</p> <p>Zkuste si nyní spusti prohlížeč a zadat do adresního řádku <strong>localhost:8095/Nu­llpointer/hello­World. Vidíte text Hello World? Gratuluji, povedl se vám malý zázrak!</strong> A také jste úspěšně dokončili tuto část seriálu. Můžete si klidně vyzkoušet, že do jsp můžete vkládat libovolné html i css, jakoby to byl opravdu obyčejný html soubor.</p> <p>Většinou se to hned napoprvé nepovede. Pokud se nepodařilo, pokusím se v následujícím odstavci poukázat na nejčastější chyby.</p> <h3>Nepovedlo se to rozjet?</h3> <p>V tomto případě po zadání adresy <strong>localhost:8095/Nu­llpointer/hello­World</strong> se určitě objeví chyba 404, že stránku nelze zobrazit.</p> <ol> <li>Zkontrolujte, že opravdu máte správně nastavený port (localhost:8095), context root (Nullpointer) a akci ve struts.xml (helloWorld, viz řádek &lt;action name=„helloWorld“))</li> <li>Zkontrolujte v Eclipse konzoli, že se neobjevují žádné Exception. Pokud ano, zkuste následující: <ul> <li>zavřít a otevřít projekt (pravé tlačítko na projekt, <strong>Close Project/Open Project</strong>)</li> <li>dejte pravé tlačítko na projekt a zvolte <strong>Refresh</strong></li> <li>dejte pravé tlačítko na server a zvolit možnosti <strong>Clean Tomcat Work Directory…</strong> a pak také ve stejném menu <strong>Clean…</strong></li> <li>v Eclipse nahoře v menu dejte <strong>Project/Clean/Cle­an all projects</strong> a rovnou zkontrolujte, jestli máte v nabídce Project zaškrtnuté <strong>Build Automatically</strong></li> <li>zkuste <strong>vypnout a znovu zapnout Eclipse</strong> a znovu provést <strong>refresh a cleanování.</strong> </li> </ul> </li> <li><strong>Výjímka SEVERE: Exception starting filter struts2 java.lang.Clas­sNotFoundExcep­tion: org.apache.strut­s2.dispatcher­.ng.filter.Strut­sPrepareAndExe­cuteFilter:</strong> zkontrolujte, že máte v projektu (v levém sloupečku v Eclipse) Maven Dependencies. Pokud nemáte, nezafungoval maven a asi máte špatně pom.xml nebo špatně instalovaný maven plugin (viz předchozí díl tohoto seriálu). Pokud tam Maven Dependencies máte, zkuste v Eclipse pomocí CTRL+T vyhledat chybějící třídu org.apache.strut­s2.dispatcher­.ng.filter.Strut­sPrepareAndExe­cuteFilter. Pokud jste tuto třídu nenalezli, nejspíš vám v pom.xml chybí závislost na struts2 (viz začátek tohoto dílu). Pokud jste třídu nalezli, nejspíš je problém v chybějících Maven Dependencies v Deployment Assembly (viz pár odstavců výše).</li> <li>Pokud se stále Exception při startu objevuje, tak asi nezbývá než <strong>googlit</strong> nebo můžete napsat (např. do komentářů pod tento článek) váš problém (např. jakou Exception vám to háže při startu) a já vám mohu zkusit poradit a současně tím poté zkvalitnit tento odstavec.</li> </ol> <p>Můžete také zkusit si na disku najít (po spuštění serveru, ať už úspěšném nebo neúspěšném) složku <strong>org.eclipse.wst­.server.core</strong>. Měla by být ve vašem workspace v cestě <strong>[CESTA_K_VASE­MU_WORKSPACE]/­.metadata/.plu­gins/ org.eclipse.wst­.server.core.</strong> Pokud tuto složku otevřete měla by tam být složka <strong>tmp0/ wtpwebapps</strong> a v ní složka <strong>Nullpointer</strong> (náš context root, viz výše). V této složce bychom měli najít další dvě složky <strong>Meta-inf</strong> a <strong>Web-inf</strong> a také naše jsp <strong>helloWorld.jsp.</strong> Sem totiž Eclipse zbuildoval (pokud se vše podařilo) náš projekt. Ještě můžeme zkontrolovat na tom stejném místě, že ve složce <strong>Web-inf/classes/cz/nu­llpointer/hello­World/</strong> je zkompilovaná třída <strong>HelloWorldActi­on.class.</strong> Pokud tohle vše vidíme, tak build a deploy pod server proběhl v pořádku a chyba by měla být v zadávané adrese (špatný port, špatný název contextRoot, špatný název akce). Pokud to tam nevidíte, proběhl špatně build, nejspíš z důvodu nějaké Exception při startu serveru (vidíme v konzoli). Řešení Exception viz výše (bod 2.).</p> <h3>Závěr</h3> <p>Myslím, že to nejhorší máme v tomto seriálu za sebou a teď už přejdeme od nudných konfigurací k zábavnějším věcem. Ještě nás samozřejmě čeká konfigurace Springu a Hibernatu, ale to až přespříští díl. Příští díl si ukážeme základní využití Struts2 frameworku a seznámíme se s nejpoužívanějšími struts2 tagy.</p> http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-hello-world-ve-struts2-zobrazeni-ve-webovem-prohlizeci-3-dil Webová aplikace v Nette pro začátečníky - DataTables - díl 4. Sun, 03 Feb 2013 22:20:53 GMT http://www.nullpointer.cz/webova-aplikace-v-nette-pro-zacatecniky-datatables-dil-4 <p>Dnes uděláme za naším seriálem malou tečku v podobě implementace šikovné jQuery tabulky DataTables. Ukážeme si na tom jak jednoduché je použití Ajaxu v Nette Frameworku.</p> <h2>DataTables</h2> <p>Poměrně často potřebujeme v aplikaci nějakou přehledovou tabulku s daty a potřebujeme tato data nějak řadit, filtrovat, hledat. Nette poskytuje podobné nástroje formou několika <a href="http://addons.nette.org/cs/#toc-datagridy">doplňků</a>, které doporučuji prostudovat a vyzkoušet, mimo jiné i proto, že ukazují ještě víc z toho, jak lze v Nette pracovat s ajaxem. My se dnes ale vydáme trochu jinou cestou – použijeme jQuery plugin, který poskytuje přinejmenším srovnatelné funkce.</p> <p>Plugin <a href="http://www.datatables.net/download">stáhneme</a> a vyzobneme si z něj soubory <code>jquery.dataTa­bles.min.js</code> a <code>jquery.dataTa­bles.css</code></p> <p>Soubory nakopírujeme do projektu a nalinkujeme standartním způsobem</p> <pre class="html"><code>&lt;head&gt; ... &lt;link rel="stylesheet" type="text/css" href="{$basePath}/css/jquery.dataTables.css" /&gt; ... &lt;script src="{$basePath}/js/jquery.dataTables.min.js"&gt;&lt;/script&gt; ... &lt;/head&gt;</code></pre> <h2>Šablona výpisu uživatelů</h2> <p>V šabloně výpisu uživatelů <code>Homepage/defau­lt.latte</code> máme odminule základní výpis uživatelů v seznamu. To nám už nebude stačit – DataTables plugin vyžaduje html tabulku ve zhruba tomto znění:</p> <pre class="html"><code>&lt;table id="users"&gt; &lt;thead&gt; &lt;th&gt;Jméno&lt;/th&gt; &lt;th&gt;Email&lt;/th&gt; &lt;th&gt;Role&lt;/th&gt; &lt;/thead&gt; &lt;tbody&gt;&lt;/tbody&gt; &lt;/table&gt;</code></pre> <p>Ze zápisu tabulky vyplývá, že jsme se rozhodli vypisovat jméno, email a roli uživatelů. Oživení a naplnění tabulky pomocí jQuery vypadá potom takto:</p> <pre class="js"><code>$('#users').dataTable( { "sAjaxSource": {link usersJson!}, "aoColumns": [ {"mData": "name"}, {"mData": "email"}, {"mData": "role"} ] });</code></pre> <p>Tímto kódem jsme řekli, že tabulka s id users bude plněna daty z adresy <code>{link usersJson!}</code>, což znamená, že framework bude hledat v presenteru, v kterém se právě nacházíme, metodu <code>handleUsersJson</code>. DataTables zároveň očekává, že mu z tohoto místa přijdou data v JSON formátu takovéto struktury:</p> <pre class="js"><code>{ "aaData": [ { "id": 9, "email": "franta@vokurka.cz", "name": "Franta Vokurka", "role": "guest" }, { "id": 10, "email": "lojza@lojza.cz", "name": "Lojza P\u0159echodn\u00edk", "role": "guest" }, }</code></pre> <p>Pomocí <code>„aoColumns“</code> potom definujeme, jaká data z JSON chceme zobrazovat v tabulce.</p> <p>Vyrobíme tedy požadovaný JSON – v (například) <code>HomepagePresen­ter.php</code> napíšeme metodu</p> <pre class="php"><code>public function handleUsersJson() { $all_users = array(); $all_users["aaData"] = $this-&gt;users-&gt;findAll()-&gt;orderBy('id')-&gt;fetchAll(); $this-&gt;sendResponse(new Nette\Application\Responses\JsonResponse($all_users)); }</code></pre> <p>Metoda si vyžádá z databáze všechny uživatele a jejich data a uloží je jako pole do proměnné <code>$all_users</code> pod klíč aaData. Tak to vyžaduje DataTables plugin. Data odešleme pomocí <code>$this-&gt;sendResponse</code> a <code>JsonResponse</code> ve formátu JSON.</p> <p>Na tomhle místě, kde poprvé posíláme data o uživatelích na frontend, bude potřeba upravit metodu <code>findAll()</code> v modelu Users, protože ve stávající podobě posílá do tabulky i hesla uživatelů. Sice zahashovaná, ale jak bychom vypadali, že? Úprava může vypadat třeba takto</p> <pre class="php"><code>public function findAll() { return $this-&gt;db-&gt;select('id, email, name, role')-&gt;from($this-&gt;table); }</code></pre> <p>Tak, a je to – <strong>hotovo</strong>.</p> <h2>Hotovo?</h2> <p>Máme co jsme chtěli a to, řekl bych, za dobrou cenu – máme tabulku, která umí data řadit ve sloupcích a umí hledat/filtrovat a řadit. To je ovšem pouze základní použití DataTables. K dispozici jsou rozšiřující <a href="http://www.datatables.net/extras/">pluginy</a>, jako například poměrně zásadní <a href="http://jquery-datatables-column-filter.googlecode.com/svn/trunk/index.html">columnFilter</a>.</p> <p>Data v tabulce také můžeme formátovat víceméně dle libosti. Například můžeme chtít z emailů udělat klikatelné odkazy – kód potom může vypadat třeba takto:</p> <pre class="javascript"><code>$('#users').dataTable( { "sAjaxSource": {link usersJson!}, "aoColumns": [ {"mData": "name"}, {"mData": "email", "fnRender": function(o) { return "&lt;a href='mailto:"+o.aData["email"]+"'&gt;"+o.aData["email"]+"&lt;/a&gt;"; } }, {"mData": "role"} ] });</code></pre> <h2>Závěr</h2> <p>Základní část seriálu je u konce. Ukázali jsme si na poměrně malém prostoru základní stavební kameny většiny webových aplikací – vkládání a čtení dat a jejich „chytré“ zobrazení. MacGyver by s tím dokázal vyrobit Facebook. Zdrojáky najdete na <a href="https://github.com/czlang/Users">githubu</a>.</p> <p>Mnoho (docela hodně) věcí jsme si naopak neukázali a zde jsou možnosti otevřené – buď je časem dopíšu jako volné pokračování na přání a/nebo odkážu. Podle komentářů z minulých dílů vybírám:</p> <h4>Testování</h4> <ul> <li>dokumentace Nette – <a href="http://doc.nette.org/cs/testing">Testování</a></li> <li><a href="http://pla.nette.org/cs/navstevni-kniha-a-testovani">Návštěvní kniha v Nette s testy (TDD)</a></li> <li><a href="http://filip-prochazka.com/blog/nette-tester-a-phpstorm">Nette/Tester a PhpStorm</a></li> <li><a href="http://blog.medio.cz/testovani-presenter">Testování presenterů v Nette</a></li> </ul> <h4>Composer</h4> <p>Správa závislostí v projektu</p> <ul> <li><a href="http://getcomposer.org/">http://getcomposer.org/</a></li> <li>dokumentace Nette – <a href="http://doc.nette.org/cs/composer">Composer</a></li> <li><a href="http://pla.nette.org/cs/sandbox-composer">Stažení sandboxu přes Composer</a></li> <li>Přednáška <a href="http://pla.nette.org/cs/posobota-38-filip-prochazka-composer">Filip Procházka: Představení nástroje Composer</a></li> </ul> <h4>Nette\Database</h4> <p>Alternativa k Dibi layeru</p> <ul> <li>dokumentace Nette – <a href="http://doc.nette.org/cs/database">Databáze &amp; ORM</a></li> <li><a href="http://pla.nette.org/cs/nette-database-vs-dibi">Nette\Database vs dibi</a></li> </ul> <p>A to je už opravdu vše, dotazy, opravy, doplnění, atakdále prosím do komentářů, díky a zase někdy příště.</p> http://www.nullpointer.cz/webova-aplikace-v-nette-pro-zacatecniky-datatables-dil-4 Webová aplikace v Javě od A do Z – Maven plugin pro Eclipse a přidání Struts2 do projektu (2. díl) Thu, 10 Jan 2013 11:31:05 GMT http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-maven-plugin-pro-eclipse-a-pridani-struts2-do-projektu-2-dil <p>V předchozím díle tohoto seriálu jsme si připravili v Eclipse java projekt. Nyní do projektu přidáme užitečné nástroje a frameworky, a to především Maven a Struts2.</p> <p><a href="http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-eclipse-priprava-prostredi-a-zalozeni-projektu-1-dil">V předchozím díle tohoto seriálu</a> jsme si připravili v Eclipse java projekt. Nyní do projektu přidáme užitečné nástroje a frameworky, a to především <strong>Maven a Struts2</strong>, později pak Spring a Hibernate. Java aplikace jsou z velké části postavené na externích knihovnách, tzv. knihovnách třetích stran, což jsou prostě hotové a vyladěné programy jiných programátorů, které nám mají ulehčit práci. Proč strávit spoustu času programováním věcí, které už někdo před námi udělal? Jedná se především o:</p> <p><strong>1) Frameworky:</strong> výrazně nám usnadňují psaní java a web kódu, protože spoustu nutných režijních věcí udělají za nás. Často tak odpadá „byrokracie“ okolo programování aplikace, o kterou se postará framework za nás. Také nás většinou nenásilně donutí psát slušně strukturovanou aplikaci, např. aby se držela architektura MVC, případně dodržovaly jiné, praxí ověřené programovací standardy. Je to, jako bychom byli zvoleni ministry a na běžnou nudnou administrativní práci bychom si najali šikovné úředníky. Ti mají znalosti o současných zákonech a jejich novelách a o nutných administrativních činnostech potřebných pro správný chod ministerstva. My se pak můžeme zvesela věnovat ministrování :-)</p> <p><strong>2) Utilitní knihovny:</strong> poskytují různou užitečnou funkcionalitu, kterou můžeme využívat v naší aplikaci, aniž bychom si ji museli sami psát. V tomto seriálu budeme nejspíš později využívat pouze knihovnu Joda time pro práci s datumy. Takže naše výsledná webová aplikace bude souhrn těchto tří částí:</p> <ul> <li>našeho vlastního kódu</li> <li>frameworků</li> <li>utilitních knihoven</li> </ul> <p>Nástroj, který umí tyto tři části slepit v jeden fungující celek se jmenuje <strong>Maven</strong>.</p> <h3>Maven</h3> <p>Maven je nástroj pro buildování java aplikací a kromě toho umí spoustu dalších věcí. My po něm ale v našem seriálu chtít jediné. Aby vzal naši aplikaci napsanou v javě a v hml, přidal k ní všechny potřebné závislosti na knihovnách třetích stran (tedy frameworky a utilitní knihovny) a vytvořil jeden tzv. WAR soubor, který si potom budeme moci spustit na lokálním serveru a následně se ve webovém prohlížeči podívat na výsledek naší práce. A nyní již prakticky. Asi nejjednodušší a nejpohodlnější způsob jak vyvíjet, je <strong>nainstalovat si do Eclipse maven plugin</strong> a nechat Eclipse, ať pomocí mavenu automaticky builduje naší aplikaci. Prakticky to pak bude vypadat tak, že budeme psát v Eclipse kód a výsledky rovnou zobrazovat ve webovém prohlížeči.</p> <h3>Maven plugin (m2eclipse)</h3> <p>Maven pluginů je víc, já budu používat <strong>m2eclipse</strong>. Do Eclipse jej nainstalujeme velmi jednoduše:</p> <ol> <li>Otevřeme Eclipse a menu vybereme možnost Help/Eclipse Marketplace.</li> <li>V okně nic nebudeme měnit, jen do políčka Search dáme vyhledat m2eclipse.</li> <li>Mezi nalezenými záznamy by měl být Maven integration for Eclipse (přesně takovýto název, neinstalujte žádný WTP, for Incubation apod.)</li> <li>U toho záznamu stiskneme tlačítko Install a nainstalujeme plugin.</li> <li>Nakonec se Eclipse bude chtít restartovat, takže mu to povolíme a plugin je připraven k používání.</li> </ol> <p>Ještě je důležité našemu vytvořenému projektu (viz první díl tohoto seriálu) říct, že má maven používat. To se dělá takto:</p> <ul> <li>v Eclipse klikněte pravým tlačítkem myši na projekt (levý sloupec)</li> <li>zvolte nabídku <strong>Configure/Convert to maven project</strong></li> </ul> <h3>Maven – Pom.xml</h3> <p>V mavenu všechno začíná a končí u souboru <strong>pom.xml.</strong> V něm vyjmenujeme všechny java knihovny, na kterých bude náš projekt záviset (viz výše). To je jediné, co se po nás chce. Maven je pro nás automaticky stáhne z internetu, připojí je k našemu projektu a my je můžeme začít používat. Vytvořme si nyní v Eclipse nový soubor pom.xml:</p> <ul> <li>pravé tlačítko myši na název projektu (v Eclipse v pravém sloupci, viz minulý díl seriálu), nabídka New/Other/Xml/Xml f­ile.</li> <li>soubor pojmenujte jako pom.xml a dejte finish.</li> </ul> <p>Do pom.xml dáme pro začátek tento obsah:</p> <pre class="xml"><code>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;groupId&gt;cz.nullpointer&lt;/groupId&gt; &lt;artifactId&gt;base-maven&lt;/artifactId&gt; &lt;packaging&gt;pom&lt;/packaging&gt; &lt;version&gt;1.0&lt;/version&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;/dependencies&gt; &lt;/project&gt;</code></pre> <p>Mezi tagy &lt;dependencies&gt;&lt;/de­pendencies&gt; budeme dávat zmiňované závislosti, jak si nyní ukážeme. První externí knihovnou, kterou budeme v našem projektu využívat (a závislost na ní tedy uvedeme v pom.xml), je Struts2 framework.</p> <h3>Struts2 – integrace do projektu pomocí Mavenu</h3> <p>Struts2 je framework, který nám významně usnadní tvorbu java webových aplikací. Abychom ho mohli začít používat, musíme jej nejdříve přidat k závislostem našeho projektu, tedy do souboru pom.xml, který jsme si vytvořili před chvílí. Celý soubor pom.xml pak bude vypadat takto:</p> <pre class="xml"><code>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;groupId&gt; cz.nullpointer&lt;/groupId&gt; &lt;artifactId&gt;base-maven&lt;/artifactId&gt; &lt;packaging&gt;pom&lt;/packaging&gt; &lt;version&gt;1.0&lt;/version&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.struts&lt;/groupId&gt; &lt;artifactId&gt;struts2-core&lt;/artifactId&gt; &lt;version&gt;2.3.8&lt;/version&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;/project&gt;</code></pre> <p>Nyní mavenu říkáme, že v našem projektu budeme chtít používat struts2 verzi 2.3.8 (v době psaní tohoto článku nejaktuálnější). Jakmile soubor pom.xml uložíme, měl by maven plugin v Eclipse stáhnout tuto závislost a přiřadit ji k našemu projektu. To poznáme tak, že v projektu <strong>uvidíme kontejner Maven Dependencies</strong>, do které nám bude maven dávat všechny jar knihovny, které jsou potřeba k závislostem, které jsme uvedli v souboru pom.xml. Měl by se objevit hned pod kontejner JRE System Library (JDK…), tedy pod Javou, kterou jsme do projektu přidali v minulém díle.</p> <p>Může se bohužel stát, že se však kontejner Maven Dependencies v projektu neobjeví, což se stalo i mně v době psaní tohoto seriálu. <strong>Nejpravděpodob­nějším viníkem je špatný obsah souboru .classpath.</strong></p> <h3>Maven plugin a .classpath</h3> <p>V první řadě zkontrolujte, že jste zkonvertovali svůj projekt na maven projekt. To se dělá pravým tlačítkem na projekt, v nabídce vyberte <strong>Configure/Convert to maven projekt</strong> (v tomto článku jsme to již dělali výše, uvádím jen pro úplnost). V ikonce projektu by se mělo objevit malé modré M. Pokud se přesto kontejner Maven Dependencies neobjevuje, problém je s nejvyšší pravděpodobností v obsahu souboru <strong>.classpath</strong>, který obsahuje každý Eclipse projekt. Tento soubor neuvidíme v Eclipse, musíme si náš projekt najít na disku, např. pomocí Total Commandera nebo průzkumníka. Můj .classpath vypadá nyní následovně:</p> <pre class="xml"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;classpath&gt; &lt;classpathentry kind="src" path="src/main/java"/&gt; &lt;classpathentry kind="src" path="src/main/resources"/&gt; &lt;classpathentry kind="src" path="src/test/java"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/&gt; &lt;classpathentry kind="output" path="build/classes"/&gt; &lt;/classpath&gt;</code></pre> <p>Což je problém, protože tu vůbec není maven a proto se nestahují potřebné závislosti (v našem případě Struts2).Změňte obsah souboru .classpath na:</p> <pre class="xml"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;classpath&gt; &lt;classpathentry kind="src" output="target/classes" path="src/main/java"/&gt; &lt;classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/&gt; &lt;classpathentry kind="src" output="target/test-classes" path="src/test/java"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/&gt; &lt;classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"&gt; &lt;attributes&gt; &lt;attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/&gt; &lt;/attributes&gt; &lt;/classpathentry&gt; &lt;classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/&gt; &lt;classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/&gt; &lt;classpathentry kind="output" path="target/classes"/&gt; &lt;/classpath&gt;</code></pre> <p><strong>Samozřejmě pokud máte jinou strukturu projektu než já, musíte soubor .classpath patřičně upravit.</strong> Jedná se o source folders, v příkladu jsou to <strong>src/main/java, src/test/java a src/main/resources</strong> (viz předchozí díl tohoto seriálu, kde jsme takto zakládali projekt). Nyní se vraťte do Eclipse a mělo by stačit zavřít a znovu otevřít projekt (pravé tlačítko myši na projekt a nabídka Close project, posléze Open project), můžete předtím pro jistotu ještě pomocí F5 projekt refreshnout. <strong>Nyní by se již v projektu měl objevit kontejner Maven Dependencies</strong> (pozor, je vidět jen v Eclipse, ne na disku u projektu, kde jsme editovali .classpath) a v něm je nyní v mém případě 11 jar knihoven.</p> <p>Pokud se stále Maven Dependencies neobjeví, zkuste re-savnout soubor pom.xml, což je i do budoucna dobrá cesta, jak donutit Maven plugin, aby provedl update závislostí.</p> <p>Ještě si zkontrolujte, že máte zaškrtnutý checkbox automatického buildování – v menu Eclipse Project/Build Automatically. Můžete také zkusit udělat Project/Clean…/Cle­an all project.</p> <h3>Lokální maven repository</h3> <p>Všechny jar knihovny, které jsou v kontejneru Maven Dependencies, maven stáhl k vám na lokální disk do tzv. lokálního maven repositáře. Cestu lze vidět v Eclipse u každé jar knihovny. Je to závislé na používaném OS, např. ve Windows 7 je cesta k repositáři tato:</p> <p><strong>C:\Users\&lt;VASE_JME­NO&gt;\.m2\reposi­tory…</strong></p> <p>Pro naše potřeby není znalost tohoto umístění příliš důležitá, ale není špatné o tom vědět.</p> <h3>Závěr</h3> <p>Ačkoliv jsem minule sliboval již Hello world, tak nakonec se ukázala problematika rozjetí maven pluginu pro Eclipse širší, než jsem původně čekal :-) a určitě si zasloužila samostatný článek . Náš projekt je nyní připraven používat Struts2 a přidávání dalších závislostí je již analogické, pouze přidáme dependency do pom.xml. Příště začneme rovnou rozjetím Tomcatu v Eclipse (což je oproti maven opravdu hračka) a konečně vypsáním Hello world v prohlížeči za pomocí frameworku Struts2.</p> http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-maven-plugin-pro-eclipse-a-pridani-struts2-do-projektu-2-dil Nette - přihlašování a registrace uživatelů Thu, 27 Dec 2012 13:56:46 GMT http://www.nullpointer.cz/nette-prihlasovani-a-registrace-uzivatelu <p>V tomto díle seriálu se budeme věnovat přihlašování a registraci uživatelů.</p> <h2>Zdrojáky v Gitu</h2> <p>Pro lepší orientaci jsou nyní zdrojáky k <a href="https://github.com/czlang/Users">dispozici na GitHubu</a>. Díly mají svoje <a href="https://github.com/czlang/Users/tags">tagy</a>.</p> <h2>Registrace</h2> <p>Začneme od šablon – v souboru <code>app/templates/@la­yout.latte</code> změňte obsah mezi tagy <code>body</code>takto</p> <pre class="html"><code>&lt;script&gt; document.body.className+=' js' &lt;/script&gt; &lt;div id="header"&gt; &lt;h1&gt;&lt;a href="{plink Homepage:}"&gt;Uživatelé&lt;/a&gt;&lt;/h1&gt; &lt;/div&gt; &lt;div id="nav"&gt; &lt;a href="{plink Register:register}"&gt;Registrovat&lt;/a&gt; &lt;a href="{plink Sign:in}"&gt;Přihlásit&lt;/a&gt; &lt;/div&gt; &lt;div n:foreach="$flashes as $flash" class="flash {$flash-&gt;type}"&gt;{$flash-&gt;message}&lt;/div&gt; &lt;div id="content"&gt; {include #content} &lt;/div&gt;</code></pre> <p>V headeru jsme si vyrobili odkaz na homepage, aby se nám vždycky dobře vracelo domů. Vyrobili jsme taky odkazy na přihlášení a registraci.</p> <p>Odkaz ve tvaru <code>plink Register:register</code> znamená „utíkej do presenteru Register na metodu register“. <code>plink Homepage:</code> zase znamená „fofrem do presenteru Homepage na metodu default“, kterou tam nemusím psát, když se mi nechce, protože je <em>default</em>.</p> <p>Když si uložíme a mrkneme na výsledek v prohlížeči, vidíme, že odkaz na <em>Přihlásit</em> se tváří celkem normálně, kdežto odkaz na <em>Registrovat</em> je celý brunátný. Když ho prozkoumáme (firebugem, nebo něčím podobným), zjistíme, že <code>error: Cannot load presenter ‚Register‘, class ‚RegisterPresenter‘ was not found in '/var/www/User­s/app/presenter­s/RegisterPre­senter.php</code>.</p> <p>Znamená to jednoduše to, že se odkazujeme na presenter a metodu, která neexistuje. Naproti tomu odkaz Přihlásit volá presenter <code>SignPresenter</code> a metodu <code>renderIn</code> (nebo actionIn), jež jsou součástí sanboxu, který jsme v minulém díle stáhli.</p> <p>Podrobné info o <a href="http://doc09.nette.org/cs/generovani-odkazu">vytváření odkazů v dokumentaci</a>.</p> <p>Pojďme vytvořit v adresáři <code>app/presenters/</code> RegisterPresen­ter.php s tímto obsahem</p> <pre class="php"><code>&lt;?php class RegisterPresenter extends BasePresenter { protected function startup() { parent::startup(); } public function renderRegister(){ } }</code></pre> <p>Uložíme, mrkneme na výsledek a vidíme, že odkaz je už spokojený. Klikneme na něj a zase chyba (říkám tomu Exception Driven Development – můžu si to patentovat, nebo tady teď byl?). Chyba mluví jasnou řečí – musíme pro akci vytvořit šablonu.</p> <p>Vytvoříme v <code>app/templates/</code> adresář Register a soubor <code>register.latte</code> s obsahem</p> <pre class="html"><code>{block #content} &lt;h2&gt;Registrovat&lt;/h2&gt; {control registerForm}</code></pre> <p>Nevypadá to ale, posunuli jsme se. Nová exception říká, že neexistuje komponenta registračního formuláře registerForm, kterou voláme pomocí <code>{control registerForm}</code> v <code>register.latte</code>.</p> <p>Vytvořme proto <em>továrničku</em> <code>createComponen­tRegisterForm</code> v <code>app/presenter­s/RegisterPre­senter.php</code> která nám formulář vyrobí:</p> <pre class="php"><code>use Nette\Application\UI, Nette\Application\UI\Form as Form; class RegisterPresenter extends BasePresenter { /** @var Users */ private $users; protected function startup() { parent::startup(); $this-&gt;users = $this-&gt;context-&gt;users; } public function renderRegister(){ } protected function createComponentRegisterForm() { $form = new Form; $form-&gt;addText('name', 'Jméno'); $form-&gt;addText('email', 'E-mail: *', 35) -&gt;setEmptyValue('@') -&gt;addRule(Form::FILLED, 'Vyplňte Váš email') -&gt;addCondition(Form::FILLED) -&gt;addRule(Form::EMAIL, 'Neplatná emailová adresa'); $form-&gt;addPassword('password', 'Heslo: *', 20) -&gt;setOption('description', 'Alespoň 6 znaků') -&gt;addRule(Form::FILLED, 'Vyplňte Vaše heslo') -&gt;addRule(Form::MIN_LENGTH, 'Heslo musí mít alespoň %d znaků.', 6); $form-&gt;addPassword('password2', 'Heslo znovu: *', 20) -&gt;addConditionOn($form['password'], Form::VALID) -&gt;addRule(Form::FILLED, 'Heslo znovu') -&gt;addRule(Form::EQUAL, 'Hesla se neshodují.', $form['password']); $form-&gt;addSubmit('send', 'Registrovat'); $form-&gt;onSuccess[] = callback($this, 'registerFormSubmitted'); return $form; } }</code></pre> <p>Tím jsme vytvořili formulář i s validačními pravidly, která se budou kontrolovat na serveru i v klientovi. V klientovi proto, že v @layout.latte načítáme netteForms.js, který se o to postará. Podrobné info o <a href="http://doc.nette.org/cs/forms">tvorbě formulářů v dokumentaci</a>.</p> <p>Teď potřebujeme presenteru říct, co má dělat po vyplnění a odeslání formuláře. Formulář definuje metodu, kterou volá, v <code>$form-&gt;onSuccess[] = callback($this, ‚registerFormSub­mitted‘)</code>, tudíž ji napíšeme</p> <pre class="php"><code>public function registerFormSubmitted(UI\Form $form) { $values = $form-&gt;getValues(); $new_user_id = $this-&gt;users-&gt;register($values); if($new_user_id){ $this-&gt;flashMessage('Registrace se zdařila, jo!'); $this-&gt;redirect('Sign:in'); } }</code></pre> <p>Pomocí <code>$form-&gt;getValues()</code> jsme získali z formuláře data a vložili je do databáze. Pokud se podařilo, spravíme o úspěchu uživatele a přesměrujeme jej k přihlášení.</p> <p>Vložení nového uživatele provedeme, jak říká právě napsaná metoda, v modelu – konkrétně v <code>Users.php</code>:</p> <pre class="php"><code>public function register($data) { unset($data["password2"]); $data["role"] = "guest"; $data["password"] = sha1($data["password"] . self::$user_salt); return $this-&gt;db-&gt;insert($this-&gt;table, $data)-&gt;execute(dibi::IDENTIFIER); }</code></pre> <p>Z dat z formuláře jsme odstranili potvrzjící opakování hesla, uživateli přiřadili primitivním způsobem jakousi roli (prozatím stačí) a vyrobili heslo. Salt si dodáme například takto</p> <pre class="php"><code>class Users extends \Nette\Object { /** @var \DibiConnection */ private $db; private $table = "users"; public static $user_salt = "AEcx199opQ"; // třída pokračuje...</code></pre> <p>Než to vyzkoušíme, potřebujeme změnit databázi</p> <pre class="sql"><code>DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(10) NOT NULL AUTO_INCREMENT, `email` varchar(50) NOT NULL, `password` char(60) NOT NULL, `name` varchar(100) NOT NULL, `role` varchar(100) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8; INSERT INTO `users` (`id`, `email`, `password`, `name`, `role`) VALUES (1, 'franta@vokurka.cz', 'f63d757c919a7707aa6c0af5946fd24a28015779', 'Franta Vokurka', 'guest'), (2, 'lojza@lojza.cz', 'ebad7341ea91cf83593b0638817c16a563bd4037', 'Lojza Přechodník', 'guest'), (3, 'mala@tonicka.cz', 'e1822661e05f4595d4ccaf4c8cd5b7f997a5e82c', 'Tonička Malá', 'guest'), (4, 'gerda@zapasnikova.cz', '51fcf163696a95f0674f123509a469092fc2d34e', 'Gerda Zápasníková', 'guest'), (5, 'anna@k.cz', '1ec2131552f3bd668591b0b99407b23355ba1ebc', 'Anna Kareninová', 'guest'), (6, 'barca@bramburka.cz', 'f04003366fb2f36149d392b547a7440d778046d7', 'Barbora Brambora', 'guest'), (7, 'hilda@zelena.cz', 'e08c606ff2fbc1a1991febf00b0fa8721d7d09ca', 'Hilda Zelená', 'guest'), (8, 'hajdy@zhor.cz', '626a453385ad62ad723655f706a2993eeb5c2922', 'Hajdy Zhor', 'guest'), (9, 'johanka@vplutu.com', '2b49d3bf378036984695dfd2a96bee427627e87d', 'Johanka Tazpluta', 'guest');</code></pre> <p>Hotovo, vyzkoušejte a běda jak to nebude fungovat.</p> <h2>Přihlášení</h2> <p>Registrace vám bezvadně funguje, přihlášení se ale nezdaří, protože k přihlášení používáme „vestavěný“ <code>app/model/Authen­ticator.php</code> a ten jsme vůbec neupravili pro práci s naší databází. Smažte obsah třídy a nahraďte jej za toto</p> <pre class="php"><code>use Nette\Security as NS; /** * Users authenticator. * * @author John Doe * @package MyApplication */ class Authenticator extends Nette\Object implements NS\IAuthenticator { /** @var \DibiConnection */ private $db; private $table = "users"; public function __construct(\DibiConnection $connection) { $this-&gt;db = $connection; } /** * Performs an authentication * @param array * @return Nette\Security\Identity * @throws Nette\Security\AuthenticationException */ public function authenticate(array $credentials) { list($username, $password) = $credentials; $row = $this-&gt;db-&gt;select('*')-&gt;from($this-&gt;table)-&gt;where('email = %s', $username)-&gt;fetch(); if (!$row) { throw new NS\AuthenticationException("User '$username' not found.", self::IDENTITY_NOT_FOUND); } if ($row-&gt;password !== sha1($password . Users::$user_salt)) { throw new NS\AuthenticationException("Invalid password.", self::INVALID_CREDENTIAL); } unset($row-&gt;password); return new NS\Identity($row-&gt;id, $row-&gt;role, $row-&gt;toArray()); } }</code></pre> <p>Třídě jsme dodali připojení k databázi a ukázali tabulku z které brát data. Taky jsme v metodě <code>authenticate</code> řekli, že pokud najde uživatele s emailem a heslem shodným s tím co přišlo z formuláře, má vrátit jeho <code>NS\Identity</code>.</p> <p>Nyní již máte všechny potřebné indicie k tomu se zaregistrovat i přihlásit. Gratulki.</p> <h2>Shrnutí, příště</h2> <p>Na to, že článek měl být bleskovým výcucem toho nejnutnějšího, je i tak dost dlouhý, takže pro další (důležité) info prosím račte navštívit ctěnou dokumentaci – <a href="http://doc.nette.org/cs/security">Přihlašování &amp; oprávnění uživatelů</a>.</p> <p>Příště bychom se možná konečně mohli dostat k „napojení“ <a href="http://datatables.net/examples/">Datatables</a> – ačkoliv se to tváří jako zlatý hřeb seriálu, uvidíte, že se jedná o v podstatě triviální kratochvíli.</p> http://www.nullpointer.cz/nette-prihlasovani-a-registrace-uzivatelu Webová aplikace v Nette pro začátečníky - 2.díl Sun, 16 Dec 2012 16:37:43 GMT http://www.nullpointer.cz/webova-aplikace-v-nette-pro-zacatecniky-2-dil <p>V tomto díle seriálu si, jak <a href="http://www.nullpointer.cz/webova-aplikace-v-nette-pro-zacatecniky-uvod">jsem minule slíbil</a>, nastavíme prostředí pro práci, rozjedeme Nette a Dibi a pozdravíme svět.</p> <h2>PHP a MySQL</h2> <p>Budeme samozřejmě pracovat v lokálním vývojovém prostředí, takže budeme potřebovat rozjet lokální server s PHP a MySQL.</p> <p>Uděláme to tím nejjednodušším způsobem – pro windows existuje několik instalačních „balíků“, které řeší většinu toho, co Běžný Franta Vývojář potřebuje.</p> <p>Jsou to například:</p> <ul> <li><a href="http://www.apachefriends.org/en/xampp.html">XAMPP</a></li> <li><a href="http://www.wampserver.com/en/">WampServer</a></li> <li><a href="http://www.easyphp.org/">EasyPHP</a></li> </ul> <p>V tomto seriálu použiju poslední jmenovaný – ze stránek EasyPHP si <a href="http://www.easyphp.org/save-easyphp-latest.php">stáhněte instalační soubor</a> a spusťte jej. Proklikejte se instalací, není v ní nic záludného. Po úspěšném skončení instalace byste měli v prohlížeči na adrese <a href="http://127.0.0.1/">http://127.0.0.1/</a> vidět rozhraní EasyPHP se seznamem projektů.</p> <p>EasyPHP si ve výchozím nastavení pro tyto projekty sahá do umístění <code>&lt;disk&gt;/Program Files/EasyPHP-&lt;verze&gt;/www</code>, zde vytvořte soubor info.php s obsahem</p> <pre class="php"><code>&lt;?php phpinfo();</code></pre> <p>V rozhraní EasyPHP v prohlížeči by se měl soubor info.php objevit – klinkěte na něj a v případě, že všechno funguje, se pokochejte konfigurací PHP.</p> <p>Pro správu MySQL databáze použijeme Adminer, který si <a href="http://www.adminer.org/#download">stáhněte</a> a stažený soubor umístěte na stejnou úroveň vedle souboru info.php. Klikněte na něj v rozhraní EasyPHP, jako uživatele zadejte root a přihlaste se. Uvidíte seznam databází, ty nás ale nezajímají, vytvoříme si pro náš projekt databázi novou :</p> <pre class="mysql"><code>CREATE DATABASE `users` COLLATE 'utf8_bin';</code></pre> <p>V této fázi, pokud vše proběhlo bez problému, máme nainstalové PHP a MySQL a vytvořenou prázdnou databázi. Pojďme na Nette a Dibi.</p> <h2>Nette Framework</h2> <p><a href="http://nette.org/cs/download">Stáhněte si Nette</a>. V seriálu budu používat Nette pro PHP 5.3 a vyšší, bez prefixů, <a href="http://files.nette.org/releases/2.0/">verzi 2.0.6</a>. Po stažení rozbalte zip a najděte v adresáři tools nástroj zvaný Requirements-Checker, který nakopírujte do EasyPHP www adresáře a spusťte v prohlížeči. Tento nástroj zkontroluje, zda je náš vývojový server způsobilý pro fungování s Nette, což je, takže můžeme směle pokračovat.</p> <p>Vedle adresáře tools v Nette balíku se nachází adresář <strong>sandbox</strong>, což je taková (skoro) minimální fungující předpřipravená Nette webová stránka. Nakopírujte celý sandbox do EasyPHP adresáře a spusťte v prohlížeči. Uvidíte uvítací projekt Nette, na kterém postavíme naši aplikaci.</p> <p>Pro další informace o instalaci a struktuře Nette vřele doporučuji <a href="http://doc.nette.org/cs/installation">Stažení a instalace v dokumentaci</a></p> <h2>Netbeans</h2> <p>Přicházíme do fáze, ve které budeme potřebovat nějaký editor. Ten je vždy otázkou osobní volby, já budu v tomto seriálu budu používat Netbeans. <a href="http://netbeans.org/downloads/">Stáhněte si Netbeans pro PHP</a>, nainstalujte a spusťte. Vytvoříme si nový projekt Users a to importem adresáře sandbox. Nejdříve si na disku přejmenujte adresář sandbox na Users a potom v Netbeans proveďte <code>File → New Project → PHP / PHP Application with existing sources → Vyberte &lt;adresar_projek­tu_na_disku&gt; a Finish.</code></p> <p>Do Netbeans si ještě nastavíme <a href="http://xdebug.org/">Xdebug</a> na krokování programem, ale to až někdy příště.</p> <h2>Dibi a databáze</h2> <p><a href="http://dibiphp.com/cs/">Dibi</a> je knihovna pro práci s databází. <a href="http://dibiphp.com/cs/download">Stáhněte si verzi 2.0.1</a>, rozbalte a vnitřní adresář <code>dibi</code> (obsahuje adresáře drivers, libs, Nette a soubour dibi.php) nakopírujte do našeho projektu do adresáře libs. Smažte obsah adresáře temp/cache a refreshněte projekt v prohlížeči – Nette loader se tak postará o „natáhnutí“ Dibi do projektu.</p> <p>Konfigurace Nette projektu probíhá v <code>&lt;projekt&gt;/app/con­fig/config.ne­on</code> a v <code>&lt;projekt&gt;/app/bo­otstrap.php</code>. V těchto místech si teď nastavíme Dibi.</p> <p>Otevřete si soubor a do config.neon pod řádek <code>development &lt; common</code> vložte</p> <pre><code>development &lt; common: dibi: host: localhost username: root password: database: users lazy: TRUE</code></pre> <p>Co jsme právě udělali – do „sekce“ <em>development</em> která je podmnožinou sekce <em>common</em>, jsme zapsali konfiguraci připojení k databázi pro vývojové prostředí. Pro nasazení na ostrý server bychom zadali konfiguraci do sekce <code>production &lt; common </code>. Nette pak automaticky rozliší v jakém prostředí se nachází. Jak je zřejmé, konfigurace platící pro všechna prostředí umístíme do sekce <code>common</code></p> <p>Při zapisování konfigurace si dávejte dobrý pozor, abyste odsazovali buď pomocí mezer, nebo skutečných tabulátorů, nikdy ne obojí zároveň – <a href="http://doc.nette.org/cs/configuring#toc-konfigurace-v-neon-souboru">více o konfiguraci v config.neon Nette v dokumentaci</a>.</p> <p>Pokračujeme v souboru <code>bootstrap.php</code>, kde Dibi zaregistrujeme pomocí rozšíření, které ve verzi 2 obsahuje. Před vytvořením <acronym title="Dependency Injection">DI</acronym> kontejneru pomocí</p> <pre class="php"><code>$container = $configurator-&gt;createContainer();</code></pre> <p>řekneme, že</p> <pre class="php"><code>$configurator-&gt;onCompile[] = function ($configurator, $compiler) { $compiler-&gt;addExtension('dibi', new DibiNetteExtension); };</code></pre> <p>Tím jsme s konfigurací Dibi hotovi. Nebo ne? Zkusíme to ověřit.</p> <h2>Model a práce s daty</h2> <p>Jak je v <acronym title="Model-View-Controller">MVC</acronym> kraji zvykem, do databáze se podíváme skrze model. V adresáři <code>app/model</code> vytvořte soubor <code>Users.php</code> s obsahem</p> <pre class="php"><code>class Users extends \Nette\Object { /** @var \DibiConnection */ private $db; private $table = "users"; public function __construct(\DibiConnection $connection) { $this-&gt;db = $connection; } public function findAll() { return $this-&gt;db-&gt;select('*')-&gt;from($this-&gt;table); } }</code></pre> <p>Zde myslím vše jasné – v konstruktoru jsme si dodali Dibi připojení a napsali si metodu <code>findAll</code>, která vrátí obsah tabulky <code>users</code>. Pokračujeme do další vrsty a to <code>app/presenter­s/HomepagePre­senter.php</code></p> <pre class="php"><code>class HomepagePresenter extends BasePresenter { /** @var Users */ private $users; protected function startup() { parent::startup(); $this-&gt;users = $this-&gt;context-&gt;users; } public function renderDefault() { $this-&gt;template-&gt;anyVariable = 'any value'; } }</code></pre> <p>Zde se naopak děje cosi na první pohled trochu zvláštního – kde se vzalo a co to je <code>$this-&gt;context-&gt;users</code> v metodě <code>startup</code>? Uložte všechny změny a zkuste reload projektu v prohlížeči. To co vidíte je váš přítel – <a href="http://doc.nette.org/cs/debugging#toc-vizualizace-chyb-a-vyjimek">ladící výpis Nette</a>, neboli takzvaná „Laděnka“.</p> <p>Podstatné je sdělení <em>Service ‚users‘ not found</em>. To je to <code>users</code>, které požadujeme v startup metodě. Pojďme do <code>config.neon</code> dodělat, co jsme začali – do common sekce pod definice services zadejte</p> <pre><code>services: users: class: \Users(@dibi.connection)</code></pre> <p>Tím by měla být konfigurace Dibi a profouknutí Modelu hotova. Ověříme to výpisem dat.</p> <h2>Výpis dat</h2> <p>V databázi vytvořte tabulku users</p> <pre class="sql"><code>CREATE TABLE `users` ( `id` int(10) NOT NULL AUTO_INCREMENT, `email` varchar(50) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; INSERT INTO `users` (`id`, `email`) VALUES (1, 'hello@world.cz'), (2, 'lojza@lojza.cz'), (3, 'mala@tonicka.cz'), (4, 'gerda@zapasnikova.cz'), (5, 'anna@k.cz'), (6, 'barca@bramburka.cz'), (7, 'hilda@zelena.cz'), (8, 'hajdy@zhor.cz'), (9, 'johanka@vplutu.com');</code></pre> <p>Blížíme se do finále, vypíšeme si naše skvostné uživatele a dáme si čaj.</p> <p>V <code>HomepagePre­senter.php</code> změňte metodu <code>renderDefault</code>, která obsluhuje domácí stránku, takto</p> <pre class="php"><code>public function renderDefault() { $all_users = $this-&gt;users-&gt;findAll()-&gt;orderBy('id')-&gt;fetchAll(); $this-&gt;template-&gt;all_users = $all_users; }</code></pre> <p>Zde je vše jasné – do šablony jsme si poslali všechny uživatele seřazené podle jejich id.</p> <p>V šabloně domácí stránky je jednoduše vypíšeme – obsah <code>app/templates/Ho­mepage/default­.latte</code> změňte na</p> <pre><code>{block content} &lt;ul&gt; {foreach $all_users as $user} &lt;li&gt;{$user-&gt;email}&lt;/li&gt; {/foreach} &lt;/ul&gt;</code></pre> <p>a pokochejte se výsledkem v prohlížeči.</p> <h2>Shrnutí</h2> <p>Pro začátek máme hotovo – máme nastaveny základní nástroje pro další práci, umíme si vypsat obsah MySQL tabulky do šablony. Mnoho věcí jsem v zájmu kompaktnosti článku vynechal/nazna­čil/zestručnil – případné nejasnosti doporučuji zatím buď neřešit, nebo vyhledat v <a href="http://doc.nette.org/cs/">dokumentaci Nette</a>, nebo na <a href="http://forum.nette.org/cs/">fóru Nette</a>.</p> <p>Samozřejmě, pokud je v článku něco nesrozumitelného, nebo je tam vyložená chyba, komentáře jsou vám k dispozici.</p> <h2>Příště</h2> <p>V příštím díle si do aplikace napíšeme obsluhu pro registraci a přihlašování uživatelů. Což bude brnkačka.</p> http://www.nullpointer.cz/webova-aplikace-v-nette-pro-zacatecniky-2-dil Webová aplikace v Nette pro začátečníky - úvod Wed, 28 Nov 2012 17:39:58 GMT http://www.nullpointer.cz/webova-aplikace-v-nette-pro-zacatecniky-uvod <h2>Co by měl seriál přinést?</h2> <p>Výsledkem seriálu bude fungl nová aplikace, která bude umět registrovat, přihlásit a spravovat uživatele. Kromě <a href="http://nette.org/">Nette</a> použijeme <a href="http://dibiphp.com/">Dibi</a> pro práci s MySQL a jQuery přinejmenším pro šikovnou tabulku s údaji uživatelů.</p> <p>Dalším potenciálně zajímavým prvkem seriálu, by také mohlo být srovnání s vývojem téměř stejné aplikace v úplně jiném prostředí, v sousedském seriálu <a href="http://www.nullpointer.cz/serial/webova-aplikace-v-jave-od-a-do-z">Webová aplikace v Javě od A do Z</a>.</p> <h2>Je to pro vás?</h2> <p>Pokud dodnes píšete v „čistém“ PHP a žádný framework jste dosud nezkusili (neboť jste přicestovali strojem času z minulosti) pak se domnívám že ano. Pokud píšete aplikace v jiném frameworku může to být pro vás zajímavé srovnání. Jestli v Nette píšete jednu složitější aplikaci za druhou, pak se nejspíš nic moc nového nedozvíte (ale zase mě můžete opravovat v komentářích).</p> <h2>Co potřebujete znát?</h2> <p>V seriálu se <strong>ne</strong>budu zabývat vysvětlováním PHP, MySQL ani Javascriptu. Naopak se pokusím ukázat fungování Nette, Dibi a některých pluginů jQuery (např. Datatables).</p> <h2>Použité technologie</h2> <ul> <li>lokální Apache server s PHP 5 a MySQL</li> <li><a href="http://netbeans.org/">IDE Netbeans</a></li> <li><a href="http://nette.org/">Nette Framework</a></li> <li><a href="http://dibiphp.com/">Dibi Database Layer pro práci s MySQL</a></li> <li><a href="http://jquery.com/">jQuery</a></li> </ul> <p>V příštím pokračování seriálu se už konečně pustíme do díla – nastavíme si prostředí pro práci, rozjedeme Nette a Dibi a pozdravíme svět!</p> http://www.nullpointer.cz/webova-aplikace-v-nette-pro-zacatecniky-uvod Webová aplikace v Javě od A do Z – Eclipse: příprava prostředí a založení projektu (1. díl) Wed, 07 Nov 2012 12:11:40 GMT http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-eclipse-priprava-prostredi-a-zalozeni-projektu-1-dil <p>Eclipse je profesionální vývojové prostředí, které vzniklo proto, aby programátoři nemuseli vyvíjet své aplikace v poznámkovém bloku nebo PSPadu :-) Přináší s sebou značný komfort pro vývoj, ale také vyšší nároky na hardware počítače…</p> <h3>Eclipse</h3> <p>Eclipse je profesionální vývojové prostředí, které vzniklo proto, aby programátoři nemuseli vyvíjet své aplikace v poznámkovém bloku nebo PSPadu :-) Přináší s sebou značný komfort pro vývoj, ale také vyšší nároky na hardware počítače a občas klade nároky na trpělivost uživatele – podobně jako u Windows je třeba jej čas od času restartovat nebo přeinstalovat. Alternativou jsou např. Netbeans, ale nebudu se zde pouštět do polemik, co je lepší, těch najdete na internetu dost. Já pracuji většinu své programátorské kariéry v Eclipse a jsem s nimi docela spokojený, takže v seriálu budu používat toto vývojové prostředí.</p> <p>Eclipse stáhnete na adrese <a href="http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a>, stáhněte verzi <strong>Eclipse IDE for Java EE Developers</strong> Používám Windows7, takže stahuji 64 bitovou verzi, ale neměl by snad být pro potřeby našeho seriálu rozdíl mezi touto a 32 bitovou verzí. Po stáhnutí Eclipse si jej rozbalte do libovolné složky a spusťte jej. Další návod píši pro tuto verzi:</p> <p>Eclipse Java EE IDE for Web Developers.</p> <p>Version: Juno Service Release 1, Build id: 20120920–0800</p> <p>Je samozřejmé, že se Eclipse vyvíjí, proto mohou být některé věci v jiných verzích Eclipse trošku jinak nebo jinde. Nicméně mohu říct, že za posledních 6 let (od roku 2006 co v Eclipse vyvíjím) se těch základních věcí, kterým se budu věnovat, mnoho nezměnilo, takže doufám, že v seriálu popsané konfigurace Eclipse nepřijdou časem o aktuálnost.</p> <p>Nejsem nějaký Eclipse guru, takže následující jednoduchý průvodce je pouze popis víceméně nejjednoduššího postupu, jak začít programovat v tomto vývojovém prostředí.</p> <h3>Spuštění, základní nastavení a konfigurace Eclipse</h3> <p>Po startu po vás bude Eclipse chtít cestu k workspace, což je místo, kam si bude ukládat svoje nejrůznější konfigurační soubory týkající se vaší pracovní plochy. Zvolte libovolnou cestu, já jsem zvolil C:\Users\Luke\Wor­kspace\Nullpo­inter. Do této složky se nebudou ukládat přímo soubory projektu, pokud to explicitně nenastavíte (viz dále). Poté uvidíte nejspíš nějakou uvítací obrazovku, v pravém horním rohu se zpravidla nachází odkaz Workbench (aspoň pár verzí už je to stejné), na který klikněte, což vás pošle již přímo do prostředí, kde můžete začít vyvíjet.</p> <p><strong>Nastavení vzhledu workbench</strong> Nastavení vzhledu je hodně individuální, asi by se dalo říci, že co programátor, to jiné preference vzhledu. Já zde popíšu způsob, jak si prostředí nastavuji já. Nikomu samozřejmě toto rozvržení nenutím, ale pro případné nováčky v Eclipse to určitě není špatný způsob jak začít. Nic zásadního zde totiž nechybí a jsou zde zobrazeny jen nejnutnější prvky.</p> <p>Pokud jste již zvyklí nějak s Eclipsem pracovat, klidně následující číslované kroky přeskočte:</p> <ol> <li>Já jsem zvyklý pracovat v <strong>perspektivě Java</strong>, perspektiva se přepíná v pravém horním rohu. Defaultně tam bude nastavená perspektiva Java EE.</li> <li>V pravém sloupečku vypnu vše, co tam je standardně zobrazené (např. okno Outline či Task list). Zvětší se tak plocha pro samotné programování.</li> <li>V dolní okně ponechám záložku <strong>Problems</strong>, odstraním záložku Java doc a Declaration. Dále sem přidám 2 užitečné záložky, <strong>Console</strong> a <strong>Server</strong>. Ty přidáte prostřednictvím menu Eclipse – Window/Show view/Console a Window/Show view/Other/Ser­ver/Servers.</li> <li>Výsledek je tedy následující: v levém sloupci ponechaný <strong>Package explorer</strong>, napravo zatím prázdné okno, kde se bude psát kód a ve spodní části obrazovky pruh se záložkami Problems, Console a Servers. Zde se pak budou automaticky objevovat některé další záložky, např. Search pro výsledky hledání apod.</li> </ol> <h3>Základní konfigurace Eclipse workspace</h3> <p>Nejdůležitější je správně nastavit Javu, kterou budeme v našem workspace používat. Pokud ji nemáte stáhnutou, tak ji stáhněte ze stránek <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">http://www.oracle.com/…s/index.html</a> a nainstalujte. <strong>V dalších částech seriálu budeme pracovat s JDK</strong> (nikoliv s JRE), proto nainstalujte nejnovější JDK, které v seznamu najdete. V době psaní tohoto článku (listopad 2012) stahuji verzi 7, devátý update, 64 bitová verze. Instalátor vám pak ukáže, kam Javu bude instalovat (standardně C:\Program Files\Java\jdk…). Tuto cestu si zapamatujte, v Eclipse ji pak bude chtít. Pokud máte nyní spuštěný Eclipse, nejspíš budete vyzváni instalátorem, abyste jej zavřeli.</p> <p><strong>Po úspěšné instalaci Javy Eclipsům řekneme, že budeme používat JDK</strong>, které jsme právě stáhli. To se dělá ve Window/Preferen­ces/Java/Insta­lled JREs. Zde klikněte na tlačítko Add, zvolte Standard VM a do JRE Home nastavte cestu, kam jste nainstalovali JDK – u mě to bylo C:\Program Files\Java\jdk1­.7.0_09. Pak dejte Finish a** v seznamu Installed JRE přepněte checkbox na JDK** a dejte ok.</p> <p>Dále se ještě hodí změnit <strong>kódování ve workspace</strong> na UTF-8 nebo na nějaké jiné, které budete chtít používat. To se dělá ve Window/Preferences, do vyhledávacího rámečku napište <strong>encoding</strong> a to vám vyfiltruje složky General, Web a XML. Nejdůležitější je General/Workspace, dolů do rámečku Text file encoding dejte Other/požadované kódování. Pokud chcete, můžete změnit kódování i u jiných souborů, jak ponechávám defaultní nastavení.</p> <p>Další věcí, které se ještě hodí zkraje nastavit, je <strong>formatter.</strong> Eclipse vám automaticky formátuje váš java kód, přidává např. prázdné řádky, má nastavenou nějakou velikost TABu, délku řádku po které vám automaticky zalomí text atd. Formatter najdeme ve Window/Preferences a do vyhledávacího okna napíšeme <strong>formatter</strong>. Zajímá nás nyní především <strong>Java/Code style/Formatter</strong>, kde je nastavený jako Active profile profil <strong>Eclipse [built-in]</strong>. Stiskneme tlačítko New a nový profil nazveme např. podle názvu naší firmy, projektu nebo jak chceme. Náš nový profil podědí nastavení Eclipse [built-in] profile, takže můžeme provést jen nějaké změny, dle naší libosti. Já většinou nastavuji hned na první záložce Indentation Tab policy na Space only a Tab size a Indentation size nastavím na 2, ale jako většina textu v této kapitole, je to individuální a mým cílem je především ukázat místa užitečných počátečních konfigurací Eclipse workspace. Dále se hodí záložka Line wrapping, na které si můžete nastavit především Maximum line width, které je defaultně 80. V dnešní době širokoúhlých monitorů je škoda tam nenastavit o něco víc, třeba 120 nebo 140, ale opět záleží na tom, co preferujete. Já třeba nemám rád, když mi nějaký delší příkaz ujede na druhý řádek, klidně si i horizontálně zascroluji, protože pak vždy vím, že na začátku řádku mám i začátek nového příkazu. Vámi nastavený formatter můžete i pomocí tlačítka Export All… vyexportovat do xml souboru a někdo jiný, či někdy v budoucnu i vy sami si můžete individuálně nastavený formatter pomocí tlačítka Import… načíst. To se hodí především ve firmách, kde více vývojářů pracuje na jednom projektu a je nežádoucí, aby měl každý jinak nastavený formatter především proto, že každý pak commituje jinak naformátované soubory a velmi špatně se hledají vlastní změny, které programátor v souboru udělal. V Eclipse můžete kdykoliv použít klávesovou zkratku CTRL+SHIFT+F, který vám právě otevřený soubor (v současnosti ještě žádný nemáme) naformátuje dle zvoleného formatteru.</p> <h3>Užitečné klávesové zkratky v Eclipse</h3> <p>Následuje seznam nejpoužívanějších a velmi užitečných klávesových zkratek v Eclipse. Pokud jste v Eclipsech a v Javě ještě moc nedělali, tak vám to asi mnoho neřekne, nicméně se sem můžete kdykoliv později vrátit a na zkratky se podívat. Především až již budeme mít založený nový projekt a uložených pár java a jsp souborů, si budete moci přímo vyzkoušet, co jaká zkratka dělá.</p> <p><strong>CTRL + SHIFT + R:</strong> hledání souborů</p> <p><strong>CTRL + SHIFT + T:</strong> hledání Java tříd (podmnožina vrchního dotazu)</p> <p><strong>CTRL + O:</strong> hledání metod v rámci Java třídy</p> <p><strong>CTRL + Mezerník:</strong> kontextová nápověda Eclipsu</p> <p><strong>CTRL + Click:</strong> pátrání po původu např. CTRL+ Click na proměnnou přenese na místo, kde je definovaná</p> <p><strong>CTRL + T:</strong> u když se použije při označení interface metody, ukáže implementaci této metody</p> <p><strong>CTRL + SHIFT + F:</strong> zapne automatické formátování u java tříd</p> <p><strong>CTRL + SHIFT + O:</strong> organizuje importy – automaticky vygeneruje všechny nutné importy, které</p> <p>třída potřebuje a odstraní importy nepoužívané</p> <p><strong>CTRL + M:</strong> zobrazí přes celou obrazovku okno, na kterém je focus (hodí se zejména u okna, do kterého píšeme kód</p> <h3>Založení webového projektu v Eclipse</h3> <p>Nyní již přišel čas založit konečně nový webový projekt. Ten založíme v Eclipse pomocí menu <strong>File/New…/Other­../Web/Dynamic web project</strong>. V následujícím okně vybereme především <strong>Project name</strong> a <strong>Project location</strong>, což je místo na pevném disku, kde budeme mít uloženy soubory projektu (všechny java, jsp, xml apod.). Je třeba rozlišovat mezi cestou k workspace (viz výše) a Project location, což se alespoň mě v začátcích trošku pletlo. V prvním případě se jedná o uložiště konfiguračních souborů nastavení workspace, které jsme dělali před chvílí (viz výše) a v druhém případě jsou to soubory s naším java a html kódem. Někdo obojí cpe do jednoho adresáře, já to mám radši oddělené, takže je to zase na vás, zda si Project location nastavíte nebo jestli ponecháte defaultní. Každopádně si cestu zapamatujte, ať víte, kde se nachází vaše projektové soubory (ne že by to nešlo později zjistit). Když zvolíte Next, budete dotázání na specifikaci zdrojových složek (source folder). Doporučuji smazat src, které tam defaultně je a zadat tyto tři složky:</p> <p><strong>src/main/java</strong> – zde budeme mít všechny java soubory</p> <p><strong>src/main/resou­rces</strong> – zde budeme mít různé konfigurační soubory pro frameworky, soubor s texty pro naše stránky atd. viz další díly seriálu</p> <p><strong>src/test/java</strong> – zde budeme mít testovací java třídy, hlavně JUnit testy (viz pozdější díly našeho seriálu)</p> <p>Stiskneme tlačítko Next a na poslední obrazovce wizardu zaškrtneme checkbox <strong>Generate web.xml deployment descriptor.</strong> Po stisknutí tlačítko Finish bude chtít Eclipse otevřít Java EE perspektivu. Jak jsem již psal výše, je to individuální, v jaké perspektivě se rozhodnete pracovat, ale já budu v dalších částech seriálu pracovat v Java perspektivě.</p> <h3>Nastavení Javy JDK do vytvořeného webového projektu</h3> <p>Nyní je důležité nastavit projektu, aby používal JDK, které jsme již nastavili výše. Nyní v projektu vidíte (mimo dalších složek, např. námi nastavených systémových) také Javu JRE System Library [JavaSE-1.6]. Klikneme na tento kontejner pravým tlačítkem myši a zvolíme v kontextovém menu nabídku <strong>Properties.</strong> Zde vybereme možnost <strong>Workspace default JRE (jdk…). Tohle je důležitý krok, protože jinak bychom používali špatnou javu, což by vedlo k nejrůznějším problémům při pozdějších konfiguracích a samotnému běhu aplikace.</strong></p> <h3>Závěr</h3> <p>Nyní máme založený nový webový projekt ve vývojovém prostředí Eclipse, u kterého jsme se seznámili s jeho základním nastavením. V další části seriálu se budeme věnovat především stáhnutí maven pluginu do Eclipse a načtení potřebných frameworků Struts2, Spring a Hibernate a dalších užitečných knihoven pomocí MAVENu do našeho projektu. Dále si již zkusíme spustit náš projekt na serveru Tomcat uvnitř Eclipse a vypsat naší aplikací do webového prohlížeče nic menšího než „Hello World“. :-)</p> http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-eclipse-priprava-prostredi-a-zalozeni-projektu-1-dil Webová aplikace v Javě od A do Z – Úvod (NULLtý díl) Thu, 25 Oct 2012 21:30:08 GMT http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-uvod-nullty-dil <p>V tomto seriálu si ukážeme, jak rozchodit webový systém naprosto od nuly, za použití těchto technologií: Java, Maven, Spring, Struts2, Hibernate, Oracle (nebo MySQL) a JQuery ve vývojovém prostředí Eclipse a serveru Tomcat. Od tohoto seriálu můžete očekávat detailní a srozumitelný návod, jak začít vývoj webové aplikace u vás na lokálním počítači. Výsledkem bude fungující webový systém postavený na MVC architektuře, který bude demonstrovat základní použití všech zmíněných technologií.</p> <h3>Důvody vzniku tohoto seriálu</h3> <p>Start-up jakéhokoliv projektu je náročnější, než by se mohlo zdát a nikdo vás za to většinou neocení. Spíš se dočkáte vět typu: „A to jste jeden formulář dělali dva týdny?“ nebo: „Chcete mi říct, že jsem zaplatil týden vývoje za to, že aplikace umí vypsat větu Hello world!???“ nebo si sami frustrovaně řeknete něco jako: „Ach jo, už se s tím týden drbu a pořád mi to vyhazuje nějaké výjímky, které nejdou odstranit ani podle všech možných návodů na internetu. Já už bych chtěl konečně začít psát vlastní aplikaci.“</p> <p>Počáteční konfigurací projektu a napsání základních obecných funkcí je práce, kterou neděláte každý den, takže se snadno zapomínají i věci, které jste si pamatovali a to vůbec nemluvím o věcech, které jste ani nikdy nevěděli :-) Samotnému se mi stalo, když jsem měnil práci, že jsem odešel z projektu, který měl za sebou mnoho let vývoje a slušné vývojářské zázemí a měl jsem najednou začít vyvíjet projekt zcela nový, takříkajíc od píky. Nemusí to ale být jen zmíněná změna práce, chcete si například rozjet nějaký soukromý projekt doma. V těchto případech zjistíte, kolik věcí již berete jako samozřejmost a to nemluvím jen o konfiguracích Springu, Hibernatu apod. Muvím i o značném počtu nezbytných utilitních funkcí a objektů, které jste si zvykli používat téměř jako vestavěné funkce jazyka Java popř. Javascriptu a najdenou se divíte, co to s tím Eclipsem zase je, že vám tyto metody nenabízí v kontextové nápovědě :-)</p> <p>Tento seriál má pomoci výrazně zrychlit tuto, dovolím si říct, neradostnou a nudnou část vývoje a mimo to také poskytnout návod na použití zmiňovaných technologií v podobě komplexního praktického příkladu.</p> <p><strong>Systém, který vznikne jako výsledný produkt tohoto seriálu, bude umět:</strong></p> <ul> <li>Registrovat nového uživatele za pomocí obsáhlejšího registračního formuláře včetně klient-side a server-side validací</li> <li>Vypsat seznam uživatelů v pěkné tabulce umožňující rychlé řazení a filtrování dle nejrůznějších hledisek</li> <li>Přihlásit uživatele do systému, provedení základní autentizace a autorizace a rozlišit 3 typy oprávnění – anonymní uživatel, registrovaný uživatel, admin a super admin.</li> <li>Možnost editace a mazání existujících uživatelů adminem + možnost přiřazení administrátor­ského práva</li> <li>Správa požadavků AJAXem</li> </ul> <p><strong>To bude obnášet z vývojářského hlediska především:</strong></p> <ul> <li>Systém bude postaven na MVC architektuře</li> <li>Aplikace se bude pomocí Mavenu buildovat přímo v Eclipse a umožní ji spustit ve webovém prohlížeči</li> <li>Rozjetí databáze</li> <li>CRUD (Create, Read, Update, Delete, tj čtení) v rámci celé MVC architektury</li> </ul> <p><strong>To obnáší zvládnout jednotlivé dílčí kroky, které zde nyní vyjmenuji. Předpokládám, že se budou víceméně krýt obsahově i chronologicky s jednotlivými díly tohoto seriálu:</strong></p> <ol> <li>Stáhnutí a konfigurace vývojového prostředí Eclipse, založení nového projektu, download potřebných pluginů (maven plugin).</li> <li>Download externích knihoven Spring, Hibernate a Struts2 a jejich integrace do našeho systému.</li> <li>Konfigurace Spring a Struts2 a „Hello World!“.</li> <li>Konfigurace Spring a Hibernate a „Hello World!“ v kompletní MVC architektuře.</li> <li>Vytvoření DB tabulky Uživatelé a CRUD nad touto tabulkou za pomocí základního webového formuláře – tzn. vytvoření, výpis, aktualizace a smazání uživatele.</li> <li>Přidání dalších DB tabulek pro komplexnější ukládání informací o uživateli a tedy i správná konfigurace Hibernatu pro DB vazby typu 1:n a m:n.</li> <li>Vytvoření moderního formuláře (klient-side validace, vyhledávací comboboxy, ajaxové odesílání formuláře apod.) pomocí JQuery a jeho pluginů.</li> <li>Vytvoření moderní tabulky (především inteligentní řazení a filtrování) pomocí JQuery a jeho pluginů.</li> <li>Přihlášení uživatele pomocí Struts2 interceptoru a jeho autorizace a autentizace.</li> <li>Základní testování pomocí JUnit testů a automatické webové testování Selenium.</li> </ol> <p>První díl seriálu se plánuji na začátek listopadu 2012.</p> http://www.nullpointer.cz/webova-aplikace-v-jave-od-a-do-z-uvod-nullty-dil JQuery Datatables columnFilter plugin: problém s více tabulkami na jedné stránce Tue, 23 Oct 2012 20:21:34 GMT http://www.nullpointer.cz/jquery-datatables-columnfilter-plugin-problem-s-vice-tabulkami-na-jedne-strance <p>Column filtr plugin pro jquery plugin DataTables zlobí, když se na jedné stránce vyskytnou dvě nebo více tabulek (typu datatable). Sloupcový filtr pak chybně filtruje pouze poslední definovanou tabulku. V praxi to vypadá tak, že když se pokusíte použít sloupcový filtr např. první tabulky, filtruje se úplně jiná tabulka – ta poslední…</p> <h3>Problém</h3> <p>Column filtr (dále „sloupcový filtr“) plugin (<a href="http://code.google.com/p/jquery-datatables-column-filter/">http://code.google.com/…lumn-filter/</a>) pro jquery plugin DataTables (<a href="http://datatables.net/">http://datatables.net/</a>) zlobí, když se na jedné stránce vyskytnou dvě nebo více tabulek (typu datatable). Sloupcový filtr pak chybně filtruje pouze poslední definovanou tabulku. V praxi to vypadá tak, že když se pokusíte použít sloupcový filtr např. první tabulky, filtruje se úplně jiná tabulka – ta poslední.</p> <h3>Upozornění</h3> <p><strong>Používám colum jquery.dataTa­bles.columnFil­ter.js verzi 0.9</strong>, která je jediná ke stažení na oficiálních stránkách zde – <a href="http://code.google.com/p/jquery-datatables-column-filter/downloads/list">http://code.google.com/…wnloads/list</a> (v době psaní tohoto článku). Sice lze najít v svn trunku vyšší verzi (<a href="http://jquery-datatables-column-filter.googlecode.com/svn/trunk/media/js/jquery.dataTables.columnFilter.js">http://jquery-datatables-column-filter.googlecode.com/…umnFilter.js</a>), v době psaní tohoto článku konkrétně 1.5, ale ta mi narozdíl od verze 0.9 nefunguje (a nevím proč), takže nemohu vyzkoušet, jestli je tam stejný problém.</p> <h3>Řešení</h3> <p><strong>Řešení bude modifikovat soubor jquery.dataTa­bles.columnFil­ter.js</strong>, pokud tedy používáte jinou verzi než 0.9, je možné, že se jednotlivé řádky mohou více či méně lišit, ale oprava problému je principiálně jednoduchá, takže věřím, že řešení bude použitelné i v jiných verzích.</p> <p>Naprosto stejný problém se řeší i zde: <a href="http://datatables.net/forums/discussion/10238/multiple-tables-in-the-same-page/p1">http://datatables.net/…same-page/p1</a> a je tam moje odpověď, jak vyřešit tento problém drobnou modifikací zdrojového souboru <strong>jquery.dataTa­bles.columnFil­ter.js</strong>. Následující řádky jsou volným přepisem této mé odpovědi do češtiny:</p> <p><strong>Veškerý níže zmiňovaný kód se týká souboru jquery.dataTa­bles.columnFil­ter.js</strong>. Problém začíná na tomto řádku:</p> <pre class="cpp"><code>$.fn.columnFilter = function (options) { oTable = this;</code></pre> <p>Globální proměnná oTable nabude hodnoty poslední tabulky, kterou definujeme. Funkce fnCreateInput se stará o vytváření input elementu používaného pro textové filtrování (ostatní typy filtrovaných polí jako date-range, number-range jsou víceméně analogické) a má tento předpis:</p> <pre class="cpp"><code>function fnCreateInput(regex, smart, bIsNumber) {</code></pre> <p>uvnitř je tento kód:</p> <pre class="cpp"><code>if (bIsNumber &amp;&amp; !oTable.fnSettings().oFeatures.bServerSide) { input.keyup(function () { /* Filter on the column all numbers that starts with the entered value */ oTable.fnFilter('^' + this.value, index, true, false); }); } else { input.keyup(function () { /* Filter on the column (the index) of this element */ oTable.fnFilter(this.value, index, regex, smart); }); }</code></pre> <p>input.keyup se zavolá, když uživatel začne psát do filtr inputu a spustí se filtrování. <strong>Problém je proměnná oTable, která má nyní hodnotu poslední definované tabulky. Jednoduché řešení spočívá ve změně proměnné oTable z globální na lokální:</strong></p> <pre class="cpp"><code>function fnCreateInput(regex, smart, bIsNumber, oTable) {</code></pre> <p>Totéž musíte udělat i pro další funkce, které generují jiné typy sloupcového filtrování:</p> <pre class="cpp"><code>function fnCreateInput(regex, smart, bIsNumber, oTable) function fnCreateRangeInput(oTable) function fnCreateDateRangeInput(oTable) function fnCreateSelect(aData, oTable)</code></pre> <p>A nakonec je samozřejmě třeba předat těmto funkcím správný argument oTable v místě, kde se volají. K tomu dochází v této funkci:</p> <pre class="cpp"><code>$.fn.columnFilter = function (options) {</code></pre> <p>Zde najdete příkaz switch, kde najdete postupně volání všech zmiňovaných funkcí a předáte tam argument oTable, který má zde ještě správnou hodnotu (je tam aktuálně vytvářená tabulka):</p> <pre class="cpp"><code>switch (aoColumn.type) { case "number": fnCreateInput(true, false, true, oTable); break; case "text": bRegex = (aoColumn.bRegex == null ? false : aoColumn.bRegex); bSmart = (aoColumn.bSmart == null ? false : aoColumn.bSmart); fnCreateInput(bRegex, bSmart, false, oTable); break; case "select": fnCreateSelect(aoColumn.values, oTable); break; case "number-range": fnCreateRangeInput(oTable); break; case "date-range": fnCreateDateRangeInput(oTable); break; default: break;</code></pre> <p>A to je vše. Můžete si stáhnout celý <a href="upload/jquery.datatables.columnfilter.js">modifkovaný columnFilter plu­gin</a></p> <h3>Závěr</h3> <p>Nejedná se rozhodně o univerzální řešení, ani nijak zvlášť hezké (jsme nuceni modifikovat knihovnu třetí strany), ale je funkční. Je možné, že jde skutečně o bug v této jinak dobré knihovně a nevím, zda je již vyřešen (špatně mi funguje dnes aktuální verze 1.5) nebo se v budoucnu vyřeší. Každopádně výše zmíněný postup vám může pomoci v případě stejného problému rychle rozběhat více tabulek datatables s column filtrem na jedné stránce a nemusíte nad tím strávit celý den jako já :-)</p> http://www.nullpointer.cz/jquery-datatables-columnfilter-plugin-problem-s-vice-tabulkami-na-jedne-strance Texyla editor a fullscreen mód Sun, 14 Oct 2012 20:41:43 GMT http://www.nullpointer.cz/texyla-editor-a-fullscreen-mod <p>Texyla editor je, jak praví <a href="https://github.com/janmarek/Texyla/wiki">oficiální stránky</a>, „javascriptový modulární přizpůsobitelný non-wysiwyg editor obsahu webových stránek specializovaný na Texy! syntaxi.“ Používáme ho i tady na Nullpointer.cz a chyběla nám funkce fullscreen editace obsahu. Ve výchozí verzi Texyla tuto možnost nenabízí, nezbývá tedy, než si ji dodělat.</p> <p>V ideálním případě by výsledkem takového snažení měl být kód, který můžu poslat jako pull request autorovi texyly a ten by ji mohl začlenit do projektu. Texyla má dokonce přesně takovou <a href="https://github.com/janmarek/Texyla/issues/9">issue</a> (postarší). V takovém stadiu nicméně moje řešení není, v duchu sloganu tohoto webu jde zatím spíše o to <strong>dexempo</strong>. Dost řečí, jdeme na věc.</p> <h3>Vytvoření nového tlačítka</h3> <p>Texyla podporuje, alespoň podle <a href="https://github.com/janmarek/Texyla/wiki/API-pro-tvorbu-plugin%C5%AF">dokumentace</a>, jednoduchý způsob jak přidat tlačítko do menu editoru a to nějak takto…</p> <pre class="js"><code>$.texyla.addButton("fullscreen", function () { // our new button magic here });</code></pre> <p>… s tím, že tlačítko <em>zaregistrujeme</em> do definice Texyly například tímto způsobem…</p> <pre class="js"><code>$("#frmpostForm-body").texyla({ toolbar: [ 'h1', 'h2', 'h3', 'h4', null, "fullscreen" ], });</code></pre> <p>… vytvoříme jazykový překlad – zatím stačí česky – do souboru <code>cs.js</code> přidáme …</p> <pre class="js"><code>btn_fullscreen: "Fullscreen editor",</code></pre> <p>… a nahrajeme tlačítku do adresáře <code>texyla/icons</code> nějakou tu ikonku.</p> <h3>Tlačí to?</h3> <p>V této fázi máme <strong>nové tlačítko</strong> a <strong>taky nový problém</strong>. Tlačítko totiž po stisknutí vyhazuje okno s varováním <em>Function „fullscreen“ is not supported!</em>. Což mi tak na hodinku dvě docela smotalo vousy. Long story short, jak se říká u nás, řešení jsem našel metodou <em>pokus-omyl-díky Bohu</em> a nachází se v souboru <code>texyla.js</code> uvnitř</p> <pre class="js"><code>Texyla.prototype.buttons={</code></pre> <p>Sem je třeba přidat:</p> <pre class="js"><code>fullscreen:function(){}</code></pre> <p>Tím máme v podstatě vyhráno, zbývá už jen našemu novému tlačítku dát nějaký smysluplný obsah. V mém případě zatím dělá práci zhruba toto:</p> <pre class="js"><code>$.texyla.addButton("fullscreen", function () { var isFullscreen = $('.texyla').hasClass('texyla-fullscreen'); if(isFullscreen){ $(".texyla").attr("style", "width: 832px;"); $("#frmpostForm-body").attr("style", ""); $(".ui-wrapper").attr("style", "height:100%;"); $(".texyla").removeClass("texyla-fullscreen"); } else{ $(".texyla").attr("style", ""); $(".preview-wrapper").attr("style", ""); $("#frmpostForm-body").attr("style", ""); $(".ui-wrapper").attr("style", "height:100%;"); $(".texyla textarea").attr("style", "width: 100%;height:100% !important;"); $(".texyla").addClass("texyla-fullscreen"); } });</code></pre> <h3>Vytlačeno jest</h3> <p>A to je prozatím myslím vše, jestli se mi časem podaří udělat rozšíření přímo do Texyly, dám vědět. Pokud tento článek někdo vezme jako odrazový můstek pro totéž, taky dobře.</p> http://www.nullpointer.cz/texyla-editor-a-fullscreen-mod