Il s'agit de donner à la liste des villes le comportement suivant :
la méthode addSelector permet d'ajouter le contrôle clavier sur la liste : le code de touche 113 correspond à la touche F2, et permet l'édition d'une ville : voir http://tutorial.kobject.net/java/ajaxinclude/keyboard
{#func:this.addSelector(113)#} {#func:this.setEditable(true)#} {#mask:<td>{cp}</td><td>{ville}</td>#} {#mask:<td>{cp}</td><td>{ville}</td>#} {#set:this.ajaxIncludes=true#} {#set:this.listContentUrl="villes.do"#} {_ajx} {_listContent} {_page} <div class="boxButtons">{_pageCounter}{_navBarre}</div> {/_listContent}
Action | Effet |
---|---|
F2 | Edition avec le formulaire de modification (il s'agit de la seule touche paramétrable) |
Touches de direction Haut, bas, gauche, droite | Déplacement entre les villes |
MAJ+Home | Atteindre la première page |
MAJ+Fin | Atteindre la dernière page |
MAJ+PageUp | Page précédente |
MAJ+PageDown | Page suivante |
Double clic | Déplacement sélection ligne |
{#func:this.addSelector(113)#} {#func:this.setEditable(false)#} ...
Pour qu'un membre soit éditable, il faut qu'il appartienne à un élément DOM de la classe editable.
Nous allons ajouter un Display associé à la classe KVille pour modifier l'affichage des éléments de la liste :
La méthode showInList à surdéfinir gère l'affichage de chaque membre de la liste.
package net.display; import net.ko.displays.KObjectDisplay; import net.ko.kobject.KObject; public class VilleDisplay extends KObjectDisplay { @Override public String showInList(KObject ko, String memberName) { String result=super.showInList(ko, memberName); //si le nom du membre est cp ou ville, on le met dans un span de classe css editable if("cp".equals(memberName) || "ville".equals(memberName)){ result="<span class='editable' title='"+memberName+"'>"+result+"</span>"; } return result; } }
... <class name="KVille" display="net.display.VilleDisplay"> <member max="5" name="cp" required="1" type="string" /> <member max="100" name="ville" required="1" type="string" transform="onlyFirstWordUpper"/> </class> ...
Action | Effet |
---|---|
Double clic | Mode édition du membre |
ESCAPE | Sortie de l'édition |
ENTREE | Sortie avec possible validation |
Perte du focus | Sortie de l'édition |
target correspond à l'élément DOM qui a reçu l'événement :
<ajax-includes> ... <request requestURL="villes.do"> <js triggerSelector=".editable" triggerEvent="updated"> <updateOne virtualURL="updateVille.do" operation="update" kobjectShortClassName="KVille" targetId="info" method="POST"> <field name="{js:target.title}" value="{js:target.innerHTML}"/> </updateOne> </js> </request> ... <ajax-includes>
<mappings> ... <virtualMapping requestURL="updateVille.do" mappingFor="updateOne"/> ... </mappings>
Le champ supplémentaire devra afficher le nombre actuel d'entreprise(s) de la ville, dans un lien cliquable qui devra ensuite afficher la liste des entreprises de la ville.
... public KVille() { super(); hasMany(KEntreprise.class); } ...
{#func:this.setEditable(false)#} {#func:this.addSelector(113)#} {#mask:<td>{cp}</td><td>{ville}</td><td>{btDetail}</td>#} {#mask:<td>{cp}</td><td>{ville}</td><td>{btDetail}</td>#} {#set:this.ajaxIncludes=true#} {#set:this.listContentUrl="villes.do"#} {_ajx} {_listContent} {_page} <div class="boxButtons">{_pageCounter}{_navBarre}</div> {/_listContent}
* Modifier le Display de la classe KVille, VilleDisplay, pour qu'il gère l'affichage de btDetail :
public class VilleDisplay extends KObjectDisplay { @Override public String showInList(KObject ko, String memberName) { String result=super.showInList(ko, memberName); if("cp".equals(memberName) || "ville".equals(memberName)){ result="<span class='editable' title='"+memberName+"'>"+result+"</span>"; } if("btDetail".equals(memberName)){ KVille ville=(KVille) ko; int nb=ville.getEntreprises().count(); if(nb>0) result="<div><a id='alink-"+ville.getId()+"' class='default' title='Entreprises de "+ville.getVille()+"'>"+KString.pluriel(ville.getEntreprises().count(),"entreprise")+"</a></div>"; else result="<div>"+KString.pluriel(ville.getEntreprises().count(),"entreprise")+"</div>"; } return result; } }
{#func:this.setEditable(false)#} {#func:this.addSelector(113)#} {#mask:<td>{cp}</td><td>{ville}</td><td>{btDetail}</td>#} {#mask:<td>{cp}</td><td>{ville}</td><td>{btDetail}</td>#} {#set:this.ajaxIncludes=true#} {#set:this.listContentUrl="villes.do"#} {_ajx} {_listContent} {_page} <div class="boxButtons">{_pageCounter}{_navBarre}</div> {/_listContent} <div id="divEntreprises"></div>
{#koDisplay:net.display.EntrepriseVilleDisplay#} {#mask:<td>{rs}</td><td>{adresse}</td><td>{tel}</td>#} {#mask:<td>{rs}</td><td>{adresse}</td><td>{tel}</td>#} <fieldset> <legend>%ville%</legend> {_ajx} {_listContent} {_page} {/_listContent} </fieldset>
Le display va permettre de filtrer les entreprises de la liste, pour ne faire apparaître que les entreprises de la ville sélectionnée :
Surdéfinir la méthode beforeLoading de la façon suivante :
package net.display; import javax.servlet.http.HttpServletRequest; import net.ko.displays.KObjectDisplay; import net.ko.http.objects.KRequest; import net.ko.http.views.KPageList; import net.ko.kobject.KObject; public class EntrepriseVilleDisplay extends KObjectDisplay { @Override public void beforeLoading(Class<? extends KObject> clazz, KPageList list, HttpServletRequest request) { list.addWhere("idVille='"+KRequest.GET("idVille", request, "-1")+"'"); } }
<mappings> ... <mapping requestURL="entrepParVille.do" responseURL="/WEB-INF/list/ville/entreprise.list"/> ... </mappings>
<ajax-includes> ... <request requestURL="villes.do"> ... <js triggerSelector="a.default" triggerEvent="click"> <include targetURL="entrepParVille.do" targetParams="idVille={js:$vId(target.id)},ville={js:target.title}" targetId="divEntreprises"></include> </js> </request> </ajax-includes>
<ajax-includes> ... <request requestURL="villes.do"> ... <js triggerSelector="a.default"> <include targetURL="entrepParVille.do" targetParams="idVille={js:$vId(target.id)},ville={js:target.title}" targetId="divEntreprises" transition="skew"> <transition targetId="divEntreprises"> <oneTransition endValue="1" startValue="0" property="opacity" duration="2" timing="ease"/> </transition> </include> </js> </request> ... </ajax-includes>