Capitolo - Mondadori Informatica

Transcript

Capitolo - Mondadori Informatica
TITOLO ORIGINALE
JavaScript Step by Step, 2E
Published with the authorization of Microsoft Corporation by:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, California 95472
Copyright © 2010 Steve Suehring
© 2011, Sperling & Kupfer
Authorized Italian translation of the English edition of JavaScript Step by Step Second edition, ISBN
978-0-7356-4552-3
@ 2010 Steve Suehring. This translation is published and sold by permission of O’Reilly Media, Inc.
ITALIAN Language Edition published by Sperling & Kupfer Editori SpA
All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form
or by any means without the written permission of the publisher.
Nessuna parte del testo può essere in alcun modo riprodotta senza autorizzazione scritta di Sperling
& Kupfer Editori.
Copertina per l’edizione italiana: Sperling & Kupfer Editori SpA
Traduzione, revisione tecnica e realizzazione editoriale: Publish Art - Pavia
Ogni cura è stata posta nella raccolta e nella verifica della documentazione contenuta in questo libro.
Tuttavia né gli autori, né O’Reilly Media, Inc., né Microsoft Corporation, né Sperling & Kupfer Editori
possono assumersi alcuna responsabilità derivante dall’utilizzo della stessa. Lo stesso dicasi per ogni
persona o società coinvolta nella creazione, nella produzione e nella distribuzione di questo libro.
Microsoft, Microsoft Press, ActiveX, Excel, FrontPage, Internet Explorer, PowerPoint, SharePoint,
Webdings, Windows e Windows 7 sono marchi o marchi registrati di Microsoft Corporation altri nomi
di prodotti e di aziende citati in queste pagine possono essere marchi dei rispettivi proprietari.
Mondadori Informatica® è un marchio registrato da Arnoldo Mondadori Editore SpA
Prima edizione Miti informatica: ottobre 2013
ISBN 978-88-6114-392-0
Edizioni:
1
2
3
4
5
20132014201520162017
6
Finito di stampare nel mese di ottobre 2013
presso ELCOGRAF S.p.A.
Stabilimento di Cles (TN)
Printed in Italy
7
8
Sommario
XIII
Sommario breve parte IV-V
Scaricabile dal sito Mondadori Informatica
Parte IV AJAX
17
18
19
20
e l’integrazione lato-server
JavaScript e XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Applicazioni JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Un tocco di AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Qualche approfondimento su AJAX . . . . . . . . . . . . . . . . . . . . . . .
331
341
345
367
Parte VjQuery
21
22
23
Introduzione alle librerie e ai framework JavaScript . . . . . . . . . 383
Introduzione a jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
Effetti e plug-in di jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Sommario parte IV-V
Scaricabile dal sito Mondadori Informatica
Parte IV AJAX e l’integrazione lato-server
17
JavaScript e XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Utilizzare XML con JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Un esempio di documento XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Caricare un documento XML con JavaScript . . . . . . . . . . . . . . . . . . . . . . . . 332
Lavorare con dati XML da Excel 2007 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
Un’anteprima del futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
18
Applicazioni JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Componenti delle applicazioni JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
I magnifici tre: visualizzazione, comportamento e dati . . . . . . . . . . . . . . . 341
JavaScript e le interfacce web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
19
Un tocco di AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Introduzione ad AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
L’oggetto XMLHttpRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Istanziare l’oggetto XMLHttpRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Inviare una richiesta AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
Elaborare una risposta AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
Elaborare risposte XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Lavorare con JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
Elaborare le intestazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
Utilizzare il metodo POST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
Caso di studio: ricerca e aggiornamento live . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
20
Qualche approfondimento su AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
Creare una tabella HTML con XML e CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
Stilizzare la tabella con CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
Cambiare gli attributi di stile con JavaScript . . . . . . . . . . . . . . . . . . . . . . . . 371
Creare una casella a discesa dinamica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
Accettare input dall’utente e AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
Parte VjQuery
21
Introduzione alle librerie e ai framework JavaScript . . . . . . . . . . . . . . . . . 383
Comprendere le librerie di programmazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
Definire una propria libreria JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
Librerie e framework JavaScript diffusi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
Yahoo! User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
MooTools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
XV
Altre librerie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
22
Introduzione a jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
Presentazione di jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
Utilizzare jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
I due download di jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
Includere jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
Sintassi jQuery di base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
Collegare jQuery all’evento load . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
Utilizzare i selettori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
Selezionare elementi tramite l’ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
Selezionare elementi tramite la classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
Selezionare elementi tramite il tipo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
Selezionare elementi tramite la gerarchia . . . . . . . . . . . . . . . . . . . . . . . . . . 392
Selezionare elementi tramite la posizione . . . . . . . . . . . . . . . . . . . . . . . . . . 393
Selezionare elementi tramite un attributo . . . . . . . . . . . . . . . . . . . . . . . . . . 396
Selezionare elementi dei form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
Altri selettori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
Funzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
Attraversare il DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
Lavorare con gli attributi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
Modificare il testo e l’HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
Inserire elementi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Funzioni callback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Eventi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
Associare e disassociare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
Eventi del mouse e hover . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
Altri gestori di evento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
AJAX e jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
Errori e timeout AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Inviare dati al server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
Altre opzioni importanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
Altro codice jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
23
Effetti e plug-in di jQuery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Funzionalità centrali per migliorare l’usabilità . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
Effetti nativi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
jQuery UI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
Utilizzare jQuery UI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
Drag-and-drop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Accordion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
Ulteriori informazioni su jQuery UI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
XVI
Appendice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
Parte IV
AJAX e l’integrazione lato-server
Capitolo 17: JavaScript e XML
Capitolo 18: Applicazioni JavaScript
Capitolo 19: Un tocco di AJAX
Capitolo 20: Qualche approfondimento su AJAX
17 Java PpP.indd 329
329
28/04/11 16:00
17 Java PpP.indd 330
28/04/11 16:00
Capitolo 17
JavaScript e XML
Dopo aver letto questo capitolo, sarete in grado di:
n
Esaminare le funzioni per aprire un documento Extensible Markup Language (XML)
utilizzando JavaScript.
n
Visualizzare un documento XML come tabella Hypertext Markup Language (HTML).
n
Visualizzare un foglio di calcolo XML di Microsoft Office Excel 2007 utilizzando
JavaScript.
Utilizzare XML con JavaScript
XML è un linguaggio che consiste quasi completamente di tag definiti dall’utente. Poiché i
tag definiti dall’utente rendono l’XML estremamente personalizzabile, l’XML è utilizzato di
frequente come formato file per lo scambio dei dati. Una considerazione importante per i
programmatori JavaScript è che l’XML rappresenta la X dell’acronimo AJAX (Asynchronous
JavaScript and XML). AJAX è un metodo molto diffuso per creare applicazioni web interattive. Ulteriori informazioni su AJAX sono riportate nei due capitoli successivi: Il capitolo 19,
“Un tocco di AJAX”, e il capitolo 20, “Qualche approfondimento su AJAX”.
XML è uno standard aperto definito dal World Wide Web Consortium (W3C) ed è attualmente alla sua quarta edizione. Questa sezione esamina brevemente l’XML in quanto
appartenente a JavaScript. Potete trovare ulteriori informazioni su XML sul sito di XML
Working Group, all’indirizzo http://www.w3.org/XML/Core/ o sul sito web di Microsoft,
all’indirizzo http://msdn.microsoft.com/xml/ (le informazioni sono in inglese).
Un esempio di documento XML
I documenti XML consistono di elementi sistemati in una struttura di documento. Questi
elementi hanno una sintassi propria, comprendente il fatto che essi richiedono un tag
iniziale e un tag finale. Per il programmatore web l’aspetto di un documento (definito nel
testo fra i tag) potrebbe essere familiare. Ecco un documento XML di esempio, che potete
trovare anche in books.xml nella cartella Chapter17 fra i file di esempio:
<books>
<book>
<title>MySQL Bible</title>
<author>Steve Suehring</author>
<isbn>9780764549328</isbn>
<publisher>Wiley Publishing Inc.</publisher>
</book>
<book>
<title>JavaScript Step by Step</title>
17 Java PpP.indd 331
331
28/04/11 16:00
332
Parte IV AJAX e l’integrazione lato-server
<author>Steve Suehring</author>
<isbn>9780735624498</isbn>
<publisher>Microsoft Press</publisher>
</book>
</books>
La struttura globale del documento deve soddisfare determinati criteri, perché il documento possa qualificarsi come documento ben formato. Come potete vedere nell’esempio, ogni
elemento ha un proprio tag iniziale seguito da un corrispondente tag finale. Gli elementi
possono anche essere nidificati l’uno nell’altro. Molte di queste regole sono simili alle regole dell’HTML.
I documenti XML possono contenere anche attributi, perciò è valido anche il seguente
codice:
<?xml version="1.0"?>
<book title="JavaScript Step by Step" author="Steve Suehring" isbn="9780735624498"
publisher="Microsoft Press" />
Caricare un documento XML con JavaScript
Potete caricare e manipolare i documenti XML utilizzando JavaScript. Questa sezione spiega come farlo.
Importare il documento
Potete importare un documento XML utilizzando uno fra due approcci, a seconda dei
browser che volete supportare. Per i browser più recenti, fra cui Chrome, Firefox e le ultime
versioni di Windows Internet Explorer, potete utilizzare l’oggetto XMLHTTPRequest(), mentre le vecchie versioni di Internet Explorer utilizzano l’oggetto ActiveXObject. Il seguente
codice carica il documento books.xml in un modo compatibile con più browser:
if (window.XMLHttpRequest) {
var httpObj = new XMLHttpRequest();
} else {
var httpObj = new ActiveXObject("Microsoft.XMLHTTP");
}
httpObj.open("GET","books.xml",false);
httpObj.send();
var xmlDocument = httpObj.responseXML;
17 Java PpP.indd 332
28/04/11 16:00
Capitolo 17 JavaScript e XML
333
Visualizzare il documento
Spesso i dati XML possono essere visualizzati al meglio in formato tabella o foglio di calcolo. La figura 17.1 mostra il file books.xml in Excel 2007.
Figura 17.1 Un file XML rappresentato in un foglio di calcolo.
Una tabella HTML è utile per rappresentare in un browser gli stessi dati mostrati nella figura
17.1. Visualizzare dati XML utilizzando JavaScript richiede soprattutto alcune conoscenze
del Document Object Model (DOM), e nessun’altra speciale funzione o metodo oltre quelli
richiesti per caricare il documento stesso, che avete già imparato.
Il successivo esempio crea una funzione chiamata displayData() che mostra informazioni in
formato tabella.
17 Java PpP.indd 333
28/04/11 16:00
334
Parte IV AJAX e l’integrazione lato-server
La proprietà readyState
Nelle versioni precedenti di questo libro utilizzavamo la proprietà readyState per
determinare quando il documento XML era caricato. La proprietà readyState è un
integer che contiene uno fra cinque valori indicanti lo stato corrente della richiesta di
documento da elaborare. La tabella 17.1 mostra i valori e le corrispondenti descrizioni
di readyState.
Tabella 17.1 La
proprietà readyState
Valore
Descrizione
0
Non inizializzato. Aperto ma non ancora chiamato.
1
Aperto. Inizializzato ma non ancora inviato.
2
Inviato. La richiesta è stata inviata.
3
In ricezione. La risposta è in fase di ricezione.
4
Caricato. La risposta è stata completamente ricevuta.
Ulteriori informazioni sulla proprietà readyState e l’evento onreadystatechange sono
riportate nel capitolo 18, “Applicazioni JavaScript”.
Per visualizzare i nodi e i nodi figlio in un documento XML, occorre eseguire un’iterazione sui livelli del documento e creare il documento di output. La successiva funzione che
vedremo lo fa iterando su un documento XML gerarchico al fine di visualizzare i dati del
documento in una tabella HTML. Questo codice continua l’esempio già mostrato, in cui una
variabile chiamata xmlDocument viene creata e caricata con un documento XML chiamato
books.xml:
function displayData(xmlDocument) {
var xmlEl = xmlDocument.getElementsByTagName("book");
var table = document.createElement("table");
table.border = "1";
var tbody = document.createElement("tbody");
// Append the body to the table
table.appendChild(tbody);
// Create the table cells for the new row
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData =
document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);
17 Java PpP.indd 334
28/04/11 16:00
Capitolo 17
JavaScript e XML
335
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
document.getElementById("xmldata").appendChild(table);
}
Per mettere insieme tutto il codice in una pagina web, associate a un evento le funzioni
che caricano e visualizzano il file XML. Il listato 17.1 (potete trovare questo codice anche in
listing17-1.html fra i file di esempio) crea una nuova funzione chiamata getXML e la associa
all’evento load dell’oggetto window. Il codice che associa l’evento è riportato in grassetto.
LiSTATO17.1 Visualizzare dati XML in una tabella HTML.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>Books</title>
<script type="text/javascript" src="ehandler.js"></script>
</head>
<body id="mainBody">
<div id="xmldata"></div>
<script type="text/javascript">
function displayData(xmlDocument) {
var xmlEl = xmlDocument.getElementsByTagName("book");
var table = document.createElement("table");
table.border = "1";
var tbody = document.createElement("tbody");
// Append the body to the table
table.appendChild(tbody);
// Create table row
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData =
document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
17 Java PpP.indd 335
28/04/11 16:00
336
Parte IV
AJAX e l’integrazione lato-server
}
document.getElementById("xmldata").appendChild(table);
}
function getXML() {
if (window.XMLHttpRequest) {
var httpObj = new XMLHttpRequest();
} else {
var httpObj = new ActiveXObject("Microsoft.XMLHTTP");
}
httpObj.open("GET","books.xml",false);
httpObj.send();
var xmlDocument = httpObj.responseXML;
displayData(xmlDocument);
}
var mainBody = document.getElementById("mainBody");
EHandler.add(mainBody, "load", function() { getXML(); });
</script>
</body>
</html>
Quando è visualizzata tramite un sito web, la tabella mostra i dati in modo molto simile a
un foglio di calcolo, come si vede nella figura 17.2.
FigUrA17.2 Rappresentare books.xml in una tabella HTML.
Esaminando il codice del listato 17.1 vediamo un grosso loop for che percorre la gerarchia
XML, creando le righe della tabella mentre procede. Un fatto da notare è che il loop cerca
solo i nodi Element all’interno del documento XML utilizzando il seguente codice:
17 Java PpP.indd 336
28/04/11 16:00
Capitolo 17 JavaScript e XML
337
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
Il nodeType 1 rappresenta un nodo XML Element. Se il tipo di nodo in fase di esame nel
loop non è element, il codice passa alla parte successiva del documento.
Nella visualizzazione della figura 17.2 potreste notare che non sono presenti le intestazioni
di colonna. Per mostrarle occorre aggiungere altro codice. La procedura che segue vi mostra come fare.
Aggiungere le intestazioni di colonna da un documento XML
1. Utilizzando Microsoft Visual Studio, Eclipse o un altro editor, modificate il file books.
htm nella cartella Chapter17 dei file di esempio (a questo punto della procedura, se lo
visualizzate in un browser web, books.htm dovrebbe essere simile alla figura 17.2).
2. In books.htm aggiungete il codice riportato in grassetto di seguito al metodo displayData() (potete trovare questo codice anche in books.txt fra i file di esempio),
sostituendo il commento TODO:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>Books</title>
<script type="text/javascript" src="ehandler.js"></script>
</head>
<body id="mainBody">
<div id="xmldata"></div>
<script type="text/javascript">
function displayData(xmlDocument) {
var xmlEl = xmlDocument.getElementsByTagName("book");
var table = document.createElement("table");
table.border = "1";
var tbody = document.createElement("tbody");
// Append the body to the table
table.appendChild(tbody);
var row = document.createElement("tr");
for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {
if (xmlEl[0].childNodes[colHead].nodeType != 1) {
continue;
}
var tableHead = document.createElement("th");
var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);
tableHead.appendChild(colName);
row.appendChild(tableHead);
}
// Append the row to the body
17 Java PpP.indd 337
28/04/11 16:00
338
Parte IV AJAX e l’integrazione lato-server
tbody.appendChild(row);
// Create table row
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData =
document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
document.getElementById("xmldata").appendChild(table);
}
function getXML() {
if (window.XMLHttpRequest) {
var httpObj = new XMLHttpRequest();
} else {
var httpObj = new ActiveXObject("Microsoft.XMLHTTP");
}
httpObj.open("GET","books.xml",false);
httpObj.send();
var xmlDocument = httpObj.responseXML;
displayData(xmlDocument);
}
var mainBody = document.getElementById("mainBody");
EHandler.add(mainBody, "load", function() { getXML(); });
</script>
</body>
</html>
3. Visualizzate la pagina in un browser web. Dovrebbe essere simile alla figura che
segue:
17 Java PpP.indd 338
28/04/11 16:00
Capitolo 17 JavaScript e XML
339
Lavorare con dati XML da Excel 2007
Excel 2007 possiede diverse funzionalità che facilitano il lavoro con i dati XML. Con Excel è
possibile sia importare sia esportare i dati XML. Quando si esportano dati da Excel, in effetti, il programma non aggiunge nulla di proprietario al documento XML. Ecco l’aspetto del
file books.xml esportato da Excel 2007 (potete trovare questo codice anche in newbooks.
xml fra i file di esempio):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<book>
<title>MySQL Bible</title>
<author>Steve Suehring</author>
<isbn>9780764549328</isbn>
<publisher>Wiley Publishing Inc.</publisher>
</book>
<book>
<title>JavaScript Step by Step</title>
<author>Steve Suehring</author>
<isbn>9780735624498</isbn>
<publisher>Microsoft Press</publisher>
</book>
</books>
Poiché Excel 2007 è XML-friendly, la funzione displayData() già vista in questo capitolo può
agire senza richiedere modifiche sui dati XML esportati da Excel 2007. Per gli sviluppatori
che hanno lavorato in passato con i formati proprietari, questa è una gradita sorpresa.
17 Java PpP.indd 339
28/04/11 16:00
340
Parte IV AJAX e l’integrazione lato-server
Un’anteprima del futuro
Essendo XML la X dell’acronimo AJAX, si può facilmente dedurre che AJAX è molto di più
che JavaScript e XML. AJAX può funzionare con tipi di dati diversi da XML, e nel capitolo 19
lavorerete con AJAX partendo dalle brevi premesse presentate in questo capitolo.
Nel capitolo 20 esaminerete l’integrazione di JavaScript, AJAX e Cascading Style Sheets
(CSS) che vi permette di presentare i dati recuperati con JavaScript.
Esercizi
1. Utilizzate il codice dell’esercizio sulla visualizzazione di questo capitolo per visualizzare la tabella dopo che è stato fatto clic su un collegamento anziché quando la pagina
viene caricata.
2. Utilizzate il codice dell’esercizio sulla visualizzazione di questo capitolo per visualizzare la tabella, ma impiegate il DOM per assegnare colori alterni alle righe, in modo che
una riga ogni due abbia lo sfondo grigio. Vi do un indizio: #aaabba è la rappresentazione esadecimale del colore grigio.
17 Java PpP.indd 340
28/04/11 16:00
Capitolo 18
Applicazioni JavaScript
Dopo aver letto questo capitolo, sarete in grado di:
n
Comprendere i componenti di un’applicazione basata su JavaScript.
Componenti delle applicazioni JavaScript
Creare un’applicazione basata sul browser con l’aspetto sofisticato di un’applicazione desktop
richiede spesso l’uso di JavaScript. Una tale applicazione possiede alcune caratteristiche e
capacità di risposta simili a quelle di un’applicazione desktop, sebbene questa risieda sul computer locale anziché funzionare tramite un browser web.
Questo breve capitolo presenta una panoramica dei componenti che formano un’applicazione basata su JavaScript. L’obiettivo è aiutarvi a comprendere l’architettura sottostante e
alcune delle complessità necessarie per creare questo tipo di applicazione.
I magnifici tre: visualizzazione, comportamento e dati
Un’applicazione web presenta tre componenti principali:
n
Visualizzazione L’aspetto e lo spirito della pagina.
n
Comportamento Ciò che l’interfaccia applicativa fa, ovvero ciò che accade quando
l’utente fa clic su un elemento sulla pagina o interagisce in altro modo con la pagina.
n
Dati Il componente server che contiene i dati ed esegue le azioni il cui risultato appare sulla pagina.
Il codice JavaScript gestisce tipicamente i primi due componenti del precedente elenco,
visualizzazione e comportamento, in modo da influenzare l’interfaccia o reagire quando un
utente esegue un’azione sulla pagina. JavaScript lavora anche con i dati restituiti dal server,
ma di solito lo fa soltanto per alterare in qualche modo la visualizzazione. Per esempio una
chiamata a un servizio web che restituisce la temperatura o le condizioni atmosferiche correnti potrebbe utilizzare JavaScript per cambiare un’icona quando è soleggiato. Le sezioni
che seguono esaminano ciascuno di questi tre elementi in maggiore dettaglio.
18 Java PpP.indd 341
341
28/04/11 16:00
342
Parte IV AJAX e l’integrazione lato-server
Visualizzazione: layout di pagina
La visualizzazione della pagina web comprende il layout di pagina e qualsiasi cosa correlata
all’aspetto e allo spirito della pagina e del sito, compresa la combinazione di colori, le immagini, la stilizzazione dei menu (se hanno angoli arrotondati o squadrati e così via), il posizionamento dei pulsanti e il contenuto, i colori dei font e l’utilizzo delle immagini. JavaScript
può influenzare tutti questi elementi, come avete visto nei capitoli precedenti su Cascading
Style Sheets (CSS) e la convalida dei form. Questi elementi rappresentano l’interesse principale del web design e ricevono la massima attenzione da parte degli utenti, perciò dovreste
considerarli nel determinare i requisiti del vostro sito.
Comportamenti: controllare cosa succede e quando
Uno dei fattori più importanti nel determinare l’esperienza dell’utente è anche uno degli
elementi più spesso trascurati nella progettazione di un’applicazione web: Il comportamento dell’interfaccia applicativa, che controlla cosa accade quando gli utenti interagiscono con
un dato elemento. Considerate questi due semplici scenari:
n
Quando un visitatore fa clic sul pulsante Submit di un web form, il pulsante rimane
attivo o viene disabilitato?
n
Quando un campo di input ottiene lo stato attivo, dovrebbe cambiare colore o essere
evidenziato?
Anche questi comportamenti minori possono migliorare notevolmente l’esperienza
dell’utente se sono progettati adeguatamente. Tuttavia quando si lavora alla progettazione
di un sito, questi comportamenti sono spesso dimenticati, ignorati o applicati in modo incoerente per lasciare più spazio all’aspetto e allo spirito o alla mera progettazione del sito.
Dati: consumo, visualizzazione e convalida
JavaScript, almeno nel suo utilizzo trattato in questo libro, non interagisce direttamente con
un database o un server. Naturalmente JavaScript lo fa attraverso Asynchronous JavaScript
e XML (AJAX) e attraverso i servizi web, ma questi processi richiedono che il codice latoserver restituisca i dati al JavaScript chiamante.
Come la porzione del sito relativa alla visualizzazione, i componenti di dati di back-end lato-server dovrebbero ricevere un’adeguata attenzione quando progettate un’applicazione
web. Dalla progettazione di database alla programmazione della logica di business, questo
codice back-end richiede attenzione.
JavaScript e le interfacce web
I programmatori utilizzano JavaScript per creare front-end che garantiscono un’esperienza
di qualità all’utente. Microsoft Bing Maps (in precedenza Live Search Maps) è un esempio di
applicazione web che fa pesante affidamento su JavaScript. La figura 18.1 mostra une esempio di Microsoft Bing Maps, che potete trovare all’indirizzo http://www.bing.com/maps/.
18 Java PpP.indd 342
28/04/11 16:00
Capitolo 18 Applicazioni JavaScript
343
Figura 18.1 L’interfaccia Bing Maps utilizza JavaScript per fornire una buona interattività.
Gli utenti possono trascinare la visualizzazione della mappa in modo molto simile a come
interagirebbero con un’applicazione desktop. La mappa è composta di porzioni a varie
risoluzioni. Quando un utente trascina la mappa, il browser invia molte richieste HTTP
al server web Virtual Earth richiedendo porzioni aggiuntive che il browser visualizza poi
velocemente.
Il motore di ricerca Bing utilizza anche una funzionalità di ricerca progressiva basata sulla
digitazione simile a quella di altri motori di ricerca come Google.
Se iniziate a digitare nella casella di testo principale su http://www.bing.com, il browser invia
immediatamente una richiesta HTTP al server per individuare ricerche simili, come si vede
nella figura 18.2.
Figura 18.2 La funzionalità di ricerca progressiva basata sulla digitazione utilizza JavaScript per ottenere
un elenco di ricerche corrispondenti dal server.
18 Java PpP.indd 343
28/04/11 16:00
344
Parte IV AJAX e l’integrazione lato-server
Tutti questi elementi del motore di ricerca Bing utilizzano JavaScript. Un numero infinito di
altre interfacce web fanno affidamento su JavaScript per migliorare l’esperienza dell’utente
controllando il livello comportamento della pagina. La parte rimanente di questo libro vi
introduce alla creazione di questo tipo di applicazioni con JavaScript. Il capitolo 19, “Un
tocco di AJAX”, e il capitolo 20, “Qualche approfondimento su AJAX”, vi insegnano come
creare una semplice interfaccia di ricerca progressiva basata sulla digitazione utilizzando
JavaScript. Introducono inoltre AJAX e mostrano esempi di come si lavora con i dati per
creare applicazioni. Il capitolo 21, “Introduzione alle librerie e ai framework JavaScript”, e
il capitolo 22, “Introduzione a jQuery”, presentano le librerie JavaScript, concentrandosi su
jQuery, che potete utilizzare per semplificare molte attività correlate alla scrittura di complesse applicazioni JavaScript.
18 Java PpP.indd 344
28/04/11 16:00
Capitolo 19
Un tocco di AJAX
Dopo aver letto questo capitolo, sarete in grado di:
n
Comprendere i fondamenti del paradigma di programmazione Asynchronous
JavaScript and XML (AJAX).
n
Comprendere la differenza fra chiamate AJAX sincrone e asincrone.
n
Utilizzare AJAX per recuperare dati.
n
Utilizzare AJAX con diversi metodi Hypertext Transfer Protocol (HTTP) per recuperare
risposte da un server.
Introduzione ad AJAX
AJAX descrive il paradigma di programmazione che combina JavaScript e un server web.
Gli sviluppatori utilizzano AJAX per creare applicazioni web altamente interattive come
Microsoft Virtual Earth.
Senza AJAX, un’applicazione web potrebbe far attendere il visitatore mentre una risposta
viene messa insieme dal server web. Un’applicazione basata su AJAX invia richieste dal
browser web al server web in background (in modo asincrono) mentre il visitatore utilizza
l’applicazione. Questo rende l’applicazione più reattiva dal punto di vista dell’utente.
In un’applicazione AJAX, JavaScript elabora la risposta e presenta i dati agli utenti. Quando
è combinata con Cascading Style Sheets (CSS) e un buon layout, un’applicazione AJAX garantisce un’eccellente usabilità e la portabilità che soltanto un’applicazione web può offrire.
Nonostante molte applicazioni AJAX possano sembrare complesse, gli effettivi processi di
invio di una richiesta e gestione della risposta non sono molto complicati. Questo capitolo
esplora come potete inviare richieste e ricevere risposte utilizzando un oggetto AJAX fondamentale: XMLHttpRequest.
Un concetto centrale di AJAX è che occorre chiamare applicazioni lato-server per restituire
dati. In questo capitolo presento una breve panoramica di come creare una tale applicazione utilizzando sia ASP.NET sia PHP (PHP è un acronimo ricorsivo che sta per PHP Hypertext
Preprocessor). Se avete bisogno di ulteriore assistenza per la creazione della porzione latoserver di un’applicazione AJAX, potete ottenerla da varie fonti.
Se state creando un’applicazione lato-server con tecnologie Microsoft, Microsoft Developer
Network è un’importante risorsa che offre numerosi tutorial e un articolo introduttivo su
AJAX (http://msdn.microsoft.com/it-it/magazine/cc163363.aspx). Microsoft Press pubblica inoltre molti eccellenti libri sulla creazione di applicazioni per il web. Uno di questi è
19 Java PpP.indd 345
345
28/04/11 16:02
346
Parte IV AJAX e l’integrazione lato-server
Microsoft ASP.NET 3.5 Step By Step (Microsoft Press, 2008). Per conoscere altri titoli, visitate
http://www.microsoft.com/mspress.
Se state sviluppando un’applicazione lato-server con altre tecnologie come lo stack LAMP
(Linux, Apache, MySQL, Perl/PHP/Python), cercare tutorial sul web è probabilmente il modo
più semplice per iniziare velocemente a sviluppare per questa piattaforma. Il libro Learning
Perl (O’Reilly, 2005) è una valida risorsa per imparare i fondamenti del linguaggio di programmazione Perl.
Nota Se vi piace il mio stile di scrittura, ho scritto anche il libro Beginning Perl Web
Development (Apress, 2005), che tratta l’utilizzo di Perl per lavorare con le applicazioni web.
Il sito web principale di PHP (http://www.php.net) è un ottimo punto di partenza per informazioni su PHP; per Python date un’occhiata al relativo sito web (http://www.python.org).
Le informazioni sono in inglese.
L’oggetto XMLHttpRequest
L’oggetto XMLHttpRequest ha un ruolo centrale per la creazione di un’applicazione AJAX.
Sebbene le implementazioni di JavaScript siano differenti, l’ECMAScript e il World Wide
Web Consortium (W3C) hanno standardizzato molti aspetti di esso, a parte l’oggetto
XMLHttpRequest, che non è mai stato sottoposto a un processo di standardizzazione.
Nonostante questo, dal rilascio di Windows Internet Explorer 7, l’oggetto XMLHttpRequest
si utilizza allo stesso modo su tutti i principali browser.
Microsoft ha implementato in origine l’oggetto XMLHttpRequest in Microsoft Internet
Explorer 5.0. Se un visitatore utilizza una precedente versione del browser, le applicazioni
che includono XMLHttpRequest non funzioneranno. Nelle versioni di Internet Explorer precedenti la 7, l’oggetto XMLHttpRequest era istanziato come un oggetto ActiveXObject, ma
altri browser hanno implementato l’oggetto XMLHttpRequest come un oggetto JavaScript
incorporato nel browser. Questo significa che se le vostre applicazioni devono lavorare con
versioni di Internet Explorer precedenti la 7, dovete istanziare l’oggetto XMLHttpRequest
per quei browser in un modo diverso, come vi mostrerò più avanti in questo capitolo. La
sezione successiva, “Istanziare l’oggetto XMLHttpRequest”, vi mostra come testare l’esistenza di XMLHttpRequest e come istanziarlo in tutte le versioni di Internet Explorer.
Istanziare l’oggetto XMLHttpRequest
Internet Explorer 7 e versioni successive, e tutti gli altri browser principali che supportano
XMLHttpRequest, istanziano l’oggetto XMLHttpRequest nello stesso modo:
var req = new XMLHttpRequest();
19 Java PpP.indd 346
28/04/11 16:02
Capitolo 19
Un tocco di AJAX
347
Per le versioni di Internet Explorer precedenti la 7, dovete istanziare invece un
ActiveXObject. Il modo in cui lo fate varia però a seconda della versione della libreria
XMLHTTP installata sul client. Perciò dovete fare un po’ di giochetti con il codice per istanziare un oggetto XMLHttpRequest in queste vecchie versioni di Internet Explorer.
Il codice del listato 19.1 è una funzione compatibile con più browser che istanzia un oggetto XMLHttpRequest su più browser.
LISTATO19.1 Istanziare un oggetto XMLHttpRequest su più browser.
function readyAJAX() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return "A newer browser is needed.";
}
}
}
}
La funzione nel listato 19.1 utilizza più livelli di blocchi try/catch per istanziare un
XMLHttpRequest, indipendentemente dal fatto che il visitatore utilizzi Internet Explorer o
un altro browser. Se la chiamata nativa di XMLHttpRequest fallisce, questo significa che il
visitatore sta utilizzando un browser Internet Explorer precedente la versione 7. In tal caso
l’errore è intercettato e viene tentato uno dei metodi di istanziazione di XMLHttpRequest
basati su ActiveXObject. Se nessuno di questi metodi ha successo, la ragione più probabile è
che il browser sia troppo vecchio per supportare XMLHttpRequest.
L’articolo “About Native XMLHTTP” su MSDN descrive vari aspetti relativi alla storia e alla
sicurezza dell’oggetto XMLHttpRequest in Internet Explorer. Questo articolo è disponibile
all’indirizzo http://msdn2.microsoft.com/en-us/library/ms537505.aspx (le informazioni sono
in inglese).
Per chiamare la funzione readyAJAX() mostrata nel listato 19.1 si procede così:
var requestObj = readyAJAX();
La variabile requestObj ora contiene l’oggetto XMLHttpRequest restituito dalla funzione
oppure, se la funzione non è riuscita a creare l’oggetto, la variabile requestObj contiene la
stringa “A newer browser is needed”.
19 Java PpP.indd 347
28/04/11 16:02
348
Parte IV AJAX e l’integrazione lato-server
Inviare una richiesta AJAX
Con un nuovo oggetto XMLHttpRequest fra le mani, potete inviare richieste al server web e
ottenere risposte. Per inviare la richiesta, utilizzate una combinazione dei metodi open() e
send() dell’oggetto XMLHttpRequest.
Ci sono due modi fondamentalmente diversi per inviare richieste AJAX: sincrono e asincrono. Quando è inviato in un modo asincrono, il codice di richiesta si limita ad attendere la
risposta, un processo chiamato blocco. Per una richiesta sincrona perciò il codice di richiesta
si bloccherà, impedendo così l’ulteriore elaborazione o esecuzione di altro JavaScript mentre lo script attende la risposta dal server web. Questo processo presenta ovvi svantaggi
quando la risposta va persa in transito o semplicemente è lenta. Con le richieste asincrone
il codice di richiesta non viene bloccato. Il chiamante può controllare lo stato della richiesta
per vedere quando la richiesta è completata. Ulteriori informazioni sulle richieste asincrone
sono riportate più avanti in questo capitolo; è più facile iniziare dalle richieste sincrone.
Per poter inviare una richiesta, dovete prima crearla. Per farlo, utilizzate il metodo open,
che presenta tre argomenti: il metodo di richiesta (GET, POST, HEAD o altri), lo Uniform
Resource Locator (URL) a cui la richiesta sarà inviata e un boolean true o false, indicante se
volete inviare la richiesta rispettivamente in modo asincrono o sincrono.
Presupponendo che il vostro oggetto richiesta sia stato recuperato utilizzando la funzione
readyAJAX() e inserito in una variabile denominata requestObj, una tipica chiamata asincrona del metodo open potrebbe essere questa:
var url = "http://www.braingia.org/getdata.php";
requestObj.open("GET", url, true);
La stessa chiamata, inviata in modo sincrono, è questa:
var url = "http://www.braingia.org/getdata.php";
requestObj.open("GET", url, false);
La richiesta viene inviata effettivamente con il metodo send, come segue:
requestObj.send();
Nota Se i parametri inviati con la richiesta includono caratteri speciali, come spazi o altri
caratteri riservati della URI RFC, dovete prima effettuarne l'escape tramite la notazione %.
L'argomento è trattato nei dettagli nella RFC 3986, che potete trovare all'indirizzo ftp://ftp.
rfc-editor.org/in-notes/rfc3986.txt (le informazioni sono in inglese). Ulteriori informazioni sono
disponibili anche all'indirizzo http://msdn2.microsoft.com/en-us/library/aa226544(sql.80).aspx
(le informazioni sono in inglese).
19 Java PpP.indd 348
28/04/11 16:02
Capitolo 19 Un tocco di AJAX
349
Come funziona il web in meno di 500 parole
L’Hypertext Transfer Protocol (HTTP) è il linguaggio del web. L’HTTP, attualmente definito dalla RFC 2616, descrive un protocollo per lo scambio di informazioni utilizzando
richieste provenienti dai client e risposte provenienti dai server.
Le richieste dei client come i browser web contengono un determinato set di intestazioni che definiscono il metodo utilizzato per il recupero, l’oggetto recuperato e la
versione del protocollo da utilizzare. Altre intestazioni contengono il nome host del
server web, le lingue richieste, il nome del browser e altre informazioni che il client
ritiene rilevanti per la richiesta.
Segue una semplice richiesta in HTTP versione 1.1 che mostra soltanto la più importante di queste intestazioni:
GET / HTTP/1.1
Host: www.braingia.org
Questa richiesta specifica il metodo GET per recuperare il documento che si trova
nella posizione di directory / (root) utilizzando HTTP versione 1.1. La seconda riga,
chiamata comunemente intestazione Host, è l’URL http://www.braingia.org. Questa
intestazione dice al server web quale sito web è richiesto. In una richiesta possono
essere utilizzati molti diversi metodi; i tre più comuni sono GET, POST e HEAD. Il client
e il server scambiano anche cookie HTTP come parte delle intestazioni. I cookie sono
inviati nella richiesta e altri potrebbero essere ricevuti nella risposta.
Quando il server web per http://www.braingia.org riceve una richiesta come questa,
invia intestazioni di risposta per indicare come ha gestito la richiesta. In questo caso il
server web invia intestazioni di risposta simili alle seguenti:
HTTP/1.1 200 OK
Date: Sat, 12 Mar 2011 01:04:34 GMT
Server: Apache/1.3.33 (Debian GNU/Linux) mod_perl/1.29 PHP/4.3.10-22
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1
Il documento richiesto segue le intestazioni di risposta. La prima e più importante
intestazione indica lo stato della risposta. Nell’esempio la risposta è 200, che significa
OK. Altre comuni risposte sono 404 (che indica che il documento richiesto non è stato
trovato), 302 (che indica una redirezione) e 500 (che indica che si è verificato un errore del server).
Conoscere queste nozioni di base di HTTP è importante per capire come costruire
richieste AJAX e come risolvere problemi relativi a queste richieste quando qualcosa
va male. Potete trovare ulteriori informazioni su HTTP, compresi vari codici di risposta,
nella RFC 2616 all’indirizzo ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt (le informazioni
sono in inglese).
19 Java PpP.indd 349
28/04/11 16:02
350
Parte IV AJAX e l’integrazione lato-server
Elaborare una risposta AJAX
È più facile lavorare con la risposta quando la richiesta è inviata in modo sincrono, perché
l’esecuzione dello script si arresta mentre attende la risposta. La variabile requestObj fornisce utili metodi per elaborare una risposta, fra cui consentire l’accesso ai codici di stato e al
testo dello stato inviato dal server. Indipendentemente dal fatto che la richiesta sia sincrona
o asincrona, dovreste valutare il codice di stato per assicurarvi che la risposta abbia avuto
successo (situazione indicata solitamente dal codice di stato 200).
Il metodo responseText contiene il testo della risposta ricevuta dal server web.
Immaginate per esempio che un’applicazione server restituisca la somma di due numeri. La
chiamata dell’applicazione per sommare i numeri 2 e 56 è questa:
http://www.braingia.org/addtwo.php?num1=2&num2=56
Ecco una chiamata asincrona e il recupero della risposta:
requestObj.open("GET", "http://www.braingia.org/addtwo.php?num1=2&num2=56", false);
requestObj.send();
if (requestObj.status == 200) {
alert(requestObj.responseText);
} else {
alert(requestObj.statusText);
}
In questo esempio presupponete che il requestObj sia creato utilizzando la funzione readyAJAX() che avete visto in precedenza. Il codice precedente chiama quindi il metodo
open utilizzando una richiesta GET all’URL specificato (http://www.braingia.org/addtwo.
php?num1=2&num2=56). La richiesta viene inviata in modo sincrono perché l’ultimo argomento del metodo open è false. Quindi il codice chiama il metodo send, che effettivamente
invia la richiesta al server web.
Quando il client riceve la risposta dal server web, chiama il metodo status per controllare il
valore di stato. Se il codice di risposta è 200, che indica successo, viene mostrato il responseText, che contiene la risposta proveniente dal server. Se il codice di stato della risposta è
diverso da 200, viene visualizzato il testo di stato.
Elaborare una risposta asincrona è un po’ più complicato. Quando una richiesta è inviata in
modo asincrono, l’esecuzione dello script continua. Perciò non è possibile prevedere quando sarà notificato allo script che la risposta è stata ricevuta. Per conoscere lo stato della
risposta, potete utilizzare l’evento onreadystatechange per attivare il codice che controlla la
proprietà readyState dell’evento al fine di determinare lo stato del ciclo richiesta/risposta.
Ricorderete dal capitolo 17, “JavaScript e XML”, che la proprietà readyState ha cinque stati,
descritti nella tabella 19.1.
19 Java PpP.indd 350
28/04/11 16:02
Capitolo 19 Un tocco di AJAX
Tabella 19.1 Valori
351
della proprietà readyState
Valore
Descrizione
0
Non inizializzato. Aperto ma non ancora chiamato.
1
Aperto. Inizializzato ma non ancora inviato.
2
Inviato. La richiesta è stata inviata.
3
In ricezione. La risposta è in fase di ricezione.
4
Caricato. La risposta è stata completamente ricevuta.
Per scopi pratici, l’unico stato che conta per i programmatori JavaScript e AJAX è lo stato
4—Loaded (caricato). Tentando di elaborare una risposta che presenta un valore readyState
diverso da 4 viene generato un errore.
Tipicamente si utilizza una funzione anonima per gestire l’evento onreadystatechange per
le chiamate AJAX asincrone. La funzione controlla per vedere se la proprietà readyState ha
raggiunto il valore 4, quindi controlla per assicurarsi che lo stato sia 200, che indica successo. Il codice presenta questo formato:
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
alert(requestObj.responseText);
} else {
alert(requestObj.statusText);
}
}
}
Nel successivo esercizio creerete un oggetto XMLHttpRequest e invierete una richiesta a un
server web per recuperare il titolo di un libro in base al suo ISBN. Avete bisogno di un server web e del codice per il server web per stampare la risposta, in quanto le richieste inviate
utilizzando XMLHttpRequest sono soggette al criterio JavaScript della stessa origine.
Il criterio della stessa origine prevede che le richieste vadano soltanto verso i server dello
stesso dominio da cui lo script chiamante è stato caricato. In altre parole, poiché sto eseguendo lo script in questo esempio direttamente dal mio server web all’indirizzo http://
www.braingia.org, il mio script è in grado di chiamare quel server e recuperare una risposta.
Se invece avete tentato di chiamare un URL su un altro server web, il criterio della stessa
origine impedisce che lo script recuperi la risposta.
Nota Un modo per aggirare la funzionalità di sicurezza della stessa origine è utilizzare un
proxy HTTP o scrivere il programma lato-server in modo che invii una richiesta per conto del
programma chiamante; questo argomento esula però dallo scopo di questo libro.
Per il successivo esercizio lo script o programma eseguito sul server deve restituire la frase
“JavaScript Step by Step” quando riceve una richiesta GET con un argomento nome/valore
con il seguente valore:
19 Java PpP.indd 351
28/04/11 16:02
352
Parte IV AJAX e l’integrazione lato-server
isbn=9780735624498
Nella sua versione più semplice per esempio il programma lato-server potrebbe essere il
seguente quando è implementato all’interno di una pagina Active Server Pages (ASP) basata su VBScript:
<%
dim isbn
isbn=Request.QueryString("isbn")
If isbn<>"" Then
If isbn=="9780735624498" Then
Response.Write("JavaScript Step by Step")
End If
End If
%>
Un programma funzionalmente simile scritto in PHP sarebbe il seguente:
<?php
$isbn = $_GET['isbn'];
if (! $isbn) {
print "That request was not understood.";
} else if ($isbn == "9780735624498") {
print "JavaScript Step by Step";
}
?>
Nel seguente esercizio l’URL a cui la richiesta è inviata è predefinito, tuttavia dovete sostituire quell’URL con l’URL in cui si trova il vostro programma lato-server. A causa del criterio
della stessa origine, il programma lato-server deve trovarsi all’interno dello stesso dominio
della pagina che lo chiama.
Inviare e ricevere con XMLHttpRequest
1. Create il vostro programma lato-server in modo che restituisca il titolo del libro quando riceve l’argomento isbn mostrato in precedenza. Potete farlo nel linguaggio che
preferite (se ne avete bisogno, osservate i due esempi mostrati in precedenza).
2. Utilizzando Microsoft Visual Studio, Eclipse o un altro editor, modificate il file isbn.htm
nella cartella Chapter19 dei file di esempio.
3. Nella pagina web sostituite il commento TODO con il codice in grassetto riportato di
seguito (potete trovare il codice anche in isbn.txt fra i file di esempio): assicuratevi di
sostituire la variabile url con l’URL appropriato per il vostro programma lato-server:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>ISBN</title>
</head>
19 Java PpP.indd 352
28/04/11 16:02
Capitolo 19 Un tocco di AJAX
353
<body>
<div id="data"></div>
<script type="text/javascript">
function readyAJAX() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return "A newer browser is needed.";
}
}
}
}
var requestObj = readyAJAX();
var url = "http://www.braingia.org/isbn.php?isbn=9780735624498";
requestObj.open("GET",url,true);
requestObj.send();
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
alert(requestObj.responseText);
} else {
alert(requestObj.statusText);
}
}
}
</script>
</body>
</html>
4. Salvate e visualizzate in un browser web. Dovreste ricevere un avviso come il
seguente:
Congratulazioni! Avete elaborato il vostro primo XMLHttpRequest.
19 Java PpP.indd 353
28/04/11 16:02
354
Parte IV AJAX e l’integrazione lato-server
Elaborare risposte XML
Gli esempi di AJAX visti finora utilizzano tutti risposte in normale Hypertext Markup
Language (HTML) e testo provenienti dal server web, perciò potreste recuperarle utilizzando il metodo responseText dell’oggetto XMLHttpRequest. Le applicazioni server invece possono anche restituire risposte XML, che potete elaborare nativamente utilizzando il metodo
responseXML.
In precedenza in questo capitolo, nel riquadro “Come funziona il Web in meno di 500 parole”, abbiamo visto un esempio di risposta del server web. La risposta del server conteneva
questa intestazione Content-Type:
Content-Type: text/html; charset=iso-8859-1
Per recuperare una risposta utilizzando il metodo responseXML, il server web deve inviare
un Content-Type text/xml o application/xml come segue:
Content-Type: application/xml
Quando l’oggetto XMLHttpRequest riceve XML nativo come risposta, potete utilizzare i metodi del Document Object Model (DOM) per elaborare la risposta.
Il metodo responseXML storicamente ha creato problemi e utilizzarlo può generare comportamenti inaspettati, a seconda del browser e del sistema operativo. Inoltre responseXML
non è ampiamente supportato quanto altri metodi JavaScript. Utilizzare responseXML significa combinare le tecniche XMLHttpRequest già viste in questo capitolo con le tecniche
di analisi XML descritte nel capitolo 17. Considerate per esempio questo documento XML
(chiamatelo book.xml):
<?xml version="1.0" encoding="ISO-8859-1"?>
<book>
<title>JavaScript Step by Step</title>
<isbn>9780735624498</isbn>
</book>
La combinazione dell’oggetto XMLHttpRequest e dell’analisi XML porta al seguente codice,
che recupera e visualizza l’ISBN del documento book.xml:
var requestObj = readyAJAX();
var url = "http://www.braingia.org/book.xml";
requestObj.open("GET",url,false);
requestObj.send();
if (requestObj.status == 200) {
var xmldocument = requestObj.responseXML;
alert(xmldocument.getElementsByTagName("isbn")[0].childNodes[0].nodeValue);
} else {
alert(requestObj.statusText);
}
19 Java PpP.indd 354
28/04/11 16:02
Capitolo 19 Un tocco di AJAX
355
Quando la richiesta viene completata con successo, requestObj.responseXML contiene il
documento XML richiesto (book.xml). Il codice xmldocument.getElementsByTagName(“isbn”)
recupera un array di tag <isbn> nel documento. In questo documento ce n’è uno solo; lo [0]
indica il primo. La porzione .childNodes[0] del codice recupera il primo nodo figlio da quel
tag <isbn>. In questo caso quello è il nodo di testo, che contiene il numero ISBN. Infine la
porzione .nodeValue del codice recupera il valore di quel nodo di testo, l’ISBN, che il precedente codice visualizza in una chiamata ad alert.
Lavorare con JSON
JavaScript Object Notation (JSON) è un modo per passare i dati nella forma di oggetti e
array JavaScript nativi, anziché codificare i dati all’interno di risposte XML (o HTML). JSON
rappresenta un modo più efficiente di passare dati dal server al client. L’analisi dell’XML tramite il DOM è più complessa e perciò più lenta, mentre l’analisi dei dati con codifica JSON
si esegue direttamente in JavaScript.
Richiamate alla mente il documento book.xml di un precedente esempio di questo capitolo.
Gli stessi dati in JSON si presentano come segue:
{
"book":
{
"title": "JavaScript Step by Step",
"isbn": "9780735624498"
}
}
Recuperare un singolo elemento è un po’ più facile con JSON che non con XML. Per analizzare la risposta con formattazione JSON utilizzerete la funzione JavaScript eval(). Ecco per
esempio il codice per recuperare e visualizzare il titolo del libro:
var requestObj = readyAJAX();
var url = "http://www.braingia.org/json.php";
requestObj.open("GET",url,false);
requestObj.send();
if (requestObj.status == 200) {
var xmldocument = eval('(' + requestObj.responseText + ')');
alert(xmldocument.book.title);
} else {
alert(requestObj.statusText);
}
L’utilizzo di JSON è rischioso dal punto di vista della sicurezza, in quanto impiega la funzione eval() per analizzare la risposta. La funzione eval() esegue essenzialmente il codice
JavaScript ricevuto, perciò se il codice è malevolo, sarebbe comunque eseguito nel contesto
dell’applicazione. È vostra responsabilità assicurare che i dati che la vostra applicazione sta
utilizzando con JSON siano puliti e liberi da codice malevolo che potrebbe causare problemi quando viene eseguito utilizzando eval().
19 Java PpP.indd 355
28/04/11 16:02
356
Parte IV
AJAX e l’integrazione lato-server
L’impiego di un framework JavaScript come jQuery vi allevia in gran parte questo problema,
come anche l’aggiunta del JSON nativo in ECMA-262 versione 5. Imparerete come utilizzare
jQuery per elaborare JSON nel capitolo 22, “Introduzione a jQuery”.
Elaborare le intestazioni
Il metodo HTTP HEAD restituisce soltanto le intestazioni di risposta dal server, anziché le
intestazioni e il body come il metodo GET. Il metodo HEAD è utile a volte per determinare
se una data risorsa è stata aggiornata o modificata.
Un’intestazione HTTP inviata di frequente è Expires, che indica quando il client dovrebbe
richiedere una copia aggiornata di un documento anziché leggerlo dalla cache del client. Se
il server invia l’intestazione Expires, il metodo HEAD è un modo efficiente per visualizzare e
analizzare l’intestazione Expires perché il metodo HEAD recupera l’intestazione di risposta
anziché l’intero body della risorsa richiesta.
Per richiedere solo le intestazioni di risposta da un server, impiegando una richiesta HEAD
o qualsiasi altro tipo di richiesta come GET o POST, utilizzate il metodo getAllResponseHeaders() dell’oggetto XMLHttpRequest, come segue:
requestObj.getAllResponseHeaders();
Il listato 19.2 mostra per esempio come recuperare le intestazioni di risposta dalla pagina
default del mio sito web.
LISTATO19.2 Recuperare le intestazioni.
T<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Response Headers</title>
</head>
<body>
<div id="data"></div>
<script type="text/javascript">
function readyAJAX() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return "A newer browser is needed.";
}
19 Java PpP.indd 356
28/04/11 16:02
Capitolo 19
Un tocco di AJAX
357
}
}
}
var requestObj = readyAJAX();
var url = "http://www.braingia.org/";
requestObj.open("HEAD",url,true);
requestObj.send();
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
alert(requestObj.getAllResponseHeaders());
} else {
alert(requestObj.statusText);
}
}
}
</script>
</body>
</html>
Soluzionedeiproblemi Il criterio della stessa origine che avete incontrato durante l’esercizio precedente si applica allo stesso modo al metodo HEAD del listato 19.2. Quando ho scritto
il listato 19.2 non mi sono ricordato del criterio della stessa origine e ho impostato la variabile
url su http://www.microsoft.com/, pensando che avrei ottenuto la pagina default del sito. Ma
dopo aver ricevuto un errore, mi sono accorto del problema e ho cambiato la variabile url in
modo che corrispondesse al dominio su cui lo script era eseguito (il mio sito). Anche voi avete
buone probabilità di incontrare lo stesso problema. Ricordate di cambiare la variabile url nel
vostro server di origine quando tentate di eseguire il codice del listato 19.2.
Utilizzare il metodo POST
Gli esempi visti finora utilizzavano i metodi GET e HEAD per recuperare dati dal server. Per
inviare query tramite HTTP, si utilizza spesso il metodo POST. Utilizzare il metodo POST con
XMLHttpRequest è un po’ più complesso che non utilizzare i metodi GET o HEAD. Il metodo
POST offre tuttavia due vantaggi specifici rispetto al metodo GET. Prima di tutto i parametri
che inviate con una richiesta POST sono contenuti nel body della richiesta anziché nell’URL,
come con il metodo GET, e perciò è meno probabile che li veda l’osservatore occasionale
che tenta di trovare modi per entrare nella vostra applicazione. In secondo luogo il metodo
POST supporta richieste di maggiori dimensioni. Alcuni server limitano la quantità o la dimensione di una richiesta GET a un determinato numero di caratteri, e sebbene questi server potrebbero anche limitare la dimensione di una richiesta POST, il limite per le richieste
POST è quasi sempre molto maggiore.
Il metodo HTTP POST richiede di impostare un’intestazione aggiuntiva nella richiesta.
Questa intestazione aggiuntiva si imposta con il metodo setRequestHeader():
19 Java PpP.indd 357
28/04/11 16:02
358
Parte IV
AJAX e l’integrazione lato-server
requestObj.setRequestHeader(header, value);
Per impostare per esempio l’intestazione Content-Type per un web form, come fareste per
una richiesta POST, potreste scrivere:
requestObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
Quando avete visto le richieste AJAX inviate in precedenza utilizzando il metodo GET, l’URL
includeva i parametri o le coppie nome/valore per l’applicazione, come segue:
http://www.braingia.org/books/javascriptsbs/isbn.php?isbn=9780735624498
Nel precedente esempio il parametro isbn ha il valore 9780735624498. Quando invece si
lavora con le richieste POST, l’URL contiene solo il documento o risorsa richiesta: non contiene alcun parametro. Perciò dovete inviare i parametri come parte del metodo send().
Il listato 19.3 presenta una richiesta AJAX che utilizza il metodo POST, riportata in grassetto.
Utilizza due parametri: provate a vedere se riuscite a individuarli.
LISTATO19.3 Costruire una richiesta POST.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Post</title>
</head>
<body>
<div id="xmldata"></div>
<script type="text/javascript">
function readyAJAX() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return "A newer browser is needed.";
}
}
}
}
19 Java PpP.indd 358
28/04/11 16:02
Capitolo 19
Un tocco di AJAX
359
var requestObj = readyAJAX();
var url = "http://www.braingia.org/books/javascriptsbs/post.php";
var params = "num1=2&num2=2";
requestObj.open("POST",url,true);
requestObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
requestObj.send(params);
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
alert(requestObj.responseText);
} else {
alert(requestObj.statusText);
}
}
}
</script>
</body>
</html>
Il listato 19.3 crea due parametri inseriti in una variabile chiamata params:
var params = "num1=2&num2=2";
Dopo la costruzione dell’oggetto richiesta (requestObj), i parametri sono passati come argomento al metodo send():
requestObj.send(params);
Casodistudio:ricercaeaggiornamentolive
Esistono molti esempi di ricerca progressiva basata sulla digitazione (o predittiva) che usano
JavaScript, come quello mostrato nel capitolo 18, “Applicazioni JavaScript”. Un esempio è
un form che cerca indirizzi email che sono stati messi in whitelist o in blacklist da un filtro
spam.
La ricerca per whitelist/blacklist utilizza AJAX per importare un file XML e fornisce risultati basati sull’input dell’amministratore. Potete facilmente adattare questa applicazione in
modo che fornisca risultati di ricerca live o segnalibri live. Il capitolo 20, “Qualche approfondimento su AJAX”, utilizza una porzione di quell’applicazione del capitolo 18 per creare un
form di ricerca live, mentre la sezione successiva introduce un adattamento dell’applicazione per creare un feed segnalibri ricercabile live utilizzando XML.
Mi capita spesso di dover accedere a segnalibri su browser web da più computer. Tenendo
presente questo, ecco un’applicazione AJAX che fornisce una pagina di segnalibri. La pagina gestisce i segnalibri utilizzando un file XML che risiede in una posizione centrale. Il
codice recupera il file e crea una pagina web che estrae i segnalibri e fornisce un’interfaccia
di ricerca.
19 Java PpP.indd 359
28/04/11 16:02
360
Parte IV AJAX e l’integrazione lato-server
L’applicazione dei segnalibri è mostrata nella figura 19.1. Anche se visualizza soltanto 3 segnalibri, può funzionare altrettanto bene anche con 300; ne utilizziamo pochi per rendere
più semplice la spiegazione.
Figura 19.1 Una visualizzazione dell’applicazione per segnalibri live.
La casella di ricerca funziona restringendo l’elenco dei segnalibri visualizzati mentre l’utente
digita nella casella di testo. Digitando per esempio la lettera m nella casella di testo, la pagina cambia immediatamente e mostra solo i segnalibri che iniziano con la lettera m, come
si vede nella figura 19.2.
Figura 19.2 Digitando la lettera m sono visualizzarti soltanto i segnalibri che iniziano per m.
Continuando a digitare, per esempio aggiungendo una i, in modo da avere mi, i segnalibri
disponibili si riducono sempre di più, come nella figura 19.3.
19 Java PpP.indd 360
28/04/11 16:02
Capitolo 19 Un tocco di AJAX
361
Figura 19.3 Aggiungere altri caratteri per restringere ulteriormente i risultati.
Quando l’utente elimina il testo nella casella di testo, la pagina Bookmarks torna al suo
aspetto predefinito (mostrato nella figura 19.1).
Ecco l’XML per questa applicazione (potete trovare questo codice anche in bookmark.xml
fra i file di esempio):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<bookmarks xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<bookmark>
<title>Steve Suehring's Home Page</title>
<url>http://www.braingia.org/</url>
</bookmark>
<bookmark>
<title>MSDN</title>
<url>http://msdn.microsoft.com/</url>
</bookmark>
<bookmark>
<title>Microsoft Press</title>
<url>http://www.microsoft.com/mspress</url>
</bookmark>
</bookmarks>
L’applicazione, insieme alla pagina web, è mostrata di seguito ed è disponibile anche in bookmark.htm fra i file di esempio:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Search</title>
</head>
<body>
<form name="nameform" id="nameform" action="" method="post">
Bookmark Search: <input id="textname" type="text" name="textname">
</form>
<div id="data"></div>
<script type="text/javascript" src="ehandler.js"></script>
<script type="text/javascript">
19 Java PpP.indd 361
28/04/11 16:02
362
Parte IV AJAX e l’integrazione lato-server
function textSearch() {
var textName = document.getElementById("textname");
var dataNode = document.getElementById("data");
while (dataNode.hasChildNodes()) {
dataNode.removeChild(dataNode.firstChild);
}
listName(textName.value);
}
function readyAJAX() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
return "A newer browser is needed.";
}
}
}
}
function listName(text) {
var xmlEl = AJAXresponse.getElementsByTagName("bookmark");
elLength = xmlEl.length;
for (i = 0; i < elLength; i++) {
var div = document.createElement("div");
// Create the row elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
var url = new RegExp("http");
if (! xmlEl[i].childNodes[j].firstChild.nodeValue.match(url)) {
var pattern = "^" + text;
var title = xmlEl[i].childNodes[j].firstChild.nodeValue;
var nameRegexp = new RegExp(pattern, "i");
var existDiv = document.getElementById(title);
if (! existDiv) {
if (title.match(nameRegexp)) {
var anchor = document.createElement("a");
var xmlData =
document.createTextNode(xmlEl[i].childNodes[j].firstChild.
nodeValue);
var urls = AJAXresponse.getElementsByTagName("url");
anchor.setAttribute("href", urls[i].firstChild.nodeValue);
anchor.appendChild(xmlData);
div.appendChild(anchor);
}
}
}
}
19 Java PpP.indd 362
28/04/11 16:02
Capitolo 19 Un tocco di AJAX
363
document.getElementById("data").appendChild(div);
}
}
var requestObj = readyAJAX();
var url = "http://www.braingia.org/books/javascriptsbs/bookmark.xml";
requestObj.open("GET",url,true);
requestObj.send();
var AJAXresponse;
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
AJAXresponse = requestObj.responseXML;
listName("");
} else {
alert(requestObj.statusText);
}
}
}
var textEl = document.getElementById("textname");
EHandler.add(textEl,"keyup", function() { textSearch(); } );
</script>
</body>
</html>
La porzione JavaScript del codice è suddivisa in diverse funzioni, di cui parlerò fra breve.
Prima di tutto il codice chiama in causa lo script di gestione eventi ehandler.js, che avete
incontrato nel capitolo 11, “Gli eventi di JavaScript e il browser”:
<script type="text/javascript" src="ehandler.js"></script>
L’HTML per la pagina consiste di poche righe. Ecco il web form:
<form name="nameform" id="nameform" action="" method="post">
Bookmark Search: <input id="textname" type="text" name="textname">
</form>
Ed ecco il div che conterrà i segnalibri:
<div id="data"></div>
La porzione JavaScript del codice dichiara varie funzioni ed esegue il codice seguente all’interno del blocco principale. Questo codice è in gran parte già stato visto in questo capitolo:
utilizza la funzione readyAJAX() e invia una richiesta AJAX per un file XML di segnalibri al
server. Quando viene ricevuta la risposta, il codice chiama la funzione listName().
Oltre al codice AJAX, un gestore di evento è associato alla casella di testo del web form.
L’evento da gestire è keyup, che rileva quando un tasto viene premuto e rilasciato nella casella di testo. Il codice diventa così:
var requestObj = readyAJAX();
19 Java PpP.indd 363
28/04/11 16:02
364
Parte IV AJAX e l’integrazione lato-server
var url = "http://www.braingia.org/books/javascriptsbs/bookmark.xml";
requestObj.open("GET",url,true);
requestObj.send();
var AJAXresponse;
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
AJAXresponse = requestObj.responseXML;
listName("");
} else {
alert(requestObj.statusText);
}
}
}
var textEl = document.getElementById("textname");
EHandler.add(textEl,"keyup", function() { textSearch(); } );
Il gestore di evento che gestisce la pressione dei tasti nel form di ricerca risiede in due funzioni: text​Search e listName. La funzione textSearch è responsabile di rimuovere i segnalibri
dall’elenco. Chiama la funzione listName().
function textSearch() {
var textName = document.getElementById("textname");
var dataNode = document.getElementById("data");
while (dataNode.hasChildNodes()) {
dataNode.removeChild(dataNode.firstChild);
}
listName(textName.value);
}
Infine la funzione listName() contiene il codice per visualizzare solo i segnalibri che corrispondono almeno parzialmente al testo che è stato digitato nella casella di testo. Se nella
casella di testo non c’è nessun testo, mostra tutti i segnalibri:
function listName(text) {
var xmlEl = AJAXresponse.getElementsByTagName("bookmark");
elLength = xmlEl.length;
for (i = 0; i < elLength; i++) {
var div = document.createElement("div");
// Create the row elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
var url = new RegExp("http");
if (! xmlEl[i].childNodes[j].firstChild.nodeValue.match(url)) {
var pattern = "^" + text;
var title = xmlEl[i].childNodes[j].firstChild.nodeValue;
var nameRegexp = new RegExp(pattern, "i");
var existDiv = document.getElementById(title);
if (! existDiv) {
if (title.match(nameRegexp)) {
19 Java PpP.indd 364
28/04/11 16:02
Capitolo 19 Un tocco di AJAX
365
var anchor = document.createElement("a");
var xmlData =
document.createTextNode(xmlEl[i].childNodes[j].firstChild.
nodeValue);
var urls = AJAXresponse.getElementsByTagName("url");
anchor.setAttribute("href", urls[i].firstChild.nodeValue);
anchor.appendChild(xmlData);
div.appendChild(anchor);
}
}
}
}
document.getElementById("data").appendChild(div);
}
}
Esercizi
1. Quale dei metodi di richiesta HTTP trattati in questo capitolo in è il più sicuro?
Perché?
2. Descrivete le differenze fra una richiesta/risposta XMLHttpRequest con HTML, XML e
JSON.
3. Costruite un programma lato-server per restituire la somma di due numeri che il
programma riceve come parametri. Chiamate il programma utilizzando un oggetto
XMLHttpRequest asincrono.
19 Java PpP.indd 365
28/04/11 16:02
19 Java PpP.indd 366
28/04/11 16:02
Capitolo 20
Qualche approfondimento su AJAX
Dopo aver letto questo capitolo, sarete in grado di:
n
Comprendere come Asynchronous JavaScript and XML (AJAX) e Cascading Style
Sheets (CSS) possono essere utilizzati insieme.
n
Comprendere meglio la relazione fra il Document Object Model (DOM), AJAX e CSS.
n
Utilizzare AJAX e CSS per creare e stilizzare una tabella Hypertext Markup Language
(HTML) con dati Extensible Markup Language (XML).
n
Creare una casella di testo a discesa basata su AJAX utilizzando CSS.
Nel capitolo precedente abbiamo visto come utilizzare l’oggetto XMLHttpRequest per inviare, ricevere ed elaborare richieste, e infine come creare un’applicazione AJAX. In questo
capitolo vedremo come utilizzare CSS per visualizzare i dati recuperati con AJAX.
La relazione fra JavaScript e CSS è stata trattata nel capitolo 15, “JavaScript e CSS”. Avete
imparato che potete cambiare gli stili del documento da programma utilizzando JavaScript.
Nel capitolo 17, “JavaScript e XML”, avete appreso come visualizzare dati XML nella forma di
tabella HTML. Nel capitolo 19, “Un tocco di AJAX”, avete visto come creare una pagina web
di segnalibri ricercabile live utilizzando CSS e il DOM. Questo capitolo mostra come utilizzare CSS per stilizzare la tabella del capitolo 17 ed espandere e rivedere l’applicazione dei
segnalibri del capitolo 19, ancora con l’aiuto di CSS e JavaScript.
Spero di riuscire a trasmettervi che AJAX è davvero facile da usare. Recuperare e analizzare
informazioni von XMLHttpRequest è la parte più semplice, ciò che importa è quello che fate
con quei dati. E qui entrano in gioco CSS e il DOM! AJAX è dove mettete insieme tutto il
JavaScript che avete imparato in questo libro per creare applicazioni più grandi.
Creare una tabella HTML con XML e CSS
Il capitolo 17 ha presentato un esempio che recupera XML e utilizza i suoi dati come parte
di una tabella HTML, come mostrato nella figura 20.1. Il codice per creare questa tabella è
stato sviluppato nel capitolo 17 e ampliato per mostrare non solo i dati ma anche le intestazioni di colonna. Il risultato del codice alla fine del capitolo 17 era il seguente:
20 Java PpP.indd 367
367
28/04/11 16:03
368
Parte IV AJAX e l’integrazione lato-server
Figura 20.1 Visualizzare dati XML in una tabella HTML.
Il codice del capitolo 17 utilizza metodi XML per ottenere i dati direttamente. Il successivo
esercizio converte il codice in modo che recuperi l’XML utilizzando XMLHttpRequest. Come
l’esercizio del capitolo 19, il seguente esercizio richiede che il file XML sia memorizzato su
un server web.
Utilizzare XMLHttpRequest per recuperare e visualizzare dati XML
1. Utilizzate il file books.xml che avete creato nel capitolo 17 oppure, se non l’avete creato o salvato, create un file denominato books.xml con i seguenti dati (potete trovare
questo codice anche in books.xml fra i file di esempio). Copiate il file sullo stesso server web del file HTML che creerete al passo successivo.
<books>
<book>
<title>JavaScript Step by Step</title>
<author>Steve Suehring</author>
<isbn>9780735624498</isbn>
<publisher>Microsoft Press</publisher>
</book>
<book>
<title>MySQL Bible</title>
<author>Steve Suehring</author>
<isbn>9780764549328</isbn>
<publisher>Wiley Publishing Inc.</publisher>
</book>
</books>
2. Utilizzando Microsoft Visual Studio, Eclipse o un altro editor, modificate il file ajaxbooks.htm nella cartella Chapter20 dei file di esempio.
3. In ajaxbooks.htm aggiungete il seguente codice riportato in grassetto (potete trovare
questo codice anche in ajaxbooks.txt fra i file di esempio), sostituendo i commenti
TODO. Assicuratevi di sostituire lo Uniform Resource Locator (URL) segnaposto YOUR
SERVER HERE con il corretto URL del server web. Notate che state cambiando soltanto
la definizione della funzione e la prima riga della funzione displayData() rispetto alla
versione originale del capitolo 18.
20 Java PpP.indd 368
28/04/11 16:03
Capitolo 20 Qualche approfondimento su AJAX
369
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.
dtd">
<html>
<head>
<title>Booksx</title>
</head>
<body>
<div id="xmldata"></div>
<script type="text/javascript">
function readyAJAX() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try {
return new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
return "A newer browser is needed.";
}
}
}
}
var requestObj = readyAJAX();
var url = "http://YOUR SERVER HERE/books.xml";
requestObj.open("GET",url,true);
requestObj.send();
var AJAXresponse;
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
AJAXresponse = requestObj.responseXML;
displayData(AJAXresponse);
} else {
alert(requestObj.statusText);
}
}
}
function displayData(response) {
var xmlEl = response.getElementsByTagName("book");
var table = document.createElement("table");
table.border = "1";
var tbody = document.createElement("tbody");
// Append the body to the table
table.appendChild(tbody);
var row = document.createElement("tr");
// Append the row to the body
tbody.appendChild(row);
for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {
20 Java PpP.indd 369
28/04/11 16:03
370
Parte IV AJAX e l’integrazione lato-server
if (xmlEl[0].childNodes[colHead].nodeType != 1) {
continue;
}
var tableHead = document.createElement("th");
var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);
tableHead.appendChild(colName);
row.appendChild(tableHead);
}
tbody.appendChild(row);
// Create table row
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData =
document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
document.getElementById("xmldata").appendChild(table);
}
</script>
</body>
</html>
4. Visualizzate la pagina in un browser web. Dovreste vedere una pagina come questa:
20 Java PpP.indd 370
28/04/11 16:03
Capitolo 20 Qualche approfondimento su AJAX
371
Questo esempio combina il codice degli ultimi due capitoli per mostrare come recuperare e visualizzare dati XML con l’oggetto xmlHttpRequest associato con applicazioni AJAX.
Sebbene l’applicazione XML originale presentata nel capitolo 18 sia stata convertita per
l’uso di xmlHttpRequest, la tabella che visualizza è comunque piuttosto sgradevole. E qui
entra in gioco la stilizzazione CSS.
Stilizzare la tabella con CSS
La funzione principale che visualizza la tabella nel precedente esercizio è displayData(). In
questa funzione potete applicare stili CSS per rendere la tabella più simile a quelle che si
possono vedere nelle applicazioni web moderne.
Nota L’approccio all’utilizzo degli stili in questo capitolo si basa sul modificare gli attributi
di stile direttamente nel JavaScript, ma dovreste sapere che questo approccio è presentano
soltanto per scopi didattici. Non si tratta infatti dell’approccio preferito nel mondo reale in
quanto può rendere difficile la risoluzione dei problemi riguardanti il perché un determinato
attributo di stile è applicato a un dato elemento, poiché le informazioni possono cambiare sia
in CSS sia nel codice JavaScript. Un altro modo per lavorare con CSS, illustrato nel capitolo 22,
“Introduzione a jQuery”, applica cambiamenti di stile alterando gli stili CSS applicati agli elementi HTML. Questo è il modo preferito per lavorare con CSS in JavaScript, in quanto mantiene
la separazione fra la visualizzazione (CSS) e il comportamento (codice JavaScript).
Cambiare gli attributi di stile con JavaScript
Una delle prime operazioni da eseguire è rimuovere il bordo eliminando la seguente riga
nella parte superiore della funzione displayData():
table.border = "1";
Nella funzione displayData() sono presenti due loop primari: uno per visualizzare le intestazioni di colonna e uno per visualizzare i dati stessi. Il primo loop mostra le intestazioni di
colonna e si presenta come segue:
for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {
if (xmlEl[0].childNodes[colHead].nodeType != 1) {
continue;
}
var tableHead = document.createElement("th");
var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);
tableHead.appendChild(colName);
row.appendChild(tableHead);
}
tbody.appendChild(row);
Il secondo loop, che visualizza i dati effettivi, è il seguente:
for (i = 0; i < xmlEl.length; i++) {
20 Java PpP.indd 371
28/04/11 16:03
372
Parte IV AJAX e l’integrazione lato-server
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData = document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
La maggior parte delle modifiche apportate alla visualizzazione della tabella saranno eseguite in questi loop. Spiegherò le modifiche quando saranno eseguite.
Un altro aspetto che potreste voler cambiare è il font (da parte mia ho sempre avuto un
debole per l’Arial). Lo fate utilizzando la proprietà di stile fontFamily in JavaScript. Questo
cambiamento deve essere eseguito all’interno di ciascun loop per stilizzare tutto il testo
della tabella con il font Arial. Dopo aver aggiunto il codice, i loop si presentano come segue
(osservate le due nuove righe in grassetto):
for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {
if (xmlEl[0].childNodes[colHead].nodeType != 1) {
continue;
}
var tableHead = document.createElement("th");
var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);
tableHead.style.fontFamily = "Arial";
tableHead.appendChild(colName);
row.appendChild(tableHead);
}
tbody.appendChild(row);
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData = document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);
td.style.fontFamily = "Arial";
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
20 Java PpP.indd 372
28/04/11 16:03
Capitolo 20 Qualche approfondimento su AJAX
373
I risultati di queste modifiche e la rimozione del bordo della tabella generano una tabella
come quella nella figura 20.2.
Figura 20.2 Prime stilizzazioni della tabella con CSS.
Un po’ di colore sarebbe certamente utile per rendere la tabella più leggibile, specialmente
se si mostrano molte righe di dati o molte centinaia di righe. È possibile migliorare la leggibilità anche applicando colori alle righe alterne e cambiando il titolo della tabella in un colore diverso. Ecco come si presentano i due loop dopo l’aggiunta di alcune proprietà di stile
backgroundColor. Anche in questo caso le modifiche sono riportate in grassetto.
for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {
if (xmlEl[0].childNodes[colHead].nodeType != 1) {
continue;
}
var tableHead = document.createElement("th");
var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);
tableHead.style.fontFamily = "Arial";
tableHead.style.backgroundColor = "#aaabba";
tableHead.appendChild(colName);
row.appendChild(tableHead);
}
tbody.appendChild(row);
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData = document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);
if (i % 2) {
td.style.backgroundColor = "#aaabba";
}
20 Java PpP.indd 373
28/04/11 16:03
374
Parte IV AJAX e l’integrazione lato-server
td.style.fontFamily = "Arial";
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
Questo codice utilizza l’operatore modulo (%) per assegnare un’ombreggiatura grigio chiaro alle righe alterne della tabella. In questa tabella sono presenti soltanto due righe di dati,
perciò solo alla seconda riga viene applicata la sfumatura. La figura 20.3 mostra il risultato
dopo l’aggiunta del colore. Potete trovare la versione completa di questa pagina nella directory CompletedCode in Chapter20 fra i file di esempio.
Figura 20.3 Aggiungere colore alla tabella con CSS.
Creare una casella a discesa dinamica
Potete utilizzare una variante dell’applicazione dei segnalibri mostrata nel capitolo 19 per
creare una casella a discesa live per qualsiasi tipo di dati di elenco testuali. Questo tipo di
casella a discesa è chiamato a volte casella con suggerimenti durante la digitazione in quanto, mentre si digita, l’interfaccia utente mostra i valori inseriti di frequente in un elenco a
discesa, facilitando il completamento dell’immissione. Google Suggest è un’applicazione di
questo tipo.
Un’altra implementazione di questo stesso principio è una casella a discesa che mostra elementi comuni (come gli stati USA) mentre il visitatore digita. La chiave per questa variante
è che il sottoinsieme dei dati che possono essere recuperati per popolare velocemente la
casella a discesa live sia maneggevole. È possibile recuperare per esempio un sottoinsieme
di stati da un elenco dei 50 stati USA mentre un visitatore digita una query in una casella
di testo, ma se lavorate con 1.000.000 di record di database, recuperarne un sottoinsieme
probabilmente non sarebbe possibile in un tempo che possa dare all’utente finale l’impressione di un’applicazione che sta rispondendo. Come ulteriore esempio potreste utilizzare
un’applicazione come questa in un’azienda per recuperare un elenco di dipendenti per una
directory della società.
20 Java PpP.indd 374
28/04/11 16:03
Capitolo 20 Qualche approfondimento su AJAX
375
Ecco una dimostrazione di questa applicazione. Utilizzando l’oggetto xmlHttpRequest, l’applicazione recupera un elenco dei 50 stati USA. Quando un utente inserisce la lettera w,
l’applicazione recupera tutti gli stati che iniziano con quella lettera, come nella figura 20.4.
Figura 20.4 Recuperare un elenco di stati che iniziano con la lettera w.
Spostando il mouse sui vari stati, cambia il colore di sfondo dello stato, come si vede nella
figura 20.5, in cui ho spostato il mouse sul Wisconsin (il puntatore del mouse non è visibile
nella figura).
Figura 20.5 Spostando il mouse sugli stati, il loro colore di sfondo cambia.
Infine facendo clic su uno dei nomi di stati, il nome viene copiato nella casella di testo. Il risultato di questa azione è mostrato nella figura 20.6. Da qui il form potrebbe essere inviato,
eseguendo qualsiasi azione appropriata per l’applicazione in base all’input.
20 Java PpP.indd 375
28/04/11 16:03
376
Parte IV
AJAX e l’integrazione lato-server
Figura20.6 Spostare uno stato nella casella di testo.
Questo codice funziona allo stesso modo di quello dell’applicazione dei segnalibri del capitolo 19, in quanto il visitatore può continuare a digitare per restringere la ricerca a una
specifica selezione. Considerate il caso in cui il visitatore abbia digitato la lettera n. Così
facendo vengono mostrati gli otto stati che iniziano con la lettera n. Continuando a digitare, per esempio digitando la parola new, la ricerca si restringe a quattro stati, e digitando
ulteriori lettere i risultati si restringono ancora di più.
Il codice per questa applicazione è riportato nel listato 20.1.
LiSTaTO20.1 Un’applicazione di ricerca.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>State Search</title>
<script type="text/javascript" src="ehandler.js"></script>
</head>
<body>
<form name="nameform" id="nameform" action="" method="post">
Enter State: <input id="textname" type="text" name="textname">
</form>
<div id="data"></div>
<script type="text/javascript">
function textSearch() {
var textName = document.getElementById("textname");
var dataNode = document.getElementById("data");
while (dataNode.hasChildNodes()) {
dataNode.removeChild(dataNode.firstChild);
}
if (textName.value != "") {
listName(textName.value);
}
}
20 Java PpP.indd 376
28/04/11 16:03
Capitolo 20
Qualche approfondimento su AJAX
377
function readyAJAX() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try {
return new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
return "A newer browser is needed.";
}
}
}
}
function listName(text) {
var nameList = AJAXresponse.split(",");
var pattern = "^" + text;
var nameRegexp = new RegExp(pattern, "i");
for (var i = 0; i < nameList.length; i++) {
var existDiv = document.getElementById(nameList[i]);
if (! existDiv) {
if (nameList[i].match(nameRegexp)) {
var displayDiv = document.getElementById("data");
var newDiv = document.createElement("div");
if (window.attachEvent) {
newDiv.attachEvent("onclick",function(e) {
document.forms["nameform"].textname.value =
e.srcElement.firstChild.nodeValue;});
newDiv.attachEvent("onmouseover",function(e) {
e.srcElement.style.background = "#FFFFFF"; });
newDiv.attachEvent("onmouseout",function(e) {
e.srcElement.style.background = "#aaabba"; });
} else {
newDiv.addEventListener("click",function () {
document.forms["nameform"].textname.value =
this.firstChild.nodeValue; },false);
newDiv.addEventListener("mouseover",function() {
this.style.background = "#FFFFFF"; },false);
newDiv.addEventListener("mouseout",function() {
this.style.background = "#aaabba"; },false);
}
newDiv.setAttribute("id",nameList[i]);
newDiv.style.background = "#aaabba";
newDiv.style.color = "#000000";
newDiv.style.border = "solid 1px";
newDiv.style.display = "block";
newDiv.style.width = "175px";
newDiv.appendChild(document.createTextNode(nameList[i]));
displayDiv.appendChild(newDiv);
}
}
}
}
20 Java PpP.indd 377
28/04/11 16:03
378
Parte IV
AJAX e l’integrazione lato-server
var requestObj = readyAJAX();
var url = "http://YOUR SERVER HERE/statelist.php";
requestObj.open("GET",url,true);
requestObj.send();
var AJAXresponse;
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
AJAXresponse = requestObj.responseText;
} else {
alert(requestObj.statusText);
}
}
}
var textEl = document.getElementById("textname");
EHandler.add(textEl,"keyup", function() { textSearch(); } );
</script>
</body>
</html>Avete già visto la maggior parte di questo codice nel listato 20.1 in altri
punti del libro, ma lo spiegherò di nuovo brevemente qui.
Il codice recupera l’elenco degli stati chiamando un file esterno basato su server, statelist.php. Questo file restituisce un semplice elenco di stati separato dalla virgola, come il
seguente:
Alabama,Alaska,Arizona,California,Colorado,Delaware,Florida,Georgia, ...
Il file divide questo elenco di stati in corrispondenza della virgola di delimitazione e inserisce i nomi in un array chiamato nameList, come segue:
var nameList = AJAXresponse.split(",");
Nel codice sono presenti alcune aggiunte alle applicazioni che avete visto negli ultimi due
capitoli, per creare piccole caselle a discesa cliccabili con stile CSS. Quel codice è finito nella
funzione listName() che avete visto nel capitolo 19. Applica listener di evento e stili CSS a
questi elementi HTML DIV nella funzione listName, mostrata di seguito con il codice aggiunto riportato in grassetto:
function listName(text) {
var nameList = AJAXresponse.split(",");
var pattern = "^" + text;
var nameRegexp = new RegExp(pattern, "i");
for (var i = 0; i < nameList.length; i++) {
var existDiv = document.getElementById(nameList[i]);
20 Java PpP.indd 378
28/04/11 16:03
Capitolo 20 Qualche approfondimento su AJAX
379
if (! existDiv) {
if (nameList[i].match(nameRegexp)) {
var displayDiv = document.getElementById("data");
var newDiv = document.createElement("div");
if (window.attachEvent) {
newDiv.attachEvent("onclick",function(e) {
document.forms["nameform"].textname.value =
e.srcElement.firstChild.nodeValue;});
newDiv.attachEvent("onmouseover",function(e) {
e.srcElement.style.background = "#FFFFFF"; });
newDiv.attachEvent("onmouseout",function(e) {
e.srcElement.style.background = "#aaabba"; });
} else {
newDiv.addEventListener("click",function () {
document.forms["nameform"].textname.value =
this.firstChild.nodeValue; },false);
newDiv.addEventListener("mouseover",function() {
this.style.background = "#FFFFFF"; },false);
newDiv.addEventListener("mouseout",function() {
this.style.background = "#aaabba"; },false);
}
newDiv.setAttribute("id",nameList[i]);
newDiv.style.background = "#aaabba";
newDiv.style.color = "#000000";
newDiv.style.border = "solid 1px";
newDiv.style.display = "block";
newDiv.style.width = "175px";
newDiv.appendChild(document.createTextNode(nameList[i]));
displayDiv.appendChild(newDiv);
}
}
}
}
Accettare input dall’utente e AJAX
Il passo logico successivo nello sviluppo di applicazioni AJAX è accettare l’input dall’utente
e fare qualcosa con quell’input. Creare un’applicazione AJAX significa creare un’applicazione altamente interattiva basata sulle azioni dell’utente. Sfortunatamente per fare giustizia a
questo argomento dovrei entrare nei dettagli della creazione delle applicazioni lato-server
che gestiscono l’input, e questo esula dallo scopo di un libro rivolto a principianti dedicato
a JavaScript. Con un po’ di fortuna scriverò un altro libro di livello intermedio su JavaScript
o sulla creazione di applicazioni JavaScript che mostrerà sia il JavaScript sia gli aspetti server
di AJAX.
20 Java PpP.indd 379
28/04/11 16:03
380
Parte IV AJAX e l’integrazione lato-server
Spero tuttavia di essere riuscito, anche con questa trattazione limitata, a farvi comprendere che le applicazioni AJAX non fanno nulla di più che fornire ai visitatori modi
amichevoli e interattivi per utilizzare le applicazioni e che gran parte di questa attività
riguarda la progettazione intorno a JavaScript, e non solo XMLHttpRequest. L’oggetto
XMLHttpRequest è fondamentalmente un corriere, un meccanismo di consegna, per inserire
i dati nel programma. Il livello su cui XMLHttpRequest opera è molto al di sotto del livello
presentazione su cui la pagina è costruita. Gli utenti perciò non vedono mai l’elaborazione di XMLHttpRequest in background, ma solo il design che avete creato sul front-end
dell’applicazione.
Gli ultimi due capitoli del libro si basano su tutto ciò che avete appreso finora, ma con l’aiuto della libreria jQuery di JavaScript.
Esercizi
1. Create un gestore di evento submit per l’esempio degli stati mostrato in questo capitolo tale che lo stato inviato sia mostrato all’utente quando invia il form.
2. Create un’applicazione che utilizza XMLHttpRequest per restituire un elenco di nomi
(come una directory di dipendenti). Potete utilizzare sia normale testo sia XML per i
dati di origine.
20 Java PpP.indd 380
28/04/11 16:03
Parte V
jQuery
Capitolo 21: Introduzione alle librerie e ai framework
JavaScript
Capitolo 22: Introduzione a jQuery
Capitolo 23: Effetti e plug-in di jQuery
21 Java PpP.indd 381
381
28/04/11 16:03
21 Java PpP.indd 382
28/04/11 16:03
Capitolo 21
Introduzione alle librerie
e ai framework JavaScript
Dopo aver letto questo capitolo, sarete in grado di:
n
Comprendere il ruolo delle librerie e dei framework di programmazione JavaScript.
n
Comprendere come definire vostre librerie.
n
Comprendere il ruolo delle librerie e dei framework JavaScript di terze parti e come
trovare ulteriori informazioni su esse.
Comprendere le librerie di programmazione
In termini di programmazione, una libreria è un raggruppamento di codice che fornisce
funzionalità comuni o aggiuntive. Tipicamente le librerie consistono di uno o più file che
espongono oggetti e funzioni. In un programma uno sviluppatore include o chiama la
libreria per utilizzare questi oggetti e funzioni aggiuntive. In questo modo le librerie e i
framework JavaScript sono utili perché evitano di dover mantenere e sviluppare funzioni
aggiuntive e migliorate. Contribuiscono a facilitare le attività di programmazione comuni
e possono anche aiutare ad attenuare le differenze e la varietà di sfumature dello sviluppo
per più browser.
Questo capitolo esplora le librerie di JavaScript, compresa la procedura per definire librerie
personalizzate, ed esamina alcune delle più diffuse librerie e framework JavaScript.
Definire una propria libreria JavaScript
Gli sviluppatori in qualsiasi linguaggio eseguono spesso funzioni comuni in modo ripetitivo
nella loro attività di programmazione, perciò diventa molto utile creare una libreria o un
raggruppamento personalizzato di funzioni comuni utilizzabile per i progetti futuri.
Lo script di gestione eventi sviluppato nel capitolo 11, ehandler.js, mostra come creare una
libreria creando uno spazio dei nomi per essa:
var EHandler = {};
In quello spazio dei nomi la libreria EHandler aggiunge due funzioni. Ecco la prima:
EHandler.add = ...
Ed ecco la seconda:
21 Java PpP.indd 383
EHandler.remove = ...
383
28/04/11 16:03
384
Parte V jQuery
Sebbene sia breve, EHandler è una vera libreria. Come potete vedere, le librerie non devono
necessariamente essere grandi per poter essere utili. Avete visto molti esempi di utilizzo
di EHandler in capitoli precedenti del libro, e tenendo presente il concetto della libreria
EHandler, in questo esempio successivo creerete una vostra libreria.
Creare una libreria
1. Utilizzando Microsoft Visual Studio, Eclipse o un altro editor, aprite il file library.js nella cartella Chapter21 fra i file di esempio.
2. In library.js aggiungete il seguente codice (sostituendo il commento TODO) per creare
uno spazio dei nomi, e poi aggiungete una funzione:
var MyLibrary = {};
MyLibrary.sendAlert = function(mesg, elm) {
alert(mesg);
};
3. Salvate il file e chiudetelo.
4. Aprite il file librarypage.htm. In librarypage.htm aggiungete il codice riportato di seguito in grassetto (per sostituire il commento TODO):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.
dtd">
<html>
<head>
<title>A Basic Example</title>
<script type="text/javascript" src="library.js"></script>
</head>
<body>
<script type="text/javascript">
MyLibrary.sendAlert("hello, this is the message");
</script>
</body>
</html>
5. Visualizzate la pagina librarypage.htm in un browser web. Dovreste ricevere un avviso
come questo:
21 Java PpP.indd 384
28/04/11 16:03
Capitolo 21 Introduzione alle librerie e ai framework JavaScript 385
Soluzione dei problemi Se non ricevete un avviso come questo, assicuratevi di aver spe-
cificato correttamente il percorso al file library.js. L’esempio mostrato nel precedente codice
librarypage.htm presuppone che il file JavaScript library.js si trovi nella stessa directory del file
HTML.
Fate attenzione quando definite e utilizzate le vostre librerie, in modo da non creare sovrapposizioni o collisioni con funzioni esistenti e parole riservate della specifica ECMA-262.
Inoltre, se utilizzare una libreria o un framework esterno come jQuery o YUI, dovete assicurarvi che la vostra libreria non collida con le convenzioni di denominazione utilizzate per
essi.
Librerie e framework JavaScript diffusi
Le librerie e i framework per JavaScript pubblicamente disponibili sono molti. Il loro scopo è
facilitare le attività difficili ai programmatori che sviluppano applicazioni web incentrate su
JavaScript.
Gli sviluppatori Web dedicano molto del loro tempo ad attività volte a ottenere pagine che
abbiano lo stesso aspetto e funzionamento su più browser. Un importante vantaggio dato
dall’uso di molte librerie o framework JavaScript è che rimuovono i problemi della compatibilità fra browser. Tutte le diffuse librerie e framework JavaScript includono il codice per far
operare le loro rispettive funzioni su tutti i browser che supportano.
jQuery
jQuery offre un ricco insieme di funzionalità, opzioni potenti, estensibilità ed eccellente
supporto da parte della comunità. Utilizzando jQuery, contenuto in un solo file JavaScript,
potete aggiungere effetti alle pagine web, migliorarne l’usabilità e facilitare l’elaborazione
dei dati con AJAX. Microsoft inoltre include jQuery in Visual Studio 2010. Il capitolo 22,
“Introduzione a jQuery”, e il capitolo 23, “Effetti e plug-in di jQuery”, esaminano jQuery in
ulteriori dettagli. Potete trovare informazioni su jQuery all’indirizzo http://jquery.com (le
informazioni sono in inglese).
Yahoo! User Interface
Yahoo! User Interface (YUI) offre sia JavaScript sia Cascading Style Sheets (CSS), e semplifica lo sviluppo di applicazioni web. Come jQuery, YUI include funzionalità per migliorare
l’usabilità e ottimizzare le applicazioni web. Inoltre la documentazione di YUI è eccellente.
Potete trovare informazioni su YUI all’indirizzo http://developer.yahoo.com/yui/ (le informazioni sono in inglese).
21 Java PpP.indd 385
28/04/11 16:03
386
Parte V jQuery
MooTools
MooTools è una piccola libreria JavaScript altamente ottimizzata. MooTools differisce da
YUI e jQuery perché si concentra sull’ottimizzazione dell’elaborazione di JavaScript, mentre
YUI e jQuery si concentrano sugli effetti, CSS e le interazioni dirette con l’esperienza utente.
Questo non significa che MooTools non abbia effetti, anche MooTools infatti offre molti
degli stessi effetti (come accordion e slider) che potete trovare in YUI e jQuery. MooTools è
consigliato per i programmatori JavaScript di livello intermedio e avanzato ed è disponibile
all’indirizzo http://mootools.net/.
Altre librerie
Molte altre librerie e framework sono disponibili per JavaScript, troppi per essere trattati e
persino menzionati in un libro. Un utile punto da cui iniziare è http://en.wikipedia.org/wiki/
Comparison_of_JavaScript_frameworks dove potete scoprire ulteriori informazioni sui framework JavaScript.
Esercizi
1. Esaminate ciascuna delle librerie e framework illustrati in questo capitolo. Quale pensate sia il più semplice da imparare per i nuovi programmatori in JavaScript? Perché?
2. Create una vostra libreria JavaScript con un file JavaScript esterno. Includete il file in
una pagina HTML e chiamatelo.
21 Java PpP.indd 386
28/04/11 16:03
Capitolo 22
Introduzione a jQuery
Dopo aver letto questo capitolo, sarete in grado di:
n
Comprendere come includere jQuery nell’HTML.
n
Comprendere importanti concetti e la sintassi di jQuery.
n
Utilizzare jQuery con le pagine web.
Presentazione di jQuery
jQuery è un framework JavaScript diffuso e facile da usare, che facilita le attività JavaScript
difficili, spesso eliminando i problemi della compatibilità con più browser.
L’intera libreria jQuery consiste di un solo file JavaScript, il che ne semplifica l’inclusione nel
nostro JavaScript. Anche la sintassi di jQuery è facile da imparare; utilizza un semplice spazio dei nomi e funzionalità coerenti. Impiegato insieme al componente aggiuntivo jQuery
User Interface (UI) (trattato nel capitolo 23, “Effetti e plug-in di jQuery”), vi permette di creare applicazioni web potenti e altamente interattive.
Questo capitolo presenta un’introduzione a jQuery, compreso come scaricarlo e utilizzarlo
nel vostro JavaScript.
Utilizzare jQuery
Potete ottenere jQuery da http://www.jquery.com/. In questa sezione vedrete come scaricare jQuery e integrarlo in una pagina web.
I due download di jQuery
Sulla home page di jQuery sono disponibili due download: una versione di produzione e
una versione di sviluppo. Se non progettate di sviluppare plug-in di jQuery o esaminare il
suo interno, dovreste scaricare e utilizzare la versione di produzione minificata.
Come altra possibile opzione, specialmente per svolgere gli esercizi proposti in questo
capitolo, potreste utilizzare una content delivery network (CDN) per accedere a una versione hosted di jQuery. Google offre in hosting jQuery e altre librerie tramite il suo sito
web API. Questo significa che potete includere jQuery nelle vostre pagine web e programmi JavaScript senza dover ospitare il file localmente sul vostro server. Visitate http://code.
google.com/apis/libraries/devguide.html per ulteriori informazioni (le informazioni sono in
inglese).
22 Java PpP.indd 387
387
28/04/11 16:02
388
Parte V
jQuery
Nota Per quasi tutti gli scenari in cui lavorate con jQuery, consiglio di scaricare e ospitare il
file jQuery localmente. Utilizzare la versione locale può essere più veloce e affidabile che non
utilizzare la versione CDN. Se per esempio utilizzate una versione ospitata su CDN e il server CDN va giù, tutti gli elementi del vostro sito che utilizzano la libreria non funzioneranno!
Tuttavia, per le attività di sviluppo proposte in questo capitolo, va benissimo utilizzare file ospitati su CDN.
Per svolgere gli esercizi e seguire le procedure di questo capitolo occorre aver scaricato
jQuery nel computer di sviluppo locale o essere connessi a esso da una CDN.
Includere jQuery
Per includere jQuery in una pagina web si procede esattamente come con qualsiasi altro
file JavaScript esterno, con un tag <script> che punta al file di origine. Considerate il codice
del listato 22.1.
liSTaTO22.1 Includere jQuery in una pagina web.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>Adding jQuery</title>
<script type="text/javascript" src="jquery-1.4.3.min.js"></script>
</head>
<body>
</body>
</html>
Ora che avete scaricato jQuery o lo avete referenziato da un sito CDN, e avete visto l’esempio precedente che mostra come includere jQuery in un file, possiamo passare alla sintassi
di jQuery.
importante La versione 1.4.3 è l’ultima rilasciata al momento della stesura di questo libro,
tuttavia sarà quasi certamente diversa quando leggerete il testo, perciò dovrete cambiare l’attributo src in base alla versione dello script jQuery che avete scaricato.
Sintassi jQuery di base
Quando includete la libreria jQuery in una pagina, jQuery aggiunge una funzione chiamata
jquery(). Potreste pensare di dover effettuare tutte le chiamate alle funzioni di jQuery tramite questa interfaccia jquery(), tuttavia esiste una scorciatoia per accedere alla funzione
jquery(): $(). Anziché digitare jquery ogni volta, accedete alla libreria jQuery utilizzando un
segno di dollaro seguito da due parentesi, come mostrato negli esempi della tabella 22.1.
22 Java PpP.indd 388
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
Tabella 22.1 Alcuni
389
selettori jQuery
Sintassi
Descrizione
$(“a”)
Tutti gli elementi <a> nel documento.
$(document)
L ’intero documento, utilizzata di frequente per accedere alla funzione
ready() descritta più avanti in questo capitolo.
$(“#elementID”)
L’elemento identificato dall’ID elementID.
$(“.className”)
L’elemento o gli elementi con la classe className.
Vedrete altri selettori e funzioni correlate più avanti in questo capitolo.
Come il codice JavaScript, le istruzioni jQuery dovrebbero terminare con un punto e virgola.
Inoltre potete utilizzare indifferentemente le virgolette singole o doppie come selettori in
jQuery. Entrambe queste istruzioni sono infatti ugualmente valide:
$("a")
$('a')
Quando vedrete esempi dell’utilizzo di jQuery nel mondo reale (non che questo libro non
faccia parte del mondo reale!), scoprirete che sono utilizzate le virgolette sia singole sia
doppie. Gli esempi di questo capitolo utilizzano un misto dei due per farvi acquisire familiarità con entrambi i casi; tuttavia, nella programmazione reale, e preferibile scegliere uno
stile e utilizzarlo in modo coerente.
Collegare jQuery all’evento load
Uno dei modi più comuni per lavorare con jQuery è collegando elementi durante l’evento
load (o onload) della pagina (gli eventi e le funzioni sono trattate in maggiori dettagli più
avanti in questo capitolo). In jQuery lo fate attraverso la funzione di utilità .ready() dell’elemento document.
Come abbiamo visto nel breve esempio della sezione precedente, jQuery accede agli elementi con la sintassi $(). Tenendo presente questo, potete accedere all’elemento document
come segue:
$(document)
Quindi potete accedere alla funzione ready() così:
$(document).ready()
Il seguente esercizio richiede che abbiate scaricato jQuery nel computer di sviluppo locale
o che utilizziate un CDN. L’esempio si basa sulla versione 1.4.3 di jQuery, ma questo numero
di versione sarà probabilmente diverso quando eseguirete l’esercizio.
22 Java PpP.indd 389
28/04/11 16:02
390
Parte V jQuery
Utilizzare document ready
1. Utilizzando Microsoft Visual Studio, Eclipse o un altro editor, modificate il file docready.html nella cartella Chapter22 dei file di esempio.
2. Nel file aggiungete il seguente codice riportato in grassetto al posto del commento
TODO:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Document Ready</title>
<script type="text/javascript" src="jquery-1.4.3.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(alert('hi'));
</script>
</body>
</html>
3. Salvate il file e visualizzate la pagina in un browser web. Riceverete un avviso come
questo:
Il codice di questo esercizio combina jQuery tramite la funzione $(document).ready() e anche il normale vecchio JavaScript, rappresentato dalla funzione alert() in questo esempio.
Questo misto di jQuery e JavaScript è un concetto importante da comprendere: si utilizza
jQuery come supplemento al normale JavaScript. jQuery facilita molte delle attività difficoltose, così tanto in effetti che potete dedicare il vostro tempo a creare funzionalità anziché a preoccuparvi delle differenze fra i browser.
La funzione $(document).ready() elimina l’esigenza di utilizzare l’evento load del browser
per inserire una chiamata di funzione nell’evento load. Con $(document).ready() tutti gli elementi del Document Object Model (DOM) sono disponibili prima della funzione .ready().
Suggerimento La funzione $(document).ready() è centrale per gran parte della programmazione che si esegue con jQuery.
22 Java PpP.indd 390
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
391
Utilizzare i selettori
I selettori sono la chiave per lavorare con jQuery e il DOM. Potete utilizzare i selettori per
identificare e raggruppare gli elementi su cui una funzione jQuery è eseguita. Come si vede
nella tabella 22.1, i selettori sono utilizzati per raccogliere tutti gli elementi con un certo
tag, ID o classe applicata. Potete anche utilizzare i selettori in modi molto più potenti, come
per selezionare un determinato numero di elementi oppure per selezionare solo elementi
che hanno particolari relazioni con altri, per esempio solo i tag <p> che seguono un tag
<div>. Questa sezione descrive i selettori in maggiori dettagli.
Suggerimento I selettori e il modo in cui funzionano in jQuery sono basati sui selettori in
CSS. Se siete a vostro agio con il loro utilizzo in CSS (trattato nel capitolo 15, “JavaScript e CSS”),
vi sentirete a casa con questo modello.
Selezionare elementi tramite l’ID
L’esempio nella tabella 22.1 ha mostrato la sintassi generale per selezionare un elemento
tramite il suo attributo ID:
$("#elementID")
Considerate per esempio questa porzione di HTML:
<a href="#" id="linkOne">Link</a>
Con il normale JavaScript accedete a questo elemento come segue:
getElementById("linkOne")
Con jQuery accedete all’elemento così:
$("#linkOne")
Selezionare elementi tramite la classe
Per selezionare elementi tramite la classe dovete far precedere un punto (.) al nome della
classe. La sintassi è questa:
$(".className")
Ecco per esempio un div con una classe applicata:
<div class="specialClass">
22 Java PpP.indd 391
28/04/11 16:02
392
Parte V jQuery
Potreste accedere a quell’elemento tramite jQuery come segue:
$(".specialClass")
Tenete presente che potreste non accedere a un solo elemento; il selettore di classe accede
a tutti gli elementi a cui la classe specificata è applicata. In altre parole se molti elementi
della pagina hanno applicata la classe speciale “specialClass”, jQuery accede a tutti utilizzando il selettore $(“.specialClass”). Approfondiremo l’argomento più avanti quando lavoreremo con le funzioni che iterano su ogni elemento recuperato con un tale selettore.
Selezionare elementi tramite il tipo
Potete anche utilizzare i selettori per accedere agli elementi per tipo, come tutti gli elementi <div>, tutti gli elementi <a> e così via. Potreste per esempio accedere a tutti gli elementi
<div> in un documento come segue:
$('div')
Analogamente per accedere a tutti gli elementi <a>, scriverete:
$('a')
Utilizzando un selettore di tipo è possibile accedere a tutti gli elementi del tipo specificato
sulla pagina. Come il selettore di classe, i selettori di tipo possono restituire più elementi.
Selezionare elementi tramite la gerarchia
Come abbiamo detto in precedenza, potete selezionare gli elementi in base alla loro posizione in relazione ad altri elementi della pagina. Per selezionare per esempio tutti gli elementi <a> che si trovano all’interno di elementi <div>, utilizzate questa sintassi:
$("div a")
E potete essere ancora più specifici. Se per esempio desiderate tutte le àncore che seguono solo un determinato div, combinate il selettore di tipo con la sintassi del selettore di ID.
Considerate questo HTML:
<div id="leftNav">
<a href="link1.html">Link 1</a>
<a href="link2.html">Link 2</a>
</div>
Ecco la sintassi del selettore di jQuery per recuperare i due elementi anchor nel div leftNav:
$("#leftNav a")
Più genericamente, se desiderate soltanto i discendenti diretti di un elemento, utilizzate il
segno di maggiore:
22 Java PpP.indd 392
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
393
$("div > p")
Questa sintassi recupera tutti gli elementi <p> che sono discendenti diretti di un div ma
non include alcun elemento <p> interno agli elementi <p> selezionati.
Potete anche scegliere il figlio ennesimo in un insieme con il selettore :nth-child(). Questo
esempio sceglie il terzo figlio:
$("p:nth-child(3)")
Esistono molti altri selettori gerarchici. Per ulteriori informazioni, consultate la
documentazione di riferimento sui selettori di jQuery all’indirizzo http://api.jquery.com/
category/selectors/ (le informazioni sono in inglese).
Selezionare elementi tramite la posizione
Come avete visto, i selettori di jQuery sono voraci. La sintassi $(‘a’) seleziona per esempio
tutti i tag anchor. jQuery offre molti modi per selezionare elementi più specifici in un gruppo. Uno di questi metodi è utilizzare i selettori first e last. Il seguente codice seleziona il
primo <p> della pagina:
$("p:first")
Analogamente, l’ultimo elemento si seleziona come segue:
$("p:last")
Potete anche selezionare gli elementi in base alla loro posizione diretta. Come ulteriore
esempio, considerate questo HTML:
<p>First P</p>
<p>Second P</p>
<p>Third P</p>
Per selezionare il secondo elemento <p>, utilizzate questa sintassi:
$("p")[1]
Notate che l’indice dell’array inizia da 0 per questo tipo di selettore, perciò il primo elemento è l’indice 0, il secondo è l’indice 1 e così via. Utilizzare questa sintassi è un po’ pericoloso perché fa affidamento sul rigido posizionamento degli elementi nella gerarchia. Se
qualcuno aggiunge un altro tag <p> alla pagina prima dell’elemento che state tentando di
selezionare, questa aggiunta fa cambiare l’indice dell’array, perciò il selettore sceglie l’elemento sbagliato. Quando è possibile, è meglio utilizzare un selettore di ID per scegliere un
elemento singolo o specifico che non fare affidamento sulla posizione dell’elemento.
Un modo alternativo di selezionare utilizzando l’indice è impiegare la sintassi :eq. Per scegliere per esempio il terzo paragrafo, potreste scrivere:
$("p:eq(3)")
22 Java PpP.indd 393
28/04/11 16:02
394
Parte V
jQuery
Infine altri selettori di posizione che a volte tornano utili sono even e odd, che selezionano
gli elementi alterni di un gruppo:
$("p:even")
I selettori even e odd sono molto utili quando si lavora con dati tabellari per alternare i colori delle righe. Il listato 22.2 mostra un esempio che utilizza il selettore oddper differenziare il colore di sfondo delle righe alterne di una tabella.
Nota Il codice del listato 22.2 utilizza due elementi che non sono ancora stati introdotti for-
malmente: una funzione definita dall’utente e la funzione .css() Ma non preoccupatevene adesso. Le vedremo nei dettagli più avanti in questo capitolo.
liSTaTO22.2 Dati tabellari e jQuery.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>Table Test</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
</head>
<body>
<table>
<tr>
<td>Row 1 Column 1 of the table</td>
<td>Row 1 Column 2 of the table</td>
</tr>
<tr>
<td>Row 2 Column 1 of the table</td>
<td>Row 2 Column 2 of the table</td>
</tr>
<tr>
<td>Row 3 Column 1 of the table</td>
<td>Row 3 Column 2 of the table</td>
</tr>
<tr>
<td>Row 4 Column 1 of the table</td>
<td>Row 4 Column 2 of the table</td>
</tr>
<tr>
<td>Row 5 Column 1 of the table</td>
<td>Row 5 Column 2 of the table</td>
</tr>
<tr>
<td>Row 6 Column 1 of the table</td>
<td>Row 6 Column 2 of the table</td>
</tr>
</table>
22 Java PpP.indd 394
28/04/11 16:02
Capitolo 22
Introduzione a jQuery
395
<script type="text/javascript">
$(document).ready(function() {
$('tr:odd').css("background-color", "#abacab");
});
</script>
</body>
</html>
Questa porzione principale del codice è contenuta nella sezione JavaScript all’interno del
body dell’HTML:
$(document).ready(function() {
$('tr:odd').css("background-color", "#abacab");
});
Il codice utilizza la funzione $(document).ready() insieme al selettore :odd per impostare il
colore di sfondo al valore esadecimale #abacab, un grigio chiaro. La figura 22.1 mostra un
esempio dell’output.
FigUra22.1 Una tabella colorata con l’aiuto di jQuery.
Avetevistoalcunideipiùcomuniselettoridiposizione,macenesonomoltialtridisponibili.
Visitatehttp://api.jquery.com/category/selectors/perulterioriinformazioni(leinformazioni
sonoininglese).
22 Java PpP.indd 395
28/04/11 16:02
396
Parte V jQuery
Selezionare elementi tramite un attributo
Come potreste immaginare considerando il selettore di classe che avete già visto, jQuery vi
permette di selezionare gli elementi che contengono semplicemente un attributo o quelli
che contengono un attributo con un determinato valore. Per selezionare per esempio tutte
le immagini che hanno un attributo alt, scriverete quanto segue:
$("img[alt]")
Per selezionare solo le immagini che hanno un attributo alt impostato su un determinato
valore, scriverete:
$("img[alt='alternate text']")
Il codice precedente seleziona un’immagine soltanto se il testo alt è la parola alternate text.
Notate in questo esempio l’utilizzo alternato delle virgolette singole e delle virgolette doppie. Il selettore è racchiuso fra virgolette doppie mentre il selettore di attributo alt interno
è racchiuso fra virgolette singole, tuttavia avremmo potuto fare l’inverso: virgolette singole
per il selettore img e virgolette doppie per il selettore di attributo alt:
$('img[alt="alternate text"]')
Potreste anche utilizzare le stesse virgolette per entrambi, ma in questo caso dovete effettuare l’escape delle virgolette interne, come segue:
$("img[alt=\"alternate text\"]")
È importante osservare che questo tipo di selettore si aspetta una corrispondenza esatta. In questo esempio l’attributo alt deve essere la stringa “alternate text”. Qualsiasi minima differenza, come “alternate text 2” o “ alternate text “ determinerà una non
corrispondenza.
jQuery include caratteri jolly di selezione che non richiedono una corrispondenza esatta
sugli attributi. Considerate gli esempi nella tabella 22.2.
Tabella 22.2 Corrispondenza
22 Java PpP.indd 396
dei selettori di attributi
Sintassi
Descrizione
attribute*=value
Seleziona gli elementi che contengono l’attributo il cui valore include il
valore specificato come sottostringa.
attribute~=value
Seleziona gli elementi che contengono l’attributo il cui valore include il
valore specificato come intera parola.
attribute!=value
Seleziona gli elementi che o non contengono l’attributo o che
contengono l’attributo ma con un valore non corrispondente al valore
specificato.
attribute$=value
S eleziona gli elementi che contengono l’attributo specificato con un
valore che termina con la stringa specificata.
attribute^=value
S eleziona gli elementi che contengono l’attributo specificato con un
valore che inizia con la stringa specificata.
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
397
Selezionare elementi dei form
jQuery contiene selettori nativi correlati ai web form. La tabella 22.3 elenca qualcuno di
questi selettori, alcuni dei quali sono utilizzati nella parte rimanente di questo capitolo.
Tabella 22.3 Selettori
correlati ai form
Selettore
Descrizione
:checkbox
Seleziona tutte le caselle di controllo
:checked
Seleziona tutti gli elementi che sono attivati, come le caselle ci controllo
:input
Seleziona tutti gli elementi di input sulla pagina
:password
Seleziona tutti gli input password
:radio
Seleziona tutti gli input pulsanti di opzione
:reset
Seleziona tutti i tipi di input reset
:selected
Seleziona tutti gli elementi attualmente selezionati
:submit
Seleziona tutti i tipi di input submit
:text
Seleziona tutti i tipi di input text
Altri selettori
jQuery dispone di molti altri selettori, come quelli che selezionano tutti gli elementi nascosti (:hidden) o visibili (:visible) oppure gli elementi abilitati, disabilitati e altri. Visitate http://
api.jquery.com/category/selectors/ per vedere l’elenco completo e aggiornato dei selettori
di jQuery.
Suggerimento Anziché escogitare una sintassi complessa e fragile per un selettore in modo
da raggiungere un determinato elemento, consultate la guida di riferimento ai selettori di
jQuery (http://api.jquery.com/category/selectors/, le informazioni sono in inglese) per vedere se
qualcuno ha già risolto il problema.
Funzioni
Finora avete visto molti esempi che selezionano elementi con jQuery, ma soltanto un
paio che mostrano cosa potete fare con quegli elementi dopo averli selezionati. jQuery
utilizza le funzioni per eseguire azioni sugli elementi selezionati. Le funzioni possono essere predefinite in jQuery o definite dall’utente. Quasi sempre utilizzerete entrambi i tipi
contemporaneamente.
22 Java PpP.indd 397
28/04/11 16:02
398
Parte V jQuery
Attraversare il DOM
La natura della programmazione sul web utilizzando JavaScript e ora jQuery richiede di frequente l’esecuzione di loop o l’iterazione su molti elementi, per esempio la funzione .each()
prende un elenco di elementi selezionati ed esegue un’iterazione su ciascuno di essi, facendo qualcosa (o nulla) a ciascuno mentre compie il loop sull’elenco. jQuery contiene numerose funzioni per eseguire loop e iterazioni. Questo processo è chiamato attraversamento
nel gergo di jQuery. Per ulteriori informazioni sulle funzioni correlate all’attraversamento,
visitate http://api.jquery.com/category/traversing/ (le informazioni sono in inglese).
Quando utilizzate le funzioni di attraversamento, quasi sempre lo fate con l’aiuto di una
funzione wrapper definita dall’utente insieme al selettore $(this). Analogamente alla parola
chiave this nella programmazione a oggetti, il selettore $(this) si riferisce all’oggetto corrente, in questo caso l’elemento attualmente attraversato.
Qui potrebbe essere utile un esempio. L’HTML che segue crea una pagina con le classifiche
relative a un torneo fittizio di volleyball:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.
dtd">
<html>
<head>
<title>Iteration Test</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
</head>
<body>
<table>
<th>Team Name</th>
<th>W-L Record</th>
<th>Win Percentage</th>
<tr>
<td>Team 1</td>
<td>12-8</td>
<td class="percentage">.600</td>
</tr>
<tr>
<td>Team 5</td>
<td>11-9</td>
<td class="percentage">.550</td>
</tr>
<tr>
<td>Team 4</td>
<td>10-10</td>
<td class="percentage">.500</td>
</tr>
<tr>
<td>Team 2</td>
<td>9-11</td>
<td class="percentage">.450</td>
</tr>
<tr>
<td>Team 6</td>
<td>6-14</td>
<td class="percentage">.300</td>
22 Java PpP.indd 398
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
399
</tr>
<tr>
<td>Team 3</td>
<td>2-18</td>
<td class="percentage">.100</td>
</tr>
</table>
<script type="text/javascript">
$(document).ready(function() {
$('tr:odd').css("background-color", "#abacab");
});
</script>
</body>
</html>
Quando è visualizzata in un browser web, si presenta come quella nella figura 22.2.
Figura 22.2 Pagina con le classifiche relative a un torneo fittizio di volleyball.
Questo esempio esegue un’iterazione su tutti gli elementi che contengono l’attributo class
percentage, una classe applicata alle celle della colonna Win/Loss Percentage della tabella.
Per qualsiasi squadra la cui Win/Loss percentage sia maggiore o uguale a .500 (ovvero che
ha vinto almeno la metà delle partite), questo esempio applica il grassetto al campo. Potete
ottenere questo con il seguente codice jQuery, aggiunto subito sotto l’altro codice jQuery
già presente nella pagina:
$('.percentage').each(function() {
if ($(this).text() >= .5) {
$(this).css('font-weight', 'bold');
}
});
22 Java PpP.indd 399
28/04/11 16:02
400
Parte V
jQuery
Questo codice utilizza un selettore per raccogliere tutti gli elementi a cui è applicata la classe percentage. Quindi accede a ciascuno di questi elementi utilizzando la funzione .each() di
jQuery. Nella funzione .each(), una funzione definita dall’utente esegue un condizionale per
determinare se il valore nella colonna WinPercentage è maggiore o uguale a .5. Se è così, il
codice chiama la funzione .css() per aggiungere una proprietà font-weight impostata a bold
per quell’elemento. Dopo aver aggiunto questo codice alla pagina, il risultato è quello del
listato 22.3.
liSTaTO22.3 Aggiungere jQuery alla pagina del torneo di volleyball.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>Iteration Test</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
</head>
<body>
<table>
<th>Team Name</th>
<th>W-L Record</th>
<th>Win Percentage</th>
<tr>
<td>Team 1</td>
<td>12-8</td>
<td class="percentage">.600</td>
</tr>
<tr>
<td>Team 5</td>
<td>11-9</td>
<td class="percentage">.550</td>
</tr>
<tr>
<td>Team 4</td>
<td>10-10</td>
<td class="percentage">.500</td>
</tr>
<tr>
<td>Team 2</td>
<td>9-11</td>
<td class="percentage">.450</td>
</tr>
<tr>
<td>Team 6</td>
<td>6-14</td>
<td class="percentage">.300</td>
</tr>
<tr>
<td>Team 3</td>
<td>2-18</td>
<td class="percentage">.100</td>
</tr>
</table>
22 Java PpP.indd 400
28/04/11 16:02
Capitolo 22
Introduzione a jQuery
401
<script type="text/javascript">
$(document).ready(function() {
$('tr:odd').css("background-color", "#abacab");
$('.percentage').each(function() {
if ($(this).text() >= .5) {
$(this).css('font-weight', 'bold');
}
});
});
</script>
</body>
</html>
Quando visualizzate questa pagina nel browser, vedete che la colonna Win Percentage è
in grassetto per le squadre che hanno vinto almeno metà delle partite, come si vede nella
figura 22.3.
FigUra22.3 La colonna Win Percentage ora è in grassetto grazie all’aiuto di jQuery.
Esaminando l’output della figura 22.3, potete vedere che sarebbe stato anche meglio applicare il grassetto all’intera riga della tabella anziché solo alla colonna Win Percentage. Fare
questo potrebbe sembrarvi difficile, perché dal punto di vista logico il codice ha già superato quella riga della tabella HTML quando viene applicato il test per trovare la percentuale di
vincite. Fortunatamente jQuery dispone di una funzione che può essere d’aiuto: .parent() (in
effetti ci sono molti modi per fare questo e la funzione .parent()e soltanto uno di essi).
Con la funzione parent() l’esecuzione si sposta essenzialmente verso l’alto nella struttura
ad albero del DOM per trovare il tag <tr> che racchiude questo particolare elemento <td>.
Applicando il cambiamento di stile CSS all’elemento <tr>, potete rendere l’intera riga in
grassetto. Il nuovo codice è il seguente, e la modifica è riportata in grassetto:
22 Java PpP.indd 401
28/04/11 16:02
402
Parte V jQuery
$('.percentage').each(function() {
if ($(this).text() >= .5) {
$(this).parent().css('font-weight', 'bold');
}
});
Quando viene aggiunto al codice del listato 22.3, l’output è simile a quello della figura 22.4.
Figura 22.4 Applicare lo stile CSS a livello di riga nella tabella.
Nota Potete trovare il codice modificato anche in listing22-4.html fra i file di esempio.
L’utilizzo della funzione .parent() introduce un nuovo concetto chiamato concatenamento. Il
concatenamento è un potente costrutto di jQuery che permette livelli di selezione aggiuntivi e l’applicazione multilivello delle funzioni. In questo esempio il selettore $(this) è concatenato alla funzione .parent(), che seleziona anche il padre di $(this). Solo allora il codice
esegue la funzione .css().
Insito nel concatenamento tuttavia c’è un grosso pericolo, quello di ottenere codice difficile
da leggere e mantenere. Inoltre il concatenamento può creare codice fragile quando gli
elementi in un selettore concatenato cambiano. Il concatenamento è potente e consiglio
di utilizzarlo tutte le volte che è possibile, ma andrà a discapito della facilità di lettura e
manutenzione.
Gli esempi mostrati finora erano tutti basati sull’accesso e la modifica diretta del CSS tramite JavaScript. Come abbiamo detto nel capitolo 15, cambiare lo stile o gli aspetti di
presentazione di un una pagina web tramite JavaScript è sconsigliato, ed è preferibile applicare o rimuovere gli stili tramite CSS anziché cambiare gli attributi direttamente. Esistono
22 Java PpP.indd 402
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
403
molti metodi per lavorare con le classi di stili CSS utilizzando jQuery, fra cui .hasClass(),
.addClass(), .removeClass() e .toggleClass(). Visitate http://api.jquery.com/category/css/ per
ulteriori informazioni su come lavorare con le classi utilizzando queste e altre funzioni (le
informazioni sono in inglese).
Lavorare con gli attributi
Oltre alle funzioni di attributo correlate alle classi, jQuery dispone di funzioni per lavorare
con gli attributi del DOM. La più generica di queste è .attr(), sebbene anche altre, come
.html() e .val(), siano altrettanto utili. Questa sezione esamina la funzione .attr(), e lascia
.html(), .val() e altre funzioni alla sezione successiva.
La funzione .attr() si utilizza sia per recuperare sia per impostare attributi. Potete per esempio recuperare e impostare l’attributo alt di un’immagine utilizzando la seguente sintassi:
// Get the alt attribute:
$("#myImageID").attr("alt")
// Set the alt attribute:
$("#myImageID").attr("alt", "new text")
Nota Recuperare il valore dell'elemento prima di impostarlo non è necessario.
Modificare il testo e l’HTML
Potete riscrivere completamente una pagina utilizzando funzioni come .text() e .val(). Il fatto
che sia possibile farlo non significa che sia una buona idea, anche se potrebbe capitarvi di
dover riscrivere porzioni dell’HTML di una pagina oppure cambiare testo o valori.
La funzione .html() recupera o modifica l’intero HTML di un elemento selezionato.
Osservate per esempio questo HTML:
<div id="myDiv">Here is a div, it's quite nice</div>
Ed ecco il jQuery:
$("#myDiv").html('<span class="redStyle">This is the new content of the div</span>');
Il risultato di questa piccola porzione di jQuery è che il <div> identificato da myDiv ora
contiene un elemento <span> con il nuovo testo, come si vede nell’esempio di codice.
Questo esempio è piuttosto semplicistico, ma immaginate se <div> includesse un’intera
sezione di contenuto. Utilizzando jQuery, potete essenzialmente riscrivere l’intera sezione,
HTML e tutto il testo.
Come la funzione .html(), anche text() supporta sia il recupero sia l’impostazione del testo
in un elemento selezionato. Diversamente dall’HTML, la funzione .text() cambia solo il testo,
perciò non permette di modificare l’HTML nell’elemento selezionato.
22 Java PpP.indd 403
28/04/11 16:02
404
Parte V jQuery
<div id="myDiv">Here is a div, it's quite nice</div>
$("#myDiv").text('This is the new content of the div');
Nel precedente esempio è stato cambiato soltanto il testo; il codice non ha aggiunto alcuno
span o applicato stili.
Inserire elementi
Potete utilizzare con facilità jQuery per aggiungere elementi a una pagina. Due funzioni
principali per fare questo sono :after() e :before(). Come i loro nomi suggeriscono, esse aggiungono elementi rispettivamente dopo o prima di un elemento selezionato.
Ecco per esempio lo stesso div:
<div id="myDiv">Here is a div, it's quite nice</div>
Ed ecco il jQuery che inserisce un altro div prima di questo:
$("#myDiv").before("<div>This is a new div</div>");
La funzione :after() opera in modo simile:
$("#myDiv").after("<div>This is a new div, it appears after myDiv</div>");
Quando è eseguita, la pagina contenente questo codice avrà tre elementi <div>:
<div>This is a new div</div>
<div id="myDiv">Here is a div, it's quite nice</div>
<div>This is a new div, it appears after myDiv</div>
Gli esempi mostrati inseriscono elementi <div> aggiuntivi, ma naturalmente potreste utilizzare qualsiasi elemento valido in queste funzioni.
Funzioni callback
In alcuni casi dovrete eseguire una funzione quando un’altra funzione o parte di essa viene
completata, un costrutto chiamato funzione callback. Una funzione callback si esegue dopo
che la sua funzione padre è stata completata. jQuery utilizza molto le funzioni callback,
specialmente in AJAX. Avete già visto un esempio di funzione callback quando abbiamo
eseguito l’iterazione utilizzando la funzione .each().
Per ulteriori informazioni sulle funzioni callback, visitate http://docs.jquery.com/Tutorials:How_jQuery_Works (le informazioni sono in inglese).
Vedrete altri esempi di funzioni più avanti in questo capitolo. Per i programmatori
JavaScript di livello principiante o intermedio, è importante non pensare troppo alle funzioni callback. Sono semplicemente raggruppamenti di codice che vengono chiamati in un’altra funzione.
22 Java PpP.indd 404
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
405
Eventi
Finora abbiamo visto molti esempi di selettori e ci siamo limitati a scalfire la superficie delle funzioni di jQuery. La parte finale di questa introduzione a jQuery riguarda gli eventi.
Esattamente come la gestione degli eventi che avete già visto in JavaScript, jQuery permette ai vostri programmi di rispondere ai clic del mouse, agli invii dei form, alle digitazioni da
tastiera e altro. Diversamente da JavaScript, in jQuery la gestione degli eventi compatibile
con più browser è molto facile. jQuery convive perfettamente con un ambiente multibrowser. Questo è vero specialmente nella gestione degli eventi, che vi risparmia di dover
tentare di indovinare come ogni browser risponderà a determinate funzioni.
Associare e disassociare
La funzione .bind() associa un gestore di evento a un evento, come un clic del mouse:
.bind(event, data, handler)
In questo caso event è l’evento a cui volete rispondere, data è un oggetto opzionale contenente i dati da passare al gestore di evento e handler è la funzione che desiderate eseguire
in risposta all’evento.
Per esempio:
<a href="/link1.html" id="myLink">A link</a>
$("#myLink").bind("click", function() {
alert("clicked the link");
});
Il risultato di questo codice è che dopo l’intercettazione dell’evento click per il tag anchor,
la pagina mostra un avviso. Notate che questo esempio non utilizza il parametro opzionale
data nella chiamata di .bind().
Potete associare i seguenti eventi con la funzione .bind():
n
beforeunload
n
hover
n
mouseout
n
blur
n
keydown
n
mouseover
n
change
n
keypress
n
mouseup
n
click
n
keyup
n
resize
n
dblclick
n
load
n
scroll
n
error
n
mousedown
n
select
n
focus
n
mouseenter
n
submit
n
focusin
n
mouseleave
n
toggle
focusout
n
mousemove
n
unload
n
22 Java PpP.indd 405
28/04/11 16:02
406
Parte V
jQuery
Nei capitoli precedenti avete intercettato eventi utilizzando lo script ehandler.js sviluppato
nel capitolo 11, “Gli eventi di JavaScript e il browser”. Lo script ehandler.js era un gestore di
evento generico compatibile con più browser. La funzione .bind() di jQuery possiede la stessa capacità. La differenza è che la funzione .bind() di jQuery è molto migliore nella gestione
degli eventi compatibile con più browser e molto più potente dello script ehandler.js.
Sebbene possiate utilizzare .bind() per la gestione degli eventi, jQuery offre anche funzioni
scorciatoia che eseguono la stessa operazione di .bind(). Anziché scrivere .bind(“click”,function())… potete scrivere semplicemente .click(function()…. Potreste per esempio riscrivere il
precedente esempio di .bind() come segue:
$("#myLink").click(function() {
alert("clicked the link");
});
Non solo potete rispondere a eventi come il clic su un collegamento, ma potete anche attivare eventi. Osservate per esempio il codice del listato 22.5:
liSTaTO22.5 Rispondere a eventi.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Trigger Test</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
</head>
<body>
<div id="myDiv">
Here is some text.<br>
It goes inside this div<br>
</div>
<p>
<a id="braingiaLink" href="http://www.braingia.org">Steve Suehring</a>
</p>
<script type="text/javascript">
$(document).ready(function() {
$('#braingiaLink').click(function() {
alert("hello");
return true;
});
$('#myDiv').click(function() {
$('#braingiaLink').click();
});
});
</script>
</body>
</html>
22 Java PpP.indd 406
28/04/11 16:02
Capitolo 22
Introduzione a jQuery
407
Quando questa pagina viene caricata in un browser web, facendo clic ovunque nel <div> si
attiva l’evento click per l’anchor come se fosse stato fatto clic sull’anchor stesso.
Per smettere di rispondere agli eventi, potete disassociarli utilizzando la funzione .unbind(),
che accetta due argomenti:
.unbind(event, function)
L’argomento event è l’evento a cui desiderate smettere di rispondere, mentre l’argomento
function è la funzione attualmente associata all’evento.
Nota Potete associare più gestori di evento allo stesso evento chiamando .bind() più volte per
quell’evento.
Eventi del mouse e hover
Avete già visto come associare e gestire l’evento click nei precedenti esempi, ma potete
anche lavorare con gli eventi del mouse come mouseover e mouseout. Una cosa divertente
da fare è far scomparire gli elementi quando l’utente sposta il mouse su essi (questo però
genererà frustrazione negli utenti, perciò non fatelo su un sito live). Il listato 22.6 mostra il
codice che fa scomparire un anchorquando il mouse viene spostato sul paragrafo che lo
contiene.
liSTaTO22.6 Lavorare con gli eventi del mouse.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Trigger Test</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<style type="text/css">
#braingiaLink {
border: solid 1px black;
padding: 3px;
}
#wrapperP {
padding: 50px;
}
</style>
</head>
<body>
<div id="myDiv">
Here is some text.<br>
It goes inside this div<br>
</div>
<p id="wrapperP">
<a id="braingiaLink" href="http://www.braingia.org">Steve Suehring</a>
</p>
22 Java PpP.indd 407
28/04/11 16:02
408
Parte V
jQuery
<script type="text/javascript">
$(document).ready(function() {
$('#braingiaLink').click(function() {
alert("hello");
return true;
});
$('#myDiv').click(function() {
$('#braingiaLink').click();
});
$('#wrapperP').mouseover(function() {
$('#braingiaLink').hide();
});
$('#wrapperP').mouseout(function() {
$('#braingiaLink').show();
});
});
</script>
</body>
</html>
Gli elementi chiave di questo codice sono i gestori di evento .mouseover() e .mouseout(),
che a loro volta utilizzano due funzioni jQuery aggiuntive, .hide() e .show(). Gli eventi .mouseover() e .mouseout() sono connessi al paragrafo con l’ID wrapperP. Quando il mouse entra
in questo paragrafo, l’anchor identificato da braingiaLink scompare e riappare solo quando
il mouse esce dall’area del paragrafo. Non ha importanza il fatto che il collegamento può
anche essere attivato utilizzando la navigazione da tastiera. Tenete sempre presente che
per creare un determinato effetto su una pagina web esistono sempre più modi.
jQuery dispone della funzione .hover() che ha un effetto molto simile agli eventi .mouseover() e .mouseout(). Visitate http://api.jquery.com/hover/ per ulteriori informazioni sulla funzione .hover() (le informazioni sono in inglese).
Altri gestori di evento
Come l’elenco sopra mostra, jQuery dispone di molti altri gestori di evento, troppi per
essere trattati in un capitolo introduttivo su jQuery. Consiglio di consultare l’eccellente documentazione sugli eventi di jQuery disponibile all’indirizzo http://api.jquery.com/category/
events/ (le informazioni sono in inglese).
22 Java PpP.indd 408
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
409
AJAX e jQuery
I due capitoli precedenti hanno mostrato come scrivere e utilizzare il codice AJAX. Come
potreste aspettarvi dopo la lettura delle precedenti sezioni di questo capitolo, jQuery dispone di propri metodi per lavorare con AJAX. E analogamente ad altre attività correlate
a JavaScript, jQuery facilita anche l’utilizzo di AJAX. Questa sezione illustra come utilizzare
AJAX con jQuery.
jQuery offre molte funzioni per lavorare con i dati provenienti da un server e per inviare
dati a un server. Fra queste compaiono .load(), .post() e .get(). jQuery include anche una
funzione specifica di AJAX, chiamata appunto .ajax().
Con la funzione .ajax() potete impostare molti parametri, fra cui il metodo HTTP che la
chiamata dovrebbe utilizzare (GET o POST), il timeout e cosa fare quando si verifica un errore (e naturalmente anche quando il codice ha successo).
Ulteriori informazioni Visitate http://api.jquery.com/jQuery.ajax/ per un elenco completo
dei parametri disponibili per l’uso con la funzione ajax().
La sintassi di base della funzione ajax() è questa:
$.ajax({
parameter: value
});
Potete passare alla funzione .ajax() numerose coppie parametro: valore, ma tipicamente
specificherete il metodo, l’URL e la funzione callback. È comune anche specificare il tipo di
dati che deve essere restituito, se la risposta va messa in cache, i dati da passare al server e
cosa fare quando si verifica un errore.
Nota La funzione .ajaxSetup() vi permette di impostare valori predefiniti per i parametri correlati ad AJAX, come il caching, i metodi, la gestione degli errori e altri.
Ecco un esempio reale della funzione .ajax() in azione:
$.ajax({
url: "testajax.aspx",
success: function(data) {
alert("Successful load");
}
});
22 Java PpP.indd 409
28/04/11 16:02
410
Parte V jQuery
jQuery include anche una funzione chiamata .getJSON() che esegue essenzialmente la stessa operazione di altre funzioni correlate ad AJAX, ma lavora specificamente con dati con
codifica JSON provenienti dal server. La funzione .getJSON() equivale a chiamare la funzione .ajax() con l’aggiunta del parametro dataType: ‘json’.
Osservate per esempio questo elenco con codifica JSON che riporta alcuni stati:
["Wisconsin","California","Colorado","Illinois","Minnesota","Oregon","Washington","New
York","New Jersey","Nevada","Alabama","Tennessee","Iowa","Michigan"]
Per questo esempio immaginate che i dati con codifica JSON siano restituiti quando il file
json.php viene chiamato sul server locale. L’utilizzo seguente della funzione .ajax() recupera
i dati e chiama una funzione denominata showStates quando ha successo:
$.ajax({
type: "GET",
url: "json.php",
dataType: "json",
success: showStates
});
La funzione showStates crea un elenco e lo aggiunge alla casella a discesa <select> del
form.
Utilizzare AJAX con jQuery
Per completare questo esercizio avete bisogno di un file denominato json.php disponibile
nella stessa directory del file che utilizzerete nella procedura (potete trovare json.php fra i
file di esempio). Come gli esempi dei capitoli precedenti su AJAX, il file json.php deve risiedere nello stesso dominio del file che esegue la richiesta AJAX.
1. Modificate il file ajax.html (che potete trovare fra i file di esempio) utilizzando un
qualsiasi editor.
2. Nel file inserite il codice riportato in grassetto di seguito (potete trovare questo codice anche in ajax.txt fra i file di esempio), sostituendo il commento TODO:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/
strict.dtd">
<html>
<head>
<title>AJAX Test</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
22 Java PpP.indd 410
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
411
</head>
<body>
<div id="states">
</div>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "GET",
url: "json.php",
dataType: "json",
success: showStates
});
function showStates(data,status) {
$.each(data, function(item) {;
$("#states").append("<div>" + data[item] + "</div>");
});
}
});
</script>
</body>
</html>
3. Salvate il file e visualizzatelo in un browser web. Vedrete un elenco di stati, come il
seguente:
22 Java PpP.indd 411
28/04/11 16:02
412
Parte V jQuery
Errori e timeout AJAX
La funzione .ajax() vi permette di gestire con grazia gli errori e i timeout. Oltre al gestore
del caso di successo, potete specificare un gestore di errore con il parametro error. Il valore
del parametro error è di solito una funzione callback. Ecco un esempio, con il nuovo parametro error in grassetto:
$.ajax({
type: "GET",
url: "json.php",
dataType: "json",
success: successFunction,
error: errorFunction
});
La funzione callback utilizzata per la gestione degli errori (errorFunction nel precedente
esempio di codice) riceve tre argomenti: l’oggetto XMLHTTPRequest, una stringa che rappresenta l’errore che si è verificato e un oggetto exception se si è verificata un’eccezione.
Perciò una funzione di gestione errori dovrebbe accettare questi tre argomenti e poi fare
qualcosa con i risultati. Questo esempio mostra un avviso:
function errorFunction(xhr, statusMessage, exceptionObj) {
alert("An error was encountered " + statusMessage);
}
Potrebbe essere necessario impostare un timeout per una richiesta AJAX. Potete impostare
un valore di timeout AJAX generico tramite il valore predefinito $.ajaxSetup, ma potete anche specificare un valore di timeout per qualsiasi singola chiamata utilizzando il parametro
timeout. Ecco un esempio:
$.ajax({
type: "GET",
url: "json.php",
dataType: "json",
success: successFunction,
error: errorFunction,
timeout: 5000
});
È importante sapere che il timeout è espresso in millisecondi. Perciò l’esempio mostrato
imposta il timeout a su secondi.
Inviare dati al server
Non solo avrete bisogno di ricevere dati da un server in una chiamata AJAX, ma anche di
inviare dati a un server e ricevere una risposta. Per questo si usa il parametro data della funzione .ajax(), inviando dati tramite GET o POST.
22 Java PpP.indd 412
28/04/11 16:02
Capitolo 22 Introduzione a jQuery
413
Potete formattare i dati come coppie chiave=valore separate dal carattere & (chiave1=valo
re1&chiave2=valore2) o come coppie mappate {chiave1: valore1, chiave2: valore2}. Questo
esempio utilizza l’opzione chiave=valore, chiamata anche opzione della stringa di query.
Questo esempio chiama un programma lato-server denominato statefull.php che, data
un’abbreviazione di due lettere dello stato, restituisce il nome completo dello stato.
$.ajax({
type: "POST",
url: "statefull.php",
dataType: "json",
success: successFunction,
data: "state=WI"
});
Altre opzioni importanti
La funzione .ajax() presenta numerose opzioni. Avete già visto come utilizzare molti di esse,
ma vorrei descriverne altre due:
n
async
n
cache
L’opzione async, che è true per impostazione predefinita, informa lo script se deve attendere (e blocca l’ulteriore input nel browser) mentre la transazione AJAX è inviata, ricevuta ed
elaborata. Quando è impostata a true, la transazione AJAX viene eseguita in modo asincrono, affinché non si blocchi.
L’impostazione cache, che assume per impostazione predefinita il valore true nella maggior
parte dei casi, controlla se jQuery metterà in cache la transazione AJAX. Questo è utile
quando i dati ricevuti non cambiano spesso, perché caching accelera la transazione, ma il
caching può causare problemi quando l’applicazione utilizza i vecchi dati in cache che sono
cambiati sul server. Ho scoperto che è utile impostare questa opzione su false in modo
che la risposta non venga messa in cache, specialmente nei casi in cui incontrate problemi
quando i dati in apparenza non vengono aggiornati.
Altro codice jQuery
Finora avete visto solo una piccola parte di ciò che jQuery può fare. Continuando nell’apprendimento di JavaScript e di come può essere utile per attivare i vostri siti web, prendete
in considerazione l’utilizzo di jQuery o di un’altra libreria JavaScript come aiuto per il lavoro
di sviluppo.
Per ulteriori informazioni su jQuery, materiali per l’apprendimento e di riferimento, consultate
le risorse all’indirizzo http://www.jquery.com (le informazioni sono in inglese).
22 Java PpP.indd 413
28/04/11 16:02
414
Parte V jQuery
Esercizi
1. Utilizzando come base il codice in ajax.html (dell’esercizio “Utilizzare Ajax con jQuery”), aggiungete uno stile CSS per far diventare blu il colore di sfondo del singolo
<div> dello stato quando il mouse passa su uno degli stati dell’elenco. Vi do un indizio: è possibile farlo in vari modi.
2. Create un programma lato-server per restituire dati quando passate parametri utilizzando la funzione $.ajax(). Elaborate questi dati in qualche modo, utilizzando un
avviso o scrivendo sulla pagina. Potreste per esempio implementare un programma
lato-server per restituire la somma di due numeri o, come l’esempio mostrato, restituire il nome completo dello stato se il programma riceve l’abbreviazione dello stato.
22 Java PpP.indd 414
28/04/11 16:02
Capitolo 23
Effetti e plug-in di jQuery
Dopo aver letto questo capitolo, sarete in grado di:
n
Comprendere e utilizzare gli effetti jQuery nativi.
n
Comprendere jQuery UI.
n
Utilizzare jQuery UI.
Funzionalità centrali per migliorare l’usabilità
Effetti e miglioramenti dell’usabilità come drag-and-drop, dissolvenza degli elementi in
ingresso e in uscita e scorrimento degli elementi sono facili da implementare con l’aiuto di
jQuery. E se queste funzionalità non sono sufficienti per farvi amare il prodotto, sappiate
che jQuery è estendibile e gode di un ampio supporto da parte della comunità.
Fra le funzionalità a cui la comunità di jQuery contribuisce ci sono i plug-in. I plug-in di
jQuery forniscono funzionalità aggiuntive non incluse nel pacchetto jQuery principale.
Potete ottenere ulteriori informazioni sui plug-in e un elenco di quelli disponibili attualmente sul sito web jQuery Plugins, all’indirizzo http://plugins.jquery.com/ (le informazioni
sono in inglese).
Questo capitolo fornisce una panoramica di alcuni effetti inclusi nel prodotto principale
jQuery oltre che in jQuery UI.
Effetti nativi
Come abbiamo detto nell’introduzione a questo capitolo, jQuery include varie funzioni che
possono migliorare l’usabilità dell’applicazione web, come mostrare e nascondere gli elementi e dissolvere gli elementi in ingresso e in uscita. Questa sezione esamina alcuni degli
effetti nativi inclusi in jQuery. Al momento della stesura del presente testo jQuery e jQuery
UI sono in fase di aggiornamento per poter funzionare con Windows Internet Explorer 9,
perciò alcuni degli esempi mostrati in questo capitolo non funzioneranno con la beta corrente di Internet Explorer 9. Ci sono tuttavia buone probabilità che, per quando leggerete
questo capitolo, jQuery e jQuery UI saranno stati aggiornati e Internet Explorer 9 rilasciato.
Mostrare, nascondere e alternare
Le funzioni .show() e .hide() mostrano e nascondono rispettivamente gli elementi sulla
pagina. Queste funzioni impostano la proprietà display di Cascading Style Sheets (CSS).
Per nascondere un elemento, dovete impostare la proprietà display a none. Notate che
23 Java PpP.indd 415
415
28/04/11 16:02
416
Parte V
jQuery
impostando display a none non si rimuove l’elemento dal DOM, perciò potete comunque
mostrare l’elemento utilizzando la funzione .show(). Il listato 23.1 riporta un esempio della
funzione .hide().
LISTaTO23.1 Nascondere un elemento.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Hide</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<style type="text/css">
.removeBtn {
color: #0000CC;
}
</style>
</head>
<body>
<ul>
<li id="option1">Option 1 <span class="removeBtn" id="remove1">(x)</span></li>
<li id="option2">Option 2 <span class="removeBtn" id="remove2">(x)</span></li>
<li id="option3">Option 3 <span class="removeBtn" id="remove3">(x)</span></li>
<li id="option4">Option 4 <span class="removeBtn" id="remove4">(x)</span></li>
</ul>
<script type="text/javascript">
$(document).ready(function() {
$('#option1').click(function()
$('#option1').hide();
});
$('#option2').click(function()
$('#option2').hide();
});
$('#option3').click(function()
$('#option3').hide();
});
$('#option4').click(function()
$('#option4').hide();
});
{
{
{
{
});
</script>
</body>
</html>
Sfortunatamente l’esempio del listato 23.1 non è molto ottimizzato perché richiede l’aggiunta della gestione per ogni elemento individualmente (non aspettatevi di vedere questo
tipo di programmazione in un programma in produzione live, tuttavia è utile per scopi
illustrativi). Una soluzione migliore è gestire le opzioni utilizzando le loro funzioni. Il listato
23.2 mostra un modo migliore per ottenere la stessa funzionalità utilizzando jQuery e senza specificare le opzioni nel codice.
23 Java PpP.indd 416
28/04/11 16:02
Capitolo 23
Effetti e plug-in di jQuery
417
LISTaTO23.2 Nascondere un elemento: tecnica migliorata con jQuery.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Hide</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<style type="text/css">
.removeBtn {
color: #0000CC;
}
</style>
</head>
<body>
<ul>
<li id="option1">Option 1 <span class="removeBtn" id="remove1">(x)</span></li>
<li id="option2">Option 2 <span class="removeBtn" id="remove2">(x)</span></li>
<li id="option3">Option 3 <span class="removeBtn" id="remove3">(x)</span></li>
<li id="option4">Option 4 <span class="removeBtn" id="remove4">(x)</span></li>
</ul>
<script type="text/javascript">
$(document).ready(function() {
$('.removeBtn').each(function(elm) {
$(this).click(function() {
$(this).parent().hide();
});
});
});
</script>
</body>
</html>
L’unica differenza nel codice del listato 23.2 è all’interno del JavaScript:
$('.removeBtn').each(function() {
$(this).click(function() {
$(this).parent().hide();
});
});
Questo JavaScript applica una funzione a ogni elemento con la classe removeBtn che imposta l’evento click su quell’elemento. Chiama la funzione .hide() ma poiché, quando l’evento
si attiva, $(this) referenzia l’elemento removeBtn (in questo caso l’elemento <span>), dovete
percorrere la gerarchia verso l’alto per trovare il nodo padre, che in questo caso è il <li>.
La funzione .toggle() mostra o nasconde un elemento in base al suo stato corrente. Quando
per esempio un elemento è attualmente visibile, chiamando .toggle() lo si nasconde.
Analogamente, quando un elemento è nascosto, diventa visibile se chiamate .toggle().
23 Java PpP.indd 417
28/04/11 16:02
418
Parte V jQuery
Tutte e tre le funzioni .show(), .hide() e .toggle() accettano due argomenti: una durata e una
funzione callback. Nel codice dei listati 23.1 e 23.2 notate che, quando l’elemento viene nascosto, scompare istantaneamente. Aggiungendo una durata alla funzione .hide(), l’elemento scompare alla velocità specificata. Come altre funzioni di jQuery, la durata è specificata
in millisecondi. In alternativa potete utilizzare le stringhe “fast” e “slow”, che rappresentano
rispettivamente 200 e 600 millisecondi.
La funzione callback esegue un’azione dopo che la procedura di mostrare o nascondere
l’elemento è stata completata. Un possibile utilizzo del callback è per visualizzare un pulsante Undo dopo che un elemento è stato nascosto per consentire agli utenti di rivisualizzare l’elemento che hanno appena nascosto.
Aggiungere una durata
1. Utilizzando un editor come Microsoft Visual Studio, Eclipse o altro, aprite il file
duration.html, che potete trovare nella cartella Chapter23 fra i file di esempio.
2. Nel file aggiungete il codice riportato in grassetto di seguito:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Hide</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<style type="text/css">
.removeBtn {
color: #0000CC;
}
</style>
</head>
<body>
<ul>
<li id="option1">Option 1 <span class="removeBtn" id="remove1">(x)</span></li>
<li id="option2">Option 2 <span class="removeBtn" id="remove2">(x)</span></li>
<li id="option3">Option 3 <span class="removeBtn" id="remove3">(x)</span></li>
<li id="option4">Option 4 <span class="removeBtn" id="remove4">(x)</span></li>
</ul>
<script type="text/javascript">
$(document).ready(function() {
$('.removeBtn').each(function(elm) {
$(this).click(function() {
$(this).parent().hide(500);
});
});
});
</script>
</body>
</html>
23 Java PpP.indd 418
28/04/11 16:02
Capitolo 23 Effetti e plug-in di jQuery
419
3. Salvate il file e visualizzate la pagina in un browser web. Dovreste vedere una pagina
come questa:
4. Ora fate clic sulla (x) accanto a uno qualsiasi degli elementi. L’elemento scompare dalla pagina e viene visualizzata una pagina come questa:
5. Se state utilizzando un browser con un debugger, come Firefox con Firebug, potete
fare clic destro su una delle altre opzioni e scegliere Inspect Element per vedere che la
proprietà display è stata impostata su none per l’elemento nascosto.
Dissolvenza in entrata e in uscita
Aggiungendo una durata alle funzioni .show(), .hide() e .toggle(), l’opacità dell’elemento
cambia fino a quando non è completamente visualizzato o nascosto. Funzionalità simili
sono disponibili tramite le funzioni .fadeIn() e .fadeOut(). Visitate http://api.jquery.com/category/effects/fading/ per ulteriori informazioni su queste funzioni e sulla funzione .fadeTo();
le informazioni sono in inglese.
23 Java PpP.indd 419
28/04/11 16:02
420
Parte V jQuery
Scorrimento
Un altro metodo per impostare la proprietà display su none è utilizzare le funzioni .slideUp()
e .slideDown(). Queste funzioni creano un effetto scorrimento che fa sembrare che l’elemento di sposti prima di scomparire o prima di apparire. Utilizzate la funzione .slideUp() per
far scomparire un elemento e .slideDown() per farlo riapparire.
Il codice che avete visto in precedenza nel capitolo, modificato in modo che utilizzi .slideUp() anziché hide, si presenta come segue:
$('.removeBtn').each(function(elm) {
$(this).click(function() {
$(this).parent().slideUp();
});
});
Nota Non lasciatevi ingannare pensando di poter scegliere in che modo far scorrere l'elemento, verso l'alto o verso il basso, a seconda del nome delle funzioni. La funzione .slideUp() fa
sempre scomparire gli elementi, mentre .slideDown() li fa sempre apparire.
jQuery UI
jQuery UI si basa su jQuery e fornisce funzionalità estese legate all’interfaccia utente. Molti
componenti di jQuery UI forniscono specifici widget o azioni, fra cui un selettore di data,
una funzionalità accordion e il completamento automatico. Questa sezione esamina alcuni
dei widget di jQuery UI.
Ulteriori informazioni Visitate http://jqueryui.com/ per ulteriori informazioni su tutti i
widget disponibili per jQuery UI (le informazioni sono in inglese).
Utilizzare jQuery UI
jQuery UI richiede di includere un file JavaScript separato nel codice. Potete ottenere questo file da http://jqueryui.com/, da dove potete scaricare la release completa e stabile o
creare un download personalizzato con i soli componenti di cui avete bisogno per il sito.
Questo capitolo utilizza la release completa di jQuery UI, ma per la maggior parte dei siti
consiglio di personalizzare il download di jQuery UI in base alle esigenze, includendo soltanto i componenti specifici necessari per gli effetti che volete applicare al sito.
23 Java PpP.indd 420
28/04/11 16:02
Capitolo 23
Effetti e plug-in di jQuery
421
Il download di jQuery UI è un file zip contenente sia il core di jQuery sia il core di jQuery UI
con i file CSS correlati a jQuery UI. Occorre decomprimere il file in una posizione adeguata
per renderlo disponibile per il server web, come la directory httpdocs o public_html. In sostanza i file devono trovarsi nella stessa posizione del resto del JavaScript e dell’HTML con
cui avete lavorato in questo libro.
Nota L’utilizzo delle funzioni di jQuery UI potrebbe comportare implicazioni a livello di accessibilità a meno che forniate un mezzo alternativo per eseguire la stessa funzione.
Drag-and-drop
jQuery UI include funzioni per spostare gli elementi tramite il drag-and-drop: si tratta di
.draggable() e .droppable().
Chiamando .draggable() gli utenti possono utilizzare il mouse per spostare un elemento
sulla pagina.
Considerate il codice del listato 23.3.
LISTaTO23.3 La funzione .draggable() in azione.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Drag</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.4.custom.min.js"></script>
<style type="text/css">
#container span {
border: solid 1px black;
padding: 3px;
}
</style>
</head>
<body>
<div id="container">
<span>Drag me around</span>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#container > span').draggable();
});
</script>
</body>
</html>
23 Java PpP.indd 421
28/04/11 16:02
422
Parte V
jQuery
Questo codice imposta un elemento <p> che poi può essere trascinato con la chiamata della funzione .draggable():
$('#container > span').draggable();
Nota Il codice del listato 23.3 si basa sul presupposto che abbiate scaricato jQuery e che i file
jQuery UI siano presenti nella directory di lavoro corrente, la stessa directory in cui risiede l'HTML del listato 23.3. Il codice di jQuery UI viene quindi caricato da una subdirectory js/.
Provate a eseguire il codice del listato 23.3 in un browser. Vedrete che è possibile fare clic e
trascinare l’elemento spostandolo.
Potete utilizzare la funzione .droppable() insieme a .draggable() per creare un target per un
elemento trascinato, al fine di consentire a qualcuno di utilizzare un’operazione di dragand-drop per lavorare con gli elementi visivamente sullo schermo. Il listato 23.4 è espanso
sull’esempio di .draggable() del listato 23.3 per fornire un <div> come target di rilascio:
LISTaTO23.4 La funzione .droppable() in azione.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Drop</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.4.custom.min.js"></script>
<style type="text/css">
#container span {
border: solid 1px black;
padding: 3px;
}
#targetContainer {
height: 200px;
width: 200px;
border: solid 1px black;
background-color: #abacab;
margin: 50px;
}
</style>
</head>
<body>
<div id="container">
<span>Drag me and drop me</span>
</div>
<div id="targetContainer">
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#container > span').draggable();
23 Java PpP.indd 422
28/04/11 16:02
Capitolo 23
Effetti e plug-in di jQuery
423
$('#targetContainer').droppable({
drop: function(event,ui) {
alert("Dropped Element: " + ui.draggable.text());
}
});
});
</script>
</body>
</html>
La chiave di questo codice è l’utilizzo della funzione .droppable() impostata sul <div> con
l’ID targetContainer:
$('#targetContainer').droppable({
drop: function(event,ui) {
alert("Dropped Element: " + ui.draggable.text());
}
});
La funzione .droppable() gestisce numerosi eventi, permettendovi di rispondere quando un
elemento è trascinato sopra l’elemento di rilascio (over), all’esterno dell’elemento di rilascio
(out), è rilasciato (drop, mostrato nell’esempio) e quando un elemento draggable valido è
selezionato o deselezionato (activate e deactivate). Visitate http://jqueryui.com/demos/droppable/ per vedere esempi di questi eventi.
Accordion
Creare un effetto accordion, in cui le opzioni sembrano arrotolarsi e srotolarsi, è possibile
utilizzando jQuery UI. La chiave per ottenere un accordion che funziona correttamente è
utilizzare HTML ben formato e un layout adeguato. Un buon candidato per un accordion è
un gruppo di voci o opzioni simili.
Il listato 23.5 riporta l’HTML e il JavaScript per creare un semplice accordion.
23 Java PpP.indd 423
28/04/11 16:02
424
Parte V
jQuery
LISTaTO23.5 Un accordion jQuery.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Accordion</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.4.custom.min.js"></script>
<style type="text/css">
#container {
border: solid 1px black;
padding: 3px;
}
.optionHead {
border: solid 1px black;
background-color: #abacab;
}
.optionDiv {
border-bottom: dotted 1px black;
}
</style>
</head>
<body>
<div id="container">
<h3 class="optionHead">Option 1</h3>
<div class="optionDiv" id="option1">
<p>Text of option 1</p>
</div>
<h3 class="optionHead">Option 2</h3>
<div class="optionDiv" id="option2">
<p>Text of option 2</p>
</div>
<h3 class="optionHead">Option 3</h3>
<div class="optionDiv" id="option3">
<p>Text of option 3</p>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#container').accordion();
});
</script>
</body>
</html>
23 Java PpP.indd 424
28/04/11 16:02
Capitolo 23 Effetti e plug-in di jQuery
425
Caricando il codice del listato 23.5 in un browser web si ottiene una pagina simile a quella
nella figura 23.1.
Figura 23.1 Un semplice accordion jQuery.
Utilizzando un accordion jQuery, noterete che la prima opzione è sempre espansa al caricamento della pagina. A seconda delle esigenze di layout e di come l’accordion è utilizzato,
potreste scoprire che sarebbe preferibile espandere un’altra opzione al caricamento della
pagina o avere tutte le opzioni compresse. La funzione .accordion() include molte opzioni che controllano il suo comportamento. L’opzione active, quando è utilizzata insieme a
collapsible true, avvia l’accordion in uno stato compresso o con una determinata opzione
selezionata.
Nel successivo esercizio vedrete un accordion in una pagina web e imposterete uno stato
predefinito per l’accordion.
Impostare lo stato predefinito per un accordion
1. Aprite il file accordion.html utilizzando un editor come Microsoft Visual Studio o
Eclipse (potete trovare questo file fra i file di esempio).
2. In accordion.html aggiungete il codice riportato in grassetto di seguito:
23 Java PpP.indd 425
28/04/11 16:02
426
Parte V jQuery
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Accordion</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.4.custom.min.js"></script>
<style type="text/css">
#container {
border: solid 1px black;
padding: 3px;
}
.optionHead {
border: solid 1px black;
background-color: #abacab;
}
.optionDiv {
border-bottom: dotted 1px black;
}
</style>
</head>
<body>
<div id="container">
<h3 class="optionHead">Option 1</h3>
<div class="optionDiv" id="option1">
<p>Text of option 1</p>
</div>
<h3 class="optionHead">Option 2</h3>
<div class="optionDiv" id="option2">
<p>Text of option 2</p>
</div>
<h3 class="optionHead">Option 3</h3>
<div class="optionDiv" id="option3">
<p>Text of option 2</p>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#container').accordion({
collapsible: true,
active: false
});
});
</script>
</body>
</html>
23 Java PpP.indd 426
28/04/11 16:02
Capitolo 23 Effetti e plug-in di jQuery
427
3. Salvate il file e visualizzate la pagina in un browser. Notate che l’accordion è avviato in
forma compressa, come si vede nella figura che segue:
4. Cambiate l’opzione active su 2 anziché false. Il codice dovrebbe presentarsi come
segue:
$('#container').accordion({
collapsible: true,
active: 2
});
5. Ricaricate la pagina nel browser. Notate che la terza opzione sullo schermo è espansa.
Questo si verifica perché l’indice inizia con 0, rendendo perciò l’indice della prima opzione (Option 1 sullo schermo) pari a 0.
Visitate http://jqueryui.com/demos/accordion/ per ulteriori informazioni sulle opzioni e gli
eventi disponibili per il widget accordion (le informazioni sono in inglese).
Ulteriori informazioni su jQuery UI
jQuery UI è un argomento infinitamente più complesso di quanto sia stato possibile trattare
qui, che include sofisticate capacità di applicazione di temi CSS con le quali potete scegliere
le combinazioni di colori per gli effetti e i widget utilizzati in jQuery UI. Su jQuery UI sono
stati scritti interi libri. Visitate http://jqueryui.com/themeroller/ per ulteriori informazioni sui
temi CSS e jQuery UI (le informazioni sono in inglese). Visitate anche http://jqueryui.com per
ulteriori informazioni e tutorial su jQuery UI (le informazioni sono in inglese).
23 Java PpP.indd 427
28/04/11 16:02
428
Parte V jQuery
Esercizi
1. Utilizzando il codice del listato 23.2 come base, aggiungere un collegamento o un
pulsante che ripristina tutte le opzioni utilizzando la funzione .show().
2. Applicando ciò che avete imparato in questo e nei capitoli precedenti, create un accordion jQuery che include opzioni create dinamicamente caricate attraverso AJAX.
23 Java PpP.indd 428
28/04/11 16:02
Appendice
Soluzioni degli esercizi
Questa appendice riporta le soluzioni e le spiegazioni degli esercizi proposti nel libro. In
molti casi esistono più modi per risolvere un problema, perciò, se la domanda non richiede
di utilizzare un determinato modo per risolvere il problema, qualsiasi implementazione funzionante è accettabile. I nomi delle vostre funzioni possono essere diversi da quelli presenti
in questa appendice.
Capitolo 1
1. Falso. Sebbene JavaScript sia definito da un ente per gli standard, ECMA International,
non è supportato su tutti i browser web. Inoltre il supporto esistente varia (a volte
ampiamente) da un browser all’altro.
2. Falso. Ci sono molte ragioni per cui un visitatore del vostro sito web potrebbe avere JavaScript disattivato. Il browser del visitatore potrebbe non supportarlo, nel
computer potrebbero essere installati software speciali che non lo supportano o
disattivare JavaScript potrebbe essere semplicemente una preferenza del visitatore.
Dovreste fare in modo che il vostro sito funzioni anche senza JavaScript o almeno fare
in modo che fallisca con grazia per i visitatori che non hanno JavaScript abilitato.
3. Un tipico blocco di definizione di JavaScript si presenta come segue:
<script type="text/javascript">
// JavaScript code goes here
</script>
4. Falso. La versione di JavaScript non è inserita nella definizione DOCTYPE. In effetti è
piuttosto insolito dichiarare la versione di JavaScript in uso.
5. Vero. Il codice JavaScript può apparire sia nell’head sia nel body di un documento
Hypertext Markup Language (HTML).
24 Java PpP.indd 429
429
28/04/11 16:03
430
Soluzioni degli esercizi
Capitolo 2
1. Il codice di mysecondpage.htm è simile a questo, anche se il vostro potrebbe differire
leggermente (e naturalmente conterrà il vostro nome anziché il mio!):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>My Second Page</title>
<script type="text/javascript">
alert("Steve Suehring");
</script>
</head>
<body>
<p>My Second Page</p>
</body>
</html>
2. Ecco il nuovo codice, con le modifiche riportate in grassetto:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>My Second Page</title>
<script type="text/javascript">
function callAlert() {
alert("Steve Suehring");
}
</script>
</head>
<body>
<script type="text/javascript">
callAlert();
</script>
<p>My Second Page</p>
</body>
</html>
3. Ho creato un file denominato 3.htm e un file denominato 3.js, mostrati di seguito (il
riferimento in 3.htm a 3.js è riportato in grassetto).
3.js:
function callAlert() {
alert("Steve Suehring");
}
3.htm:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
24 Java PpP.indd 430
28/04/11 16:03
 Soluzioni degli esercizi
431
<head>
<title>My Second Page</title>
<script type="text/javascript" src="3.js"> </script>
</head>
<body>
<script type="text/javascript">
callAlert();
</script>
<p>My Second Page</p>
</body>
</html>
Capitolo 3
1. Le istruzioni valide sono a, b, c, d. L’unica istruzione non valida è la e, perché utilizza
una parola riservata, case, come nome di variabile.
2. Falso. Non tutte le istruzioni JavaScript richiedono un punto e virgola finale. In effetti
il punto e virgola di solito è opzionale.
3. La variabile orderTotal è modificata dopo che il visitatore è avvisato della quantità ordinata per ogni articolo ma prima che il valore sia restituito dalla funzione. Questo vi
insegna che dovete fare attenzione a non alterare il valore o il contenuto delle variabili inavvertitamente. Il visitatore si aspetta di ordinare una determinata quantità, ma
il codice cambia quella quantità dopo aver mostrato il numero al visitatore!
Capitolo 4
1. Dichiarazioni di variabili:
var first = 120;
var second = "5150";
var third = "Two Hundred Thirty";
2. Array (i vostri valori sono probabilmente diversi, ma la parte importante sono i tipi di
dati e la sintassi):
var newArray = new Array(10, 20, 30, "first string", "second string");
3. Stringa con escape:
alert("Steve's response was \"Cool!\"");
4. La risposta a questo esercizio sta al lettore: non esiste una soluzione giusta o
sbagliata.
24 Java PpP.indd 431
28/04/11 16:03
432
Soluzioni degli esercizi
Capitolo 5
1. Array (i vostri valori sono probabilmente diversi, ma la parte importante sono i tipi di
dati e la sintassi):
var num1 = 1;
var num2 = 1;
var num3 = 19;
var fourthvar = "84";
var name1 = "Jakob";
var name2 = "Edward";
alert(num1 + num2);
alert(num3 + fourthvar);
alert(name1 + name2);
2. Postfisso:
var theNum = 1;
alert(theNum);
alert(theNum++);
alert(theNum);
Prefisso:
var theNum = 1;
alert(theNum);
alert(++theNum);
alert(theNum);
3. Codice:
var num1 = 1;
var num2 = 1;
var num3 = 19;
var fourthvar = "84";
var name1 = "Jakob";
var name2 = "Edward";
alert(typeof num1);
alert(typeof num2);
alert(typeof num3);
alert(typeof fourthvar);
alert(typeof name1);
alert(typeof name2);
Dovrebbero essere visualizzati tre avvisi con la parola number seguiti da altri tre con
la parola string.
4. Falso. Gli operatori unari appaiono piuttosto spesso in JavaScript, specialmente nei
loop for che incrementano una variabile utilizzando l’operatore ++ postfisso.
5. Falso. Sebbene risparmiare byte sia utile, specialmente per le applicazioni web, è quasi
sempre preferibile spendere questi stessi byte per rendere il codice leggibile e facile
da mantenere. Comunque è una questione di stile personale e di standard di scrittura
del codice. In uno dei capitoli successivi apprenderete jQuery. La tipica versione “minimizzata” di questa libreria è un esempio di estremizzazione del risparmio di byte.
24 Java PpP.indd 432
28/04/11 16:03
 Soluzioni degli esercizi
433
Capitolo 6
1. Sostituite YOUR NAME nel seguente codice con il contenuto appropriato:
var inputName = prompt("Please enter your name:");
switch(inputName) {
case "YOUR NAME":
alert("Welcome " + inputName);
break;
case "Steve":
alert("Go Away");
break;
default:
alert("Please Come Back Later " + inputName);
}
2. Ecco il codice:
var temp = prompt("Please enter the current temperature");
if (temp > 100) {
alert("Please cool down");
} else if (temp < 20) {
alert("Better warm up");
}
Notate che sarebbe una buona idea fornire un’azione predefinita nel caso la temperatura fosse fra 20 e 100!
3. Questo esercizio è impossibile da eseguire nel modo indicato.
Poiché gli operatori ternari si aspettano una singola condizione di test e l’esercizio 2
richiede due condizioni, un operatore ternario non può essere utilizzato per eseguire
esattamente la stessa attività. Il codice che segue crea un avviso che dice al visitatore
di raffreddare quando la temperatura è maggiore di 100 e scaldare quando è minore
o uguale a 100:
var temp = prompt("Please enter the current temperature");
temp > 100 ? alert("Please cool down") : alert("Better warm up");
4. Ecco il codice:
for (var i = 1; i < 101; i++) {
if (i == 99) {
alert("The number is " + i);
}
}
Notate che poiché la variabile i ha iniziato il conteggio da 1 (come richiede l’esercizio),
il contatore deve arrivare a 101 per soddisfare il requisito di contare da 1 a 100.
5. Ecco il codice:
var i = 1;
while (i < 101) {
if (i == 99) {
alert("The number is " + i);
24 Java PpP.indd 433
28/04/11 16:03
434
Soluzioni degli esercizi
}
i++;
}
Notate il posizionamento dell’incremento postfisso della variabile i nel loop. Potreste
anche utilizzare i=i+1, ma l’operatore postfisso è preferibile.
Capitolo 7
1. È importante notare che questo codice utilizza la funzione isNaN per controllare se
l’input è un numero. Questa è una best practice che potrebbe non essere sempre
ovvia. Un altro modo per ottenere il valore return finale qui è utilizzare invece return
theNumber++; come return finale, come mostrato. Ecco il codice:
<head>
<title>Chapter 7 Exercise 1</title>
<script type = "text/javascript" >
function incrementNum(theNumber) {
if (isNaN(theNumber)) {
alert("Sorry, " + theNumber + " isn't a number.");
return;
}
return theNumber + 1;
}
</script>
</head>
<body>
<script type = "text/javascript" >
alert(incrementNum(3));
</script>
</body>
2. Ecco il codice:
function addNums(firstNum,secondNum) {
if ((isNaN(firstNum)) || (isNaN(secondNum))) {
alert("Sorry, both arguments must be numbers.");
return;
}
else if (firstNum > secondNum) {
alert(firstNum + " is greater than " + secondNum);
}
else {
return firstNum + secondNum;
}
}
3. Questo esercizio intende dimostrare alcuni problemi relativi all’area di validità delle
variabili. Notate che il valore della variabile result cambia all’esterno della funzione,
sebbene il cambiamento sia eseguito soltanto all’interno della funzione. Le due posizioni per gli alert sono mostrate in grassetto nel seguente codice:
24 Java PpP.indd 434
28/04/11 16:03
 Soluzioni degli esercizi
435
function addNumbers() {
firstNum = 4;
secondNum = 8;
result = firstNum + secondNum;
return result;
}
result = 0;
alert(result);
result = addNumbers();
alert(result);
4. Ecco il codice:
<head>
<title>Chapter 7 Exercise 4</title>
<script type="text/javascript">
var stars = ["Polaris","Aldebaran","Deneb","Vega","Altair","Dubhe","Regulus"];
var constells = ["Ursa Minor","Taurus","Cygnus","Lyra","Aquila","Ursa Major","Leo"];
function searchStars(star) {
var starLength = stars.length;
for (var i = 0; i < starLength; i++) {
if (stars[i] == star) {
return constells[i];
}
}
return star + " Not Found.";
}
</script>
</head>
<body>
<script type = "text/javascript" >
var inputStar = prompt("Enter star name: ");
alert(searchStars(inputStar));
</script>
<p>Stars</p>
</body>
Capitolo 8
1. Ecco il codice:
var star = ["Polaris", "Deneb", "Vega", "Altair"];
var starLength = star.length;
for (var i = 0; i < starLength; i++) {
alert(star[i]);
}
2. Un modo è questo:
function Song(artist,length,title) {
this.artist = artist;
this.length = length;
this.title = title;
24 Java PpP.indd 435
28/04/11 16:03
436
Soluzioni degli esercizi
}
song1 = new Song("First Artist","3:30","First Song Title");
song2 = new Song("Second Artist","4:11","Second Song Title");
song3 = new Song("Third Artist","2:12","Third Song Title");
3. Presupponendo che stiate utilizzando il codice dato nell’esercizio, questo codice nel
body concatenerebbe tutti i nomi in una sola lunga stringa, come segue:
var names = new Array;
for (var propt in star) {
names += propt;
}
alert(names);
Il codice per delimitare i nomi con la virgola sarebbe questo:
var names = new Array;
for (var propt in star) {
if (names != "") {
names += "," + propt;
} else {
names = propt;
}
}
alert(names);
Capitolo 9
1. Ecco il codice:
if (screen.availHeight < 768) {
alert("Available Height: " + screen.availHeight);
}
if (screen.availWidth < 1024) {
alert("Available Width: " + screen.availWidth);
}
2. Qui è riportato il codice completo, incluso quello dell’esercizio, e il codice aggiuntivo
per questo esercizio è in grassetto. Notate l’utilizzo della funzione unescape() per rimuovere il carattere con codifica URL %20 (spazio) dal nome del paese. Questo è necessario perché il nome del paese “Great Britain” specificato in questo esercizio deve
avere l’escape dell’URL per le richieste HTTP GET.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Location, Location, Location</title>
</head>
24 Java PpP.indd 436
28/04/11 16:03
 Soluzioni degli esercizi
437
<body>
<script type="text/javascript">
var body = document.getElementsByTagName("body")[0];
for (var prop in location) {
var elem = document.createElement("p");
var text = document.createTextNode(prop + ": " + location[prop]);
elem.appendChild(text);
body.appendChild(elem);
}
if (location.search) {
var querystring = location.search.substring(1);
var splits = querystring.split('&');
for (var i = 0; i < splits.length; i++) {
var splitpair = splits[i].split('=');
var elem = document.createElement("p");
var text = document.createTextNode(splitpair[0] + ": " +
splitpair[1]);
if (splitpair[0] == "country") {
switch(unescape(splitpair[1])) {
case "Brazil":
alert("Obrigado");
break;
case "Great Britain":
alert("Thank You");
break;
}
}
elem.appendChild(text);
body.appendChild(elem);
}
}
</script>
</body>
</html>
3. Questo esercizio non ha una soluzione che possa essere riportata qui. Potete installare lo User Agent Switcher per completare l’esercizio.
Capitolo 10
1. Ecco il codice:
var newelement = document.createElement("p");
newelement.setAttribute("id","pelement");
document.body.appendChild(newelement);
newelement.appendChild(document.createTextNode("This is a paragraph, albeit a short
one."));
var anchorelem = document.createElement("a");
anchorelem.setAttribute("id","aelement");
anchorelem.setAttribute("href","http://www.braingia.org/");
document.body.appendChild(anchorelem);
anchorelem.appendChild(document.createTextNode("Go To Steve Suehring's Web Site."));
24 Java PpP.indd 437
28/04/11 16:03
438
Soluzioni degli esercizi
2. Ecco il codice:
// create the initial elements (if you use an existing HTML file, you won't
need to do this)
var newelement = document.createElement("p");
newelement.setAttribute("id","pelement");
document.body.appendChild(newelement);
newelement.appendChild(document.createTextNode("This is a paragraph, albeit a
short one."));
var anchorelem = document.createElement("a");
anchorelem.setAttribute("id","aelement");
anchorelem.setAttribute("href","http://www.braingia.org/");
document.body.appendChild(anchorelem);
anchorelem.appendChild(document.createTextNode("Click Here"));
// make the change
var existingp = document.getElementById("pelement");
existingp.firstChild.nodeValue="This is the new text.";
var newanchor = document.getElementById("aelement");
newanchor.setAttribute("href","http://www.microsoft.com/");
3. Ecco il codice:
<head>
<title>Chapter 10 Exercises</title>
</script>
</head>
<body>
<div id="thetable"></div>
<script type = "text/javascript" >
var table = document.createElement("table");
table.border = "1";
var tbody = document.createElement("tbody");
// Append the body to the table
table.appendChild(tbody);
var row = document.createElement("tr");
// Create table row
for (i = 1; i < 3; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 1; j < 3; j++) {
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var data = document.createTextNode("Hello - I'm Row " + i + ", Column " + j);
td.appendChild(data);
row.appendChild(td);
}
tbody.appendChild(row);
}
document.getElementById("thetable").appendChild(table);
</script>
</body>
24 Java PpP.indd 438
28/04/11 16:03
 Soluzioni degli esercizi
439
Capitolo 11
1. Ecco il codice:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Onclick</title>
<script type="text/javascript">
function handleclick() {
alert("You Clicked Here");
return false;
}
</script>
</head>
<body>
<p><a href="#" onclick="return handleclick();">Click Here</a></p>
</body>
</html>
2. Ecco il codice:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Onclick</title>
<script type="text/javascript" src="ehandler.js"></script>
<script type="text/javascript">
function handleclick() {
alert("You Clicked Here");
return false;
}
</script>
</head>
<body>
<p><a href="#" id="clickMe">Click Here</a></p>
<script type="text/javascript">
var aLink = document.getElementById("clickMe");
EHandler.add(aLink, "click", function() { handleclick(); });
</script>
</body>
</html>
3. Per questo esercizio non serve codice JavaScript. Il codice HTML è il seguente:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>New Tab</title>
</head>
<body>
24 Java PpP.indd 439
28/04/11 16:03
440
Soluzioni degli esercizi
<p><a target="Microsoft" href="http://www.microsoft.com" id="mslink">Go To Microsoft
</a></p>
</body>
</html>
Capitolo 12
1. Una variante di un esempio del capitolo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Hello Cookie</title>
<script type = "text/javascript">
var cookName = "cookie1";
var cookVal = "testvalue";
var date = new Date();
date.setTime(date.getTime()+86400000); // one day, in milliseconds
var expireDate = date.toGMTString();
var myCookie = cookName + "=" + cookVal + ";expires=" + expireDate;
document.cookie = myCookie;
</script>
</head>
<body>
<p>Hello</p>
</body>
</html>
2. Questo codice è fondamentalmente lo stesso dell’esercizio 1, e le righe modificate
sono mostrate in grassetto:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Hello Cookie</title>
<script type = "text/javascript">
var cookName = "cookie2";
var cookVal = "testvalue";
var date = new Date();
date.setTime(date.getTime()+86400000); // one day, in millseconds
var expireDate = date.toGMTString();
var myCookie = cookName + "=" + cookVal + ";expires=" + expireDate + ";secure";
document.cookie = myCookie;
</script>
</head>
<body>
<p>Hello</p>
</body>
</html>
3. Se non utilizzate una connessione Secure Sockets Layer (SSL), non potete leggere un
cookie con il flag secure impostato.
24 Java PpP.indd 440
28/04/11 16:03
 Soluzioni degli esercizi
441
4. Nell’esercizio 1 ho impostato un cookie denominato cookie1; perciò quello è l’unico
che desidero visualizzare per questo esercizio. Il codice è il seguente:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Reading Cookie</title>
<script type = "text/javascript">
var incCookies = document.cookie.split(";");
for (var c = 0; c < incCookies.length; c++) {
var splitCookies = incCookies[c].split("=");
if (splitCookies[0] == "cookie1") {
alert(incCookies[c]);
}
}
</script>
</head>
<body>
<p>Hello</p>
</body>
</html>
Capitolo 13
1. Fate riferimento al listato 13.2 del capitolo 13 per un esempio di questo esercizio.
2. Fate riferimento al listato 13.2 di questo capitolo per un esempio di pre-caricamento
di immagini. Applicherete la stessa logica del codice alla mappa immagine creata per
questo esercizio.
Capitolo 14
1. Consultate la sezione “Lavorare con le caselle di selezione” nel capitolo 11 per un
esempio di soluzione per questo esercizio.
2. In base all’esempio pizza.htm, la porzione <head> del codice ora si presenta così, con
le aggiunte mostrate in grassetto:
<head>
<title>Pizza</title>
<script type = "text/javascript">
function prepza() {
var checkboxes = document.forms["pizzaform"].toppingcheck.length;
var crusttype = document.forms["pizzaform"].crust;
var size = document.forms["pizzaform"].size;
var crustlength = crusttype.length;
var sizelength = crusttype.length;
var newelement = document.createElement("p");
newelement.setAttribute("id","orderheading");
document.body.appendChild(newelement);
24 Java PpP.indd 441
28/04/11 16:03
442
Soluzioni degli esercizi
newelement.appendChild(document.createTextNode("This pizza will have:"));
for (var c = 0; c < crustlength; c++) {
if (crusttype[c].checked) {
var newelement = document.createElement("p");
newelement.setAttribute("id","crustelement" + i);
document.body.appendChild(newelement);
newelement.appendChild(document.createTextNode(
crusttype[c].value + " Crust"));
}
}
for (var s = 0; s < sizelength; s++) {
if (size[s].checked) {
var newelement = document.createElement("p");
newelement.setAttribute("id","sizeelement" + i);
document.body.appendChild(newelement);
newelement.appendChild(document.createTextNode(size[s].value + "
Size"));
}
}
for (var i = 0; i < checkboxes; i++) {
if (document.forms["pizzaform"].toppingcheck[i].checked) {
var newelement = document.createElement("p");
newelement.setAttribute("id","newelement" + i);
document.body.appendChild(newelement);
newelement.appendChild(document.createTextNode(
document.forms["pizzaform"].toppingcheck[i].value));
}
}
}
</script>
</head>
L’HTML segue. Questa particolare soluzione utilizza una tabella a tre colonne, sebbene ciò non sia tecnicamente richiesto per la correttezza di questa risposta: questo è
solo uno dei modi possibili. Anche in questo codice le aggiunte sono in grassetto:
<form id="pizzaform" action="#">
<table>
<tr><td>Toppings</td><td>Crust</td><td>Size</td></tr>
<tr>
<td><input type="checkbox" id="topping1" value="Sausage" name="toppingcheck"
/>Sausage</td>
<td><input type="radio" name="crust" value="Regular" checked="checked" id="radio1"
/>Regular</td>
<td><input type="radio" name="size" value="Small" checked="checked" id="radiosize1"
/>Small</td>
</tr>
24 Java PpP.indd 442
28/04/11 16:03
 Soluzioni degli esercizi
443
<tr>
<td><input type="checkbox" id="topping2" value="Pepperoni" name="toppingcheck"
/>Pepperoni</td>
<td><input type="radio" name="crust" value="Deep Dish" id="radio2" />Deep Dish</td>
<td><input type="radio" name="size" value="Medium" id="radiosize2" />Medium</td>
</tr>
<tr>
<td><input type="checkbox" id="topping3" value="Ham" name="toppingcheck" />Ham</td>
<td><input type="radio" name="crust" value="Thin" id="radio3" />Thin</td>
<td><input type="radio" name="size" value="Large" id="radiosize3" />Large</td>
</tr>
<tr>
<td><input type="checkbox" id="topping4" value="Green Peppers" name="toppingcheck"
/>Green Peppers</td>
<td></td>
<td></td>
</tr>
<tr>
<td><input type="checkbox" id="topping5" value="Mushrooms" name="toppingcheck"
/>Mushrooms</td>
<td></td>
<td></td>
</tr>
<tr>
<td><input type="checkbox" id="topping6" value="Onions" name="toppingcheck" />Onions
</td>
<td></td>
<td></td>
</tr>
<tr>
<td><input type="checkbox" id="topping7" value="Pineapple"
name="toppingcheck">Pineapple</td>
<td></td>
<td></td>
</tr>
</table>
<p><input type="submit" id="prepBtn" name="prepBtn" value="Prep Pizza"></p>
</form>
3. Aggiungete il seguente codice alla porzione <head> dell’applicazione pizza dal precedente esercizio:
function flip(pizzatype) {
if (pizzatype == "veggiespecial") {
document.getElementById("peppers").checked = "true";
document.getElementById("onions").checked = "true";
document.getElementById("mushrooms").checked = "true";
} else if (pizzatype == "meatspecial") {
document.getElementById("sausage").checked = "true";
document.getElementById("pepperoni").checked = "true";
document.getElementById("ham").checked = "true";
} else if (pizzatype == "hawaiian") {
document.getElementById("ham").checked = "true";
document.getElementById("pineapple").checked = "true";
}
}
24 Java PpP.indd 443
Utilizzate il seguente form HTML (notate l’aggiunta dei tre pulsanti e la modifica
dell’attributo id di ogni ingrediente).
28/04/11 16:03
444
Soluzioni degli esercizi
<form id="pizzaform" action="#">
<p>
<input type="button" id="veggiespecial" name="veggiespecial" value="Veggie Special"
/>
<input type="button" id="meatspecial" name="meatspecial" value="Meat Special" />
<input type="button" id="hawaiian" name="hawaiian" value="Hawaiian" />
</p>
<table>
<tr><td>Toppings</td><td>Crust</td><td>Size</td></tr>
<tr>
<td><input type="checkbox" id="sausage" value="Sausage" name="toppingcheck"
/>Sausage</td>
<td><input type="radio" name="crust" value="Regular" checked="checked" id="radio1"
/>Regular</td>
<td><input type="radio" name="size" value="Small" checked="checked" id="radiosize1"
/>Small</td>
</tr>
<tr>
<td><input type="checkbox" id="pepperoni" value="Pepperoni" name="toppingcheck"
/>Pepperoni</td>
<td><input type="radio" name="crust" value="Deep Dish" id="radio2" />Deep Dish</td>
<td><input type="radio" name="size" value="Medium" id="radiosize2" />Medium</td>
</tr>
<tr>
<td><input type="checkbox" id="ham" value="Ham" name="toppingcheck" />Ham</td>
<td><input type="radio" name="crust" value="Thin" id="radio3" />Thin</td>
<td><input type="radio" name="size" value="Large" id="radiosize3" />Large</td>
</tr>
<tr>
<td><input type="checkbox" id="peppers" value="Green Peppers" name="toppingcheck"
/>Green Peppers</td>
<td></td>
<td></td>
</tr>
<tr>
<td><input type="checkbox" id="mushrooms" value="Mushrooms" name="toppingcheck"
/>Mushrooms</td>
<td></td>
<td></td>
</tr>
<tr>
<td><input type="checkbox" id="onions" value="Onions" name="toppingcheck" />Onions</
td>
<td></td>
<td></td>
</tr>
<tr>
<td><input type="checkbox" id="pineapple" value="Pineapple" name="toppingcheck"
/>Pineapple</td>
<td></td>
<td></td>
</tr>
</table>
<p><input type="submit" id="prepBtn" name="prepBtn" value="Prep Pizza"
onclick="prepza();" /></p>
</form>
24 Java PpP.indd 444
28/04/11 16:03
 Soluzioni degli esercizi
445
Aggiungete gestori alla sezione JavaScript all’interno del <body> della pagina:
var veggieBtn = document.getElementById("veggiespecial");
EHandler.add(veggieBtn,"click",function() { flip("veggiespecial"); });
var meatBtn = document.getElementById("meatspecial");
EHandler.add(meatBtn,"click",function() { flip("meatspecial"); });
var hawaiiBtn = document.getElementById("hawaiispecial");
EHandler.add(hawaiiBtn,"click",function() { flip("hawaiian"); });
Capitolo 15
1. Ecco una pagina di esempio; ci sono molti modi per completare questo esercizio
correttamente:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>CSS</title>
<link href="exercise1.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1 id="h1element">The Title</h1>
<p id="firstelement">The first element.</p>
<p id="secondelement">The second element.</p>
</body>
</html>
Ecco il foglio di stile exercise1.css:
#h1element {
background-color: #abacab;
}
#firstelement {
color: red;
}
#secondelement {
color: blue;
}
2. Questo codice cambia l’elemento denominato firstelement in modo che il suo colore
di font sia il blu:
<script type="text/javascript">
var element1 = document.getElementById("firstelement");
element1.style.color = "#0000FF";
</script>
3. Questo codice nasconde tutti gli elementi <p> utilizzando la proprietà visibility di
Cascading Style Sheets (CSS) :
<script type="text/javascript">
var pelements = document.getElementsByTagName("p");
var pelmLength = pelements.length;
24 Java PpP.indd 445
28/04/11 16:03
446
Soluzioni degli esercizi
for (var i = 0; i < pelmLength; i++) {
pelements[i].style.visibility = "hidden";
}
</script>
4. Questo codice mostra l’impostazione di visibilità sia prima sia dopo che è stata impostata nello script. Quando eseguite il codice, notate che l’alert è vuoto prima che la
proprietà sia impostata.
<script type="text/javascript">
var pelements = document.getElementsByTagName("p");
var pelmLength = pelements.length;
for (var i = 0; i < pelmLength; i++) {
alert(pelements[i].style.visibility);
pelements[i].style.visibility = "hidden";
alert(pelements[i].style.visibility);
}
</script>
Capitolo 16
1. Il listato 16.3 del capitolo 16 fornisce una soluzione per questo esercizio.
2. Un alert fornisce un feedback visivo e questo può essere una soluzione al problema.
Potete trovare modi migliori per fornire feedback visivo nella soluzione all’esercizio 5
del capitolo 15, mostrato in precedenza, che utilizza un nuovo elemento. Ecco la soluzione di base a questo problema:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Try/Catch</title>
<script type="text/javascript">
</script>
</head>
<body>
<form name="formexample" id="formexample" action="#">
<div id="citydiv">Enter a City: <input id="city" name="city"></div>
<div><input id="submit" type="submit"></div>
</form>
<script type="text/javascript">
function checkValid() {
try {
var cityField = document.forms[0]["city"];
if (cityField.value != "Stockholm") {
throw "It's not Stockholm";
}
}
catch(errorObject) {
alert(errorObject);
}
}
24 Java PpP.indd 446
28/04/11 16:03
 Soluzioni degli esercizi
447
function init() {
document.forms[0].onsubmit = function() { return checkValid() };
}
window.onload = init;
</script>
</body>
</html>
3. Questo è un possibile metodo per svolgere l’esercizio. Esistono altri metodi, compreso
l’uso dello script ehandler.js:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Try/Catch</title>
<script type="text/javascript">
</script>
</head>
<body>
<form name="formexample" id="formexample" action="#">
<div id="citydiv">Enter a Number Between 1 and 100: <input id="num" name="num"></div>
<div><input id="submit" type="submit"></div>
</form>
<script type="text/javascript">
function checkValid() {
try {
var numField = document.forms[0]["num"];
if (isNaN(numField.value)) {
throw "it's not a number";
}
if ((numField.value > 100) || (numField.value < 1)) {
numField.style.background = "#FF0000";
return false;
}
else {
numField.style.background = "#FFFFFF";
return true;
}
}
catch(errorObject) {
alert(errorObject);
}
finally {
alert("Thank you for playing.");
}
}
function init() {
document.forms[0].onsubmit = function() { return checkValid() };
}
window.onload = init;
</script>
</body>
</html>
24 Java PpP.indd 447
28/04/11 16:03
448
Soluzioni degli esercizi
Capitolo 17
1. Questa soluzione richiede i file books.htm e books.xml utilizzati nel capitolo 17. La soluzione modifica soltanto books.htm. Le modifiche al file sono riportate in grassetto.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script type="text/javascript" src="ehandler.js"></script>
<title>Books</title>
</head>
<body>
<div id="xmldata"></div>
<p><a href="#" id="displaytable">Display Table</a></p>
<script type="text/javascript">
function displayData() {
var xmlEl = docObj.getElementsByTagName("book");
var table = document.createElement("table");
table.border = "1";
var tbody = document.createElement("tbody");
// Append the body to the table
table.appendChild(tbody);
var row = document.createElement("tr");
for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {
if (xmlEl[0].childNodes[colHead].nodeType != 1) {
continue;
}
var tableHead = document.createElement("th");
var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);
tableHead.appendChild(colName);
row.appendChild(tableHead);
}
tbody.appendChild(row);
// Create table row
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData = document.createTextNode(xmlEl[i].childNodes[j].firstChild.
nodeValue);
24 Java PpP.indd 448
28/04/11 16:03
 Soluzioni degli esercizi
449
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
document.getElementById("xmldata").appendChild(table);
}
function getXML()
{
tablelink.style.visibility = "hidden";
if (typeof document.implementation.createDocument != "undefined")
{
docObj = document.implementation.createDocument("", "", null);
docObj.onload = displayData;
}
else if (window.ActiveXObject)
{
docObj = new ActiveXObject("Microsoft.XMLDOM");
docObj.onreadystatechange = function () {
if (docObj.readyState == 4) displayData()
};
}
docObj.load("books.xml");
}
var tablelink = document.getElementById("displaytable");
EHandler.add("tablelink","click",function() { getXML(); });
</script>
</body>
</html>
Esercizio extra: Il seguente codice aggiunge un collegamento “Display Table” e poi,
quando la tabella è visualizzata, aggiunge un collegamento “Hide Table”. Questo non
era incluso nell’esercizio.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script type="text/javascript" src="ehandler.js"></script>
<title>Books</title>
</head>
<body>
<div id="xmldata"></div>
<p><a href="#" id="displaytable">Display Table</a></p>
<script type="text/javascript">
function displayData() {
var xmlEl = docObj.getElementsByTagName("book");
var table = document.createElement("table");
table.setAttribute("id","bookstable");
table.border = "1";
var tbody = document.createElement("tbody");
// Append the body to the table
table.appendChild(tbody);
24 Java PpP.indd 449
28/04/11 16:03
450
Soluzioni degli esercizi
var row = document.createElement("tr");
for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {
if (xmlEl[0].childNodes[colHead].nodeType != 1) {
continue;
}
var tableHead = document.createElement("th");
var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);
tableHead.appendChild(colName);
row.appendChild(tableHead);
}
tbody.appendChild(row);
// Create table row
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
var xmlData = document.createTextNode(xmlEl[i].childNodes[j].firstChild.
nodeValue);
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
var tableanchor = document.createElement("a");
var tableanchortext = document.createTextNode("Hide Table");
tableanchor.setAttribute("id","hidetable");
tableanchor.setAttribute("href","#");
tableanchor.appendChild(tableanchortext);
if (typeof window.addEventListener != "undefined") {
tableanchor.addEventListener("click",hideTable,false);
} else {
tableanchor.attachEvent("onclick",hideTable);
}
document.getElementById("xmldata").appendChild(tableanchor);
document.getElementById("xmldata").appendChild(table);
}
function hideTable() {
var bookstable = document.getElementById("bookstable");
bookstable.style.display = "none";
tablelink.style.display = "";
var tableanchor = document.getElementById("hidetable");
tableanchor.style.display = "none";
}
24 Java PpP.indd 450
28/04/11 16:03
 Soluzioni degli esercizi
451
unction getXML()
{
tablelink.style.display = "none";
if (typeof document.implementation.createDocument != "undefined")
{
docObj = document.implementation.createDocument("", "", null);
docObj.onload = displayData;
}
else if (window.ActiveXObject)
{
docObj = new ActiveXObject("Microsoft.XMLDOM");
docObj.onreadystatechange = function () {
if (docObj.readyState == 4) displayData()
};
}
docObj.load("books.xml");
}
var tablelink = document.getElementById("displaytable");
EHandler.add("tablelink","click",function() { getXML(); });
</script>
</body>
</html>
2. Anche questa soluzione richiede il file books.xml. La maggior parte del codice corrisponde alla versione finale di books.htm del capitolo 17 e le differenze sono riportate
in grassetto:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Books</title>
</head>
<body>
<div id="xmldata"></div>
<script type="text/javascript">
window.onload = getXML;
function displayData() {
var xmlEl = docObj.getElementsByTagName("book");
var table = document.createElement("table");
table.border = "1";
var tbody = document.createElement("tbody");
// Append the body to the table
table.appendChild(tbody);
var row = document.createElement("tr");
for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {
if (xmlEl[0].childNodes[colHead].nodeType != 1) {
continue;
}
var tableHead = document.createElement("th");
24 Java PpP.indd 451
28/04/11 16:03
452
Soluzioni degli esercizi
var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);
tableHead.appendChild(colName);
row.appendChild(tableHead);
}
tbody.appendChild(row);
// Create table row
for (i = 0; i < xmlEl.length; i++) {
var row = document.createElement("tr");
// Create the row/td elements
for (j = 0; j < xmlEl[i].childNodes.length; j++) {
// Skip it if the type is not 1
if (xmlEl[i].childNodes[j].nodeType != 1) {
continue;
}
// Insert the actual text/data from the XML document.
var td = document.createElement("td");
if (i % 2) {
td.style.background = "#aaabba";
}
var xmlData = document.createTextNode(xmlEl[i].childNodes[j].firstChild.
nodeValue);
td.appendChild(xmlData);
row.appendChild(td);
}
tbody.appendChild(row);
}
document.getElementById("xmldata").appendChild(table);
}
function getXML()
{
if (typeof document.implementation.createDocument != "undefined")
{
docObj = document.implementation.createDocument("", "", null);
docObj.onload = displayData;
}
else if (window.ActiveXObject)
{
docObj = new ActiveXObject("Microsoft.XMLDOM");
docObj.onreadystatechange = function () {
if (docObj.readyState == 4) displayData()
};
}
docObj.load("books.xml");
}
</script>
</body>
</html>
24 Java PpP.indd 452
28/04/11 16:03
 Soluzioni degli esercizi
453
Capitolo 18
Non ci sono esercizi per il capitolo 18.
Capitolo 19
1. Nessuno dei metodi Hypertext Transfer Protocol (HTTP) trattati nel capitolo offre
maggiore sicurezza degli altri. Solo l’aggiunta di Secure Sockets Layer (SSL) fornisce
un livello di sicurezza sopra i metodi HTTP. Dovreste notare che utilizzando il metodo
POST non vengono nascosti i dati di input e che soltanto il metodo POST dovrebbe
essere utilizzato con SSL perché il metodo GET inserisce i parametri direttamente
nell’URL, dove potrebbero essere visti indipendentemente da SSL.
2. Le risposte che utilizzano l’HTML standard sono recuperate con il metodo responseText e possono contenere qualsiasi cosa che si potrebbe ottenere tramite HTTP. Le
risposte in Extensible Markup Language (XML) devono essere ottenute con il metodo
responseXML e devono essere servite come XML content type dal server. Le risposte
in JavaScript Object Notation (JSON) sono risposte JavaScript, perciò offrono vantaggi
di prestazioni rispetto agli altri metodi.
3. Questa soluzione è stata trattata nel capitolo stesso, ma qui è riportata la chiamata
asincrona (sostituite YOUR SERVER con quanto appropriato per il vostro ambiente):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Async</title>
</head>
<body>
<div id="xmldata"></div>
<script type="text/javascript">
function readyAJAX() {
try {
return new XMLHttpRequest();
} catch(e) {
try {
return new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try {
return new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
return "A newer browser is needed.";
}
}
}
}
var requestObj = readyAJAX();
var url ="http://YOUR SERVER/sum.php?num1=2&num2=2";
24 Java PpP.indd 453
28/04/11 16:03
454
Soluzioni degli esercizi
requestObj.open("GET",url,true);
requestObj.send();
requestObj.onreadystatechange = function() {
if (requestObj.readyState == 4) {
if (requestObj.status == 200) {
alert(requestObj.responseText);
} else {
alert(requestObj.statusText);
}
}
}
</script>
</body>
</html>
Il file sum.php è un programma lato-server in PHP estremamente piccolo e non sicuro
che ha il seguente aspetto:
<?php
print $_GET['num1'] + $_GET['num2'];
?>
Capitolo 20
1. Questa soluzione utilizza il listato 19.1 e richiede l’aggiunta di un pulsante di invio al
form. Il form ora è il seguente:
<form name="nameform" id="nameform" action="" method="GET">
Enter State: <input id="textname" type="text" name="textname">
<input type="submit" name="submit" id="statesubmit">
</form>
A parte includere ehandler.js, un gestore di evento e una nuova funzione sono tutto
ciò che questa soluzione richiede. Sono aggiunti all’interno del JavaScript esistente.
var formSubmit = document.getElementById("nameform");
EHandler.add("formSubmit","submit",function() { showstate(); });
function showstate() {
alert(document.forms[0].textname.value);
}
2. Questa soluzione è una variante della precedente e di altre del capitolo 19. Il programma lato-server deve restituire l’elenco delimitato dalla virgola di persone per la
directory della società, in modo simile a come l’esempio sugli stati restituiva un elenco degli stati USA.
24 Java PpP.indd 454
28/04/11 16:03
 Soluzioni degli esercizi
455
Capitolo 21
1. Sia jQuery sia MooTools sono veloci da imparare, e anche PrototypeJS è facile da apprendere. Dojo non è uno strumento per programmatori JavaScript alle prime armi,
mentre per quanto riguarda YUI ho incontrato diversi sviluppatori che ne sono confusi nonostante la sua completa documentazione. Tuttavia ognuno apprende in modo
diverso, perciò vi consiglio di provare ciascuno di questi strumenti, anziché prendere
alla lettera il giudizio di altri!
2. L’esercizio di questo capitolo fornisce un esempio di creazione di una vostra libreria e
della sua inclusione in una pagina.
Capitolo 22
1. Un metodo per ottenere questo è utilizzare la funzione .hover() insieme alla funzione .css() per cambiare il colore di sfondo. Questo avviene nella funzione showStates.
Segue la funzione showStates modificata di ajax.html:
function showStates(data,status) {
$.each(data, function(item) {
$("#states").append("<div>" + data[item] + "</div>");
$('#states').children().hover(
function() {
$(this).css('background-color','blue');
},
function() {
$(this).css('background-color','');
}
);
});
}
2. Ecco il codice lato-serve scritto in PHP. Questo codice restituisce “Wisconsin” quando
è passata l’abbreviazione WI:
<?php
$stateAbbrev = trim($_POST['state']);
if ($stateAbbrev == "WI") {
print json_encode("Wisconsin");
}
?>
24 Java PpP.indd 455
28/04/11 16:03
456
Soluzioni degli esercizi
3. Ecco l’HTML, JavaScript e jQuery per generare l’output basato sulla chiamata AJAX:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>AJAX Data Test</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
</head>
<body>
<div id="state">
</div>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "POST",
url: "statefull.php",
dataType: "json",
success: showStateFull,
data: "state=WI"
});
function showStateFull(data,status) {
$("#state").text(data);
}
});
</script>
</body>
</html>
Capitolo 23
1. Potete aggiungere funzionalità per mostrare tutte le opzioni in molti modi. Questo
esempio aggiunge un elemento àncora con l’ID showAll. Questo ID è poi legato a
una funzione nel codice jQuery/JavaScript. La funzione esegue un loop su ciascuna
delle opzioni e, se la proprietà di visualizzazione di un’opzione è impostata a none, il
codice esegue la funzione .show() per essa. Un’altra possibilità, forse migliore, sarebbe
aggiungere una classe chiamata hidden all’elemento <li> quando la funzione .hide()
viene eseguita in origine. Quindi trovare l’elemento nascosto sarebbe molto più facile,
perché potreste limitarvi a cercare qualsiasi elemento <li> che sia nascosto nel tag
<ul>. C’è anche un modo per fare questo con il selettore jQuery :hidden, tuttavia ho
incontrato alcune difficoltà nel far funzionare il selettore :hidden in browser diversi, e
questo è il motivo per cui ho scelto di mostrare gli altri approcci per svolgere l’attività.
In ogni caso ecco il codice:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
24 Java PpP.indd 456
28/04/11 16:03
 Soluzioni degli esercizi
457
<html>
<head>
<title>Hide</title>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<style type="text/css">
.removeBtn {
color: #0000CC;
}
</style>
</head>
<body>
<ul>
<li id="option1">Option 1 <span class="removeBtn" id="remove1">(x)</span></li>
<li id="option2">Option 2 <span class="removeBtn" id="remove2">(x)</span></li>
<li id="option3">Option 3 <span class="removeBtn" id="remove3">(x)</span></li>
<li id="option4">Option 4 <span class="removeBtn" id="remove4">(x)</span></li>
</ul>
<a href="" id="showAll">Show All</a>
<script type="text/javascript">
$(document).ready(function() {
$('.removeBtn').each(function(elm) {
$(this).click(function() {
$(this).parent().hide();
});
});
$('#showAll').click(function() {
$('.removeBtn').each(function(elm) {
if ($(this).parent().attr("display","none")) {
$(this).parent().show();
}
});
});
});
</script>
</body>
</html>
2. La chiave per questo esercizio è l’utilizzo dell’opzione async nella funzione .ajax() di
jQuery. Senza async, la funzione .accordion() tende ad avviarsi prima che le opzioni
per l’accordion siano ricevute ed elaborate da AJAX. Questo esempio di codice utilizza una chiamata JSON per recuperare l’elenco degli stati utilizzati nel capitolo 22.
Questo elenco viene quindi inserito nell’accordion. Il codice imposta async a false nella chiamata di .ajax() e poi aggiunge un po’ di elaborazione alla funzione showStates
del capitolo 22. Per il resto questa è una variante dell’esempio di accordion del capitolo 23.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Accordion</title>
24 Java PpP.indd 457
28/04/11 16:03
458
Soluzioni degli esercizi
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.4.custom.min.js"></script>
<style type="text/css">
#container {
width: 350px;
height: 700px;
border: solid 2px black;
padding: 3px;
}
.optionHead {
border: solid 1px black;
background-color: #abacab;
}
.optionDiv {
border-bottom: dotted 1px black;
}
</style>
</head>
<body>
<div id="container">
</div>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type: "GET",
url: "json.php",
dataType: "json",
success: showStates,
async: false
});
function showStates(data,status) {
$.each(data, function(item) {;
$("#container").append(
"<h3 class=\"optionHead\">" +
data[item] +
"</h3>" +
"<div class=\"optionDiv\">" +
"Option text goes here</div>");
});
}
$('#container').accordion({
collapsible: true,
active: false
});
});
</script>
</body>
</html>
24 Java PpP.indd 458
28/04/11 16:03