martedì 10 luglio 2012

PHP & NetBeans: Introduzione ad Ajax per Applicazioni Web PHP

Questo articolo è una personale traduzione di un posto originariamente presente su NetBeans.org ed ora su Apache.org. in fondo alla pagina i link agli articoli originali in inglese.

Questo documento fornisce una introduzione ad Ajax e dimostra alcune delle caratteristiche di NetBeans che permettono di programmare più velocemente ed efficientemente quando si lavora con tecnologia Ajax. Mentre apprendi le funzionalità base di Ajax, costruirai una semplice applicazione che impiega l'auto-completamento in un campo di testo. I contenuti sono stati adattati da articolo ed esempio di Greg Murray Using Ajax with Java Technology.


Ajax sta per Asynchronous JavaScript and XML. Ajax è essenzialmente un modo efficiente per una pagina web di gestire l'interazione con l'utente - un modo per ridurre il bisogno di aggiornare o ricaricare l'intera pagina ad ogni interazione dell'utente. Ciò permette un comportamento ottimale (simile a quello di una applicazione desktop o di una applicazione web basata su plug-in) utilizzando un browser. Le interazioni Ajax sono gestite in modo asincrono e in background. Mentre avviene, l'utente può continuare a lavorare sulla pagina. Le interazioni Ajax sono avviate da codice JavaScript. Quando l'interazione Ajax è completa, JavaScript aggiorna il sorgente HTML della pagina. I cambiamenti sono fatti immediatamente senza richieder un aggiornamento della pagina. Le interazioni Ajax possono essere utilizzate per fare cose quali la validazione dei dati di un form (mentre l'utente inserisce i dati) utilizzando logiche lato server, recuperare dati dettagliati dal server, aggiornare dinamicamente la data sulla pagina, e inviare moduli parziali dalla pagina.
Contenuti
  • Panoramica dell'Applicazione
  • Programmare Lato Client: Parte 1
    • Utilizzare l'Editor HTML
    • Utilizzare l'Editor JavaScript
  • Programmare Lato Server
    • Creare l'Archivio Dati
    • Creare la Logica di Business
  • Programmare Lato Client: Parte 2
    • Aggiungere la Funzionalità di Callback
    • Aggiornare il DOM HTML
    • Agganciare un Foglio di Stile
  • Conclusione
Per completare questo tutorial, hai bisogno del seguente software e risorse.
Software o RisorsaVersione Richiesta
NetBeans IDE, PHP bundle6.7, 6.8 o 6.9
Java Development Kit (JDK)6
PHP enginePHP 5
Apache web server2.2
Note:
  • L'ambiente di sviluppo PHP è spesso configurato utilizzando un pacchetto *AMP, a seconda del proprio sistema operativo. Tale pacchetto include il motore PHP e il web server Apache. Per istruzioni sulla configurazione dell'ambiente, vedi PHP Learning Trail.
  • Questo tutorial suppone che si abbiano delle conoscenze sulle varie tecnologie impiegate (per esempio, HTML, CSS, JavaScript e PHP). Si cerca di dare una panoramica delle funzionalità fornite dal codice, ma non si spiega come il codice lavora linea per linea.
  • Se hai bisogno di confrontare il tuo progetto con una soluzione funzionante, puoi scaricare l'applicazione d'esempio. Utilizza la procedura guidata New Project dell'IDE (Ctrl-Shift-N; ⌘-Shift-N su Mac), e seleziona il tipo di progetto PHP Application with Existing Sources. Nella procedure guidata, individua i sorgenti scaricati nel tuo computer.

Panoramica dell'Applicazione

Immagina una pagina web in cui l'utente possa cercare informazioni sui compositori. La pagina include un campo in cui l'utente può inserire il nome del compositore. Nell'applicazione d'esempio, il campo ha una caratteristica di auto-completamento. In altre parole, l'utente può digitare parte del nome del compositore, e l'applicazione web tenta di completare il nome elencando tutti i compositori il cui nome o cognome inizi con i caratteri inseriti. La caratteristica di auto-completamento risparmia all'utente il dover ricordare il nome completo del compositore e può fornire un percorso più intuitivo e diretto all'informazione.
Implementare il completamento  automatico in un campo di ricerca è qualcosa che può essere realizzato utilizzando Ajax. Ajax funziona impiegando un oggetto XMLHttpRequest per trasmettere richieste e risposte asincrone tra il client e il server. il seguente diagramma illustra il flusso di elaborazione della comunicazione che avviane tra il client ed il server.


Il flusso di elaborazione del diagramma può essere descritto dai seguenti passi:
  1. L'utente genera un evento, per esempio rilasciando un tasto quando digita un nome. Questo provoca una chiamata JavaScript a una funzione che inizializza un oggetto XMLHttpRequest.
  2. L'oggetto è configurato con una parametro di richiesta che comprende l'ID del componente che ha generato l'evento, e qualunque valore inserito dall'utente. L'oggetto XMLHttpRequest fa una richiesta asincrona al server web.
  3. Sul sever web, un oggetto come una servlet o listener gestisce la richiesta. Recupera i dati e appronta una risposta contenente i dati sotto forma di documento XML.
  4. Infine l'oggetto XMLHttpRequest riceve i dati XML utilizzando una funzione di callback, li elabora, e aggiorna il DOM (Document Object Model) HTML per visualizzare la pagina contenente i nuovi dati.
Questo tutorial dimostra come realizzare uno scenario di auto completamento seguendo il flusso di elaborazione indicato nel precedente diagramma. Prima crea i file lato client per la presentazione e funzionalità necessarie a generare l'oggetto XMLHttpRequest. Poi, predisponi il lato server creando i dati e la logica di business utilizzano la tecnologia PHP. infine, ritorna al client ed implementa la callback(), e le altre funzionalità JavaScript necessarie all'aggiornamento del DOM.

Programmare Lato Client: Parte 1

Inizia creano un nuovo progetto PHP Application nell'IDE.
  1. Scegli File > New Project. In Categorie, seleziona PHP. In progetti, seleziona PHP Application quindi clic su Next.
  2. Step 2: In Name and Location chiama il progetto MyAjaxApp. Il campo Sources Folder permette di specificare la posizione del progetto sul computer. Lascia le opzioni con sono e clicca su Next.

  3. Step 3: Run Configuration, specifica come vuoi distribuire l'applicazione. Se hai preparato il tuo ambiente di sviluppo PHP con un pacchetto *AMP, dovresti selezionare il Local Web Site dall'elenco a discesa, e specificare la URL del progetto, così come appare in un browser.
  4. Seleziona Copy files from Sources Folder to another location option. Quindi, nel campo Copy to Folder, digita il percorso per la distribuzione sul server. (In Apache, la cartella di default è htdocs.)

  5. Clic Finish. L'IDE crea la cartella del progetto nel tuo file system e lo apre.

    Puoi anche aggiungere la procedura guidata per aggiungere il supporto ad un framework.
    E' creata ed aperta una una pagina indice di default chiamata index.php. Anche il progetto appare nella finestra Project.

  6. Prima di iniziare con il codice, prova rapidamente ad eseguire l'applicazione per assicurarti che la configurazione tra l'IDE, il web server e il browser sia impostata correttamente.

    Ne''Editor, aggiungi una istruzione echo alla pagina indice:
    <?php
        // put your code here
        echo "<h2>Hello World!</h2>";
    ?>
    
  7. Nella finestra Projects, clic con il tasto destro sul nodo del progetto e scegli Run. Il browser di default è aperto e visualizza il messaggio Hello World appena creato in index.php.

    Nota: Se hai difficoltà nell'impostare il tuo progetto o nello stabilire le comunicazioni tra IDE, server e browser, vedi Setting Up a PHP Project per una descrizione più completa. Il PHP Learning Trail può fornire maggiori informazioni sulla configurazione del tuo ambiente.

Utilizzare l'Editor HTML



Ora che sei certo della corretta configurazione dell'ambiente, inizia con lo sviluppo dell'interfaccia di completamento automatico da visualizzare agli utenti. Poiché la pagina indice che creerai non richiede elementi lato server. inizia creando una pagina HTML e impostandola come punto d'ingresso per l'applicazione.
Uno dei vantaggi nell'uso di un IDE è che l'editor spesso fornisce il code compeltion che, se impari ad utilizzare quando stendi il tuo codice, può incrementare rapidamente la tua produttività. L'editor dell'IDE in genere si adatta alla tecnologia che stai utilizzando, quindi se stai lavorando in una pagina HTML, premendo la combinazione di tasti che attiva il code completion (Ctrl-Spazio) produce suggerimenti per tag e attributi HTML. Come mostrato più avanti, lo stesso avviene per altre tecnologie, quali CSS e JavaScript.
Una seconda caratteristica di cui puoi fare uso è la Palette dell'IDE. La Palette fornisce dei modelli di semplice uso per elementi che sono comunemente applicati nella tecnologia in uso. Semplicemente clicca su una voce, e trascinala in una posizione nel file aperto nell'editor.
Puoi rendere le icone più grandi (come visualizzate qui) facendo clic con il tasto destro nella Palette e scegliendo Show Big Icons.
  1. Nella finestra Projects, fai clic con il tasto destro sul nodo del progetto MyAjaxApp e scegli New > HTML File.
  2. Nella procedura guidata per il file HTML, chiama il file index, e fai clic su Finish. Il nuovo file index.html si apre nell'editor.
  3. sostituisce il contenuto esistente per il file con il seguente.
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
    
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <title>Auto-Completion using AJAX</title>
        </head>
        <body>
            <h1>Auto-Completion using AJAX</h1>
        </body>
    </html>
    
  4. Aggiungi del testo esplicativo che descrive lo scopo del campo di testo. Puoi copiare e incollare il seguente testo appena dopo il tag <h1>:
    <p>This example shows how you can do real time auto-completion using Asynchronous
        JavaScript and XML (Ajax) interactions.</p>
    
    <p>In the form below enter a name. Possible names that will be completed are displayed
        below the form. For example, try typing in "Bach," "Mozart," or "Stravinsky,"
        then click on one of the selections to see composer details.</p>
    
  5. Aggiungi un modulo HTML alla pagina. Puoi farlo utilizzando gli elementi elencati nella Palette dell'IDE. Se la Palette non è aperta, scegli Window > Palette dal menu principale. Quindi, sotto HTML Forms, clicca e trascina nella pagina un elemento Form sotto il tag <p> appena aggiunto. Il box di dialogo Insert Form appare. Specifica quanto segue:

    • Action: autocomplete.php
    • Method: GET
    • Name: autofillform

    Clic su OK. Il tag HTML <form> è inserito nella pagina contenente gli attributi specificati. (GET è applicato per default, e quindi non è esplicitamente dichiarato.)
  6. Aggiungi una tabella HTML alla pagina. Sotto la categoria HTML nella Palette, clicca su un elemento Table e trascinalo in un punto tra i tag <form>. Si apre il box di dialogo Insert Table. Specifica quanto segue:

    • Rows: 2
    • Columns: 2
    • Border Size: 0
    • Width: 0
    • Cell Spacing: 0
    • Cell Padding: 5

  7. Fai clic con il tasto destro all'interno dell'editor e scegli Format. In tal modo riordini il codice. Il tuo modulo dovrebbe apparire simile al seguente:
    <form name="autofillform" action="autocomplete.php">
      <table border="0" cellpadding="5">
        <thead>
          <tr>
            <th></th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td></td>
            <td></td>
          </tr>
          <tr>
            <td></td>
            <td></td>
          </tr>
        </tbody>
      </table>
    </form>
    
  8. Dentro la prima riga e prima colonna della tabella, digita il seguente testo:
    <td><strong>Composer Name:</strong></td>
  9. Dentro la seconda colonna della prima riga, invece di trascinare un campo Text Input dalla Palette, digita il codice sottostante manualmente.
    <input type="text"
        size="40"
        id="complete-field"
        onkeyup="doCompletion();">
    
    Quando digiti, cerca di utilizzare code completion fornito dall'IDE. Per esempio, digita <i, quindi premi Ctrl-Spazio. Una lista di opzioni suggerite appare sotto il cursore, e una descrizione di ogni elemento selezionato appare nel sottostante box. Nell'Editor puoi premere in qualunque momento Ctrl-Spazio per  evidenziare possibili opzioni. Anche, se c'è solo una possibile opzione, premendo Ctrl-Spazio l'IDe competerà automaticamente il nome dell'elemento.


    L'attributo onkeyup che hai digitato punta alla funzione JavaScript doCompletion(). Questa funzione è chiamata ogni volta che un tasto è premuto nel campo di testo del modulo, e mappa la chiamata JavaScript illustrata nel precedente diagramma di flusso Ajax.
  10. Prima di spostarsi al lavoro nell'editor JavaScript, assicurati di sostituire il nuovo file index.html al file index.php quale punto d'ingresso per l'applicazione.

    Per farlo, fsi clic con il tasto destro sul nodo del progetto nella finestra Projects e scegli Properties. Seleziona la categoria Run Configuration, quindi inserisci index.html nel campo Index File.

  11. Clic su OK per salvare i cambiamenti ed uscire dalla finestra Project Properties.
  12. Esegui il progetto per vedere come appare nel browser. Clicca il pulsante Run Project (). Il file index.html è visualizzato nel tuo browser predefinito.

Utilizzare l'editor JavaScript

L'Editor JavaScript dell'IDE fornisce molte funzionalità avanzate, quali code completion intelligente, colorazione del codice, ridenominazione istantanea e capacità di refactoring, nonché molte altre caratteristiche. vedi Editing JavaScript per una introduzione e http://wiki.netbeans.org/JavaScript per una specifica dettagliata.
JavaScript code completion è abilitato automaticamente quando scrivi il codice all'interno di un file .js, oltre che all'interno del tag <script> quando operi con altre tecnologia (per esempio HTML, RHTML, JSP, PHP). Quando utilizzi l'Editor JavaScript, l'IDE ti fornisce informazioni sulla compatibilità con i browser, a seconda del tipo e versione di browser specificato nel pannello Options di JavaScript. Apri il pannello Options di JavaScript scegliendo Tools > Options (NetBeans > Preferences su Mac), quindi Miscellaneous > JavaScript.


L'IDE  fornisce supporto per FireFox, InternetExplorer, Safari e Opera. Dal pannello Options di JavaScript, puoi anche specificare la versione del motore JavaScript che code completion deve applicare.
Aggiungi un file JavaScript all'applicazione e inizia ad implementare doCopmpletion().
  1. Nella finestra Projects, fai clic con il tasto destro sul nodo del progetto e scegli New > JavaScript file. (Se JavaScript file non è in elenco, scegli Other, Poi scegli JavaScript file dalla categoria Other nella procedura guidata New File.
  2. Chiama il file javascript, quindi fai clic su Finish. Il nuovo file JavaScript appare nella finestra Projects ed è aperto nell'editor.
  3. Digita il codice seguente nel file javascript.js.
    var req;
    var isIE;
    
    function init() {
        completeField = document.getElementById("complete-field");
    }
    
    function doCompletion() {
            var url = "autocomplete.php?action=complete&id=" + escape(completeField.value);
            req = initRequest();
            req.open("GET", url, true);
            req.onreadystatechange = callback;
            req.send(null);
    }
    
    function initRequest() {
        if (window.XMLHttpRequest) {
            if (navigator.userAgent.indexOf('MSIE') != -1) {
                isIE = true;
            }
            return new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            isIE = true;
            return new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    
    Il codice precedente realizza un semplice controllo di compatibilità del browser per Firefox 3 e Internet Explorer 6 e 7). Se ti piacerebbe incorporare un codice più robusto per ragioni di compatibilità, considera l'utilizzo di questo browser detect script da http://www.quirksmode.org.
  4. Torna al file index.html e aggiungi un riferimento al file JavaScript tra i tag <head>
    <script type="text/javascript" src="javascript.js"></script>
    
    Puoi velocemente spostarti tra le pagine aperte nell'editor premendo Ctrl-Tab.
  5. Inserisci una chiamata a init() nell'apertura del tag <body>.
    <body onload="init()">
    
    Ciò assicura che init() sia chiamata ogni volta che la pagina è caricata.
Il ruolo di doCompletion() è:
  • creare una URL che contenga i dati che possano essere utilizzati dal server,
  • inizializzare un oggetto XMLHttpRequest, e 
  • chiedere all'oggetto di inviare una richiesta asincrona al server.
L'oggetto XMLHttpRequest è il cuore di Ajax e è divenuto lo standard di fatto per il passaggio asincrono di dati su HTTP. Interazione asincrona implica che il browser può continuare a elaborare eventi nella pagina dopo l'invio della richiesta. I dati sono passati in background, e possono essere automaticamente caricati nella pagina senza richiederne l'aggiornamento.
Si noti che l'oggetto XMLHttpRequest è attualmente creato da initRequest, che è chiamata da doCompletion(). La funzione controlla se XMLHttpRequest può essere compreso dal browser, e in caso affermativo, crea l'oggetto XMLHttpRequest. Altrimenti, realizza un controllo su ActiveXObject (l'equivalente di XMLHttpRequest per Internet Explorer 6), e se identificato crea un ActiveXObject.
Tre parametri sono specificati quando crei un oggetto XMLHttpRequest: un URL, il metodo HTTP (GET o POST), e se o no l'interazione è asincrona. Nell'esempio precedente, i parametri sono:
  • L'URL autocomplete.php, e il testo inserito dall'utente in complete-field:
    var url = "autocomplete.php?action=complete&id=" + escape(completeField.value);
  • GET, significa che l'interazione HTTP utilizza il metodo GET, e
  • true, ossia che l'interazione è asincrona:
    req.open("GET", url, true);
Se l'interazione è impostata come asincrona, deve essere specificata una funzione di callback. La funzione di callback per questa interazione è impostata con l'istruzione:
req.onreadystatechange = callback;
e una funzione callback() deve essere definita successivamente. L'interazione HTTP inizia quando è invoacata XMLHttprequest.send(). Questa azione mappa la richiesta HTTP che è inviata al web server nel precedente diagramma di flusso.

Programmare Lato Server

L'IDE di NetBeans fornisce un completo supporto per lo sviluppo web utilizzando PHP. Puoi impostare il tuo ambiente di sviluppo utilizzando un pacchetto *AMP, abilitando la modifica e distribuzione dall'IDE velocemente ed in modo efficiente. L'IDE permette di configurare il tuo ambiente con un server locale, ovvero remoto, utilizzando FTP o SFTP. Puoi anche configurare un debugger esterno, come XDebug, e configurare l'unità di test con PHPUnit dalla finestra Options PHP dell'IDE (scegli Tools > Options; NetBeans > Preferences su Mac, quindi selezione la scheda PHP.) L'editor PHP è dotato di caratteristiche standard di modifica come code completion, colorazione della sintassi, segnatura ricorrenze, refactoring, templates, documentazione pop-up, navigazione del codice, avvertimenti e, da NetBeans 6.9, simboli di errore per sintassi malformata. Vedi la pagina NetBeans Video Tutorials and Demos per uno screencasts sul supporto di PHP.
Per applicazioni che richiedono un database, l'IDe supporta la maggior parte dei database, specialmente MySQL. Vedi NetBeans MySQL screencast e le caratteristiche di Database Integration per maggiori dettagli.
La logica di business per l'applicazione auto-complete che stai realizzando ha bisogno di elaborare le richieste recuperando i dati, quindi preparare ed inviare la risposta. Ciò è implementato qui utilizzano un file PHP chiamato aoutocomplete. Prima di iniziare a scrivere il codice, imposta l'archivio dati e le funzionalità richieste dal file per accedere ai dati.
  • Creare l'Archivio Dati
  • Creare la Logica di Business

Creare l'Archivio Dati

Per questa semplice applicazione, creerai una classe chiamata Composer che permette alla logica di business di recuperare i dati dalle voci contenute in un array di compositori. Poi creerai una classe chiamata ComposerData che trattiene i dati del compositore utilizzando l'array.
  1. Fai clic con il tasto destro sul nodo del progetto MyAjaxApp nella finestra Projects e scegli New > PHP Class.
  2. Chiama la classe Composer, e clicca su Finish. La classe è creata e aperta nell'editor.
  3. Incolla il seguente codice all'interno della classe (Modifiche in grassetto).
    <?php
    
    class Composer {
    
        public $id;
        public $firstName;
        public $lastName;
        public $category;
    
        function __construct($id, $firstName, $lastName, $category) {
            $this->id = $id;
            $this->firstName = $firstName;
            $this->lastName = $lastName;
            $this->category = $category;
        }
    }
    
    ?>
Crea la classe ComposerData.
  1. tasto destro sul nodo del progetto MyAjaxApp nella finestra Projects e scegli New > PHP Class.
  2. Chiama la classe ComposerData, e clicca su Finish. La classe è creata e aperta nell'editor.
  3. Aggiungi le istruzioni necessarie all'inizio della classe per specificare che la classe necessita della classe Composer.php appena creata (modifiche in grassetto).
    <?php
    
    require "Composer.php";
    
    class ComposerData {
    
    }
  4. Nell'editor, incolla il seguente codice nella classe (modifiche in grassetto).
    <?php
    
    require "Composer.php";
    
    class ComposerData {
    
        public $composers;
    
        function __construct() {
            $this->composers = array(
                new Composer("1", "Johann Sebastian", "Bach", "Baroque"),
                new Composer("2", "Arcangelo", "Corelli", "Baroque"),
                new Composer("3", "George Frideric", "Handel", "Baroque"),
                new Composer("4", "Henry", "Purcell", "Baroque"),
                new Composer("5", "Jean-Philippe", "Rameau", "Baroque"),
                new Composer("6", "Domenico", "Scarlatti", "Baroque"),
                new Composer("7", "Antonio", "Vivaldi", "Baroque"),
    
                new Composer("8", "Ludwig van", "Beethoven", "Classical"),
                new Composer("9", "Johannes", "Brahms", "Classical"),
                new Composer("10", "Francesco", "Cavalli", "Classical"),
                new Composer("11", "Fryderyk Franciszek", "Chopin", "Classical"),
                new Composer("12", "Antonin", "Dvorak", "Classical"),
                new Composer("13", "Franz Joseph", "Haydn", "Classical"),
                new Composer("14", "Gustav", "Mahler", "Classical"),
                new Composer("15", "Wolfgang Amadeus", "Mozart", "Classical"),
                new Composer("16", "Johann", "Pachelbel", "Classical"),
                new Composer("17", "Gioachino", "Rossini", "Classical"),
                new Composer("18", "Dmitry", "Shostakovich", "Classical"),
                new Composer("19", "Richard", "Wagner", "Classical"),
    
                new Composer("20", "Louis-Hector", "Berlioz", "Romantic"),
                new Composer("21", "Georges", "Bizet", "Romantic"),
                new Composer("22", "Cesar", "Cui", "Romantic"),
                new Composer("23", "Claude", "Debussy", "Romantic"),
                new Composer("24", "Edward", "Elgar", "Romantic"),
                new Composer("25", "Gabriel", "Faure", "Romantic"),
                new Composer("26", "Cesar", "Franck", "Romantic"),
                new Composer("27", "Edvard", "Grieg", "Romantic"),
                new Composer("28", "Nikolay", "Rimsky-Korsakov", "Romantic"),
                new Composer("29", "Franz Joseph", "Liszt", "Romantic"),
    
                new Composer("30", "Felix", "Mendelssohn", "Romantic"),
                new Composer("31", "Giacomo", "Puccini", "Romantic"),
                new Composer("32", "Sergei", "Rachmaninoff", "Romantic"),
                new Composer("33", "Camille", "Saint-Saens", "Romantic"),
                new Composer("34", "Franz", "Schubert", "Romantic"),
                new Composer("35", "Robert", "Schumann", "Romantic"),
                new Composer("36", "Jean", "Sibelius", "Romantic"),
                new Composer("37", "Bedrich", "Smetana", "Romantic"),
                new Composer("38", "Richard", "Strauss", "Romantic"),
                new Composer("39", "Pyotr Il'yich", "Tchaikovsky", "Romantic"),
                new Composer("40", "Guiseppe", "Verdi", "Romantic"),
    
                new Composer("41", "Bela", "Bartok", "Post-Romantic"),
                new Composer("42", "Leonard", "Bernstein", "Post-Romantic"),
                new Composer("43", "Benjamin", "Britten", "Post-Romantic"),
                new Composer("44", "John", "Cage", "Post-Romantic"),
                new Composer("45", "Aaron", "Copland", "Post-Romantic"),
                new Composer("46", "George", "Gershwin", "Post-Romantic"),
                new Composer("47", "Sergey", "Prokofiev", "Post-Romantic"),
                new Composer("48", "Maurice", "Ravel", "Post-Romantic"),
                new Composer("49", "Igor", "Stravinsky", "Post-Romantic"),
                new Composer("50", "Carl", "Orff", "Post-Romantic"),
            );
        }
    }
    
    ?>
    

Creare la logica di business

Implementa la logica per gestire la url autocomplete che è ricevuta dalla richiesta in ingresso. Invece di creare un nuovo file PHP utilizzando la procedure guidata vista nella sezione precedente, modifica il file index.php esistente a tale scopo.
  1. Nella finestra Projects, clicca sul nodo del file index.php. Il nome del file diventa modificabile, permettendoti di cambiarlo.

  2. Chiama il file autocomplete, quindi clicca Enter. Doppio clic sul nuovo file autocomplete.php per visualizzarlo nell'editor.
  3. sostituisci il codice esistente con il seguente script.
    <?php
    
    require_once("ComposerData.php");
    
    session_start();
    
    $composerData = new ComposerData();
    $composers = $composerData->composers;
    
    $results = array();
    $namesAdded = false;
    
    // simple matching for start of first or last name, or both
    if(isset($_GET['action']) && $_GET['action'] == "complete") {
        foreach($composers as $composer) {
            if(!is_numeric($_GET['id']) &&
    
                // if id matches first name
                (stripos($composer->firstName, $_GET['id']) === 0 ||
    
                // if id matches last name
                stripos($composer->lastName, $_GET['id']) === 0) ||
    
                // if id matches full name
                stripos($composer->firstName." ".$composer->lastName, $_GET['id']) === 0) {
    
                    $results[] = $composer;
            }
        }
    
        // prepare xml data
        if(sizeof($results) != 0) {
            header('Content-type: text/xml');
            echo "<composers>";
            foreach($results as $result) {
                echo "<composer>";
                echo "<id>" . $result->id . "</id>";
                echo "<firstName>" . $result->firstName . "</firstName>";
                echo "<lastName>" . $result->lastName . "</lastName>";
                echo "</composer>";
            }
            echo "</composers>";
        }
    }
    
    // if user chooses from pop-up box
    if(isset($_GET['action']) && isset($_GET['id']) && $_GET['action'] == "lookup") {
        foreach($composers as $composer) {
            if($composer->id == $_GET['id']) {
                $_SESSION ["id"] = $composer->id;
                $_SESSION ["firstName"] = $composer->firstName;
                $_SESSION ["lastName"] = $composer->lastName;
                $_SESSION ["category"] = $composer->category;
    
                header("Location: composerView.php");
            }
        }
    }
    
    ?>
Nota: Il file composerView.php non è descritto in questo tutoria. Puoi creare tale file per vedere il risultato finale della ricerca. Un esempio del file è incluso nell'applicazione d'esempio.
Come puoi vedere, non c'è nulla di veramente nuovo da imparare per scrivere codice lato server per elaborazioni Ajax. Il tipo di contenuto della risposta ha bisogno di essere impostato a text/xml qualora si vogliano scambiare documenti XML. Con Ajax, puoi anche scambiare testo o anche frammenti di JavaScript che potrebbero essere valutati o eseguiti dalla funzione di callback sul client. Nota anche che qualche browser potrebbe mettere in cache i risultati, rendendo quindi necessaria l'impostazione della header HTTP Cache-Control a no-cache.
In questo esempio, il file autocomplete.php genera un documento XML che contiene tutti i compositori con un nome o cognome che iniziano con i caratteri inseriti dall'utente. Questo documento mappa l'illustrato XML Data nel precedente diagramma di flusso. Ecco un esempio di documento XML ritornato dall'oggetto XMLHttpRequest:
<composers>
    <composer>
        <id>12</id>
        <firstName>Antonin</firstName>
        <lastName>Dvorak</lastName>
    </composer>
    <composer>
        <id>45</id>
        <firstName>Aaron</firstName>
        <lastName>Copland</lastName>
    </composer>
    <composer>
        <id>7</id>
        <firstName>Antonio</firstName>
        <lastName>Vivaldi</lastName>
    </composer>
    <composer>
        <id>2</id>
        <firstName>Arcangelo</firstName>
        <lastName>Corelli</lastName>
    </composer>
</composers>

Programmare Lato Client: Parte 2

Devi definire la funzione di callback per gestire la risposta del server, e aggiungere qualche funzionalità necessaria a riflettere i cambiamenti nella pagina visualizzata dall'utente. Ciò richiede modifiche al DOM HTML. Infine, puoi lavorare con l'edito CSS dell'IDE per aggiungere un semplice fogli di stile per la presentazione.
  • Aggiungere la Funzionalità di Callback
  • Aggiornare il DOM HTML
  • Agganciare un Foglio di Stile

Aggiungere la Funzionalità di Callback

La funzione di callbask è chiamata in modo asincrono al punto specificato nell'interazione HTTP quando la proprietà redyState dell'oggetto XMLHttpRequest cambia. Nell'applicazione che stai realizzando, la funzione di callback è callback(). La richiami in doCompletion(), in cui callback è stata impostata come valore per la proprietà XMLHttpRequest.onreadystatechange. Ora, implementa la funzione di callback come segue..
  1. Apri nell'editor javascript.js e digita il seguente codice.
    function callback() {
        if (req.readyState == 4) {
            if (req.status == 200) {
                parseMessages(req.responseXML);
            }
        }
    }
    
Un readyState di "4" significa il completamento dell'interazione HTTP. L'API per XMLHttpRequest.readyState indica che ci sono 5 possibili valori e sono:
readyState ValueObject Status Definition
0uninitialized
1loading
2loaded
3interactive
4complete

Si noti che la funzione parseMessages() è chiamata solo quando XMLHttpRequest.readyState vale 4 e lo stato - la definizione del codice di stato HTTP della richiesta - vale "200", ossia ha avuto successo. Definirai parseMessages() più avanti in "Aggiornare il DOM HTML".
Notice that the parseMessages() function is called only when the XMLHttpRequest.readyState is "4" and the status -- the HTTP status code definition of the request -- is "200", signifying a success. You will defineparseMessages() next in Updating the HTML DOM.

Aggiornare il DOM HTML

La funzione parseMessages() gestisce i dati XML in ingresso. Così facendo, si basa su diverse funzioni accessorie, quali appendComposer(), gerElementY() e clearTable(). Devi anche introdurre nuovi elementi nella pagina indice, come una seconda tabella HTML che serva da box di auto-complete, e l'ID per gli elementi di modo che possano essere referenziati in javascript.js. Infine, creerai le nuove variabili corrispondenti agli ID degli elementi in index.php, le inizializzi nella funzione init() precedentemente implementata, e aggiungi qualche qualche funzionalità necessaria ogni volta che index.php è caricato.
Nota: Le funzioni e gli elementi che crei nei seguenti passi lavorano indipendentemente. Si raccomanda di completare la sezione, poi esaminare il codice ottenuto.
  1. Apri index.html nell'editor e digita il codice sottostante nella seconda riga della tabella HTML precedentemente creata.
    <tr>
        <td id="auto-row" colspan="2">
    
        <td/>
    </tr>
    Questa nuova riga, che può essere identificata come 'auto-row', serve al codice JavaScript come punto d'inserimento per una nuova tabella HTML che costituisca il box di auto-complete.
  2. Apri javascript.js nell'editor e metti le seguenti tre variabili in cima al file.
    var completeField;
    var completeTable;
    var autoRow;
  3. Aggiungi le seguenti linee (in grassetto) alla funzione initi().
    function init() {
        completeField = document.getElementById("complete-field");
        completeTable = document.createElement("table");
        completeTable.setAttribute("class", "popupBox");
        completeTable.setAttribute("style", "display: none");
        autoRow = document.getElementById("auto-row");
        autoRow.appendChild(completeTable);
        completeTable.style.top = getElementY(autoRow) + "px";
    }
    Uno scopo di init() è di rendere gli elementi interni a index.html accessibili ad altre funzioni che modificheranno il DOM della pagina. Sopra, lo script crea un nuova tabella HTML, le aggiunge la classe popupBox e modifica l'attributo style dell'elemento in display: none. Infine, ottiene l'elemento il cui id è auto-row e vi inserisce la tabella. In altre parole, il codice HTML modificato appare come segue quando il codice è in esecuzione.
    <tr>
        <td id="auto-row" colspan="2">
            <table class="popupBox" style="display: none"></table>
        <td/>
    </tr>
  4. Aggiungi appendComposer() a javascript.js.
    function appendComposer(firstName,lastName,composerId) {
    
        var row;
        var cell;
        var linkElement;
    
        if (isIE) {
            completeTable.style.display = 'block';
            row = completeTable.insertRow(completeTable.rows.length);
            cell = row.insertCell(0);
        } else {
            completeTable.style.display = 'table';
            row = document.createElement("tr");
            cell = document.createElement("td");
            row.appendChild(cell);
            completeTable.appendChild(row);
        }
    
        cell.className = "popupCell";
    
        linkElement = document.createElement("a");
        linkElement.className = "popupItem";
        linkElement.setAttribute("href", "autocomplete.php?action=lookup&id=" + composerId);
        linkElement.appendChild(document.createTextNode(firstName + " " + lastName));
        cell.appendChild(linkElement);
    }
    Questa funzione crea una nuova riga della tabella, vi inserisce un link al compositore utilizzando i dati passati alla funzione tramite i tre parametri, e inserisce la riga nell'elemento complete-table della pagina indice.
  5. Aggiungi clearTable() a javascript.js.
    function clearTable() {
        if (completeTable.getElementsByTagName("tr").length > 0) {
            completeTable.style.display = 'none';
            for (loop = completeTable.childNodes.length -1; loop >= 0 ; loop--) {
                completeTable.removeChild(completeTable.childNodes[loop]);
            }
        }
    }
    Questa funzione imposta l'attributo display dell'elemento complete-table a 'none', (rendendolo invisibile), e rimuove qualunque voce di compositore creata in precedenza.
  6. Aggiungi getElementY() a javascript.js.
    function getElementY(element){
    
        var targetTop = 0;
    
        if (element.offsetParent) {
            while (element.offsetParent) {
                targetTop += element.offsetTop;
                element = element.offsetParent;
            }
        } else if (element.y) {
            targetTop += element.y;
        }
        return targetTop;
    }
    Questa funzione è applicata per trovare la posizione verticale dell'elemento genitore. E' necessaria perché la posizione attuale dell'elemento, quando visualizzato, è spesso dipendente dal tipo e versione del browser. Nota che l'elemento complete-table, quando visualizzato e contenente i nomi dei compositori, scivola in basso a destra della tabella in cui esiste. L'altezza corretta per il posizionamento è determinata da getElementY().

    Nota: Vedi questa spiegazione dell'offset su http://www.quirksmode.org/.
  7. Modifica la funzione callback() perché chiami clearTable() ogni volta che riceve dei nuovi dati dal server. Qualunque voce di compositore già esistente nel box auto-complete è rimossa prima che lo stesso sia popolato con le nuove voci.
    function callback() {
    
        clearTable();
    
        if (req.readyState == 4) {
            if (req.status == 200) {
                parseMessages(req.responseXML);
            }
        }
    }
  8. Aggiungi parseMessages() a javascript.js.
    function parseMessages(responseXML) {
    
        // no matches returned
        if (responseXML == null) {
            return false;
        } else {
    
            var composers = responseXML.getElementsByTagName("composers")[0];
    
            if (composers.childNodes.length > 0) {
                completeTable.setAttribute("bordercolor", "black");
                completeTable.setAttribute("border", "1");
    
                for (loop = 0; loop < composers.childNodes.length; loop++) {
                    var composer = composers.childNodes[loop];
                    var firstName = composer.getElementsByTagName("firstName")[0];
                    var lastName = composer.getElementsByTagName("lastName")[0];
                    var composerId = composer.getElementsByTagName("id")[0];
                    appendComposer(firstName.childNodes[0].nodeValue,
                        lastName.childNodes[0].nodeValue,
                        composerId.childNodes[0].nodeValue);
                }
            }
        }
    }
La funzione parseMessages() riceve come parametro un oggetto, rappresentazione del documento XML restituito dal file autocomplete.php. La funzione analizza il documento XML, estraendo il firstName, lastName e id do ogni record, quindi passa questi dati a appendComposer(). Ciò produce un aggiornamento dinamico del contenuto dell'elemento compete-table. Per esempio, un record che sia generato e inserito  in complete-table potrebbe apparire come segue:
<tr>
    <td class="popupCell">
        <a class="popupItem" href="autocomplete?action=lookup&id=12">Antonin Dvorak</a>
    </td>
</tr>
L'aggiornamento dinamico dell'elemento complete-table rappresenta il passo finale dell'elaborazione del flusso di comunicazione che ha luogo durante la comunicazione utilizzando Ajax. Questo aggiornamento mappa i dati HTML & CSS inviati per la presentazione nel precedente diagramma di flusso.

Agganciare un Foglio di Stile

A questo punto, hai completato tutto il codice necessario per il funzionamento dell'applicazione. Per vedere il risultato dei tuoi sforzi, prova ad eseguire l'applicazione ora.
  1. Esegui il progetto per vedere come appare nel browser. Clicca il pulsante Run Project (). Il file index.html è visualizzato nel tuo browser.

Per agganciare un foglio di stile alla tua applicazione, crea un file CSS (Cascading Style Sheet) e collegalo alla tua pagina/e di presentazione. Quando lavori con i file CSS, l'IDE fornisce il code completion, e parecchia altre caratteristiche che aiutano nella produzione di regole per i fogli di stile. Queste includono:
  • CSS Style Builder: Una interfaccia progettata per permetterti di creare regole utilizzando una selezione di controlli e widget (Window > Other > CSS Style Builder)
  • CSS Preview: Una finestra di anteprima che, quando metti il cursore in una regola, visualizza un esempio di testo disegnato secondo tale regola.(Window > Other > CSS Preview)
  • Style Rule Editor: Una finestra di dialogo che crea regole basate sulle classi, ID e elementi HTML, e imposta la loro posizione nella gerarchia del documento. (Pulsante Create Rule (), posizionato nella regione in alto a sinistra della toolbar dell'editor CSS)
NetBeans 6.9 fornisce supporto per Rename Refactoring e Find Usages. Tale supporto è disponibile non solo nei file CSS, ma in tutti in fiel che incorporano codice CSS (come HTML e PHP). Gli elementi calsse, id e tipo di CSS possono essere ricostruiti (refactoring) in tutti i file del progetto. Per fare uso di questa caratteristica, premi Ctrl-R su un elemento CSS e usa la finestra di dialogo per rinominare l'elemento. Puoi anche visualizzare in anteprima i cambiamenti prima di realizzare il cambio di nome. Per utilizzare Find Usages, clic con il stato destro su un elemento CSS e scegli Find Usages. Vedi NewAndNoteworthy69m1 per ulteriori dettagli.
Compi i seguenti passi per agganciare un foglio di stile alla tua applicazione.
  1. Nella finestra Projects, tasto destro sul nodo del progetto e scegli New > Cascading Style Sheet (se Cascading Style Sheet non è in elenco, scegli Other. Poi scegli Cascading Style Sheet dalla categoria Other nella procedura guidata New File.)
  2. Nel campo di testo CSS File Name, digita stylesheet.
  3. Clic su Finish. Il nuovo file è aggiunto alla finestra Projects, e aperto nell'IDE dell'editor.
  4. In stylesheet.css, digita le seguenti regole. Puoi fare uso del code completion premendo Ctrl-Spazio nel punto in cui vuoi richiamare un suggerimento.
    body {
       font-family: sans-serif;
       font-size: smaller;
       padding: 50px;
       color: #555;
       width: 650px;
    }
    
    h1 {
       letter-spacing: 6px;
       font-size: 1.6em;
       color: #be7429;
       font-weight: bold;
    }
    
    h2 {
       text-align: left;
       letter-spacing: 6px;
       font-size: 1.4em;
       color: #be7429;
       font-weight: normal;
       width: 450px;
    }
    
    table {
       width: 550px;
       padding: 10px;
       background-color: #c5e7e0;
    }
    
    td {
       padding: 10px;
    }
    
    a {
      color: #be7429;
      text-decoration: none;
    }
    
    a:hover {
      text-decoration: underline;
    }
    
    .popupBox {
      position: absolute;
      top: 170px;
      left: 140px;
    }
    
    .popupCell {
       background-color: #fffafa;
    }
    
    .popupCell:hover {
      background-color: #f5ebe9;
    }
    
    .popupItem {
      color: #333;
      text-decoration: none;
      font-size: 1.2em;
    }
    Fai un controllo sulla validità del CSS facendo clic con il tasto destro nell'editor e scegliendo Check CSS. Qualunque errore è visualizzato nella finestra di Output (Windows > Output).
  5. Apri la finestra CSS Preview scegliendo Window > Other > CSS Preview.
  6. Metti il cursore dentro una regola che modifica testo e colore (per esempio h1). La finestra CSS Preview genera un esempio di visualizzazione del testo nel browser.
    CSS Preview window displaying sample text for h1 rule
  7. Vai alla pagina index.html (premi Ctrl-Tab), e aggiungi un riferimento al foglio di stile tra i tag <head>.
    <link rel="stylesheet" type="text/css" href="stylesheet.css">
    
  8. Esegui ancora l'applicazione. La pagina indice appare nel browser utilizzando il foglio di stile appena creato. Ogni volta che digiti un carattere, una richiesta asincrona è inviata al server, che ritorna dei dati XML preparati da autocomplete.php. Inserendo ulteriori caratteri, il numero di compositori diminuisce per riflettere la nuova lista dei corrispondenti.

Conclusione

Questo conclude l'introduzione ad Ajax. This concludes the Introduction to Ajax. Sperando che tu abbia avuto modo di comprendere che Ajax è solo uno scambio di informazioni su HTTP in background, ed aggiornamento dinamico della pagina in base ai risultati ottenuti.

Puoi notare che questa applicazione ha numerose carenze, per esempio non accade nulla quando il nome del compositore è selezionato dal box auto-complete! Si consiglia di scaricare l'applicazione d'esempio per vedere come ciò può essere implementato utilizzando PHP. Inoltre, potresti voler controllare la validità dell'input per evitare che l'utente inserisca un nome che non esiste nell'archivio dati. Puoi apprendere di più su tali tecniche seguendo altri tutorial su NetBeans PHP Learning Trail.

Articolo originale http://netbeans.org/kb/docs/php/ajax-quickstart.html