Un esempio di applicazione ajax ottimizzata per dispositivi mobili: xml e javascript.

Pubblicato da Davide, Aggiornato giovedì 22 aprile 2010 5 Commenti »

Questo articolo e' stato scritto piu' di 6 mesi fa.. In teoria non cambia nulla, sed panta rei: se trovi link o informazioni datate segnalalo pure. :)

Ajax è sempre cool, se poi lo affianchi a iPhone & Co. è ancora più cool. Perchè non vedere un esempio di applicazione web fruibile da cellulare che va a interrogare i dati contenuti in un file xml? Pensiamo ai webservices, ormai l’xml è un po’ ovunque. Dobbiamo solo sfruttarlo.

Alcune utili consigli per chi sviluppa applicazioni ajax destinate ad essere fruibili attraverso dispositivi mobili:

  • Blackberry: il browser deve essere abilitato per usare javascript. Inoltre, se si fa largo uso dello script lato client, è bene evitare di spuntare tra le opzioni il flag “Termina script in esecuzione lenti”, un semplice Bubble Sort lo manderebbe in tilt.
  • Nokia (symbian): nel browser standard il metodo open(“GET”,”xml/test2.xml”,true) funziona solo in modalità asincrona, ovvero con l’ultimo parametro settato a true; scaricando il browser Opera Mini invece non ci sono problemi in entrambi i casi: sincrono/asincrono.
  • iPhone: che dire.. finora nessun problem riscontrato: browser e processore appartengono a una categoria superiore.

Purtroppo non ho ancora avuto modo di fare test su dispositivi con Android..

Ma veniamo al dunque.. Tutto prende il via dagli esempi sul sito W3C, utilissimi per fare pratica.

L’obiettivo è realizzare una applicazione che va a interrogare un file xml, riportante i dati di produzione (magari estratti direttamente dal gestionale aziendale), visualizzandoli in maniera ottimizzata per schermi di modeste dimensioni.

L’esempio con il risultato finale è visibile qui.

Questa è la struttura dela file XML:
<?xml version="1.0" encoding="UTF-8"?>
<db>
<item>
<period>04.2010</period> <!-- Periodo: mese o giorno -->
<logunit id="0010">Italy Milan</logunit> <!-- Divisione di produzione-->
<delivered matcode="000123">268</delivered> <!-- Quantita' spedita -->
<finished matcode="100123">265</finished> <!-- Quantita' versata -->
<description>Product One</description> <!-- Descrizione codice materiale  -->
<update>15.04.2010 - 16:43</update> <!-- Ultimo aggiornamento -->
</item>
</db>

Supponiamo di voler offrire all’utente un menù per selezionare la divisione logistica su cui fare l’analisi e filtrare così i dati relativi alla singola divisione raggruppati in righe in base agli intervalli temporali, cliccando sulla singola riga è poi possibile vedere il dettaglio.

Ecco il codice della pagina web, con il suo javascript:
<html>
<head>
<title>Mobile Web Access</title>
<script type="text/javascript">
var xmlDoc;
var x; //array dove memorizzo la risposta xml
//inizio chiamata
if (window.XMLHttpRequest)
{
xhttp=new XMLHttpRequest();
if (xhttp.overrideMimeType) {
xhttp.overrideMimeType('text/xml');
}
}
else // Internet Explorer 5/6
{
xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onreadystatechange = alertContents; //gestione eventuali errori
xhttp.open("GET","xml/test2.xml",true); //chiamata asincrona
xhttp.send("");
// Questo metodo viene eseguito in modo asincrono quando arriva la risposta dal server
function alertContents() {
if (xhttp.readyState == 4) {
if (xhttp.status == 200) {
processResponse(); //gestione risposta
}
else {
document.write('<small>There was a problem with the request, sorry. Try later or contact your system administrator..</small>');
}
}
}
function processResponse() {
xmlDoc=xhttp.responseXML;
x=xmlDoc.getElementsByTagName("item");
}
//mostra i dati nel div in alto
function show(i) {
logunit=(x[i].getElementsByTagName("logunit")[0].childNodes[0].nodeValue);
logunitID=(x[i].getElementsByTagName("logunit")[0].getAttribute("id"));
period=(x[i].getElementsByTagName("period")[0].childNodes[0].nodeValue);
description=(x[i].getElementsByTagName("description")[0].childNodes[0].nodeValue);
delivered=(x[i].getElementsByTagName("delivered")[0].childNodes[0].nodeValue);
deliveredCode=(x[i].getElementsByTagName("delivered")[0].getAttribute("code"));
finished=(x[i].getElementsByTagName("finished")[0].childNodes[0].nodeValue);
finishedCode=(x[i].getElementsByTagName("finished")[0].getAttribute("code"));
update=(x[i].getElementsByTagName("update")[0].childNodes[0].nodeValue);
txt="<strong>Logistic Unit</strong>: "+logunitID+" - "+logunit+"<br /><strong>Period</strong>: "+period+"<br /><strong>Description</strong>: "+description+"<br /><img style='float:left; margin-right: 2px;' src='icon.png' alt='icon'/><strong>Delivered</strong>: "+delivered+"<br /><strong>Finished</strong>: "+finished+"<br /><div style='border: 1px dotted #fff; padding: 2px; background: #f9f9f9; color: #666;'><small><em>Last update: "+update+"</em></small><br/><small><a href='#item"+i+"'>Go Down To List..</a> | <a href='#show' onclick='show(" + (i-1) + ")'>Prev..</a> | <a href='#show' onclick='show(" + (i+1) + ")'>Next..</a></small></div>"  ;
document.getElementById("show").innerHTML=txt;
}
//crea tabella coi record relativi alla singola divisione
function createTable(t) {
document.getElementById("show").innerHTML="<em>"+t+": click on a table row to display the full production information.</em>";
txt="<table style='border: 2px solid #ccc; width: 100%;'>";
altStyle=0;
for (var i=0;i<x.length;i++)
{
if (x[i].getElementsByTagName("logunit")[0].getAttribute("id")==t) {
altStyle++;
if (altStyle % 2 == 0) { txt=txt+"<tr style='background: #e3efff;' onclick='show(" + i + ")'>"; }
else { txt=txt+"<tr style='border-bottom: 1px dotted #ccc;' onclick='show(" + i + ")'>"; }
txt=txt+"<td id='item"+i+"'><img src='cal.png' alt='ico'/><a href='#show'>";
txt=txt+(x[i].getElementsByTagName("period")[0].childNodes[0].nodeValue);
txt=txt+"</a></td><td><img src='car.png' alt='ico'/><a href='#show'>";
txt=txt+(x[i].getElementsByTagName("description")[0].childNodes[0].nodeValue);
txt=txt+"</a></td></tr>";
}
}
txt=txt+"</table>";
document.getElementById("table-content").innerHTML=txt;
}
</script>
</head>
<body>
<img src='mobile-logo.gif' alt='logo' /><br/>
<div id='show' style='background: #e3efff; padding: 3px; margin: 3px 0; border: 2px solid #ccc;'><em>Select Logistic Unit then click on a table row to display the full production information.</em></div>
<!--Per aggiungere una divisione, modificare questo menu -->
<img src='industry.png' alt='ico'/><a href='#show' onclick='createTable("0010")'>Italy Milan</a> | <img src='industry.png' alt='ico'/><a href='#show' onclick='createTable("0020")'>Italy Rome</a> | <img src='industry.png' alt='ico'/><a href='#show' onclick='createTable("0030")'>USA</a> | <img src='industry.png' alt='ico'/><a href='#show' onclick='createTable("0040")'>Germany</a> | <img src='industry.png' alt='ico'/><a href='#show' onclick='createTable("0050")'>China</a> | <img src='industry.png' alt='ico'/><a href='#show' onclick='createTable("0060")'>Brasil</a>
<!-- fine menu selezione divisione -->
<div id='table-content'></div>
</body>
</html>

Il codice è interamente commentato, e più che descriverlo a parole vale la pena scorrerlo e leggere i commenti. Se vuoi scaricare l’esempio completo, con sorgenti e immagini: ecco lo zip.

La scelta di incorporare css e javascript all’interno della stessa singola pagina è voluta, per ottimizzare il caricamento da parte di dispositivi mobili. Certo questa è solo una base di partenza, dalla quale si potrebbero sviluppare altre funzionalità: l’esigenza di avere dati disponibili anche su dispositivi mobili è sempre più sentita; è inevitabile che in futuro si debba far fronte a queste richieste.
In fondo è pure divertente!

5 Commenti »

Puoi lasciare un tuo commento, oppure fare un trackback dal tuo sito.

Vuoi essere il primo a lasciare un commento per questo articolo? Utilizza il modulo sotto..

Lascia il tuo commento

 

http://livregratis.fr/ - http://club-ebook.fr/

Utilizzando il sito, accetti l'utilizzo dei cookie da parte nostra. maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi