[PHP] Problema Form/Ajax e Refresh della pagina
Dopo aver googlato un'eternità ho deciso di postare qui un mio problema con la programmazione web dinamica e php...
PREMESSA: sto tentando di creare dei selettori per filtrare una query il cui risultato modifica una cartina generata con il visualizator di google, il problema è che quando vengono passati i dati con metodo POST tramite ajax al server, la pagina viene ricaricata per intero annullando, di fatto, eventuali altre selezioni contestuali (come la checkbox che ho inserito per effettuare il test); nonostante questo la cartina viene generata correttamente.
Sto lavorando in locale su xammp.
Ho provato in tante maniere diverse e senza risultato, la pagina si ricarica ogni volta da zero restituendomi la query aggiornata e annullando eventuali selezioni effettuate.
Come posso fare per far si che il server accetti i dati tramite metodo POST restituendomi un caricamento della sola cartina e non dell'intera pagina?
Grazie per l'aiuto.
PS: Il codice nativo era splittato ma per un tentativo di "visione di insieme" lo ho ricompilato in un unico file *.php
PREMESSA: sto tentando di creare dei selettori per filtrare una query il cui risultato modifica una cartina generata con il visualizator di google, il problema è che quando vengono passati i dati con metodo POST tramite ajax al server, la pagina viene ricaricata per intero annullando, di fatto, eventuali altre selezioni contestuali (come la checkbox che ho inserito per effettuare il test); nonostante questo la cartina viene generata correttamente.
Sto lavorando in locale su xammp.
<html> <head> <?php /* Qui c'erano i dettagli riguardanti la connessione al database, li ometto in quanto funzionanti e non inerenti al problema*/ if(isset($_POST['genere'])) { $selection = $_POST['genere']; $sql="SELECT COD, Value FROM view_codici WHERE `Classe di et` LIKE '15 anni e pi' AND `Titolo di studio` LIKE 'totale' AND Cittadinanza LIKE 'totale' AND Genere LIKE '$selection' AND `Tempo_e_frequenza` LIKE 'T2-2012'"; $res=mysql_query($sql,$conn); if (!$res) die ("Errore query" .mysql_error()); } ?> <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> <script type='text/javascript' src='https://www.google.com/jsapi'></script> <script type='text/javascript'> google.load('visualization', '1', {'packages': ['geomap']}); google.setOnLoadCallback(drawMap); function drawMap() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Codice'); data.addColumn('number', 'Valore'); data.addRows([ <?php while($r = mysql_fetch_assoc($res)) { echo "['$r[COD]', $r[Value]],"; } ?> ]); var options = {}; options['dataMode'] = 'regions'; options['region'] = 'IT'; var container = document.getElementById('map_canvas'); var geomap = new google.visualization.GeoMap(container); geomap.draw(data, options); }; </script> <script type=text/javascript> function checkUncheck() { $('#check').click(function() { if (this.checked) { $("#id2").show(); } else { $("#id2").hide(); } }); } $(document).ready(function() { <!-- con la funzione checkUncheck al caricamento della pagina veniva ignorata la cond di partenza --> $('#id2').hide(); }); </script> <script type="text/javascript"> function submitForm() { $.ajax({type:'POST', url: 'proto5.php', data:$('#x').val()}); } </script> </head> <body onload="checkUncheck();"> <input type="checkbox" id="check" name="comparative" value="comparative" uncheck>Abilita Moadalità Comparativa<br> <div id="id1"> <form action="proto5.php" method="post" id="x" onsubmit="submitForm();"> <select name="Genere" onsubmit="return submitForm();"> <option selected>Scegli</option> <option value="totale">totale</option> <option value="maschi">maschile</option> <option value="femmine">femminile</option> </select> <input type="submit" name="submit" value="Submit" /> </form> <div id='map_canvas'></div> </div> <div id="id2"> <form method="post"> <select name="Genere" onchange="this.form.submit();"> <option selected>Scegli</option> <option value="totale">totale</option> <option value="maschi">maschile</option> <option value="femmine">femminile</option> </select> </form> <div id='map_canvas'></div> </div> </body> </html>
Ho provato in tante maniere diverse e senza risultato, la pagina si ricarica ogni volta da zero restituendomi la query aggiornata e annullando eventuali selezioni effettuate.
Come posso fare per far si che il server accetti i dati tramite metodo POST restituendomi un caricamento della sola cartina e non dell'intera pagina?
Grazie per l'aiuto.
PS: Il codice nativo era splittato ma per un tentativo di "visione di insieme" lo ho ricompilato in un unico file *.php
Risposte
Suppongo il form:
Ammetto che è la prima volta che mi affaccio a jQuery venendo da Javascript, e ovviamente avrò tempo e modo di assimilarlo.
Detto questo, con l'istruzione che mi hai fornito, non avviene il caricamento della nuova mappa con i nuovi dati forniti dal filtraggio rimanendomi la pagina completamente bianca. Ho controllato con firebug e non rileva alcun errore.
Qualche idee su quale possa essere la causa?
Grazie comunque per ogni aiuto ^^
Detto questo, con l'istruzione che mi hai fornito, non avviene il caricamento della nuova mappa con i nuovi dati forniti dal filtraggio rimanendomi la pagina completamente bianca. Ho controllato con firebug e non rileva alcun errore.
Qualche idee su quale possa essere la causa?
Grazie comunque per ogni aiuto ^^
"~Rose":
Come posso fare per far si che il server accetti i dati tramite metodo POST restituendomi un caricamento della sola cartina e non dell'intera pagina?
Non puoi farlo in questo modo. Devi trovare un'altra strada.
"Rggb":
[quote="~Rose"]Come posso fare per far si che il server accetti i dati tramite metodo POST restituendomi un caricamento della sola cartina e non dell'intera pagina?
Non puoi farlo in questo modo. Devi trovare un'altra strada.[/quote]
in pratica mi stai dicendo che non è possibile, ma a causa di cosa? Implementazione errata del codice? Il metodo POST refresha per forza il contenuto della pagina? Giusto per capire dove è l'errore di fondo e evitarlo in futuro per quanto possibile.
"~Rose":
Il metodo POST refresha per forza il contenuto della pagina?
"Refresha"?

Comunque sì, il problema è quello (come ho detto prima: alla domanda "come posso fare per..." ho risposto "non puoi"). Del resto, se pensi per un attimo a come funziona il protocollo HTTP alla risposta ci arrivavi anche da solo, no?
In pratica non è un "errore" - è una limitazione, e quindi devi aggirarla.
Allora ho rivisto il mio codice alla luce del primo elaborandolo anche con firebugs cercando soluzioni ma non ne trovo... Quindi torno a chiedere...
Il codice funziona egregiamente dato che il profiler mostra chiaramente che il metodo POST arriva a destinazione e restituisce in output i dati che mi servono per la creazione della mappa. L'unico problema è che non ricaricando la pagina non viene ricaricata la mappa nel div "map_canvas" non mostrando, di conseguenza, nulla.
A questi punti non cerco più di non far ricaricare la pagina (dato che prende i dati con metodo POST senza dover ricaricare) penso piuttosto che sia sufficente ricaricare (al termine dell'elaborazione della query in php) la funzione che disegna la mappa... solo che come ho detto prima, è la prima volta che mi affaccio a Jquery e non saprei bene come andare a implementare il tutto.
Qualcuno ha qualche buona idea?
<html> <head> <?php /*stesso discorso di prima, i dati per la connessione al database sono irrilevanti dato che funziona*/ $sql= "USE csv_db"; $ok = mysql_query ($sql, $conn); if(!$ok) die("imposs. selezionare DB: ".mysql_error()); if(isset($_REQUEST['genere'])) { $selection = $_REQUEST['genere']; $titolo = $_REQUEST['titolo']; $sql="SELECT COD, Value FROM view_codici WHERE `Classe di et` LIKE '15 anni e pi' AND `Titolo di studio` LIKE '$titolo' AND Cittadinanza LIKE 'totale' AND Genere LIKE '$selection' AND `Tempo_e_frequenza` LIKE 'T2-2012'"; $res=mysql_query($sql,$conn); if (!$res) die ("Errore query" .mysql_error()); } ?> <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> <script type='text/javascript' src='https://www.google.com/jsapi'></script> <script type='text/javascript'> google.load('visualization', '1', {'packages': ['geomap']}); google.setOnLoadCallback(drawMap); function drawMap() { var data = new google.visualization.DataTable(); data.addColumn('string', 'Codice'); data.addColumn('number', 'Valore'); data.addRows([ <?php while($r = mysql_fetch_assoc($res)) { echo "['$r[COD]', $r[Value]],"; } ?> ]); var options = {}; options['dataMode'] = 'regions'; options['region'] = 'IT'; var container = document.getElementById('map_canvas'); var geomap = new google.visualization.GeoMap(container); geomap.draw(data, options); }; </script> <script type=text/javascript> function checkUncheck() { $('#check').click(function() { if (this.checked) { $("#id2").show(); } else { $("#id2").hide(); } }); } $(document).ready(function() { <!-- con la funzione checkUncheck al caricamento della pagina veniva ignorata la cond di partenza --> $('#id2').hide(); $("#x").on('submit',function(event) { event.preventDefault(); $.ajax({type:'POST', url: 'proto7.php', data:$(this).serialize()}); }); }) </script> </head> <body onload="checkUncheck();"> <input type="checkbox" id="check" name="comparative" value="comparative" uncheck>Abilita Moadalità Comparativa<br> <div id="id1"> <form id="x" action="#"> <select name="genere"> <option selected>Scegli</option> <option value="totale">totale</option> <option value="maschi">maschile</option> <option value="femmine">femminile</option> </select> <select name="titolo"> <option selected>Scegli</option> <option value="totale">totale</option> <option value="diploma">diploma</option> </select> <input type="submit" name="submit" value="Submit" /> </form> <div id='map_canvas'></div> </div> <div id="id2"> <form method="post"> <select name="genere" onchange="this.form.submit();"> <option selected>Scegli</option> <option value="totale">totale</option> <option value="maschi">maschile</option> <option value="femmine">femminile</option> </select> </form> <div id='map_canvas'></div> </div> </body> </html>
Il codice funziona egregiamente dato che il profiler mostra chiaramente che il metodo POST arriva a destinazione e restituisce in output i dati che mi servono per la creazione della mappa. L'unico problema è che non ricaricando la pagina non viene ricaricata la mappa nel div "map_canvas" non mostrando, di conseguenza, nulla.
A questi punti non cerco più di non far ricaricare la pagina (dato che prende i dati con metodo POST senza dover ricaricare) penso piuttosto che sia sufficente ricaricare (al termine dell'elaborazione della query in php) la funzione che disegna la mappa... solo che come ho detto prima, è la prima volta che mi affaccio a Jquery e non saprei bene come andare a implementare il tutto.
Qualcuno ha qualche buona idea?

Scusa la "latenza", ma ho ricontrollato il codice solo adesso (bisogna aver un po' di tempo per queste cose).
Secondo me è sufficiente tu aggiusti la drawMap. In pratica pre-carichi i vari possibili risultati in php (anche se quel \$selection impostato solo su condizione non mi piace molto) creando più resultset o un array di resultset. Poi in Javascript modifichi la funzione:
A questo punto passare i valori con POST serve solo per la prima volta, e per le successive selezioni devi mettere eventi onChange per ricaricare la mappa (ovvero richiamare la funzione da JS). Facci sapere, anche se hai già risolto.
Secondo me è sufficiente tu aggiusti la drawMap. In pratica pre-carichi i vari possibili risultati in php (anche se quel \$selection impostato solo su condizione non mi piace molto) creando più resultset o un array di resultset. Poi in Javascript modifichi la funzione:
//... if (quel_che_vuoi_controllare == "uno") { // condizione "uno" data.addRows([ <?php while($r = mysql_fetch_assoc($res1)) { // primo resultset echo "['$r[COD]', $r[Value]],"; } ?> } else if (quel_che_vuoi_controllare == "due" ) { // condizione "due" data.addRows([ <?php while($r = mysql_fetch_assoc($res2)) { //secondo resultset echo "['$r[COD]', $r[Value]],"; } ?> } // et al...
A questo punto passare i valori con POST serve solo per la prima volta, e per le successive selezioni devi mettere eventi onChange per ricaricare la mappa (ovvero richiamare la funzione da JS). Facci sapere, anche se hai già risolto.
Allora, ho risolto xD
In pratica il passaggio del serialize con ajax avveniva con successo ma ricevevo come risposta l'intero html completo... Non avrebbe mai generato nulla!
Per risolvere ho cambiato strategia, ho compilato in php server side una matrice definendo manualmente le variabili di base e caricando con il while i dati dal database via php esterno:
Dato che ora la mia "tabella"/matrice è codificata in JSON il codice di caricamento del Geomap cambia in questo modo:
Ora funziona, la pagina non viene ricaricata a ogni submit e la mappa viene generata correttamente. Unico lato negativo di tutto questo è il tempo di caricamento che si rivela essere più lento del previsto, ma questo è un problema legato alla natura in flash dell'applicazione. Grazie mille per l'aiuto a tutti ^^
In pratica il passaggio del serialize con ajax avveniva con successo ma ricevevo come risposta l'intero html completo... Non avrebbe mai generato nulla!
Per risolvere ho cambiato strategia, ho compilato in php server side una matrice definendo manualmente le variabili di base e caricando con il while i dati dal database via php esterno:
$response = array(); $response[0][0] = "codice"; $response[0][1] = "valore"; $i=1; while($r = mysql_fetch_assoc($res)) { $response[$c][0] = "$r[COD]"; $response[$c][1] = "$r[Value]"; $i++; } print(json_encode($response))
Dato che ora la mia "tabella"/matrice è codificata in JSON il codice di caricamento del Geomap cambia in questo modo:
$("#x").on('submit',function(event) { event.preventDefault(); $.getJSON("protoext.php", $('#x').serialize(), function(dataJson){ var data = new google.visualization.arrayToDataTable(dataJson); ecc....
Ora funziona, la pagina non viene ricaricata a ogni submit e la mappa viene generata correttamente. Unico lato negativo di tutto questo è il tempo di caricamento che si rivela essere più lento del previsto, ma questo è un problema legato alla natura in flash dell'applicazione. Grazie mille per l'aiuto a tutti ^^
Boia, dé! Ti piace complicarti la vita, eh?
