Beren.it

All that you can leave behind

Dynamic Data Entry - Un datepicker per le date

Personalizzare il controllo di editing delle date con i Dynamic Data Entity

Sappiamo tutti che uno dei formati di dato più pericolosi in assoluto è la data. Fondamentalmente perchè ognuno la scrive un pò come gli pare e piace con il problema che poi quando si va a scriverla sul DB ci possono essere spiacevoli sorprese. Nell'ambito dei Dynamic Data Entry di cui da un pò di post mi occupo per la notevole versatilità che hanno l'idea che più di tutte si è fatta largo nel mio ideale di applicazione è quella di consentirne l'inserimento e la modifica attraverso un datepicker. Dato che molti però, come il sottoscritto ;), non masticano molto JQuery magari ripiegare su una soluzione più semplice può essere di utilità ed in questo ci viene in aiuto l'Ajax Control Toolkit che potete scaricare gratuitamente qui.
Questo fantastico set di controlli oob Ajax contiene un buon Calenda Extender che fa al caso nostro. Scaricata infatti la dll ed inclusa come referenza del progetto potremo infatti usufruire di tale funzionalità.

Per implementare tale modifica dovremo dunque aprire la lista dei controlli ed, una volta individuato il controllo generico di Edit delle date aprirlo nell'editor.

Nella toolbox a sinistra selezionate il Calendar Extender e trascinatelo nel controllo a destra. Se nella toolbox a sinistra non doveste trovare il controllo significa che dovete semplicemente aggiungere la dll cliccando con in destro sulla toolbox quindi premendo "Choose items" ed infine nella finestra che si aprirà browsandola.

Una volta che avete trascinato l'extender all'interno del controllo, il gioco è praticamente fatto. Basterà infatti modificare le sue proprietà per ottenere l'effetto voluto:

  • TargetControlID: è l'ID del controllo che conterrà poi effettivamente la data che nel nostro caso è la textbox preesistente. In pratica con questa proprietà l'extender sa su quale controllo deve visualizzare il datepicker. Questa proprietà deve essere valorizzata altrimenti il datepicker non funzionerà.
  • Format: questa indica semplicemente il formato in cui verrà tradotta la data scelta nel date picker ed inserita nel controllo. Nel nostro caso nel classico formato che si usa in Italia.

Una volta concluso questo il gioco è fatto senza JQuery e con un effort ridicolo.

 

Dynamic Data Entity - Gridview Pager

Customizzare il controllo di paginazione del GridView nei Dynamic Data Entity

Una delle cose più scomode che mi è capitato di utilizzare con i Dynamic Data è il paginatore out of the box. O meglio, diciamo che la configurazione di default mi risultava davvero parecchio scomoda: avere il numero di righe di default visualizzate a 10. Troppo poche, specie se si ha uno schermo ad alta definizione e degli occhi buoni, si rischia di avere perennemente mezza pagina vuota.

Come fare allora? Mi metto a spulciare un pò il codice e mi accorgo che il tutto è assai più semplice di quanto si possa pensare. Infatti la modifica/personalizzazione interessa solamente 2 files:

  • GridViewPager.ascx è il controllo ascx che contiene la dropdown con i valori selezionabili di righe
  • List.aspx è il template di pagina di default che utilizza la gridview che viene visualizzata nelle pagine

La prima modifica in GridViewPager.ascx è opzionale nel senso che si possono cambiare i valori nella dropdown, aggiungerne di nuovi o toglierne a piacere. Il consiglio è quello di lasciare sempre il valore 10 che corrisponde al default della griglia come vedremo tra un pò. Ma in generale anche qui la libertà è massima.

Nel mio caso rimuoverò i valori 5 e 15 ed aggiungerò il 50, ma voi potete ovviamente fare come vi aggrada.
Fatto questo procediamo però con la modifica più importante cioè: dove cambiare il valore di default da quello scomodo 10 al più comodo 20? Semplicissimo: aprite il template di pagina List.aspx individuate il tag del GridView e tra gli attributi metteteci un bel PageSize=20. In questo modo:

Fatto questo con un seplice reload della pagina avrete personalizzato con facilità il numero di righe visualizzate nel paginatore della griglia. Ecco il risultato:

ASP.NET Ajax client-side framework failed to load

Errore ASP.NET Ajax client-side framework failed to load

Qualche giorno fa mi ero trovato a dover riconfigurare su una macchina nuova un'applicazione ASP.NET 4.0 che avevo inizialmente sviluppato su di un'altra. In pratica sulla vecchia macchina tutto funzionava a dovere, invece sulla nuova mi ritrovavo ad avere sempre in caricamento l'errore "ASP.NET Ajax client-side framework failed to load". In effetti tutto ciò che era Ajax nell'applicazione non funzionava più. Ho fatto così una serie di ricerche sul web ed ho trovato gli errori più assortiti e fantasiosi: da un problema al web.config, ad inserire codice custom nel routing dell'applicazione (è un app MVC) e infine modificare mille settaggi diversi in IIS. Tutto senza alcun esito.

Finalmente questa mattina mi imbatto in questo post che mi ha risolto tutti i problemi. In effetti come suggerisce il tipo, ho guardato sotto il site di IIS in cui gira l'applicazione e nella sezione Handler Mapping ho verificato che c'erano pochissime voci e nessuna su ASP.NET 4.0, di conseguenza ho fatto come consigliava lui cioè ho fatto un rerun del comando aspnet_regiis nella directory del Framework 4.0 (perchè a me lo dava con le applicazioni 4.0)

Una volta eseguita questa operazione magicamente negli Handler Mapping mi sono ritrovato tutte le voci mancanti (specie quelle su ASP.NET 4.0) e soprattutto l'errore ed i problemi ad esso correlati erano svaniti.

Dynamic Data Entities - Customization Parte 1 - Name & Scaffolding

In un post di qualche giorno fa illustravo la facilità con cui realizzare una web application per il data entry attraverso l'utilizzo dei Dynamic Data Entities. Ora proseguo in questo argomento illustrando come procedere con la customizzazione di quanto automaticamente prodotto dal template di Visual Studio. Apriamo ad esempio la pagina principale dell'applicazione.

Effettivamente la web application ha l'elenco completo delle tabelle come si vede dall'immagine qui sopra. Però supponiamo che non tutte le tabelle siano da visualizzare. Per nascondere o visualizzare le tabelle bisogna agire sulla proprietà di ScaffolAllTables che abbiamo già visto essere settata all'interno del file Global.asax. Essa infatti se settata a true informa il framework che tutte le tabelle presenti nello schema edmx devono esssere visualizzabili.

[C#]

    DefaultModel.RegisterContext(typeof(FOFEntities), 
    new ContextConfiguration() { ScaffoldAllTables = false });

Settiamo dunque a False tale property, ma questo non basta infatti se lanciamo l'applicazione verrà sollevata un'eccezione. In effetti l'applicazione in questo modo non ha nessuna table da visualizzare, quindi bisogna trovare una maniera per informare il framework quale tabele specifiche mostrare dal momento che non le deve visualizzare tutto. In generale questo tipo di operazioni di customizzazione si applicano all'entity framework decorando le classi con attributi specifici. Ad esempio se volessimo indicare una tabella, o meglio la classe che la rappresenta nel file edmx, come visualizzabile dall'applicazione dovremmo usare l'attributo ScaffoldTable(true) e collocarlo appena prima della dichiarazione. Non è però nelle best practice questa operazione, inquanto dovrebbe andare a modificare un file autogenerato qual'è il Designer del edmx. Infatti se la struttura del database cambiasse per una qualche ragione e volessimo aggiornare il file edmx attraverso l'interfaccia del designer, tutte le modifiche apportate manualmente andrebbero perse...
Che fare dunque? Fortunatamente le Partial Classes di .NET ci vengono in aiuto e ci forniscono un efficiente workaround al problema consentendo di separare in un altro file tutte le personalizzazioni realizzate manualmente. Aggiungendo infatti un file cs al progetto. A questo punto prendiamo il nome della classe che si riferisce alla tabella che vogliamo visualizzare e ne scriviamo la definizione partial. In questa classe però non andremmo a specificare nient'altro ad esccezione di un attributo MetadataType che serve a linkare alla classe stessa una classe di metadata appunto.

[C#]

    [MetadataType(typeof(TB_SEASONMetadata))]
    public partial class TB_SEASON
    {

    }

    [ScaffoldTable(true)]
    [TableName("Stagione")]
    public class TB_SEASONMetadata
    {
        ...
    }

E' in questa classe di metadata che andremo a specificare tutte le customizzazioni che ci interessano. In particolare nel nostro caso sfrutteremo il già sopra citato attributo ScaffoldTable(true) che indica al framework che questa classe è gestibile dal sistema ed un altro attribute di nome TableName che serve a rinominare la tabella e nel nostro caso utilizzeremo per passare dal nome poco user-friendly "TB_SEASON" a "Stagione". Compiliamo, refreshamo la pagina. Ed otteniamo il risultato desiderato. Una sola tabella visualizzata nell'elenco e con un nome maggiormente esplicativo.

Dynamic Data Entity: una web application per il data entry in pochi click

Una cosa che capita spesso di realizzare in ambito web è creare un'interfaccia che riesca a fornirici un buon supporto per le modifiche di una base dati. Purtroppo ciò in passato richiedeva montagne di righe di codice spesso ripetitivo e noioso prima di arrivare a produrre anche solo un paio di pagine per interfacciarsi ad altrettante tabelle. Dal framework 3.5 sp1 in poi però, Microsoft ha introdotto una nuova tipologia di web application out-of-the-box in grado di ridurre sensibilmente questa fase assai laboriosa di stesura del codice per il layer dati e la sua visualizzazione in pagine user frendly.

Vediamo più nei dettagli come funziona il tutto. Per l'esperimento servono un database con alcune tabelle in relazione per le quali vogliamo creare una web application che ci fornisca la possibilità di realizzare le classiche operazioni CRUD (Create Read Update Delete). Una volta trovata la base dati che fa al caso nostro basta aprire Visual Studio 2010 e una volta cliccato sul tasto crea nuovo progetto, dai template presenti selezionare "ASP.NET Dynamic Data Entities Web Application".

Una volta effettuata questa operazione avremo già una serie di cartelle nell'albero del progetto che sono utilizzate dal framework. A questo punto dovremo linkare il database che ci serve al fine di poterlo amministrare attraverso l'applicazione. Ci posizioniamo dunque sulla root del progetto e clicchiamo su "Add New Item".

Selezioniamo "ADO.NET Entity Data Model". Questo vi porterà all'interno di un wizard per la selezione del database qualora esistesse già oppure ad un modello vuoto se non esistesse uno già pronto. Nel nostro caso partiamo da un db esistente e dunque scegliamo la prima opzione.

Fatto questo, una volta selezionata la connessione desiderata possiamo selezionare quali elementi del database importare in termini di Tabelle, Viste e Stored Procedure. Quindi premendo Finish, troveremo un file edmx nella root dell'applicazione che è a tutti gli effetti il nostro Entity Model Appena Creato.

Bene. Se a questo punto proviamo a lanciare l'applicazione però ci viene ritornato una errore che recita "There are no accessible tables. Make sure that at least one data model is registered in Global.asax and scaffolding is enabled or implement custom pages.". Questo perchè dobbiamo dire all'applicazione che si deve pluggare all'Entities model appena creato. Farlo è molto semplice basta infatti aprire il file Global.asax (come del resto ben suggerito dal messaggio di errore) e decommentare una line di codice commentata sostituendo alla parola "YourDataContextType" il nome della classe generata nel file edmx, che trovate nel file designer all'interno della region "Contexts".

Se però proviamo a lanciare l'applicazione ora riceveremo ancora l'errore di prima. Questo perchè in effetti nella riga di codice decommentata poco fa abbiamo lasciato il frammento in cui si setta a false la property "ScaffoldAllTables". Settandola a true automaticamente tutte le tabelle saranno visibili ed editabili. Salviamo, buildiamo e voilat il gioco è fatto l'applicazione gira e funziona perfettamente. Abbiamo l'elenco completo delle tabelle e per ognuna possiamo effettuare ogni tipo di modifica il tutto con i benefici delle validationa Ajax automaticamente embeddate senza scrivere una linea di codice! Provare per credere.

Visualizzare una progress bar animata con Javascript dopo un submit

Visualizzare una progress bar animata con Javascript dopo un submit

Riporto qui una libera traduzione di un post interessante sull'argomento. Infatti in alcuni casi, specie quando la sottomissione di una pagina richiede tempi di processamento piuttosto lunghi, è utile visualizzare un'immagine che dia l'impressione che l'applicazione stia lavorando e non sia bloccata. Ciò può essere ottenuto semplicemente con un Javascript e una gif animata.
Un sito molto carino da cui è possibile con un paio di click generare un'icona di caricamento in maniera personalizzata è : www.ajaxload.info.
Vediamo ora invece in dettaglio come scriver il codice per ottenere il comportamento voluto.
Anzitutto settiamo la visibilità di testo ed immagine a hidden.

[ASPX/HTML]

<p style="visibility:hidden;" id="progress">
<img id="progress_image" style="padding-left:5px;padding-top:5px;" 
              src="images/ajax-loader.gif" alt="Operation in progress..." />
              Operation in progress...
</p> 

 

A questo punto scriviamo la funzione javascript che esegue la visualizzazione della progress bar.

[javascript]

function loadsubmit(){
      ProgressImage = document.getElementById('progress_image');
      document.getElementById('progress').style.visibility = 'visible';
      setTimeout('ProgressImage.src = ProgressImage.src',100);
      return true; 
}

 

La funzione setTimeout è necessaria per IE6 e IE7. Infatti IE termina le animazioni dell gif alla sottomissione. Quindi la chiamata della funzione di timeout avviene prima della sottomissione della form (return true), ma i suoi effetti, grazie al timeout, si verificheranno dopo. A questo punto non ci resta che invocare la funzione javascript sull'evento OnClick del tasto di sottomissione, in questo modo:

[ASPX/HTML]

<input onclick="return loadSubmit();" 
              src="images/submitinfo_btn.jpg" type="image" />