jQuery http://blogs.ugidotnet.org/rgm/category/jQuery.aspx jQuery it-IT Gian Maria Ricci Subtext Version 2.6.0.0 jQuery tip #8 &ndash; caricare dinamicamente parti di pagina con jQuery.load() http://blogs.ugidotnet.org/rgm/archive/2009/06/15/jquery-tip-8-ndash-caricare-dinamicamente-parti-di-pagina-con.aspx <p>Nei tip precedenti si è visto come comunicare con il server con la chiamata getJSON e restituiendo dalla pagina aspx un oggetto .net serializzato JSON. In molte situazioni è comunque conveniente formattare l’html direttamente lato server. Grazie a jQuery caricare parti di pagina dinamicamente è un gioco da ragazzi. </p> <p>Lo script del tip 8 è il seguente.</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:0d39ce0f-6e1c-49a2-8598-e5dc87a35cd9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">$(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { $(</span><span style="color: #000000;">'</span><span style="color: #000000;">[id=btnGetData]</span><span style="color: #000000;">'</span><span style="color: #000000;">).log(</span><span style="color: #000000;">'</span><span style="color: #000000;">button</span><span style="color: #000000;">'</span><span style="color: #000000;">).click(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> button </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">; </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> code </span><span style="color: #000000;">=</span><span style="color: #000000;"> $(</span><span style="color: #000000;">'</span><span style="color: #000000;">[id=txtCode]</span><span style="color: #000000;">'</span><span style="color: #000000;">).val(); $(</span><span style="color: #000000;">'</span><span style="color: #000000;">.result</span><span style="color: #000000;">'</span><span style="color: #000000;">).load( </span><span style="color: #000000;">'</span><span style="color: #000000;">/Tip8/CustomerService.aspx [id=thecontent]</span><span style="color: #000000;">'</span><span style="color: #000000;">, { Code: code }); </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">false</span><span style="color: #000000;">; }); });</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Come si può vedere per cambiare il contenuto del div principale non si fa altro che chiamare la funzione load(). In questo caso il primo parametro è la url che restituisce i dati seguita da uno spazio e poi da un selettore opzionale (in questo caso [id=thecontent]) che va ad individuare un elemento della pagina restituita dalla chiamata. Come si può notare in questo caso non c’è bisogno di una callback, perchè jQuery va direttamente a sostituire il contenuto restituito dalla chiamata all’elemento su cui si è invocata la funzione load. Lato server la pagina CustomerService ora è cosi fatta</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:0b9ae2b8-f5b5-4d74-9e2d-6d080ad84614" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">body</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">form </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">="form1"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">div </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">="thecontent"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">h1</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Customer </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:Label </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="id"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #FF0000;"> Text</span><span style="color: #0000FF;">="Label"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">asp:Label</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">h1</span><span style="color: #0000FF;">&gt;&lt;</span><span style="color: #800000;">br </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">b</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Name:</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">b</span><span style="color: #0000FF;">&gt;&lt;</span><span style="color: #800000;">asp:Label </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="Name"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #FF0000;"> Text</span><span style="color: #0000FF;">="Label"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">asp:Label</span><span style="color: #0000FF;">&gt;&lt;</span><span style="color: #800000;">br </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">b</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">ContactName:</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">b</span><span style="color: #0000FF;">&gt;&lt;</span><span style="color: #800000;">asp:Label </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="ContactName"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #FF0000;"> Text</span><span style="color: #0000FF;">="Label"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">asp:Label</span><span style="color: #0000FF;">&gt;&lt;</span><span style="color: #800000;">br </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">b</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;">Address:</span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">b</span><span style="color: #0000FF;">&gt;&lt;</span><span style="color: #800000;">asp:Label </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="Address"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #FF0000;"> Text</span><span style="color: #0000FF;">="Label"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">asp:Label</span><span style="color: #0000FF;">&gt;&lt;</span><span style="color: #800000;">br </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">form</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">body</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">html</span><span style="color: #0000FF;">&gt;</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>In questo caso ho creato un po di html, lato codice non si fa altro che popolare il contenuto delle label, il risultato è il seguente.</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/rgm/WindowsLiveWriter/jQuerytip8caricaredinamicamentepart.load_F412/image_2.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="215" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/rgm/WindowsLiveWriter/jQuerytip8caricaredinamicamentepart.load_F412/image_thumb.png" width="298" border="0" /></a> </p> <p>Come si può vedere il contenuto della pagina CustomerSErvice viene sostituito al div originale. Per maggiori dettagli potete leggere il mio <a href="http://www.ugidotnet.org/Article/Detail/739">terzo articolo su jQuery pubblicato su ugi</a>.</p> <p>Alk.</p> <p>Tags: <a href="http://technorati.com/tag/jQuery" rel="tag">jQuery</a></p><img src="http://blogs.ugidotnet.org/rgm/aggbug/96435.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2009/06/15/jquery-tip-8-ndash-caricare-dinamicamente-parti-di-pagina-con.aspx Mon, 15 Jun 2009 18:21:30 GMT http://blogs.ugidotnet.org/rgm/archive/2009/06/15/jquery-tip-8-ndash-caricare-dinamicamente-parti-di-pagina-con.aspx#feedback http://blogs.ugidotnet.org/rgm/comments/commentRss/96435.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/96435.aspx jQuery tip #6 &ndash; segnalare all&rsquo;utente le chiamate ajax http://blogs.ugidotnet.org/rgm/archive/2009/05/21/jquery-tip-6-ndash-segnalare-allrsquoutente-le-chiamate-ajax.aspx <p>Nel tip5 ho mostrato come interrogare il server con getJSON, per questo tip ho semplicemente aggiunto nella pagina CustomerService.aspx una istruzione Thread.Sleep(3000) per fare attendere tre secondi il rendering della pagina. Lo scopo è simulare una operazione lunga.</p> <p>In situazioni in cui la risposta del server non può essere stimata (praticamente sempre), è necessario mostrare all’utente un qualche segnale che l’operazione è in corso, in modo che non possa più premere nel bottone, ma soprattutto sia avvertito visualmente che il sistema non è bloccato ma sta facendo qualche cosa.</p> <p>Questa operazione è cosi frequente che è stata implementata come plugin nel file jqueryext.js, le due estensioni si chiamano quindi setwait() e clearwait(), rispettivamente per impostare uno stato di attesa per un div e riportare il div alla situazione originaria. </p> <p /> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:c04efe27-7a00-496e-a9ff-cddfbcb2f854" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">($) { $.fn.setwait </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">function</span><span style="color: #000000;">(options) { </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> settings </span><span style="color: #000000;">=</span><span style="color: #000000;"> $.extend({ slidecss: </span><span style="color: #000000;">'</span><span style="color: #000000;">waitindicatormasx</span><span style="color: #000000;">'</span><span style="color: #000000;">, imagecss: </span><span style="color: #000000;">'</span><span style="color: #000000;">waitindicator</span><span style="color: #000000;">'</span><span style="color: #000000;">, waitoffset: </span><span style="color: #000000;">200</span><span style="color: #000000;"> }, options </span><span style="color: #000000;">||</span><span style="color: #000000;"> {}); </span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p /> <p>La prima parte della funzione è la classica dichiarazione di plugin jQuery, la funzione $.extend( serve invece per comporre due oggetti, e verrà spiegata in dettaglio in un prossimo tip.</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:5ba072e9-0033-4a3d-b544-5b7f8897acaa" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;"> </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> context </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">; </span><span style="color: #008000;">//</span><span style="color: #008000;"> debugger;</span><span style="color: #008000;"> </span><span style="color: #000000;"> context[</span><span style="color: #000000;">0</span><span style="color: #000000;">].timer </span><span style="color: #000000;">=</span><span style="color: #000000;"> setTimeout(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> position </span><span style="color: #000000;">=</span><span style="color: #000000;"> context.position(); </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> thediv </span><span style="color: #000000;">=</span><span style="color: #000000;"> context; </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> innerslide </span><span style="color: #000000;">=</span><span style="color: #000000;"> $(</span><span style="color: #000000;">'</span><span style="color: #000000;">&lt;div style="width:</span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> thediv.width() </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">px; height:</span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> thediv.height() </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">px" class="</span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> settings.slidecss </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">" /&gt;</span><span style="color: #000000;">'</span><span style="color: #000000;">) .css(</span><span style="color: #000000;">'</span><span style="color: #000000;">opacity</span><span style="color: #000000;">'</span><span style="color: #000000;">, </span><span style="color: #000000;">0.5</span><span style="color: #000000;">); </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> progress </span><span style="color: #000000;">=</span><span style="color: #000000;"> $(</span><span style="color: #000000;">'</span><span style="color: #000000;">&lt;div style="width:</span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> thediv.width() </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">px; height:</span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> thediv.height() </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">px" class="</span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> settings.imagecss </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">"/&gt;</span><span style="color: #000000;">'</span><span style="color: #000000;">); thediv.prepend(innerslide) thediv.prepend(progress); context[</span><span style="color: #000000;">0</span><span style="color: #000000;">].innerslide </span><span style="color: #000000;">=</span><span style="color: #000000;"> innerslide; context[</span><span style="color: #000000;">0</span><span style="color: #000000;">].progress </span><span style="color: #000000;">=</span><span style="color: #000000;"> progress; }, settings.waitoffset); </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">;</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Il resto della funzione non fa altro che creare un timer con la funzione setTimeout. In questo modo lo stato di attesa viene impostato solo allo scadere del timer, che per default è impostato a 200 millisecondi; grazie a questo piccolo offset, se il server risponde prima di 200 millisecondi lo stato di attesa non viene mai impostato. Grazie a jQuery lo stato di attesa viene impostato creando un nuovo div, impostandone le dimensioni al div target, sovrapponendolo al div originale con una opacità dello 0.5. In questo modo il contenuto originale del div si schiarisce perchè viene visualizzato sotto un div con sfondo bianco e opacita 50%, poi viene inserito un altro div con al centro una immagine gif animata per mostrare l’attesa.</p> <p>La funzione clearwait non fa altro che controllare se il timer è scaduto, in caso contrario semplicemente lo annulla, altrimenti rimuove i due div. Gli stili base dei due div sono fatti cosi, ma possono essere modificati</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:565fba1c-9f6a-4fdc-b22e-79320aed77b9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #800000;">.waitindicatormasx </span><span style="color: #000000;">{</span><span style="color: #FF0000;"> position</span><span style="color: #000000;">:</span><span style="color: #0000FF;"> absolute</span><span style="color: #000000;">;</span><span style="color: #FF0000;"> background-color</span><span style="color: #000000;">:</span><span style="color: #0000FF;"> White</span><span style="color: #000000;">;</span><span style="color: #FF0000;"> z-index</span><span style="color: #000000;">:</span><span style="color: #0000FF;"> 2</span><span style="color: #000000;">;</span><span style="color: #FF0000;"> </span><span style="color: #000000;">}</span><span style="color: #800000;"> .waitindicator </span><span style="color: #000000;">{</span><span style="color: #FF0000;"> position</span><span style="color: #000000;">:</span><span style="color: #0000FF;"> absolute</span><span style="color: #000000;">;</span><span style="color: #FF0000;"> background-image</span><span style="color: #000000;">:</span><span style="color: #0000FF;"> url(Images/ajax-loader3.gif)</span><span style="color: #000000;">;</span><span style="color: #FF0000;"> background-repeat</span><span style="color: #000000;">:</span><span style="color: #0000FF;"> no-repeat</span><span style="color: #000000;">;</span><span style="color: #FF0000;"> background-position</span><span style="color: #000000;">:</span><span style="color: #0000FF;">center</span><span style="color: #000000;">;</span><span style="color: #FF0000;"> z-index</span><span style="color: #000000;">:</span><span style="color: #0000FF;"> 3</span><span style="color: #000000;">;</span><span style="color: #FF0000;"> </span><span style="color: #000000;">}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>è importante il posizionamento assoluto per sovrapporsi al div originale, per il resto si può magari cambiare il colore, tipo il classico giallino.</p> <p>Ora che si è creata questa funzione, usarla è banale.</p> <p /> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:9e7c75e1-a51e-45ce-a667-afcd472e2291" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">$(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { $(</span><span style="color: #000000;">'</span><span style="color: #000000;">[id=btnGetData]</span><span style="color: #000000;">'</span><span style="color: #000000;">).log(</span><span style="color: #000000;">'</span><span style="color: #000000;">button</span><span style="color: #000000;">'</span><span style="color: #000000;">).click(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> button </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">; </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> code </span><span style="color: #000000;">=</span><span style="color: #000000;"> $(</span><span style="color: #000000;">'</span><span style="color: #000000;">[id=txtCode]</span><span style="color: #000000;">'</span><span style="color: #000000;">).val(); $(</span><span style="color: #000000;">'</span><span style="color: #000000;">.maindiv</span><span style="color: #000000;">'</span><span style="color: #000000;">).setwait(); $.getJSON( </span><span style="color: #000000;">'</span><span style="color: #000000;">/Tip6/CustomerService.aspx</span><span style="color: #000000;">'</span><span style="color: #000000;">, { Code: code }, </span><span style="color: #0000FF;">function</span><span style="color: #000000;">(result) { </span><span style="color: #008000;">//</span><span style="color: #008000;">Here result object has the same properties as Customers</span><span style="color: #008000;"> </span><span style="color: #000000;"> $(</span><span style="color: #000000;">'</span><span style="color: #000000;">.maindiv</span><span style="color: #000000;">'</span><span style="color: #000000;">).clearwait(); </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> showresult; </span><span style="color: #0000FF;">for</span><span style="color: #000000;"> (p </span><span style="color: #0000FF;">in</span><span style="color: #000000;"> result) showresult </span><span style="color: #000000;">+=</span><span style="color: #000000;"> p </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">: </span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> result[p] </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">&lt;br /&gt;</span><span style="color: #000000;">'</span><span style="color: #000000;">; $(</span><span style="color: #000000;">'</span><span style="color: #000000;">.result</span><span style="color: #000000;">'</span><span style="color: #000000;">).html(showresult); }); </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">false</span><span style="color: #000000;">; }); });</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p /> <p>Come si può vedere il div identificato dalla classe “maindiv” viene posto in stato di attesa alla pressione del bottone, nella funzione callback la prima cosa che si fa è rimuovere lo stato di attesa, e poi modificare il div con i nuovi dati. La pagina principale ora è fatta cosi</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:37d50ce1-8572-4e48-96de-6604fb877400" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">div </span><span style="color: #FF0000;">class</span><span style="color: #0000FF;">="maindiv"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:TextBox </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="txtCode"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">asp:TextBox</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:Button </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="btnGetData"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #FF0000;"> Text</span><span style="color: #0000FF;">="Button"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">div </span><span style="color: #FF0000;">class</span><span style="color: #0000FF;">="result"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000FF;">&gt;</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Tutti i controlli sono racchiusi nel div mainDiv, premendo il bottone per la ricerca si può notare come tutto il contenuto sia schiarito e grazie al div sovrapposto, è impossibile cliccare ancora nel tasto e quindi fare più richieste.</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/rgm/WindowsLiveWriter/jQuerytip6segnalareallutentelechiamateaj_10618/image_2.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="476" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/rgm/WindowsLiveWriter/jQuerytip6segnalareallutentelechiamateaj_10618/image_thumb.png" width="272" border="0" /></a> </p> <p>Grazie al fatto di avere incluso la funzionalità in un plugin, usarla è solo questione di due righe di codice.</p> <p>alk.</p> <p>Tags: <a href="http://technorati.com/tag/jQuery" rel="tag">jQuery</a></p><img src="http://blogs.ugidotnet.org/rgm/aggbug/96263.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2009/05/21/jquery-tip-6-ndash-segnalare-allrsquoutente-le-chiamate-ajax.aspx Thu, 21 May 2009 19:38:14 GMT http://blogs.ugidotnet.org/rgm/archive/2009/05/21/jquery-tip-6-ndash-segnalare-allrsquoutente-le-chiamate-ajax.aspx#feedback 2 http://blogs.ugidotnet.org/rgm/comments/commentRss/96263.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/96263.aspx jQuery tip #5 &ndash; passare parametri con getJSON http://blogs.ugidotnet.org/rgm/archive/2009/05/19/jquery-tip-5-ndash-passare-parametri-con-getjson.aspx <p>Nel <a href="http://blogs.ugidotnet.org/rgm/archive/2009/05/16/jquery-tip-4-ndash-dialogare-con-il-server-tramite-json.aspx">precedente tip</a> è stato mostrato come chiamare in maniera asincrona una pagina del server, e farsi restituire dati in formato json. Nell’esempio mostrato si è semplicemente chiamata una funzione che restituisce l’utente correntemente loggato. </p> <p>In situazioni reali è sicuramente necessario passare parametri alla pagina in questione, questo può essere tranquillamente fatto tramite il secondo parametro di getJSON. Supponiamo di avere una pagina CustomerService che permette di restituire un oggetto Customers del database northwind dato un suo id. Il codice lato server è il seguente</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:50c42064-4e4a-4a38-a7d7-852e67e7d4c4" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">String code </span><span style="color: #000000;">=</span><span style="color: #000000;"> Request[</span><span style="color: #800000;">"</span><span style="color: #800000;">Code</span><span style="color: #800000;">"</span><span style="color: #000000;">]; </span><span style="color: #0000FF;">using</span><span style="color: #000000;"> (Northwind ctx </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> Northwind()) { JavaScriptSerializer serializer </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> JavaScriptSerializer(); Response.Write( serializer.Serialize( ctx.Customers .Where(c </span><span style="color: #000000;">=&gt;</span><span style="color: #000000;"> c.CustomerID </span><span style="color: #000000;">==</span><span style="color: #000000;"> code).FirstOrDefault())); Response.End(); }</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Grazie ad Entity Framework il recupero dell’oggetto è veramente banale. Ora si crei una pagina Customers.aspx con il seguente contenuto.</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:cc176837-61ae-43d0-8937-9ac5af751e07" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptManager </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="ScriptManager1"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Scripts</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptReference </span><span style="color: #FF0000;">Path</span><span style="color: #0000FF;">="~/jQuery/jquery-1.3.2.js"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptReference </span><span style="color: #FF0000;">Path</span><span style="color: #0000FF;">="~/jQuery/jqueryext.js"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptReference </span><span style="color: #FF0000;">Path</span><span style="color: #0000FF;">="~/scripts/Tip5/GetData.js"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Scripts</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">asp:ScriptManager</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">div</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:TextBox </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="txtCode"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">asp:TextBox</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:Button </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="btnGetData"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #FF0000;"> Text</span><span style="color: #0000FF;">="Button"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">div </span><span style="color: #FF0000;">class</span><span style="color: #0000FF;">="result"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000FF;">&gt;</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Una semplice textbox dove inserire il codice, un bottone per effettuare la richiesta al server ed infine un div vuoto dove inserire il risultato, a questo punto non rimane alrto da fare che esaminare lo script GetData.js che aggiunge a questa pagina le funzionalità richieste.</p> <p /> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a1505fba-407b-4326-b2fa-4d83d7baa5d2" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">$(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { $(</span><span style="color: #000000;">'</span><span style="color: #000000;">[id=btnGetData]</span><span style="color: #000000;">'</span><span style="color: #000000;">).log(</span><span style="color: #000000;">'</span><span style="color: #000000;">button</span><span style="color: #000000;">'</span><span style="color: #000000;">).click(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> button </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">; </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> code </span><span style="color: #000000;">=</span><span style="color: #000000;"> $(</span><span style="color: #000000;">'</span><span style="color: #000000;">[id=txtCode]</span><span style="color: #000000;">'</span><span style="color: #000000;">).val(); $.getJSON( </span><span style="color: #000000;">'</span><span style="color: #000000;">/Tip5/CustomerService.aspx</span><span style="color: #000000;">'</span><span style="color: #000000;">, { Code: code }, </span><span style="color: #0000FF;">function</span><span style="color: #000000;">(result) { </span><span style="color: #008000;">//</span><span style="color: #008000;">Here result object has the same properties as Customers</span><span style="color: #008000;"> </span><span style="color: #000000;"> </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> showresult; </span><span style="color: #0000FF;">for</span><span style="color: #000000;"> (p </span><span style="color: #0000FF;">in</span><span style="color: #000000;"> result) showresult </span><span style="color: #000000;">+=</span><span style="color: #000000;"> p </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">: </span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> result[p] </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;">&lt;br /&gt;</span><span style="color: #000000;">'</span><span style="color: #000000;">; $(</span><span style="color: #000000;">'</span><span style="color: #000000;">.result</span><span style="color: #000000;">'</span><span style="color: #000000;">).html(showresult); }); </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">false</span><span style="color: #000000;">; }); });</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Il codice è veramente semplice, prima di chiamare la pagina grazie alla funzione jQuery <a href="http://docs.jquery.com/Val">val</a> si recupera il contenuto della textbox, poi come secondo parametro della funzione <a href="http://docs.jquery.com/Ajax/jQuery.getJSON">getJSON</a> viene passato un oggetto javascript composto da una serie di coppie (proprietà, valore) che costituiscono i parametri che verranno passati alla pagina. Nell’esempio la pagina richiede solamente un parametro chiamato <strong>Code, </strong>per questo il parametro viene definito come { Code : code }. </p> <p>Il risultato è un oggetto Customer di Entity Framework, e viene brutalmente rappresentato all’interno di un div iterando tra le sue proprietà. In tip successivi vedremo come gestire in maniera migliore la rappresentazione lato client degli oggetti restituiti dalle chiamate ajax.</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/rgm/WindowsLiveWriter/jQuerytip5passareparametricongetJSON_8AF9/image_2.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="386" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/rgm/WindowsLiveWriter/jQuerytip5passareparametricongetJSON_8AF9/image_thumb.png" width="251" border="0" /></a> </p> <p>alk.</p> <p><a href="http://www.nablasoft.com/alkampfer/itablog/jQueryTip.zip">Il codice lo trovate qui</a>.</p> <p>Tags: <a href="http://technorati.com/tag/jQuery" rel="tag">jQuery</a></p><img src="http://blogs.ugidotnet.org/rgm/aggbug/96228.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2009/05/19/jquery-tip-5-ndash-passare-parametri-con-getjson.aspx Tue, 19 May 2009 10:53:00 GMT http://blogs.ugidotnet.org/rgm/archive/2009/05/19/jquery-tip-5-ndash-passare-parametri-con-getjson.aspx#feedback http://blogs.ugidotnet.org/rgm/comments/commentRss/96228.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/96228.aspx jQuery tip #4 &ndash; dialogare con il server tramite json http://blogs.ugidotnet.org/rgm/archive/2009/05/16/jquery-tip-4-ndash-dialogare-con-il-server-tramite-json.aspx <p>Nel <a href="http://blogs.ugidotnet.org/rgm/archive/2009/05/15/jquery-tip-3-ndash-dialogare-con-un-webservice.aspx">precedente</a> tip è stato mostrato come dialogare con il server tramite un semplice webservice asmx. Sebbene questo modo di procedere sia molto intuitivo, comporta spesso un overhead causato dal file javascript generato dal server per permettere la chiamata del servizio. Nel precedente esempio infatti potete vedere, come oltre ai normali script, venga restituito al client il file <strong>http://localhost:21963/MyService.asmx/js </strong>che contiene tutto il codice per permettere l’invocazione del webservice.</p> <p>jQuery mette a disposizione modi molto più intelligenti di dialogare con il server, in particolare la funzione <a href="http://docs.jquery.com/Ajax/jQuery.getJSON">getJSON</a> che permette di effettuare una chiamata ad una url che restituisce i dati in formato <a href="http://it.wikipedia.org/wiki/JSON">json</a>. Se controllate nel sorgente potrete vedere nella cartella tip4, una pagina aspx chiamata <strong>Servicepage.aspx </strong>il cui codice è veramente semplice.</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:c324cc8c-7649-4a68-a0e1-feb623bf9bff" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">partial</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> ServicePage : System.Web.UI.Page { </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> Page_Load(</span><span style="color: #0000FF;">object</span><span style="color: #000000;"> sender, EventArgs e) { JavaScriptSerializer serializer </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> JavaScriptSerializer(); Response.Write(serializer.Serialize(Membership.GetUser())); Response.End(); } }</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Come potete notare grazie alla classe JavaScriptSerializer è possibile restituire al chiamante un qualsiasi oggetto (in questo caso il MembershipUser) in formato json. Se chiamate direttamente la pagina potete infatti osservare cosa viene restituito.</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:5bf3e2eb-153e-47c4-a465-1059d44c5aa5" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">{</span><span style="color: #000000;">"</span><span style="color: #000000;">UserName</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">admin</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">ProviderUserKey</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">5f7b1fdb-0322-4cab-96d8-c1c3771f414d</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">Email</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">a@nablasoft.com</span><span style="color: #000000;">"</span><span style="color: #000000;"> ,</span><span style="color: #000000;">"</span><span style="color: #000000;">PasswordQuestion</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #0000FF;">null</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">Comment</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #0000FF;">null</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">IsApproved</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #0000FF;">true</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">IsLockedOut</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #0000FF;">false</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">LastLockoutDate</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">\/Date (-6816268800000)\/</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">CreationDate</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">\/Date(1242062048000)\/</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">LastLoginDate</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">\/Date(1242470020860)\ /</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">LastActivityDate</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">\/Date(1242470194907)\/</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">LastPasswordChangedDate</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">\/Date(1242062048000)\/</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">IsOnline</span><span style="color: #000000;">"</span><span style="color: #000000;"> :</span><span style="color: #0000FF;">true</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">ProviderName</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">SqlProvider</span><span style="color: #000000;">"</span><span style="color: #000000;">}</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p /> <p /> <p>Sebbene questa stringa sia di difficile lettura, è semplicemente la serializzazione json dell’oggetto MembershipUser, ecco quindi che nella pagina <strong>tip4/auth.aspx</strong> basta referenziare lo script <strong>scripts/tip4/auth.js</strong> che non fa altro che recuperare tramite jQuery tutte le info sull’utente attualmente loggato.</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:fd4a06e4-aa74-4980-8026-3db377bdeff8" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">$(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { $(</span><span style="color: #000000;">'</span><span style="color: #000000;">.askname</span><span style="color: #000000;">'</span><span style="color: #000000;">).log(</span><span style="color: #000000;">'</span><span style="color: #000000;">button</span><span style="color: #000000;">'</span><span style="color: #000000;">).click(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { </span><span style="color: #0000FF;">var</span><span style="color: #000000;"> button </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">; $.getJSON(</span><span style="color: #000000;">'</span><span style="color: #000000;">/Tip4/ServicePage.aspx</span><span style="color: #000000;">'</span><span style="color: #000000;">, {}, </span><span style="color: #0000FF;">function</span><span style="color: #000000;">(result) { </span><span style="color: #008000;">//</span><span style="color: #008000;">Here result object has the same properties as MembershipUser</span><span style="color: #008000;"> </span><span style="color: #000000;"> $(button).siblings(</span><span style="color: #000000;">'</span><span style="color: #000000;">.userdata</span><span style="color: #000000;">'</span><span style="color: #000000;">).text( </span><span style="color: #000000;">'</span><span style="color: #000000;">UserName:</span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> result.UserName </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #000000;">'</span><span style="color: #000000;"> Email:</span><span style="color: #000000;">'</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> result.Email ); }); }); });</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Grazie alla getJSON si può invocare una pagina ed impostare come callback, una funzione anonima il cui unico parametro è l’oggetto restituito dalla pagina. L’aspetto importante è che nella callback si accede direttamente alle proprietà dell’oggetto MembershipUser come la <strong>result.UserName</strong> e <strong>result.Email</strong>. Tutto questo grazie al fatto che javascript è un linguaggio dinamico ;) e quindi può riscostruire l’oggetto dalla stringa json senza problemi.</p> <p>Il vantaggio di questo approccio è evitare di passare al client file js inutili e anche in questo caso dato che la pagina che restituisce i dati è una normalissima pagina aspx, potete usare Session, Membership, proteggere la pagina con i ruoli, etc etc.</p> <p>alk.</p> <p>Il codice è <a href="http://www.nablasoft.com/alkampfer/itablog/jquerytip.zip">scaricabile da qui</a>.</p> <p>Tags: <a href="http://technorati.com/tag/jQuery" rel="tag">jQuery</a></p><img src="http://blogs.ugidotnet.org/rgm/aggbug/96207.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2009/05/16/jquery-tip-4-ndash-dialogare-con-il-server-tramite-json.aspx Sat, 16 May 2009 13:55:52 GMT http://blogs.ugidotnet.org/rgm/archive/2009/05/16/jquery-tip-4-ndash-dialogare-con-il-server-tramite-json.aspx#feedback 4 http://blogs.ugidotnet.org/rgm/comments/commentRss/96207.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/96207.aspx jQuery tip #3 &ndash; dialogare con un webservice http://blogs.ugidotnet.org/rgm/archive/2009/05/15/jquery-tip-3-ndash-dialogare-con-un-webservice.aspx <p>La potenza di jQuery risiede principalmente nel rendere semplice manipolare un oggetto complesso come il DOM. La chiave di jQuery è quindi quella di dialogare con il server, invocando operazioni ed aggiornando l’interfaccia, senza effettuare postback ed inviando solamente i dati minimali.</p> <p>Esistono molti modi per dialogare con il server, ad esempio grazie ad asp.net ajax è semplicissimo invocare una funzione contenuta in un webservice .asmx. Il vantaggio di usare un asmx è che potete direttamente inserirlo nel sito, in questo modo anche la security standard di asp.net vi protegge dall’uso indesiderato. Se ad esempio chiedete il servizio con la richiesta </p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f7306272-97de-45df-874d-35ed28b16da6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">http:</span><span style="color: #000000;">//</span><span style="color: #000000;">localhost:</span><span style="color: #800080;">21963</span><span style="color: #000000;">/</span><span style="color: #000000;">Login.aspx?ReturnUrl</span><span style="color: #000000;">=</span><span style="color: #000000;">%2fMyService.asmx</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Il server vi chiede correttamente la login perché il servizio è protetto, quindi abbiamo la stessa garanzia di sicurezza di una normale pagina. Supponiamo ora di avere nel servizio la funzione:</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a1fc0c73-6870-4593-86b5-5c430fae214b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">[WebService(Namespace </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">"</span><span style="color: #800000;">http://blogs.ugidotnet.org/rgm/jQueryTip/</span><span style="color: #800000;">"</span><span style="color: #000000;">)] [WebServiceBinding(ConformsTo </span><span style="color: #000000;">=</span><span style="color: #000000;"> WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(</span><span style="color: #0000FF;">false</span><span style="color: #000000;">)] [System.Web.Script.Services.ScriptService] </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> MyService : System.Web.Services.WebService { [WebMethod] </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> GetLoggedUser() { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> Membership.GetUser().UserName; } }</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Come vedete non è altro che un webservice standard che può essere chiamato da client grazie all’attributo ScriptService, e l’unica funzione presente recupera l’utente attualmente loggato, a questo punto grazie allo ScriptManager di asp.net ajax si può chiamare questa funzione da javascript , ecco il codice della pagina Auth1.aspx</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e7cb5e02-4b9c-4c36-94f1-a1a2315a8518" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">body</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">form </span><span style="color: #FF0000;">id</span><span style="color: #0000FF;">="form1"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptManager </span><span style="color: #FF0000;">ID</span><span style="color: #0000FF;">="ScriptManager1"</span><span style="color: #FF0000;"> runat</span><span style="color: #0000FF;">="server"</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Scripts</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptReference </span><span style="color: #FF0000;">Path</span><span style="color: #0000FF;">="~/jQuery/jquery-1.3.2.js"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptReference </span><span style="color: #FF0000;">Path</span><span style="color: #0000FF;">="~/jQuery/jqueryext.js"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ScriptReference </span><span style="color: #FF0000;">Path</span><span style="color: #0000FF;">="~/scripts/Auth1.js"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Scripts</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">Services</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">asp:ServiceReference </span><span style="color: #FF0000;">Path</span><span style="color: #0000FF;">="~/MyService.asmx"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">/&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">Services</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">asp:ScriptManager</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">div</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">input </span><span style="color: #FF0000;">type</span><span style="color: #0000FF;">="button"</span><span style="color: #FF0000;"> class</span><span style="color: #0000FF;">="askname"</span><span style="color: #FF0000;"> value</span><span style="color: #0000FF;">="loggedusername"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">input</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;</span><span style="color: #800000;">input </span><span style="color: #FF0000;">type</span><span style="color: #0000FF;">="text"</span><span style="color: #FF0000;"> class</span><span style="color: #0000FF;">="askname"</span><span style="color: #FF0000;"> </span><span style="color: #0000FF;">&gt;&lt;/</span><span style="color: #800000;">input</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">div</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">form</span><span style="color: #0000FF;">&gt;</span><span style="color: #000000;"> </span><span style="color: #0000FF;">&lt;/</span><span style="color: #800000;">body</span><span style="color: #0000FF;">&gt;</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p /> <p /> <p>Come si può vedere ci sono solamente due controlli, un bottone ed una texbox, ma sono controlli html, senza attribute runat=”server”, e quindi sono completamente ignorati da asp.net.Ora si vuole creare una funzione che alla pressione del bottone, metta nella textbox il nome dell’utente loggato. </p> <p>Notate come nello scriptmanager sia stato inserito un riferimento al webservice precedentemente mostrato e sono stati inclusi gli script javascript, i primi due sono la libreria jQuery ed una libreria di estensioni, il terzo è lo script che realizza la logica della pagina.</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:34b7ee6d-cc54-45b7-ac73-db4a2cf8ea79" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { $(</span><span style="color: #000000;">'</span><span style="color: #000000;">.askname</span><span style="color: #000000;">'</span><span style="color: #000000;">).log(</span><span style="color: #000000;">'</span><span style="color: #000000;">button</span><span style="color: #000000;">'</span><span style="color: #000000;">).click(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { SampleSite.MyService.GetLoggedUser( </span><span style="color: #0000FF;">function</span><span style="color: #000000;">(result, context, method) { $(context).siblings(</span><span style="color: #000000;">'</span><span style="color: #000000;">input</span><span style="color: #000000;">'</span><span style="color: #000000;">).val(result); }, </span><span style="color: #0000FF;">function</span><span style="color: #000000;">(error, context, method) { alert(</span><span style="color: #000000;">'</span><span style="color: #000000;">Exception during the save.</span><span style="color: #000000;">'</span><span style="color: #000000;">); }, </span><span style="color: #0000FF;">this</span><span style="color: #000000;">); }); });</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>Come si può vedere basta aggiungere un handler click() al bottone, alla pressione dello bottone si chiama quindi il webservice, proprio come se la classe del webservice fosse definita nel javascript (in effetti lo script manager vi genera uno script con tutta la definizione). La chiamata accetta tutti i parametri della funzione originale (in questo caso nessuno), e di seguito tre parametr:, la funzione da chiamare in caso di successo, quella da chiamare in caso di fallimento ed un oggetto che viene ripassato alle precedenti due funzioni nel campo context. In caso di successo non si fa altro che individuare la textbox grazie alla funzione jQuery siblings, e modificarne il contenuto. Come si può vedere il bottone premuto, era stato passato come ultimo parametro alla funzione GetLoggedUser(), per cui lo ritroviamo nel parametro context delle funzioni di callback. </p> <p><a href="http://www.nablasoft.com/alkampfer/itablog/jquerytip3.zip">Il codice è contenuto qui</a>.</p> <p>Alk.</p> <p>Tags: <a href="http://technorati.com/tag/jQuery" rel="tag">jQuery</a> <a href="http://technorati.com/tag/asp.net ajax" rel="tag">asp.net ajax</a></p><img src="http://blogs.ugidotnet.org/rgm/aggbug/96201.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2009/05/15/jquery-tip-3-ndash-dialogare-con-un-webservice.aspx Fri, 15 May 2009 12:10:13 GMT http://blogs.ugidotnet.org/rgm/archive/2009/05/15/jquery-tip-3-ndash-dialogare-con-un-webservice.aspx#feedback 2 http://blogs.ugidotnet.org/rgm/comments/commentRss/96201.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/96201.aspx JQuery tip #1 http://blogs.ugidotnet.org/rgm/archive/2009/05/11/jquery-tip-1.aspx <p>siderata l’importanza sempre maggiore che jQuery riveste per gli sviluppatori web, vorrei condividere qualche piccolo tip appreso qua e la, non so quanto riuscirò a mantenere la continuità, visto gli impegni sempre più pressanti di questo periodo lavorativo. I buoni propositi ci sono tutti :D.</p> <p>Iniziamo con il tip più importante, come fare log con la <a href="http://getfirebug.com/">firebug</a> di firefox. Ecco un estensione per poter effetturare il dump di un wrapped-set nella firebug</p> <p> </p><div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:2b87ca9e-3a28-49bd-b924-11b5c078fe5e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">($) { $.fn.log </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">function</span><span style="color: #000000;">(msg) { </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (</span><span style="color: #0000FF;">typeof</span><span style="color: #000000;"> (console) </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #000000;">"</span><span style="color: #000000;">undefined</span><span style="color: #000000;">"</span><span style="color: #000000;">) { console </span><span style="color: #000000;">=</span><span style="color: #000000;"> { log: </span><span style="color: #0000FF;">function</span><span style="color: #000000;">() { } }; } </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (console) { console.log(</span><span style="color: #000000;">"</span><span style="color: #000000;">%s: %o</span><span style="color: #000000;">"</span><span style="color: #000000;">, msg, </span><span style="color: #0000FF;">this</span><span style="color: #000000;">); } </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">this</span><span style="color: #000000;">; } })(jQuery);</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p>La sintassi può apparire un po cervellotica, ma è la modalità standard di scrivere estensioni per jQuery, in modo da poter usare il $ all’interno della funzione, ma mantenere allo stesso tempo la compatibilità in caso di conflitto con altre librerie.</p> <p>Questa funzione si utilizza in maniera veramente semplice, come ogni plugin che si rispetti è concatenabile, questo significa che potete selezionare un wrappedset, poi chiamare il log e poi continuare a utilizzare il wrapped set. Ecco un esempio di utilizzo</p> <div class="wlWriterEditableSmartContent" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:b27a7ceb-e79f-4208-884d-abea568a5669" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><pre style="background-color:#FFFFFF;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;overflow: auto;"><span style="color: #000000;">$(</span><span style="color: #000000;">'</span><span style="color: #000000;">.hierarchicmaindiv input[id=btnSearch]</span><span style="color: #000000;">'</span><span style="color: #000000;">).log(</span><span style="color: #000000;">'</span><span style="color: #000000;">searchdiv</span><span style="color: #000000;">'</span><span style="color: #000000;">) .click(</span><span style="color: #0000FF;">function</span><span style="color: #000000;">() {</span></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin. http://dunnhq.com --></div> <p /> <p>con questa istruzione seleziono tutti i bottoni con id btnSearch dentro un elemento che ha come stile hierarchicmaindiv, poi chiamo il log e successivamente proseguo attaccando gli eventi, in questo modo però in firebug mi trovo:</p> <p><a href="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/rgm/WindowsLiveWriter/JQuerytip1_9758/image_2.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="157" alt="image" src="http://blogs.ugidotnet.org/images/blogs_ugidotnet_org/rgm/WindowsLiveWriter/JQuerytip1_9758/image_thumb.png" width="460" border="0" /></a> </p> <p>Per ogni log ho una riga che mi dice gli elementi selezionati, la cosa interessante è che se clicco sopra l’elemento, firebug mi porta immediatamente nel sorgente della pagina relativo all’elemento selezionato. Se invece mi posiziono con il mouse sopra l’elemento, firebug mi evidenzia nella pagina l’elemento selezionato.</p> <p>Soprattutto agli inizi quando non si ha troppa familiarità con i selettori è fondamentale visualizzare cosa si è selezionato, la funzione log è quindi la soluzione migliore. </p> <p>Alk.</p> <p>Tags: <a href="http://technorati.com/tag/jQuery" rel="tag">jQuery</a></p><img src="http://blogs.ugidotnet.org/rgm/aggbug/96153.aspx" width="1" height="1" /> Gian Maria Ricci http://blogs.ugidotnet.org/rgm/archive/2009/05/11/jquery-tip-1.aspx Mon, 11 May 2009 11:45:48 GMT http://blogs.ugidotnet.org/rgm/archive/2009/05/11/jquery-tip-1.aspx#feedback 2 http://blogs.ugidotnet.org/rgm/comments/commentRss/96153.aspx http://blogs.ugidotnet.org/rgm/services/trackbacks/96153.aspx