martedì 11 novembre 2008

JQuery + thickbox con url dinamici

Ormai da tempo mi affido a jQuery per rendere più dinamica l'interfaccia grafica e non preoccuparmi della portabilità, dopo aver perso il sonno causa browser assolutamente non standard (che non nominerò, ma già sapete..).
Oggi mi trovo a dover sostituire, in un sito abbastanza recente, un parte fatta a popup con una più elegante e moderna versione ajax con tanto di thickbox, plugin che ho usato già per altri lavori.

Il problema è il seguente: allo stato attuale, all'href del link è associato una funzione javascript (selectSite()) che carica parametri in base a selezioni fatte dall'utente in diverse parti della pagina, crea un url con questi parametri e apre un "simpatico" popup con la pagina generata dinamicamente.

Ora, se attivo thickbox direttamente su questo link, esso cambierà l'href associato.
Il risultato è che se poi si cambiano i parametri nel resto del form, un click sul link genererà comunque la richiesta con i vecchi parametri. All'inizio ho pensato a come associare una callback alla chiusura della finestra thickbox per rimettere di nuovo la funzione "selectSite()" all'href del link in questione. Ma mi sembrava un po' macchinosa, soprattutto contando che esistono altri link del genere, con funzioni simili ("selectService()", "selectSupplier()".. etc).

Allora ho pensato di indirizzare il mio refactor in una direzione differente: lasciare intatto il link, ma usarne uno di appoggio fatto apposta per aprire il thickbox e niente più.
Quindi ho creato un link vuoto ed invisibile () ed una funzione a cui si appoggiano selectSite e le sue sorelle:


function loadAjaxContent(url) {
var urlPar = url + "&height=500&width=800";
var nodeId = '#HiddenLink';
if(!$(nodeId).hasClass( "thickbox" )) {
$(nodeId).addClass("thickbox");
tb_init('a.thickbox');
}
$(nodeId).attr("href", urlPar);
$(nodeId).click();
}


Vediamo cosa fa nel dettaglio:

* prepara l'href a partire dall'url (che prima veniva richiamato come popup)
* cerca il link nascosto; se è la prima richiesta aggiungo la classe "thickbox" al link nascosto ed inizializzo thickbox, questo perchè la pagina stessa viene chiamata attraverso ajax e messa dentro un div con innerHTML, quindi l'unico modo per inizializzare thickbox è lanciare l'init dopo il caricamento del contenuto (una callback sull'avvenuto inserimento) oppure on-demand.
* aggiorno l'href del link nascosto e lancio un click su questo.

In questo modo l'href viene aggiornato costantemente, i link non vengono toccati ed il mio refactor va a sostituire i window.open(url) con loadAjaxThickbox(url).. non male, direi..
Ora miglioro alcune cose:
* potrei creare direttamente il link con id HiddenLink in questa funzione
* lancio tb_init('a#HiddenLink') per non appesantire nel caso ci siano diversi thickbox nella pagina
* aggiungo altri parametri per rendere più flessibile la gestione della finestra (altezza, larghezza, modal..)

8 commenti:

Davy ha detto...

Ciao, premetto che non sono affatto un esperto ed ho scoperto solo oggi thickbox.
Il mio problema è solo questo: come avviare thickbox automaticamente?
Mi spiego: dovrei avviare automaticamente una pagina news.html qundo apro la mia home page con la funzione thickbox, senza cliccare su un url specifico. Tu ci sei riuscito, ma dire iil vero ... non ci ho capito niente! Mi puoi aiutare? Grazie in anticipo.

Davide

Shatsar ha detto...

Ciao Davide,
la cosa più rapida secondo me è questa: crea prima un link che attivi thickbox al click. Una volta verificato che funziona tutto metti un id al link (tipo "aprinews") e poi metti in fondo alla pagina
<script type="text/javascript">
$(document).ready(function () {
$("a#aprinews").click();
});
</script>

Infine imposta lo stile css al link in modo da non renderlo visibile..

Davy ha detto...

Ciao, ti ringrazio della risposta!
Solo che, come ti avevo detto, sono veramente 'gnorante in materia! E più di copiare i vari codici non sono capace!
Come si fa a mettere l'id al link - come da te suggerito - e impostare il css al link in modo che sia invisibile?
Scusa la seccatura e ti ringrazio della pazienza!

Davy ha detto...

Ci sono riuscito! Come posso impostare, però il ritardo di "aprinews")
Grazie ancora.

Davide

Shatsar ha detto...

Ciao Davide,
una soluzione è impostare il timeout:
$(document).ready(function () {
setTimeout('$("a#aprinews").click()', 1000);
});

Davy ha detto...

Grazie ancora della tua gentilezza!
:-)

Davy ha detto...

Grazie ancora della tua gentilezza!
:-)

Davy ha detto...

Grazie ancora della tua gentilezza!
:-)