Apr 302013
 

Le chiamate AJAX classiche lavorano con l’oggetto XMLHTTPREQUEST (XHR). La maggior parte dei browser non consenton ad XHR di accedere ad altri server, o meglio a domini diversi rispetto a quello da cui parte la chiamata. Pero ovviare a questa limitazione è stato invantato JSONP, ovvero il JSON viene avvolto all’interno di una chiamata a una funzione. Invece di fare una richiesta AJAX, viene aggiunto un elemento script che punta allo script JSONP all’interno del documento HTML e una funzione di callback viene chiamata per accedere allo script.

Ovviamente attenzione perché i vendors hanno fatto questa scelta per motivi di sicurezza: infatti no c’è nessuna validazione del codice prima dell’esecuzione, quindi serve cautela.


<!DOCTYPE html>
<html lang="en">
<head>
<title>JSONP</title>
</head>
<body>
<h2>Premi il bottone per effettuare una richiesta.</h2>
<button id="trigger">GET</button>
<br>
<div id="target"></div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$(document).ready(function() {
$('#trigger').click(function() {
$.getJSON('http://search.twitter.com/search.json?q=jquery&callback=?', function(data) {
$.each(data.results, function(index, value) {
$('#target').append(value.text + '<br>');
});
});
});
});
</script>
</body>
</html>

La maggor parte del codice dovrebbe essere chiara alla luce dei post precedenti.

Per impostazione predefinita, il gestore JSONP in jQuery cerca il parametro callback=? nella stringa di query. Il “?” viene sostituito con una funzione di callback jQuery generato da inserire nel JSONP dal server È possibile modificare le impostazioni se il parametro ha un altro nome di callback o quando il metodo di callback non è parametrizzato. Il miglior consiglio è quello di evitare, quando possibile JSONP

L’esempio

 

 

Apr 262013
 

Quali sono gli eventi ajax? Prepariamo un piccolo tutorial per esporli tutti.

Partiamo da una semplicissima pagina che esegue una chiamata ajax:

<h2>Premi il pulsante per effettuare una richiesta ajax.</h2>
<button id="trigger">GET</button><br>
<div id="target"></div>
<div id="log"></div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$(document).ready(function() {
$('#trigger').click(function() {
$('#target').load('snippet.html');
});
});
</script>

A questo punto aggiungiamo una porzione di script che appenderà al document la gestione di tutti gli eventi e quando questi si scatenano scriverà all’interno del div con id log

$.each(('ajaxError ajaxSend ajaxStart ajaxStop ajaxSuccess ajaxComplete').split(' '),
function( i, name ) {
$(document).bind(name, function(event, xhr) {
$('#log').append('Event: ' + event.type + '<br/>');
});
});

L’esempio

Apr 242013
 

Un problema classico e particolare della chiamata ajax potrebbe essere legato al timeout della chiamata.

Potremmo ipotizzare che dopo un po’ non siamo disposti ad aspettare oltre il server e procederemo con un messaggio di errore.

Nel nostro caso fissereme questo timeout a un secondo.

Riutilizzaremo ancora una volta la nostra struttura consolidata:


<h2>Premi il pulsante per effettuare una richiesta ajax.</h2>
<button id="trigger">GET</button><br>
<div id="target"></div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$(document).ready(function() {
$('#trigger').click(function() {
...
});
</script>

E andiamo a impostare la chiamata ajax specificando un timeout:


$.ajax({url: 'sleep', timeout : 1000})

quello che succederà dopo sarà gestito dalle funzioni done() e fail() in modo tradizionale


.done(function(data, xhr) {
$('#target').append('ok: ' + data);
})
.fail(function(xhr, text, error) {
$('#target').append('Timeout: ' + error);
});

Nel nostro caso non trovando la url, andrà in timeout

L’esempio

 

Apr 222013
 

Oltre a gestire il successo o l’insuccesso della chiamata ajax potrebbe essere necessario avere qualche informazione in più sul motivo dell’insuccesso.

Predisporremo una chiamata simile a quelle del post precedenti ma questa volta chiameremo una url non esistente:


<h2>Premi il pulsante per effettuare una richiesta ajax.</h2>
<button id="trigger">GET</button><br>
<div id="target"></div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
$(document).ready(function() {
$('#trigger').click(function() {
$.ajax('url-non-esistente')
...
});
});
</script>

Nel caso in cui tutto andasse bene, ma in questo contesto sarebbe un problema, abbiamo il metodo done():


.done(function(data, xhr) {$('#target').append('Esito OK');})

Se invece le cose andassero male come previsto useremo fail() e gestiremo tramite i parametri di ingresso il codice dell’errore e il messaggio testuale, nel nostro esempio saranno rispettivamente codice errore 404 e messaggio: “file not found”


.fail(function(xhr, text, error) {
$('#target').append('Errore! Code ' + xhr.status + ' and text ' + error);
});

L’esempio

Apr 202013
 

Quando facciamo chiamate ajax e quindi richieste asincrone al nostro web server, potremmo incappare nel problema delle chiamate fantasma: ovvero faccio una richieste, ovviamente resto nella pagina, ma per qualche motivo il server non risponde, vediamo come gestire questa situazione.

La prima parte di html è semplice: bottone e div target:


<h2>Premi il pulsante per effettuare una richiesta ajax.</h2>
<button id="trigger">GET</button><br>

La parte successiva la dedicheremo a gestire la chiamata in modo tradizionale, chiederemo un json:


$(document).ready(function() {
$('#trigger').click(function() {
...
});
});

A questo punto si tratta di strutturare la chiamata ajax in modo un po’ diverso,

ovvero alla chiamata ajax passeremo come coppia key/value la url e il dataType


e successivamente useremo il metodo then() che accetta due parametri che saranno due funzioni di callback

una per il successo, la prima, una per la gestione dell’errore, la seconda.


.then(
function(data) {$('#target').append('Valore restituito: '+ data.name + '<br>');},
function() {$('#target').append('Chiamata AJAX fallita.<br>');}

Ultimo step con il metodo always() dichiareremo la fine delle operazioni, dato che avviene sia in caso di successo sia in caso di insuccesso.


.always(function() {
$('#target').append('FINE');

L’esempio

 

 

 

 

Apr 182013
 

Il metodo più semplice per effettuare delle richieste ajax e caricare del codice html all’interno di un ben preciso target è utilizzare il metodo load().

Nella nostra pagina inseriremo un bottone sul quale faremo il solito binding del click che farà una chiamata ajax a un file html.

Il nostro web server manderà il file html richiesto che verrà iniettato all’interno di un div target opportunamente predisposto.

Per comprendere quanto succede nella pagina è consigliabile osservare gli eventi tramite la console di firebug se si usa firefox oppure la console di chrome.

Il codice html


<button id="trigger">GET</button><br>
<div id="target"></div>

E poi il codice javascript che sarà composto da gestione dell’evento e chiamata ajax con il metodo load()


$(document).ready(function() {
$('#trigger').click(function() {
$('#target').load('snippet.html');
});
});

Ovvero all’evento click sull’oggetto che ha id trigger vai a riempire il div con id target con la risposta della chiamata load()

L’esempio

 

Apr 162013
 

In questo tutorial proponiamo una semplice chiamata ajax che riceverà come risposta dei dati in formato json.

La risposta sarà laseguente:


{
"name": "lorenzo de ambrosis",
"email" : "pippo@gmail.com"
}

La chiamata ajax sarà innescata dal click su un buttone e la risposta verrà inserita in un div target:


<button id="trigger">GET</button><br>
<div id="target"></div>

Associamo l’evento click come al solito al document.ready:


$(document).ready(function() {
$('#trigger').click(function() {
....
});
});

E arriviamo al cuore dell’esercizio: useremo il metodo get al quale passeremo come primo parametro la URL da richiedere, il secondo parametro sarà la funzione di callback il terzo il tipo di dato:


$.get('02a-test-values.json', function(data) { }, 'json');

La funzioen di callback riceve come parametro di input data che è la risposta del nostro web server, ovvero i dati in formato json,

che noi useremo per riempire la nostra pagina

$('#target').append('The returned value is: ' + data.name);

L’esempio

Mar 132013
 

Oggi vedremo come usare l’autocomplete, via ajax su jQuery Mobile, la soluzione potrebbe essere interessante per risolvere, almeno in parte, alcuni problemi di spazio tipici delle applicazioni mobile.

La possibilità di partire con oggetti precostituiti è data dalle ultime versioni del nostro framework.

Tanto per iniziare creiamo la solita pagina jqm con all’interno del content una listview con il filter, queste opzioni dovrebbero essere già note da precedenti esperienze sul framework


<div data-role="page" id="page1">
<div data-role="header" data-position="fixed">
<h1>Page 1</h1>
</div>
<div data-role="content">
<h3>Citt&agrave; italiane</h3>
<ul id="autocomplete" data-role="listview" data-inset="true" data-filter="true" data-filter-placeholder="Cerca una città..." data-filter-theme="d"></ul>
</div>
<div data-role="footer" data-position="fixed">
<h3>Footer</h3>
</div>
</div>

 

La parte interessante sarà la funzione javascript che permetterà di gestire tutto. Per il bind degli eventi useremo l’evento pageinit e sull’oggetto che ha id autocomplete intercettiamo l’evento listviewbeforefilter per iniziare a pulire e settare qualche variabile:


$( document ).on( "pageinit", "#page1", function() {
$( "#autocomplete" ).on( "listviewbeforefilter", function ( e, data ) {
var $ul = $( this ),
$input = $( data.input ),
value = $input.val(),
html = "";
$ul.html( "" );

 

La parte successiva valuterà se è stata inserita una stringa nel filtro e se ha una lunghezza superiore a un carattere, se è così verrà effettuata una chiamata ajax a una pagina php che restituirà una stringa json.


if ( value && value.length > 1 ) {
$ul.html( "<li><div class='ui-loader'><span class='ui-icon ui-icon-loading'></span></div></li>" );
$ul.listview( "refresh" );
$.ajax({
url: "autocomplete2.php",
dataType: "json",
data: {q: $input.val()},
async:false,
success: function ( response ) {

 

 

Il passo successivo sarà ciclare sul json e appendere gli elementi alla lista, compiuto questo step faremo il refresh della lista per attribuire lo stile corretto:


success: function ( response ) {
$.each( response, function ( i, val ) {
html += "<li>" + val + "</li>";
});
$ul.html( html );
$ul.listview( "refresh" );
$ul.trigger( "updatelayout");
}

L’ultima porzione di codice ci permetterà di associare il click agli elementi della lista per nasconderli e mettere l’elemento selezionato nell’input.
In alternativa si potrebbe stampare liste di link e proseguire nella navigazione:

$('#autocomplete').on('click','li',function(){
$('#autocomplete').empty();
$('input[data-type="search"]').val($(this).text())
})

Per comodità la pagina php che produce il json:

error_reporting(0);
require('include/mysql.inc.php');
$return_arr=array();
$nome=$_GET['q'];
$sql='select nome, sigla from province where nome like "%'.mysql_real_escape_string($nome).'%" order by nome';
$fetch=mysql_query($sql);
while($row=mysql_fetch_array($fetch, MYSQL_ASSOC)){
array_push($return_arr,$row['nome']);
}
mysql_close($conn);
echo json_encode($return_arr);

L’esempio

Mar 012013
 

Sulla scorta dell’esempio precedente vediamo come renderlo dinamico con php e mysql.

La prima operazione sarà quindi allestire una pagina php che interroghi una tabella del database gestendo la paginazione in modo classico.


<?php
error_reporting(0);
require('include/mysql.inc.php');
$out='';
$page=1;if(isset($_GET['page'])){$page=$_GET['page'];}
$page=filter_var($page,FILTER_SANITIZE_NUMBER_INT);
$sql='select count(sigla) from province where 1';
$fetch=mysql_query($sql);
$row=mysql_fetch_row($fetch);
$totale=$row[0];
$perpage=20;
$pagine=ceil($totale/$perpage);
if($page>$pagine){$page=$pagine;}
if($page==0){$page=1;}
$primo=($page-1)*$perpage;
$sql='select sigla, nome from province where 1 order by nome limit '.$primo.','.$perpage.'';
$fetch=mysql_query($sql);
while($row=mysql_fetch_array($fetch, MYSQL_ASSOC)){
$out.='<div><h1>'.$row['sigla'].' - '.$row['nome'].'</h1></div>';
}
mysql_close($conn);
if($page<$pagine){$out.='<nav id="page-nav"><a href="lista-prov.php?page='.($page+1).'"></a></nav>';}
echo $out;
?>

I punti centrali sono il passaggio di una variabile page in GET, lettura e santize della variabile; paginazione dei record (classica); stampa del codice html da iniettare nella pagina e infine, se non siamo all’ultima pagina, aggiunta del link alla chiamata successiva.

Non resta che apportare le modifiche necessarie alla pagina di visualizzazione:

la prima questione riguarda la chiamata iniziale per presentare i dati al caricamento, via ajax, attenzione all’async:false altrimenti il nostro plugnis non riesce a fare il bind per la seconda chiamata


$(function(){
$.ajax({
url:'lista-prov.php',
type:'GET',
async:false,
success: function(str){
$('#container').html(str);
}
})

...

Il resto del codice resterà inalterato rispetto all’esempio precedente

La pagina in opera

Feb 032013
 

Siamo oggi di fronte all’annosa questione: come fare l’apload di un file usando un sisstema un po’ moderno e intelligente ma facilemente integrabile nei binari gà noti della programmazione php.

La soluzione proporsta prevede l’uso del celebre plugin di jQuery uploadify

Da questo sito scaricheremo i files che ci servono dalla pagina di download, ovvero il plugin, il suo css, un file swf per la realizzazione della prgogress bar e, già che ci siamo, il file php per spostare il file nella cartella di destinazione finale. Il nostro scopo sarà consentire all’utente la scelta e l’upload del file prima e indipendetemente dall’invio del form, gestiremo la risposta per sapere il nome del file caricato.

Partiamo quindi dalle intestazioni del file html:


<link rel="stylesheet" type="text/css" href="uploadify.css" />
<script src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<script src="js/jquery.uploadify.min.js"></script>

Proseguiamo con il form:


<form>
<fieldset>
<legend>File upload</legend>
<label for="file_upload_1">File</label><br>
<input type="hidden" id="file_upload" name="file_upload">
<input type="file" id="file_upload_1" name="file_upload_1"><br><br>
<input type="submit">
</fieldset>
</form>


Useremo il campo nascosto per memorizzare il nome del file così come verrà salvato.

Per attivare il controllo sull’input file procederemo in questo modo:


$(function() {
$("#file_upload_1").uploadify({
height        : 30,
swf           : 'uploadify.swf',
uploader      : 'uploadify.php',
width         : 120,
onUploadSuccess : function(file, data, response) {$('#file_upload').val(data);}
});
});

La maggiorn parte delle informazioni dovrebbero essere evidenti, la parte forse pià interessante è l’onUploadSuccess che scrive nell’input hidden, per il resto sono i percorsi dei due file scaricati.

Per quanto rigarda il file php, il codice è il seguene e l’unica personalizzazione riguarda il path di destinazione dei files, poi lo si potrà personalizzare e integrare con gli opportuni controlli come meglio si crede:


$targetFolder = '/blog/tutorial/upload'; // Relative to the root
if (!empty($_FILES)) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
$targetFile = rtrim($targetPath,'/') . '/' . $_FILES['Filedata']['name'];

// Validate the file type
$fileTypes = array('jpg','jpeg','gif','png'); // File extensions
$fileParts = pathinfo($_FILES['Filedata']['name']);

if (in_array($fileParts['extension'],$fileTypes)) {
move_uploaded_file($tempFile,$targetFile);
echo $_FILES['Filedata']['name'];
} else {
echo 'Invalid file type.';
}
}

L’esempio