Table des matières

Prise en main d'un framework

Introduction

Objectifs

Ressources

Contexte

Il s'agit de concevoir une application web (exemple) permettant aux internautes d'évaluer des entreprises.

Principales fonctionnalités :

Base de données

Travail à faire

-- Configuration

  1. Créer le Dynamic web project koTd5
  2. Ajouter les jars suivants dans le dossier WebContent/WEB-INF/lib du projet
  3. Remplacer le fichier userStyle.css dans le dossier css : userstyle.css

-- Génération du modèle

-- Modifications métier

Classes

Décommenter la relation belongsTo dans la classe KEntreprise :

	public KEntreprise() {
		super();
		belongsTo(KVille.class);//hasMany(KEvaluation.class);
	}

Modifier la méthode toString de la classe KVille :

public class KVille extends KObject {
	...
	@Override
	public String toString() {
		return cp +" "+ville;
	}

conf/kox.xml

	<class name="KEntreprise" caption="Entreprise">
		<member max="60" name="rs" required="1" type="string" caption="Raison sociale"/>
		<member max="200" name="adresse" required="0" type="string" caption="Adresse"/>
		<member max="11" name="idVille" required="0" type="int" caption="Ville"/>
		<member max="200" name="mail" required="0" type="string" caption="Mail"/>
		<member max="20" name="tel" required="0" type="string" caption="Tél."/>
	</class>

	<class name="KEntreprise" caption="Entreprise">
		<member max="60" name="rs" required="1" type="string" caption="Raison sociale"/>
		<member max="200" name="adresse" required="0" type="string" caption="Adresse"/>
		<member max="11" name="idVille" required="0" type="int" caption="Ville"/>
		<member max="200" name="mail" required="0" type="mail" caption="Mail"/>
		<member max="20" name="tel" required="0" type="tel" caption="Tél."/>
	</class>

Validation JS personnalisée

* Associer tel2 au type du membre tel de KEntreprise dans kox.xml :

	<class name="KEntreprise" caption="Entreprise">
		<member max="60" name="rs" required="1" type="string" caption="Raison sociale"/>
		<member max="200" name="adresse" required="0" type="string" caption="Adresse"/>
		<member max="11" name="idVille" required="0" type="int" caption="Ville"/>
		<member max="200" name="mail" required="0" type="mail" caption="Mail"/>
		<member max="20" name="tel" required="0" type="tel2" caption="Tél."/>
	</class>

Transformation

Même si la validité du numéro de téléphone est contrôlée, il se peut que les numéros saisis ne soient pas uniformes : En effet, les formats suivants des numéros sont acceptés :

0231101112, 02.31.10.11.12, 02-31-10-11-12, 02 31 10 11 12

Nous allons créer un Transformer pour faire en sorte que tous les numéros saisis aient le même format : 02.31.10.11.12

Création d'une classe Transformer

package net.validation;

import net.ko.controller.KTransformer;

public class MyTransformers extends KTransformer {
	public static String tel(String value){
        return value.replaceAll("\\W", ".");
    }
}

Association au membre tel de KEntreprise

	<class name="KEntreprise" caption="Entreprise" transformer="net.validation.MyTransformers">
		<member max="60" name="rs" required="1" type="string" caption="Raison sociale"/>
		<member max="200" name="adresse" required="0" type="string" caption="Adresse"/>
		<member max="11" name="idVille" required="0" type="int" caption="Ville"/>
		<member max="200" name="mail" required="0" type="mail" caption="Mail"/>
		<member max="20" name="tel" required="0" type="tel2" caption="Tél." transform="tel"/>
	</class>

D'autres Transformers existent par défaut dans KObject et peuvent être utilisés : voir http://tutorial.kobject.net/java/configcontroller.

-- Logique applicative

mappings

Un mapping permet d'associer une url à une ressource présente sur le serveur. Toutes les requêtes d'une application KObject doivent logiquement passer par des mappings d'url, par défaut en *.do

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="header.jsp"%>
<div id="main">
	<div id="menu">
		<a id="entreprises" title="Afficher la liste des entreprises">Liste des entreprises</a>&nbsp;|&nbsp;
		<a id="villes" title="Afficher la liste des villes">Liste des villes</a>
	</div>
	<div id="content">
	Main page
	</div>
	<div id="message"></div>
</div>
<%@ include file="footer.jsp"%>

Une requête vers Affichera la page
index.do /WEB-INF/index.jsp
entreprises.do /WEB-INF/entreprises.jsp
villes.do /WEB-INF/villes.jsp

	<mappings>
		<mapping requestURL="index.do" responseURL="/WEB-INF/index.jsp"/>
		<mapping requestURL="entreprises.do" responseURL="/WEB-INF/entreprise.list"/>
		<mapping requestURL="villes.do" responseURL="/WEB-INF/ville.list"/>
	</mappings>

Inclusions ajax

Il s'agit maintenant de créer la dynamique de l'interface : la logique applicative côté client.

Toutes les modifications de la logique client sont implémentées dans le fichier conf/mox.xml

	<ajax-includes>
		<request requestURL="index.do">
			<js triggerSelector="#entreprises">
				<include targetURL="entreprises.do" targetId="content"/>
			</js>
		</request>
	</ajax-includes>

	<ajax-includes>
		<request requestURL="index.do">
			<js triggerSelector="#entreprises" triggerEvent="click">
				<include targetURL="entreprises.do" targetId="content"/>
			</js>
			<js triggerSelector="#villes" triggerEvent="click">
				<include targetURL="villes.do" targetId="content"/>
			</js>
		</request>
	</ajax-includes>

Factorisation des inclusions

Il est possible de réduire les 2 inclusions précédentes à une seule :

	<ajax-includes>
		<request requestURL="index.do">
			<js triggerSelector="#menu a" triggerEvent="click">
				<include targetURL="{js:target.id}.do" targetId="content"/>
			</js>
		</request>
	</ajax-includes> 

{js:} permet d'inclure du code javascript dans les inclusions ajax
target fait référence à l'élément cible de l’événement déclenché (ici, le lien a cliqué dans la zone menu)

Selector

Le sélecteur est une inclusion ajax permettant d'associer du code à un ensemble d'éléments, l'un d'entre eux devenant à l'exécution l'élément actif.

	<ajax-includes>
		<request requestURL="index.do">
			<js triggerSelector="#menu a">
				<include targetURL="{js:target.id}.do" targetId="content"/>
			</js>
			<js triggerSelector="body" triggerEvent="load">
				<selector selector="#menu a" event="mouseenter" startIndex="0">
					<message targetId="message">target.title</message>
				</selector>
			</js>
		</request>
	</ajax-includes>

Le selecteur body associé à l’événement load charge l'élément selector après le chargement de la page
Le message peut contenir du javascript (target.title)

-- Templates

Pour l'instant, les vues affichées (formulaires et listes) sont les pages par défaut : voir http://tutorial.kobject.net/java/khttpdefaultpages

Nous allons maintenant créer nos pages à partir des templates : voir http://tutorial.kobject.net/java/listtemplate

Pour des raisons d'organisation, il est préférable d'organiser les vues dans des sous-dossiers du dossier WEB-INF

Template de liste

{#func:this.setEditable(false)#}
{#set:this.ajaxIncludes=true#}
{#set:this.isShowCaption=true#}
{#set:this.listContentUrl="entreprises.do"#}
{#mask:<td>{rs}</td><td>{adresse}</td><td>{ville}</td>#}
{#mask:<td>{rs}</td><td>{adresse}</td><td>{ville}</td>#}
{_ajx}
{_listContent}
	{_filtre}
	{_page}
	<div class="boxButtons">{_pageCounter}{_navBarre}</div>
{/_listContent}

{#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}

La répétition du masque (il est présent en 2 exemplaires) permet d'alterner la présentation entre les lignes, ce que saurait très bien faire le css dans le cas présent,
mais dans des cas plus complexes, il sera possible de créer une alternance sur 3 ou 4 positions, ou de définir la présentation de chaque ligne.

suite TD n°6 : Conception de logique applicative