JQuery UI consente facilmente di rappresentare i button con uno stile gradevole e personalizzabile, ad esempio il button in figura, nella versione normale e con rollover. Per altri esempi si può vedere il sito JQuery UI ThemeRoller.


Purtroppo lo stile viene applicato in automatico solo ai tag HTML button, ossia:
<button type="button">A button element</button>
Mentre non viene applicato ai tag HTML input di tipo button, ossia:
<input type="submit" value="A button element"/>
che è proprio il tag utilizzato per il rendering del button ASP.NET.
Per poter applicare lo stile di un tema JQuery UI ai button di ASP.NET, quindi, oltra a referenziare jQueryUI e il tema scelto, è necessario trasformare tutti i button ASP.NET in button HTML.
Ciò può essere fatto con jQuery stesso:
<script type="text/javascript">
$(document).ready(function () {
$('input:submit, input:reset, input[type=button]').button();
});
</script>
In questo modo jQuery UI si occuperà automaticamente dello stile dei button, applicando il tema scelto.
Se però i button sono all’interno di un UpdatePanel della pagina ASPX, ad ogni PostBack asincrono ci sarà una brutta sorpresa, in quanto i button torneranno al loro aspetto classico. Infatti l’evento $(document).ready avviene solo al caricamento del documento, e non dopo un PostBack asincrono. Per questo è necessario intercettare l’evento PageLoaded del framework AJAX di Microsoft e inserire lì il codice per la trasformazione dei button.
Il codice allora diventa:
<script type="text/javascript">
$(document).ready(function () {
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(
function () {
// qui viene eseguito dopo un postback asincrono
SetupButtons();
});
// qui viene eseguito dopo il primo caricamento del documento
SetupButtons();
});
function SetupButtons() {
$('input:submit, input:reset, input[type=button]').button();
}
</script>
Utilizzando questo codice, tuttavia, mi è capitato di ricevere l’errore “Sys is undefined” effettuando un semplice refresh con la pagina con Internet Explorer 9.
Non mi sono chiare le cause, probabilmente il refresh su IE9 causa l’esecuzione del codice in $(document).ready prima del caricamento del framework Microsoft AJAX.
Un possibile workaround che ho usato per risolvere il problema consiste nel verificare il caricamento del framework prima di provare ad usare Sys.WebForms.PageRequestManager.getInstance(), riprovando dopo 100 ms nel caso in cui Sys risulti undefined. Ecco il codice:
<script type="text/javascript">
$(document).ready(function () {
setupDocument();
});
function setupDocument() {
if (typeof Sys != "undefined") {
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(
function () {
SetupButtons();
});
SetupButtons();
} else {
setTimeout(SetupDocument, 100);
}
}
function SetupButtons() {
$('input:submit, input:reset, input[type=button]').button();
}
</script>
Con jQuery.UI è possibile creare un’interfaccia utente a tab in una pagina web con pochissimo codice.
Ad esempio, consideriamo la pagina ASP.NET seguente:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Tabs with jQueri.UI</title>
<link rel="Stylesheet"
href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.17/themes/smoothness/jquery-ui.css" />
<script type="text/javascript"
src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js" ></script>
<script type="text/javascript"
src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.17/jquery-ui.min.js" ></script>
<script type="text/javascript">
$(function () {
$("#tabs").tabs();
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div id="tabs">
<ul>
<li><a href="#tabPresentazione">Presentazione</a></li>
<li><a href="#tabPortfolio">Portfolio</a></li>
<li><a href="#tabContatti">Contatti</a></li>
</ul>
<div id="tabPresentazione">
<h2>Chi siamo</h2>
<p>... </p>
</div>
<div id="tabPortfolio">
<h2>I nostri prodotti</h2>
<p>...</p>
</div>
<div id="tabContatti">
<h2>I nostri recapiti</h2>
<p>...</p>
</div>
</div>
</form>
</body>
</html>
Il risultato sarà un’interfaccia a tabs come quella in figura:

Che cosa succede se nella pagina è inserito un controllo che effettua il postback? Ad esempio consideriamo un semplice LinkButton nel tab Contatti.
<div id="tabContatti">
<h2>I nostri recapiti</h2>
<p>... </p>
<asp:LinkButton id="lbPostBack" runat="server">
Clicca per un postback
</asp:LinkButton>
</div>
Corrispondente all'immagine seguente:

Dopo il postback, la pagina viene ricaricata e il primo tab ritorna ad essere il tab attivo e ciò può costituire un problema. Per risolverlo ci sono diverse soluzioni, quella che mi piace di più l’ho trovata qui su Stack Overflow (non è quella indicata come risposta migliore, ma è la più votata) e consiste nel memorizzare il tab corrente in un controllo di tipo HiddenField, il cui valore è persistito nel ViewState della pagina e recuperato dopo il postback.
Pertanto è sufficiente inserire nella form precedente un controllo HiddenField:
<form id="form1" runat="server">
<asp:HiddenField runat="server" ID="hfLastTab" Value="0" />
<div id="tabs">
e aggiungere il seguente pezzo di codice javascript nella sezione head del precedente esempio:
$(function () {
$("#tabs").tabs({
show: function () {
var sel = $('#tabs').tabs('option', 'selected');
$("#<%= hfLastTab.ClientID %>").val(sel);
},
selected: '<%= hfLastTab.Value %>'
});
});
e a questo punto si può vedere come il tab selezionato rimanga attivo anche dopo un pòostback.
In allegato la pagina aspx di esempio, WebFormForTabs.zip (2,96 kb)