jamp day 2010 - roma (4)
TRANSCRIPT
JAMP DAY
22 Maggio 2010
Relatori:
Ruben Patanè
Giampiero Ancilletta
Università degli Studi di Roma "Tor Vergata"
INTERAZIONE CLIENT - SERVER
TRANSAZIONE HTTP
WEB BROWSER SERVER-SIDE
HTTP request
Response
Gestisce interfacciautente
Elaborazione delle richieste
HTTP is stateless
•Utilizzare il tag html form o tramite url•Transazioni AJAX
CLASSIC AND AJAX WEB APPLICATION
Permette uno scambio di dati in background fra web browser e server.
AJAX permette un risparmio di tempo e banda
INVIARE UNA RICHIESTA TRAMITE UN FORM<idform typeobj="form" action=“mypage.php" method=“post“> <idtag1 type =“text” value=“param1” name=“field1” /> <idtag2 type =“hidden” value=“val” name=“hiddenfield” /> …………………………</idform>
<idtag type =“a” href=“mypage.php?field1=val1&field2=val2” text=“link” />
function html_load() { $_SESSION['param1'] = $_POST['param1']; $_SESSION['param2'] = $_POST['param2']; }
<page type =“page” fowardrequest=“true” />
INVIARE UNA RICHIESTA TRAMITE UN URL
LEGGERE I DATI
INVIARE UNA RICHIESTA TRAMITE AJAX
In JAMP la classe javascript AJAX(js/ajax.js), contiene tutti i metodi necesssari a gestire le transazioni AJAX:
•Invio di qualsiasi tipo di richiesta AJAX•Parsing della richiesta•Gestione degli errori
Metodo AJAX.request(method, page, param, sync, returnxml);
method: GET o POSTpage: Nome della pagina a cui inviare la rispostaparams: Parametri da inoltrare al server websync: Transazione sincrona/asincrona(booleano true|false)returnxml: Restituzione codice XML(booleano true|false)
GESTIONE DELLE TRANSAZIONI IN JAMP
STANDARD REQUEST
WEB BROWSER
CUSTOM REQUEST
STANDARD ACTION
CUSTOM ACTION
WEB SERVER
HTTP request
Response
HTTP request
Response
RICHIESTA DATI
Tutti i dati del datasourse ds1:params = 'data=load&dsobjname=ds1‘;
AJAX.request('POST', 'mypage.php', params, false, true);
Sintassi params per passaggio parametri: param=value¶m=1• data: Indicare il tipo di azione da eseguire load o loadall• dsobjname: id dell'oggetto ds da utilizzare • dswhere(opzionale): Imposta un filtro su tutti i ds • iddswhere(opzionale): Imposta un filtro esclusivo sul ds chiamato
idds(per un ds chiamato "prova" la variabile sarà "provawhere")
Tutti i dati del datasourse ds1,ds2,..,dsn:params = 'data=load&dsobjname=ds1,ds2,..,dsn';
Tutti i dati dei datasourse presenti nella pagina:params = 'data=loadall';
RICHIESTA DATI CON FILTRO
Filtro per singola transazione sul datasource ds1:params = 'data=load&dsobjname=ds1&dswhere='+encodeURIComponent('field=fieldvalue');
AJAX.request('POST', 'mypage.php', params, false, true);
Sintassi params per passaggio parametri: param=value¶m=1• data: Indicare il tipo di azione da eseguire • dsobjname: id dell'oggetto ds da utilizzare • dswhere(opzionale): Imposta un filtro su tutti i ds • iddswhere(opzionale): Imposta un filtro esclusivo sul ds chiamato
idds(per un ds chiamato "prova" la variabile sarà "provawhere")
Filtro permanente sul datasource ds1:dsObj.DSsearch = ‘field='+encodeURIComponent(fieldvalue);AJAX.dsmore(dsObj, 'data=load&dsobjname=ds1');
RICHIESTA MODIFICA DATI
Richiesta di inserimento dati:
params = 'data=new&dsobjname=ds1&nome=mario&cognome=rossi';
AJAX.request('POST', 'mypage.php', params, true, true|false);
Sintassi params per passaggio parametri: param=value¶m=1• data: Indicare il tipo di azione da eseguire • dsobjname: id dell'oggetto ds da utilizzare • keyname: Nome del campo chiave. • keynamevalue: Valore del campo chiave.
Richiesta di aggiornamento dati:params = 'data=update&dsobjname=ds1&cognome=verdi&keyname=id&keynamevalue=5';
Richiesta di cancellazione dati:params = 'data=delete&dsobjname=ds1&keyname=id&keynamevalue=5’;
RICHIESTA CUSTOM
Richiesta di inserimento dati:params = 'data=myfunction¶m1=value1...¶mn=valuen';
AJAX.request(method, page, params, sync, returnxml);La stringa params contiene nel parametro data il nome della funzione da richiamare:
In una richiesta custom ilparametro data non può assumere valori di parole chiave riservate come:
"loadall","load","update","new","delete","deleteall",ecc.
Richieste per le quali non è prevista un risposta da parte del framework.
function myfunction(){ global $event; $code = “alert(‘OK’);”;
$event->returnRequest("", $code); }
RISPOSTA CUSTOM
INTERCETTARE UNA RICHIESTA PRIMA DELL'AZIONE DA PARTE DEL FRAMEWORKfunction data_select_before($ds) { global $xml; if ($ds->getPropertyName("id") == "ds1") { $result = array(); $result[0]["field1"] = "value1"; $result[0]["field2"] = "value2"; $result[1]["field1"] = "value3"; $result[1]["field2"] = "value4"; $ds->setProperty("xml", $xml->dataJSON($result)); //$ds->setProperty("xml", $xml>dataXML($result)); return false; // interrompe l'esecuzione del codice } }
INTERCETTARE UNA RICHIESTA DOPO AZIONE DA PARTE DEL FRAMEWORKfunction data_select_after($ds) { global $xml; if ($ds->getPropertyName("id") == "ds1") { $i=0; $result = array(); while($ds->ds->dsGetRow()) { $result[$i]['field1'] = $ds->ds->property["row"]->field1; if ($result[$i++]['field1']=="value1") $result[$i]['field2'] = "YES"; else $result[$i++]['field2'] = "NO"; } $ds->setProperty("xml", $xml->dataJSON($result)); } }
RICHIESTA DI REWRITE OBJECT
Sorgente XML:<select1 typeobj="dsselect" label="Select:" /><dsbutton typeobj="button" value="REWRITE OBJ" onclick="AJAX.rewriteObj('select1', 'page.php')" />
Sorgente PHP:function data_select_after($select) { $select->setProperty("optiontext", array("new1", "new2")); $select->setProperty("optionvalue", array("newval1", "newval2"));}
Permette di sostituire un oggetto già presente nella pagina.
RISPOSTA DA PARTE DEL SERVER<?xml version="1.0" encoding="utf-8"><data> <html id="dsselect1"> <![CDATA[ <div style="display:inline;" id="dsselect1_container"> <label>Select:</label> <select onchange="DSSELECT.change(this); " id="dsselect1"> <option value="newval1">new1</option> </select> </div> ]]> </html> <script> <![CDATA[ $('ds2').DSresult = [ {ID:"1",DENOMINAZIONE_COMUNE:"AGRIGENTO",CAB:"16601"} AJAX.setDsJSON('ds1',0,1,8109,1);]]> </script> <ds1 start="0" end="0" limit="0" tot="1" action="/jamp/frm/jamptree.php" order=""> <row> <id>jamp</id> <nome>base</nome> <cognome>false</cognome> </row> </ds1> </data>
<script>Tutto quello contenuto
al suo interno viene eseguito tramite eval
<html>Per sostituire un oggetto, attualmente usato dalla
funzione rewrite
[DATA]Tutto il resto viene
interpretato come dati e caricato nella struttura del tag corrispondente
LETTURA DEI DATI CONTENUTI IN UN DS
$('ds1').DSresult[row][fieldname] // array bidimensionale contenente i dati$('ds1').DSchange // indica se i campi del DS sono stati modificati dall'utente flag(true|false)$('ds1').DSMultipos // Multi selezione di record(esempio tenendo premuto SHIFT in una gridds)$('ds1').DSpos // posizione cursore di record$('ds1').DSsearch // Permette di impostare un filtro$('ds1').DSpre // Posizione cursore record prededente$('ds1').DSrow // Numero totale di righe$('ds1').DSlimit // Equivale all'attributo dslimit impostato nel XML$('ds1').DSstart // Posizione primo record$('ds1').DSend // Posizione dell'ultimo record$('ds1').p.DSaction // Pagina di destinazione della richiesta$('ds1').p.DSengine // Tipo di engine(es. mysql, xml, ldap, ecc)$('ds1').p.DSkey // Nome campo chiave$('ds1').p.DSorder // Nome campo/i per l'ordinamento$('ds1').p.DSreferences // Nome del ds padre$('ds1').p.DSreferenceskey // Nome del campo del ds padre relazionato con ds corrente$('ds1').p.DSforeignkey // Nome del campo del ds corrente relazionato con ds padre$('ds1').p.DSsavetype // modalità di salvataggio row, table, live$('ds1').p.typeObj // tipo di oggetto ds
<ds1 typeobj="ds" ..... />
FORMATTAZIONE E CONTROLLO DATI
LA FORMATTAZIONE DEI DATI
Tecnica con la quale un dato “grezzo” può essere presentato in maniera diversa fornendo sempre la stessa informazione
20100522
22/05/2010
05-22-2010
22 Maggio 20105-22-10
LA FORMATTAZIONE IN JAMP
JAMP gestisce tre tipologie di formattazione:
Date e ora: Numeri Stringhe
La formattazione di date e numeri è completamente reversibile
1,000.00 1.000,00
1.200,201,200.20
Formattazione output
Formattazione input
Modifica dato
FORMATTAZIONE DATE E ORA
Sintassi: date|lingua|formato|lingua|formato
<text typeobj=”text” format=”date|EN|yyyy-mm-dd|IT|dd/mm/yyyy” />
Dato originale Format Output
20100522 EN|yyyy|mm|dd|IT|dd/mm/yyyy 22/05/2010
20100522 EN|yyyy|mm|dd|IT|dd mmm yyyy 22 Maggio 2010
20100522 EN|yyyy|mm|dd|IT|mm-dd-yyyy 05-22-2010
20100522 EN|yyyy|mm|dd|IT|m-dd-yy 5-22-10
Formato input Formato ouput
FORMATTAZIONE NUMERI
Sintassi: number|lingua|formato|lingua|formato
<text typeobj=”text” format=”number|EN|,0.00|IT|.0,00” />
Dato originale Format Output
10,012.345.67890 EN|,00000|IT|0 10012346
10,012.345.67890 EN|,00000|IT|0,0 10012345,6
10,012.345.67890 EN|,00000|IT|0,00 10012345,67
10,012.345.67890 EN|,00000|IT|.0,000000 10.012.345,678900
Formato input Formato ouputLingua: EN separatore delle migliaia(,) delle decine(.)IT separatore delle migliaia(.) delle decine(,)
FORMATTAZIONE STRINGHE
Sintassi: string|[lower][upper][trim][!][@@@@]
<text typeobj=”text” format=”string|upper” />
Dato originale Format Output
Jamp string|lower jamp
Jamp string|upper JAMP
Formato ouputLingua: lower: trasforma tutti i caratteri in minuscoloupper: trasforma tutti i caratteri in maiuscolotrim: elimina gli spazi alla sinistra e destra della stringa@: se lunghezza stringa < aggiunge degli spazi alla sua destra!: da usare con @ se lunghezza stringa < aggiunge degli spazi alla sua sinistra
INPUT CONTROLLATO
JAMP prevede la validazione dei dati inseriti dagli utenti.
VALIDAZIONEDIGIT
VALIDAZIONESTRINGA
VALIDAZIONEDATASOURCE
VALIDAZIONE SINGOLO DIGITL'espressione regolare va specificata nell'attributo keypress.
number // Solo caratteri numericinonumber // Escluso caratteri numericialphanumeric // Solo caratteri alphanumericinoalphanumeric // Escluso caratteri alphanumericialphabetic // Solo caratteri alfabeticiloweralphabetic // Solo caratteri alfabetici minuscoliupperalphabetic // Solo caratteri alfabetici maiuscolidecimal // Solo caratteri decimalipermission // Numerico da 0-7
<id typeobj="text" maxlength=”10” />
<id typeobj="text" keypress="[a-dA-P]" />Espressioni regolari predefinite:
<id typeobj="text" keypress="number" />
Lunghezza massima:
VALIDAZIONE STRINGAAttributo da utilizzare blur nel quale specificare l'espressione regolare.
number // Solo caratteri numericidecimal // Solo caratteri decimaliip // Indirizzo IPemail // Indirizzo e-mailcf // Codice fiscalepiva // P.Ivapermission // Permission
<id typeobj="text" blur="email" />
<id typeobj="text" blur="^[0-6]$" />
Espressioni regolari predefinite:
<id typeobj="text" minlength=”3” />Lunghezza minima:
VALIDAZIONE DATASOURCE$DS_VALIDATE_RULE["idds"]= "Codice JS";
<?php$DS_VALIDATE_RULE["ds3"]= "var dsObj = $('ds3');var items = dsObj.DSresult[dsObj.DSpos];if (items['votanti'] > 100){ alert('ATTENZIONE! Numero di voti non validi '); return false;}return true;”;?>
I TEMPLATE
STRUTTURA DEI TEMPLATE
Definito nella costante TEMPLATE
Framework
Page
object <idob typeobj=”typeobj” template=”template” />
<page typeobj=”page” template=”template” />
Livello applicazione:<idob typeobj=”xmlpage” src=”mypage.php” />
<page typeobj=”page” template=”template” />
GESTIONE DEGLI ERRORI E DEBUG
LA GESTIONE DEGLI ERRORI IN JAMP
ERRORI LATO SERVER
• ECCEZIONI
• ERRORI
ERRORI LATO CLIENT
• ERRORI XML
• ERRORI JAVASCRIPT
Tutti gli errori generati dal PHP, in tutte le sue fasi: parsing, compilazione, errori in fase di run-time ed errori generati tramite trigger_error
• E_ERROR (fatal errors)
• E_WARNING (problematic yet non-fatal errors)
• E_NOTICE (not critical, could inidicate an error)
• E_PARSE (not at runtime, generated by the parser)
• E_STRICT (suggestions)
• E_RECOVERABLE_ERROR (catchable fatal error, since PHP 5.2)
• E_DEPRECATED (since PHP 5.3)
• E_USER_* (user generated events, using trigger error())
• E_CORE_* (ERROR and WARNING during PHP's initial startup)
• E_COMPILE_* (ERROR and WARNING compile-time)
GESTIONE DELLE ECCEZIONI
La classe exception.class.phpLa classe exception.class.php intercetta gli errori generati dal PHP tramite:
set_exception_handler(array($this, 'ExceptionHandler'));
set_error_handler(array($this, 'ErrorHandler'));
function before_exception_error($exception) {
$exception->param['errno'] = “.....”;$exception->param['message'] = “.....”; $exception->param['errfile'] = “.....”;$exception->param['errline'] = “.....”;$exception->param['title'] = “.....”;return false; // disabilita il comportamento di default(die)
}
function after_exception_error($exception) { // i parametri $exception->param sono disponibili in sola lettura. return false; // disabilita il comportamento di default(die)}
Errori generati dal framework a seguito del fallimento di un comando ritenuto critico.
ClsError::showError("ERROR_CODE", [param]);
ERROR_CODE: è il codice dell'errore, si utilizza un codice per la gestione della lingua. Le descrizioni degli errori si trovano nei files class/lang/[LANGUAGE].php(la costante LANGUAGE è definita nel file conf/setting.inc.php)
[param]: parametro aggiuntivo che può essere aggiunto all'errore per dare maggiori dettagli.
Esempio: ClsError::showError("DS00", “ ”MYSQL”);
GESTIONE DEGLI ERRORI
La classe error.class.phpLa classe exception.class.php intercetta gli errori generati dal PHP tramite:
function before_error() {
ClsError::$param['title'] = "........"; ClsError::$param['message'] = "........"; ClsError::$param['errno'] = "........"; ClsError::$param['obj'] = "........"; ClsError::$param['extra'] = "........";
return false; // disabilita il comportamento di default(die)}
function after_error() { // i parametri ClsError::$param sono disponibili in sola lettura. return false; // disabilita il comportamento di default(die)}
ERROR LEVEL & ERROR REPORTING
Nel file conf/setting.inc.php definiamo le costanti:
FASE DI SVILUPPO
define(" "LAN G U AG E , “ IT” );define("ERROR_LEVEL", 1 );define("ERROR_REPORTING", _ | _E ALL E S TR IC T );
FASE DI DEPLOY
define("ERROR_LEVEL", 0 );
ERRORI XML
Errori generati a seguito di una transazione AJAX o durante il parsing del dati inviati dal server.
errorXML : function(message){ ............}
Intercettare l'evento:
function xml_error(message){ .............
return false;}SYSTEMEVENT.addBeforeCustomFunction('SYSTEMEVENT','errorXML', 'xml_error');
ERRORI JAVASCRIPTSono errori generati durante l'esecuzione di codice javascript e vengono intercettati da JAMP tramite:
window.onerror = SYSTEMEVENT.errorJAVASCRIPT;
Non tutti i browser gestiscono l'evento window.error
errorJAVASCRIPT : function(message, url, row){ ............}
Intercettare l'evento:
function js_error(message, url, row){ .............}window.onerror = js_error;
IL DEBUGPer facilitare le operazioni di controllo e debug del codice e delle transazione AJAX, JAMP mette a disposizione la versione lite del famoso tool "firebug". In JAMP oltre all'integrazione sono state effettuate delle castomizzazioni per sfruttare al massimo le potenzialità di questo validissimo strumento, tra le molte funzionalità offerte abbiamo:
* Eseguire dei comandi in javascript da console. * Visualizzare le transazioni codice oggetti. * Visualizzare codice oggetti JAMP. * Visualizzare le transazioni AJAX. * Visualizzare i fogli di stile. * Visualizzare il codice javascripts. * Struttura DOM della pagina. * Modificare in real-time aspetti relativi ad una pagina web e vedere subito i risultati ottenuti.
I GRAFICI
L'oggetto graphic permette di realizzare dei grafici all'interno di una pagina web o di un report pdf.
I grafici sono realizzati grazie all'integrazione di JAMP con le librerie jpgraph.
Attualmente supportati:IstogrammiLineariDiagramma a torna, di Gantt e PolareRadarScatterStockCastomizzati
I GRAFICI<graphic typeobj="graphic" width="...." height="...." scale="...."> <parameter>
..........................
..........................
..........................
.......................... </parameter> </graphic>
I dati innerenti i grafici possono essere inseriti:Manualmente: <bar objtype="bar" data="30,22,8,10,15,24" />
Con datasource:<bar objtype="bar" dsobj="dsa" dsitem="fieldname" /><bar objtype="bar" dsobj="dsb" dsitem="fieldname" />
I REPORT
<page typeobj=”page” out=”pdf” />
In JAMP i report sono realizzati tramite integrazione con la classe fdpf.
Differenze tra output html e pdf
La creazione di un pdf avviene in un unica fase
Disposizione degli oggetti avviene attraverso coordinate assolute(attributo style)
I REPORT<page typeobj=”page” out=”pdf” />
Corpo
Pié di pagina
Piè report
<pageheader typeobj="header"> ..................
</pageheader> <body typeobj="gridds o xgridds">
..................
</body>
<pagefooter typeobj="footer"> ..................
</pagefooter>
Intestazione report
Intestazione pagina
Prima del page header
Dopo pagefooter