BusyBoxDotNet

Se ritieni utile questo articolo, considera la possibilità di effettuare una donazione (il cui importo è a tua completa discrezione) tramite PayPal. Grazie.

Nella costruzione di applicazioni web può accadere di dover effettuare sul server delle operazioni che richiedono una discreta quantità di tempo per essere eseguite, come ad esempio la generazione di report o l'esecuzione di query complesse su database.

Attualmente i browser disponibili non prevedono un metodo d'effetto per informare l'utente che la richiesta è stata effettuata e si è in attesa di una risposta, inducendo l'utilizzatore a non capire perchè continui ad essere visualizzata la stessa pagina, e di conseguenza inrtroducendo il rischio che esso continui ad effettuare operazioni che comportano un invio multiplo dei dati, che in molti casi può essere dannoso.

Per ovviare a questo problema BusyBoxDotNet propone una soluzione che non si limita soltanto ad informare l'utente dell'esecuzione dell'operazione, ma lo fa in modo stilisticamente elegante e può prevenire il submit ripetuto di dati.

Background

L'idea originale è meritatamente dovuta a Mark Wagner - di cui BusyBoxDotNet mantiene il nome - che ne ha implementato una versione eccellente e funzionale.

Il motivo per cui BusyBoxDotNet è stato creato è la necessità di includere il tutto in un componente riutilizzabile ed altamente personalizzabile, senza il bisogno di dover scrivere codice Javascript o di modificare manualmente le pagine web.

BusyBoxDotNet è infatti una libreria di WebControls per ASP.NET, il cui controllo principale è appunto BusyBox. Gli altri controlli presenti nella libreria permettono di personalizzarne il comportamento e facilitarne l'integrazione.

Oltre a questo, sebbene BusyBoxDotNet sia inizialmente nato come un semplice porting dell'idea originale ad ASP.NET, in seguito ad un primo rilascio e grazie ai suggerimenti di Matteo Casati i sorgenti della versione originale sono stati abbandonati ed è stato ricreato dal nulla per estenderne la compatibilità con i browser disponibili e per migliorarne il comportamento.

Tecnologie e linguaggi utilizzati

  • ASP.NET

  • Javascript

  • C#

Browser testati

Il funzionamento di BusyBoxDotNet è stato verificato sui seguenti browser:

  • Internet Explorer 6.0

  • Opera 8.52 *

  • Netscape 8.1

  • Firefox 1.5

* Opera è supportato con alcune limitazioni; vedi le note di seguito.

Introduzione

Esistono diversi modi per risolvere il problema della notifica all'utente di un processo che può potenzialmente richiedere molto tempo per essere completato. Un metodo comune è la visualizzazione di una pagina intermedia che si occupi della notifica, visualizzando ad esempio un'immagine animata ed un messaggio informativo. E' sempre questa poi che si occupa di iniziare il processo a lunga durata, in modo che essa possa restare visualizzata fino al suo completamento.

Questo approccio ha tuttavia alcune limitazioni, più o meno significative:

  • Funziona solo nella navigazione tra due pagine differenti, non può essere applicato al postback della stessa pagina.

  • Richiede la modifica manuale di tutte le pagine nel caso in cui voglia essere incluso in un'applicazione preesistente.

  • Implica la perdita di tutti i vantaggi apportati dal ViewState.

Per questo motivo BusyBoxDotNet è stato realizzato per superare tutte queste limitazioni, nonchè per apportare notevoli miglioramenti:

  • È applicabile a qualsiasi richiesta al server web, dal postback alla richiesta di una nuova pagina.

  • Benchè non sia il suo scopo originale è possibile utilizzarlo anche se non avviene un roundtrip verso il server ma anche soltanto lato client.

  • E' semplice da inserire in pagine preesistenti e non richiede nessuna modifica manuale delle pagine.

L'approccio di BusyBoxDotNet può quindi essere riassunto in questi punti:

  • Viene incluso nella pagina uno script Javascript che si occupa della sua creazione, assieme ad altre funzioni helper.

  • La visualizzazione può avvenire intercettando l'evento onbeforeunload dell'elemento window - implicando quindi la visualizzazione durante qualsiasi transizione di pagina, sia essa la richiesta di una nuova risorsa o un postback - intercettando il solo postback della pagina, oppure personalizzando la visualizzazione scegliendo manualmente quando esso debba essere visualizzato (utile per i browser che non supportano l'evento onbeforeunload come Opera).

  • Tramite Javascript e DOM viene dinamicamente creato ed aggiunto al documento un elemento div, che contiene il messaggio da visualizzare all'utente ed opzionalmente un'immagine animata.

  • Il recupero delle risorse embedded nell'assembly (scripts e immagini) avviene tramite HttpHandler. Per gli script è anche possibile includere nella pagina il loro contenuto, ed in questo caso l'HttpHandler non viene utilizzato.

Caratteristiche

BusyBoxDotNet può essere utilizzato come qualsiasi altra libreria di controlli web, e come queste i controlli contenuti in BusyBoxDotNet hanno un comportamento di default, che è possibile personalizzare sia a design time che programmaticamente.

Il comportamento standard del controllo BusyBox è riassunto in questi punti:

  • Visualizzazione al postback della pagina in cui viene inserito. (compatibile con tutti i browser con cui è stato testato)

  • Layout con messaggi ed immagine standard:

    Anteprima del controllo in esecuzione

  • Visualizzazione di uno strato di overlay semitrasparente dello stesso colore dello sfondo della pagina, che impedisce ogni ulteriore interazione con gli elementi della pagina durante la visualizzazione del box.

Mentre questo è il comportamento di default, la notevole quantità di proprietà esposte dal controllo consente di personalizzarlo liberamente.

Cosa è possibile fare

Di seguito è riportata una lista di ciò che è possibile fare con BusyBoxDotNet, e successivamente anche di ciò che al momento non è possibile fare, ma che potrà essere presente in future versioni.

  • Scelta dell'evento che scatena la visualizzazione del BusyBox: onbeforeunload, onsubmit o personalizzato.

  • Modifica dello stile del box: testo, dimensione, immagine, bordo, sfondo, layout.
    Sono presenti immagini preinserite tra le quali è possibile scegliere (accesso tramite HttpHandler), ma è anche possibile sceglierne una personalizzata (recupero dal file system).

  • Possibilità di far apparire il box con un ritardo, nonchè di nasconderlo dopo un certo timeout. Queste caratteristiche sono interessanti nel caso si voglia visualizzare il box solo se un determinato processo richiede più di un tempo definito per essere completato, o nel caso in cui lo si voglia nascondere se entro un certo tempo il processo non sia stato ancora portato a termine.

  • Possibilità di far apparire il box con un effetto di fade-in, scegliendone la velocità.

  • Possibilità di effettuare il fading del box quando il mouse vi è posizionato sopra.

  • Possibilità di disabilitare la visualizzazione dello strato di overlay.

  • Scelta del colore e dell'opacità dello strato di overlay.

  • Timing dello strato di overlay. Nel caso in cui il box sia fatto apparire con ritardo e/o scomparire con anticipo, è possibile scegliere il comportamento dello strato di overlay.

  • Possibilità di scegliere se visualizzare il box anche se il documento non è stato completamente caricato e di mostrare un messaggio di alert in caso affermativo.

Cosa ancora non è possibile fare

  • Definire manualmente un layout per il box.

  • Impostare un posizionamento diverso da quello di default (sempre centrato all'interno dell pagina).

  • Non prevede la presenza di smartnavigation nella pagina.

  • Non può essere spostato tramite drag-and-drop.

  • Non può essere chiuso manualmente come una qualsiasi finestra.

Proprietà pubbliche

La tabella seguente elenca le proprietà che è possibile utilizzare per personalizzare lo stile ed il comportamento del controllo BusyBox.

Categoria: stile (appearance)

Nome Tipo Descrizione
BackColor Color Colore dello sfondo del box. Attenzione: le immagini embedded nell'assembly hanno tutte sfondo bianco, quindi con uno sfondo di altro colore l'effetto non sarà eccezionale.
BorderColor Color Colore del bordo del box.
BorderStyle BorderStyle Stile del bordo del box.
BorderWidtd Unit Spessore del bordo del box.
FadeOnMouseOverOpacity Int Opacità del box quando il mouse vi è sopra. Valore da 0 a 100. 0 significa trasparente, 100 completamente opaco. Questa proprietà è valutata solo se la proprietà FadeOnMouseOver è impostata a true.
Image ImageTemplate Selezione dell'immagine tra quelle precaricate nell'assembly.
ImagePosition ImagePositioning Posizione dell'immagine nel box. Disponibile due layout predefiniti.
ImageUrl String Url dell'immagine personalizzata da mostrare nel busybox. Valutata solo se la proprietà Image è impostata a Custom.
Opacity Int Opacità del box. Valore da 0 a 100. 0 trasparente, 100 opaco.
Text String Messaggio da mostrare nel box.
TextBold Bool Proprietà bold del messaggio.
TextColor Color Colore del messaggio.
TextFontName String Font del messaggio.
TextItalic Bool Proprietà italic del messaggio.
TextSize FontUnit Dimensione del testo del messaggio.
Title String Titolo da mostrare nel box.
TitleBold Bool Proprietà bold del titolo.
TitleColor Color Colore del titolo.
TitleFontName String Font del titolo.
TitleItalic Bool Proprietà italic del titolo.
TitleSize FontUnit Dimensione del titolo.

Categoria: comportamento (behavior)

Nome Tipo Descrizione
FadeInSpeed Int Velocità di comparsa del box. 0 lenta, 100 immediata.
FadeOnMouseOver Bool Se impostato a true il box diventa semitrasparente al passaggio del mouse.
ShowBusyBox ShowBehavior Impostazioni di comparsa del box.
  • Always: sia su postback che navigazione su altra pagina

  • OnPostBackOnly: solo su postback

  • Custom: il box non viene visualizzato automaticamente. La sua apparizione può essere gestita tramite i controlli helper.

ShowDelay Int Valore in millisecondi del ritardo di comparsa del box.
ShowTimeout Int Valore in millisecondi del timeout di comparsa del box. Scaduto il tempo esso verrà nascosto.
Visible Bool Abilita o disabilita la visualizzazione del box a livello di pagina.

Categoria: layout

Nome Tipo Descrizione
Height Unit Altezza del box. Se non impostata assume dimensioni predefinite.
Width Unit Larghezza del box. Se non impostata assume dimensioni predefinite.

Categoria: misc

Nome Tipo Descrizione
ID Int ID del controllo.
AlertIfDocumentNotCompletelyLoaded Bool Visualizza un messaggio di alert se si cerca di visualizzare il box prima che il documento sia completamente caricato.
IncludeScriptsInPage Bool

Include gli script Javascript direttamente nella pagina, invece che referenziarli tramite l'attributo src.

ShowOnlyIfDocumentCompletelyLoaded Bool Visualizza il box solo se il documento è stato completamente caricato.

Categoria: overlay

Nome Tipo Descrizione
ImmediatelyOverlay Bool Utilizzato quando la proprietà ShowDelay ha un valore maggiore di 0. Se impostata a true, l'overlay viene mostrato appena l'evento di visualizzazione del box viene scatenato, anche se esso, a causa del delay, non è ancora visibile.
KeepOverlay Bool Utilizzato quando la proprietà ShowTimeout ha un valore maggiore di 0. Se impostato a true, l'overlay viene mantenuto anche il box è scomparso a causa del timeout.
Overlay Bool Consente di decidere se mostrare o meno l'overlay. Tutte le altre proprietà di questa categoria sono valutate solo se questa assume valore true.
OverlayColor Color Colore dell'overlay. Se non impostato assume il colore impostato per il tag body della pagina.
OverlayOpacity Int Opacità dell'overlay. Valore da 0 a 100. 0 trasparente, 100 coprente.

Alternative all'utilizzo degli eventi OnBeforeUnload e OnSubmit

In alcuni casi le due alternative disponibili per la visualizzazione del box non sono quello di cui si può avere bisogno.

Il valore Always della proprietà ShowBusyBox registra l'evento OnBeforeUnload dell'elemento window, mentre il valore OnPostBackOnly registra l'evento OnSubmit della form.

Assieme al problema dell'evento OnBeforeUnload che in Opera non è supportato, è stato il motivo per cui alla libreria sono stati aggiunti tre controlli ulteriori: BusyBoxPanel, BusyBoxHyperLink e BusyBoxButton.

Ognuno di essi eredita dall'omonimo controllo standard di ASP.NET ed espone una proprietà ulteriore: BusyBoxToShow.

Questa proprietà consente di selezionare il controllo BusyBox inserito nella pagina del quale si vuole effettuare la visualizzazione. Per ognuno dei controlli l'evento che triggera la visualizzazione del BusyBox al quale è associato è l'evento onClick lato client.

In altre parole, se si inserisce nella form un controllo di tipo BusyBoxButton e lo si associa ad un controllo BusyBox presente nella pagina, al click sul bottone verrà anche visualizzato il BusyBox. La stessa cosa accade per il controllo BusyBoxHyperLink e per gli elementi, di qualsiasi tipo essi siano, posizionati all'interno di un controllo BusyBoxPanel.

Compatibilità

La libreria BusyBoxDotNet è pienamente compatibile con le versioni indicate del browser, ma non è escluso che sia compatibile con altri browser e versioni differenti da quelle indicate.

Gli unici limiti di compatibilità sono stati riscontrati con Opera, e possono essere sintetizzabili nei seguenti punti:

  • Opera non supporta l'evento OnBeforeUnload, di conseguenza quando la proprietà ShowBusyBox del controllo BusyBox è impostata a Always (evento OnBeforeUnload), il box non viene visualizzato.

  • Opera non supporta l'opacità degli elementi, perciò sia il box che l'overlay saranno o completamente invisibili o completamente opachi, e gli effetti di fading non sono ottenibili.

Guida all'utilizzo

Di seguito sono riportati i passi necessari per integrare BusyBoxDotNet all'interno di web forms ASP.NET.

Importare i controlli in Visual Studio .NET

Nel caso si utilizzi Visual Studio .NET è consigliabile importare i controlli contenuti nella libreria all'interno della toolbox.

La procedura dettagliata è descritta in questo articolo: Gestione di elementi e schede nella Casella degli strumenti

Document Type

Per il modo in cui è stato costruito, BusyBoxDotNet richiede che le pagine in cui è inserito siano almeno di tipo XHTML 1.0 Transitional. Il DocType è specificato nella prima riga della pagina e può trovarsi solo in quel punto.

Visual Studio .NET 2003 di default utilizza HTML 4.0, quindi se si utilizza l'IDE di casa Microsoft è necessario modificare manualmente le pagine inserendo questa direttiva:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Registrazione dell'HttpHandler

Per utilizzare le immagini e gli script inclusi nell'assembly è necessario registrare un HttpHandler nel file di configurazione web.config dell'applicazione in cui BusyBoxDotNet verrà utilizzato, che si occuperà del recupero delle risorse. Per fare ciò è necessario aggiungere la seguente dichiarazione all'interno della sezione <system.web> del web.config:

<httpHandlers>
    <add
        verb="*"
        path="BusyBoxDotNet.axd"
        type="BusyBoxDotNet.ResourceHttpHandler, BusyBoxDotNet" />
</httpHandlers>

Riferimenti

Il progetto BusyBoxDotNet è ospitato su sourceforge.net:

Questo articolo è riferito alla versione 0.1.2 di BusyBoxDotNet