Select concatenate PHP con jQuery/Ajax

Oggi affrontiamo insieme un argomento che mi è mstato richiesto molte volte. Vediamo come creare un motore per select concatenate in PHP usando jQuery/Ajax.

Questo è un argomento già semi-trattato molto tempo fa in cui vi avevo proposto una soluzione molto semplice ma anche molto poco professionale e “usabile” al tempo stesso. Puoi vedere il mio vecchio articolo qui. 

AVVISO: per una trattazione completa devi prima aver letto questo articolo: Invio dati via POST con ajax.

GUARDA LA DEMO >>

Panoramica Progettuale

Lo scopo del progetto è di creare delle select dinamiche. Il “tema” che ho scelto per questo esempio è quello di gadget e libri di targetweb in vendita. Il mio scopo è di far apparire (se inserito nel database) un prezzo minimo e massimo che varia a seconda del prodotto scelto. Tutti i dati sono ovviamente recuperati dinamicamente con Ajax.

Impostazione del database mysql

Per il nostro database andiamo a creare due tabelle essenziali:

TABELLA TIPOLOGIA

Conterrà il prodotto principale e sarà (come si suol dire in gergo tecnico) la nostra “discriminante” per far apparire il prezzo dinamico. Ci servono solo due campi: id_tipologia(INT) e titolo_tipologia(VARCHAR o TEXT). Il campo titolo_tipologia verrà usato per far “comunicare” il flusso di dati.

TABELLA CARATTERISTICHE

 Questa tabella conterrà invece le caratteristiche che vogliamo rendere dinamiche in base alla tipologia scelta dall’utente. Nel nostro caso la tabella avrà essenzialmente 4 campi: id_car(INT), prezzo_base(VARCHAR), prezzo_massimo(VARCHAR), e tipologia_collegata(VARCHAR).

Quest’ultimo campo è molto importante in quanto fa di fatto comunicare i due database e i dati. Senza quest’ultimo infatti non sapremmo mai a cosa si riferisce quel determinato prezzo base e massimo.

Ovviamente l’esempio dei prezzi è puramente dimostrativo, potete rendere dinamico qualsiasi campo e potete usare questo “setting” per adattare questo esempio alle vostre esigenze. Ad esempio potremmo mettere come tipologia: Carta fotografica e come variabili al posto di prezzo_base e prezzo_massimo potremmo usare costo_grana_minimo/massimo o molto altro.

NOTA: prima di avventurarvi nella creazione di select dinamiche sviscerate per bene le vostre reali esigenze e mettete giù una struttura di database SOLIDA per porre delle basi funzionanti al 100%.

 NOTA2: Questo esempio usa un’impostazione a due campi dinamici (prezzo_base e prezzo_massimo), volendo potete ovviamente rendere un solo campo dinamico a seconda delle vostre necessità.

Form HTML

Fatte queste doverose premesse (spero di essere stato il più chiaro possibile nel precedente punto) ecco la struttura “visiva” ovvero il front-end che vedrà l’utente finale. Andiamo a comporre un form con due blocchi di select distinte. Per tutto questo esempio ho usato PDO ma è possibile replicare il tutto anche con mysql classico (SCONSIGLIATO). Ecco il codice:

    <form>

    	   <p>tipologia</p>
            <select name="tipologia" id="tipologia">
                <option>Scegli...</option>

                <?php 
                //recupero tipologie dal database
                $sql = "SELECT * FROM tipologia";
                $q = $db->prepare($sql);
                $q->execute();

                $q->setFetchMode(PDO::FETCH_ASSOC);

                while($row = $q->fetch()) {  

                ?>

            <option><?php echo $row['titolo_tipologia']; ?></option>
            <?php  }  //fine recupero tipologie ?>
            </select>

            <br />

           <p>caratteristiche</p>
            <select name="caratteristiche" id="caratteristiche">
            <option>Scegli...</option>
            </select>

    </form>

Il loop per il recupero delle tipologie attualmente presenti nel database va fatto subito dopo <select> e NON prima. Ecco alcune considerazioni:

– Ho aggiunto un <option>Scegli..</option> fuori dal loop per rendere più gradevole il tutto agli occhi dell’utente. Oltre a questo si fa capire al visitatore che si deve effettuare una scelta.

– La seconda select (caratteristiche) per ora ovviamente è vuota perchè andrà riempita grazie ad ajax in base a cosa sceglie il visitatore nel primo select.

– Ogni select ha un id in quanto i dati vanno recuperati con ajax. Se non sai di cosa parlo leggi prima questo articolo.

– Prima del codice qui sopra in verità va inserito ovviamente il codice di connessione al database (tutto presente nella demo e nel pacchetto zip finale).

Codice Ajax/jQuery

Ora che abbiamo riempito la prima select (ovvero la discriminante di scelta) dobbiamo riempire la seconda in base a cosa sceglie l’utente finale. ecco il codice ajax per inviare i dati al nostro file di elaborazione che si occuperà di far apparire i risultati direttamente dentro la select.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script>
$(document).ready(function() {

	$('#tipologia').change(function() {

		//recupero variabile "discriminante"
		var tipologia = $("#tipologia").val();

		//chiamata ajax
		$.ajax({

		type: "POST",

		url: "http://localhost/select-concatenate-targetweb/elaborazione_dati.php",

		data: "tipologia=" + tipologia,
		dataType: "html",

		success: function(msg)
		{
		$("#caratteristiche").html(msg);//stampa i risultati dentro la seconda select
		},
		error: function()
		{
		alert("Chiamata fallita, si prega di riprovare..."); //sempre meglio impostare una callback in caso di fallimento
		}
	});
 });	

});//FINE DOM
</script>

Come sempre vi invito a visionare il codice commentato. Ad ogni modo il funzionamento è semplice: grazie a .change() di jQuery possiamo inviare la tipologia scelta ogni volta che l’utente la cambia. Lo script viene eseguito così ad ogni cambio di scelta della prima select. Con html(msg) stampiamo poi il risultato del file elaborazione_dati.php direttamente dentro la select “caratteristiche”.

File di elaborazione dati

Il file di elaborazione dati (elaborazione_dati.php) si occupa di gestire la seconda select in base alla scelta dell’utente. Ecco il codice:

<?php
$tipologia_selezionata = $_POST['tipologia'];
?>
<?php
	$sql = "SELECT * FROM caratteristiche WHERE tipologia_collegata = '$tipologia_selezionata' ";
	$q = $db->prepare($sql);
	$q->execute();

	$q->setFetchMode(PDO::FETCH_ASSOC);

	echo "<option>---</option>";

	while($caratt = $q->fetch()) {  

	 $prezzo_base = $caratt['prezzo_base'];
	 $prezzo_massimo = $caratt['prezzo_massimo'];

if ($prezzo_base == "") { } else { echo "<option>$prezzo_base</option>";}

if ($prezzo_massimo == "") { } else { echo "<option>$prezzo_massimo</option>";}

}  //while loop

?>

Anche in questo caso ovviamente prima del recupero della variabile va inserito anche il file di connessione al database.  Vediamo il dettaglio del codice:

Step1: recupero della variabile tipologia

$tipologia_selezionata = $_POST['tipologia'];

Step2: Query recupero dati (tipologia_collegata è la discriminante):

	$sql = "SELECT * FROM caratteristiche WHERE tipologia_collegata = '$tipologia_selezionata' ";
	$q = $db->prepare($sql);
	$q->execute();

	$q->setFetchMode(PDO::FETCH_ASSOC);

	echo "<option>---</option>"; //serve a rendere più gradevole la scelta

	while($caratt = $q->fetch()) {

Step3: associazione e filtraggio degli elementi vuoti (opzionale)

 $prezzo_base = $caratt['prezzo_base'];
 $prezzo_massimo = $caratt['prezzo_massimo'];

if ($prezzo_base == "") { } else { echo "<option>$prezzo_base</option>";}

if ($prezzo_massimo == "") { } else { echo "<option>$prezzo_massimo</option>";}

Grazie a dei semplici if possiamo evitare che vengano stampati anche i campi vuoti. Gli ultimi echo (se presenti) vengono passati via ajax al file di front-end index.php che li mette grazie allo script creato precedentemente, all’interno della select “caratteristiche”.

Conclusioni

Una volta assemblato il tutto avrete creato la vostra prima select dinamica con PHP e jQuery/Ajax. Non male vero? 😉

LICENZA: Lo script è usabile e modificabile in tutte le sue parti! Se lo hai migliorato o usato per i tuoi progetti fammelo sapere nei commenti o nei social network, potresti essere protagonista su targetweb.it!

GUARDA LA DEMO COMPLETA >>

Per scaricare il file completo devi condividere l'articolo su un social network.

NOTA INSTALLAZIONE: Per far funzionare il pacchetto zip sostiuisci al posto di “tuapassword” la tua password phpmyadmin. Righe da modificare: – index.php (riga 73)  – elaborazione_dati.php (riga 9). Se ti appare l’errore “chiamata fallita” devi modificare il percorso assoluto al file elaborazione_dati.php presente nel file index.php all’interno dello script.

Se ti è servito questo articolo condividi qui sotto o commentalo, fa sempre piacere sentire le vostre opinioni! Enjoy!

Lascia la tua opinione

13 comments

  • Ottimo Articolo… Fatto veramente Benissimo…

  • Ciao Riccardo,
    le tue lezioni sull’AJAX sono molto chiare e scorrevoli, bravo bravo! 🙂
    Però ho un problema: perchè riadattando lo script alle mie esigenze, la mia url non funziona?! :/

    ho inserito sia il nome del file, che l’intero percorso, ma mi esce sempre l’alert! :/

    • Ehi risolto risolto! 😀
      Ho messo solo parte del percorso del file in questione, mi spiego:

      $(document).ready(function()
      {
      $('#settore_attivita2').change(function()
      {
      var settore_attivita2 = $("#settore_attivita2").val();

      $.ajax(
      {
      type: "POST",
      url: "../modules/mod_e-simposio_semico/categoria.php",
      data: "settore_attivita2="+settore_attivita2+"&host="+host+"&user="+user+"&password="+password+"&database="+database,
      dataType: "html",
      success: function(msg)
      { $("#id_categoria").html(msg); },
      error: function()
      { alert("Chiamata fallita, si prega di riprovare..."); }
      });
      });
      });

      $(document).ready(function()
      {
      $('#id_categoria').change(function()
      {
      var id_categoria = $("#id_categoria").val();

      $.ajax(
      {
      type: "POST",
      url: "../modules/mod_e-simposio_semico/prodotti.php",
      data: "id_categoria="+id_categoria+"&host="+host+"&user="+user+"&password="+password+"&database="+database,
      dataType: "html",
      success: function(msg)
      { $("#id_prodotti").html(msg); },
      error: function()
      { alert("Chiamata fallita, si prega di riprovare..."); }
      });
      });
      });

      e la cosa si può ripetere anche per più menù a tendina! 🙂

  • Ma se per esempio ho un’altra variabile da passare al file elaborazionedati.php ?

    mi spiego meglio due selezioni dinamiche e un risultato … come adesso ma con una variabile in più ,,, per altro già selezionata

    puoi aiutarmi ?

    grazie

    nicola

  • Ciao articolo interessante, vorrei scaricare il pacchetto zip, ho condiviso su facebook ma non ho capito come scaricare il file.
    Ti ringrazio
    Pino

  • articolo molto interessante! Ho elaborato qualcosa di simile ma ho dei problemi di compatibilità con alcune versioni di IE mentre tutto funziona correttamente con Google Chrome e Firefox. Ho verificato il tuo esempio su IE 10 Windos 8 e il comportamento è corretto. Hai mai avuto segnalazioni di incompatibilità con IE? Hai dei consigli in merito. Grazie tante.

  • Articolo molto utile, spiegato veramente bene. Complimenti!
    Mi sono permesso di utilizzarlo, risponde proprio a quello che cercavo.
    Grazie.

  • ciao Riccardo,
    Praticamente ho un form di ricerca con CITTA’ e AZIENDA vorrei realizzare una select in cascata. Mi spiego meglio.
    L’utente scrive nella label, appare la lista di città (uso l’autocomplete) e seleziona la città interessata.
    Dopo aver selezionato la città l’utente seleziona l’azienda con la stessa modalità.

    Io vorrei che l’autocomplete visualizzi nella lista SOLO le aziende della città inserita in precedenza.

    Tutti gli script che trovo in web fanno l’esempio di regione-provincia-comune. Nel mio caso sarebbe una lista infinita di città e aziende quindi uso l’autocomplete.

    Uso DB Mysql 2 tabelle Città e aziende

    Spero di essere stato chiaro.

    Secondo te come posso fare??

    GRAZIE

  • Buongiorno…..ho eseguito login con facebook ma non posso scaricare il file con il codice completo….
    come è possibile scaricarlo?

    grazie

    Alberto

  • Grazie! Articolo veramente utile!

  • Articolo ben fatto ma ho un problema..Quando esegue la query mi mostra tutti i campi della 2 select e non solo quello selezionato; inoltre cliccando sulla prima scelta della 2 select non mi funziona

  • Se buongiorno si vede dal mattino oggi sto a letto.

    Non ho letto tutto l’articolo (la demo non funziona per errori di connessione al db e quindi non so se può servirmi e vale la pena leggerlo o no) e non lo leggo neanche dato è evidente l’autore è un poveraccio che non scrive ne per passione e neppure perché sa cosa sta scrivendo ma semplicemente per una condivisione sui social network.

    Condividere un contenuto dovrebbe essere un premio del tipo: Mi piace il tuo lavoro e lo condivido con gli amici.

    Non un qualcosa di simile a: Ei…ho scritto un articolo che non vale un piffero, non so assolutamente di cosa sto parlando, l’ho scopiazzato qua e la, non sono capace di far funzionare la demo ma se per caso vuoi passare un paio di ore a vedere come ho copiato bene mi devi prima dare una condivisione.

    Ma va a cagher……

    • Buongiorno Marco, non capisco molto il senso del commento, non obbligo nessuno a condividere ci mancherebbe, se si vuole supportare il progetto lo si fa altrimenti nessun problema… cosa ti ha dato così fastidio?

      Altresì scusami ma come si permette di fare certe affermazioni diffamatorie del tipo: “articolo scoppiazzato” etc.?

      L’articolo è stato fatto molto tempo fa ormai, non mi ero accorto che la demo non andasse, ad ogni modo l’errore di connessione al db è relativo al fatto che ho cambiato hosting e non mi sono messo ad aggiornare tutti i file demo creati nel corso di 6 anni di blog (mi scuserà ma ho altro da fare per fortuna). Se invece di parlare provasse a replicare e studiarne il funzionamento sono sicuro che basterà far puntare correttamente al SUO db mettendo i giusti parametri per far andare il tutto. Appena avrò modo in ogni caso modificherò.

      ricordo, che scrivo a fini non lucrativi, i banner che vede servono solo per rientrare nelle spese di hosting…

      Saluti (sicuramente più composti dei suoi). Ad ogni modo (spero) a mai più rivederci 😉

×