Une Webapp en moins de 10 minutes avec Jo


Nous allons voir comment réaliser une "todolist" simpliste en quelques minutes grâce au framework javascript "Jo".
Jo est léger, simplissime à utiliser, destiné à faire des webapps pour nos jouets.
L'objectif de ce mini article est justement de démontrer tout ça.

Le code de Jo est très très lisible, donc s'il manque quelque chose dans la documentation vous trouverez très vite vos petits dans le code source.

  1. Créons tout d'abord le squelette de notre application :
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    	<title>Ma ToDo List</title>
    
    	<!-- stylesheets -->
    	<link rel="stylesheet" href="css/aluminum.css" type="text/css">
    	<link rel="stylesheet" href="css/webkit.css" type="text/css">
    </head>
    <body onload="App.load();">
    <!-- lib -->
    <script src="jo_min.js"></script>
    <!-- app -->
    <script>
    	// Charger "Jo"
    	jo.load();
    	
    	var App = {
    
    		// initialisation de l'application
    		load: function() {
    			// l'application principale avec une "pile"
    			this.screen = new joScreen([
    				this.stack = new joStackScroller()
    			]);
    			
    			// la "carte/card" principale (=écran principal)
    			// avec une barre de titre
    			this.card = new joCard([
    				new joTitle("Ma ToDo List"),
    				
    			]);
    			
    			// mettre la "card"  dans la pile
    			this.stack.push(this.card);
    		},
    	};
    	
    </script>
    </body>
    </html>
    
  2. Ensuite ajoutons un label et un champ texte pour saisir nos tâches, un bouton pour les enregistrer, tout ça regroupé dans un composant (pour le moment le bouton ne fait rien)
    [...]
    // la "carte/card" principale (=écran principal)
    // avec une barre de titre
    this.card = new joCard([
    		new joTitle("Ma ToDo List"),
    				
    	new joGroup([
    		new joLabel("à faire :"),
    		this.currentTask = new joInput("saisir ici").setStyle({width:"90%"}),
    		this.addTask = new joButton("Ajouter").selectEvent.subscribe("rien", this)	
    	]),				
    				
    ]);
    [...]
    

    Vous devriez obtenir ceci :

  3. Nous allons initialiser un tableau des tâches (ligne 5):
    [...]
    	var App = {
    
    		// quelques tâches en dur
    		tasks: ["Faire la vaisselle", "Aller au boulot", "Prez Scrum"],
    
    		// initialisation de l'application
    		load: function() {
    [...]
    
  4. ça c'est fait, maintenant on ajoute le composant liste (ligne 8):
    [...]
    		new joGroup([
    			new joLabel("à faire :"),
    			this.currentTask = new joInput("saisir ici").setStyle({width:"90%"}),
    			this.addTask = new joButton("Ajouter").selectEvent.subscribe("rien", this)	
    		]),
    				
    		this.taskListcontrol = new joList(this.tasks).setAutoSort(true),	
    [...]
    

    Vous devriez obtenir ceci :

  5. Maintenant nous allons rajouter du code au bouton pour qu'il puisse ajouter les tâches saisies, juste après la fonction load :
    [...]
    		addNewTask: function(){
    			//on ajoute le texte saisi dans le tableau
    			this.tasks.push(this.currentTask.getData());
    			//on rafraichit la liste
    			this.taskListcontrol.refresh();
    			//on affiche une popup
    			this.screen.alert("Nouvelle Tâche", "Ajoutée !!!");
    		},
    [...]
    
  6. On modifie le code du bouton :
    	this.addTask = new joButton("Ajouter").selectEvent.subscribe(this.addNewTask, this)	
    

    Et vous devriez avoir quelque chose comme ceci :

Le code final de votre webapp est le suivant :

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>Ma ToDo List</title>

	<!-- stylesheets -->
	<link rel="stylesheet" href="css/aluminum.css" type="text/css">
	<link rel="stylesheet" href="css/webkit.css" type="text/css">
</head>
<body onload="App.load();">
<!-- lib -->
<script src="jo_min.js"></script>
<!-- app -->
<script>
	// Charger "Jo"
	jo.load();
	
	var App = {

		// quelques tâches en dur
		tasks: ["Faire la vaisselle", "Aller au boulot", "Prez Scrum"],

		// initialisation de l'application
		load: function() {
			// l'application principale avec une "pile"
			this.screen = new joScreen([
				this.stack = new joStackScroller()
			]);
			
			// la "carte/card" principale (=écran principal)
			// avec une barre de titre
			this.card = new joCard([
				new joTitle("Ma ToDo List"),
				
				new joGroup([
					new joLabel("à faire :"),
					this.currentTask = new joInput("saisir ici").setStyle({width:"90%"}),
					this.addTask = new joButton("Ajouter").selectEvent.subscribe(this.addNewTask, this)	
				]),
				
				this.taskListcontrol = new joList(this.tasks).setAutoSort(true),				
				
			]);
			
			// mettre la "card"  dans la pile
			this.stack.push(this.card);
		},
		
		addNewTask: function(){
			//on ajoute le texte saisi dans le tableau
			this.tasks.push(this.currentTask.getData());
			//on rafraichit la liste
			this.taskListcontrol.refresh();
			//on affiche une popup
			this.screen.alert("Nouvelle Tâche", "Ajoutée !!!");
		},
	};
	
</script>
</body>
</html>

IMPORTANT : Pour que le rendu sur un mobile ou un ipad soit "parfait", il faut ajouter cette ligne dans le header de votre page html :

	<meta name="viewport" content="width=device-width; initial-scale=1.0; user-scalable=0;">

Ainsi vous obtenez une webapp que vous pouvez utilisez aussi bien sur un iPad, iPhone, Android, WebOS, ...

Aller plus loin avec Jo :

Je vous engage à creuser la doc et le code source, ce "petit" framework est terriblement puissant, il sait aussi "jouer" avec les bases de données SQLite de Webkit, propose d'autres composants, gère les effets de transition, etc. ...

Bon dimanche à tous. @+ P.

Comments

css

Bonjour et merci pour cet article très clair.
As-tu déjà utilisé le fichier jo.css fourni avec la librairie, je vois que tu utilises webkit.css, car je rencontre de gros problèmes de compatilbilité avec jo.css...

jo.css

oui je l'ai utilisé mais essentiellement pour ipad
j'ai eu des pb sous android par contre
peut être que la dernière version ? pas eu le tps de tester encore

c'est quoi le pb ?

Très fort

Vraiment génial ce framework, on dirait un Swing pour JS en plus simple

Loïc, merci pour les twitts

Loïc, merci pour les twitts


Warning: INSERT command denied to user 'kgkyojmt001'@'10.0.95.44' for table 'drp_watchdog' query: INSERT INTO drp_watchdog (uid, type, message, variables, severity, link, location, referer, hostname, timestamp) VALUES (0, 'php', '%message in %file on line %line.', 'a:4:{s:6:\"%error\";s:12:\"user warning\";s:8:\"%message\";s:242:\"UPDATE command denied to user &#039;kgkyojmt001&#039;@&#039;10.0.95.44&#039; for table &#039;drp_node_counter&#039;\nquery: UPDATE drp_node_counter SET daycount = daycount + 1, totalcount = totalcount + 1, timestamp = 1368913565 WHERE nid = 50\";s:5:\"%file\";s:60:\"/homez.312/kgkyojmt/www/modules/statistics/statistics.module\";s:5:\"%line\";i:54;}', 3, '', 'http://www.k33g.org/?q=node/50', '', '50.17.109.248', 1368913565) in /homez.312/kgkyojmt/www/includes/database.mysql.inc on line 128

Warning: INSERT command denied to user 'kgkyojmt001'@'10.0.95.44' for table 'drp_watchdog' query: INSERT INTO drp_watchdog (uid, type, message, variables, severity, link, location, referer, hostname, timestamp) VALUES (0, 'php', '%message in %file on line %line.', 'a:4:{s:6:\"%error\";s:12:\"user warning\";s:8:\"%message\";s:392:\"INSERT command denied to user &#039;kgkyojmt001&#039;@&#039;10.0.95.44&#039; for table &#039;drp_accesslog&#039;\nquery: INSERT INTO drp_accesslog (title, path, url, hostname, uid, sid, timer, timestamp) values(&#039;Une Webapp en moins de 10 minutes avec Jo&#039;, &#039;node/50&#039;, &#039;&#039;, &#039;50.17.109.248&#039;, 0, &#039;b9149e2489ff68b689c4d62db923d5bb&#039;, 797, 1368913565)\";s:5:\"%file\";s:60:\"/homez.312/kgkyojmt/www/modules/statistics/statistics.module\";s:5:\"%line\";i:64; in /homez.312/kgkyojmt/www/includes/database.mysql.inc on line 128

Warning: INSERT command denied to user 'kgkyojmt001'@'10.0.95.44' for table 'drp_watchdog' query: INSERT INTO drp_watchdog (uid, type, message, variables, severity, link, location, referer, hostname, timestamp) VALUES (0, 'php', '%message in %file on line %line.', 'a:4:{s:6:\"%error\";s:12:\"user warning\";s:8:\"%message\";s:1303:\"UPDATE command denied to user &#039;kgkyojmt001&#039;@&#039;10.0.95.44&#039; for table &#039;drp_sessions&#039;\nquery: UPDATE drp_sessions SET uid = 0, cache = 0, hostname = &#039;50.17.109.248&#039;, session = &#039;messages|a:1:{s:5:\\&quot;error\\&quot;;a:2:{i:0;s:332:\\&quot;user warning: UPDATE command denied to user &amp;#039;kgkyojmt001&amp;#039;@&amp;#039;10.0.95.44&amp;#039; for table &amp;#039;drp_node_counter&amp;#039;\\nquery: UPDATE drp_node_counter SET daycount = daycount + 1, totalcount = totalcount + 1, in /homez.312/kgkyojmt/www/includes/database.mysql.inc on line 128