Quando si sviluppano pagine di inserimento dati, può tornare comodo avere un textbox che, una volta raggiunto il numero massimo di caratteri, sposti il fuoco automaticamente sul controllo successivo. Questo può essere ottenuto o iniettando del codice Javascript nel textbox, o creando un TextBox che eredita da quello standard e ingloba già questa funzionalità.
Prima di tutto analizziamo il codice Javascript. La funzione Tab viene chiamata all'evento OnKeyUp del textbox. Questa controlla quale tasto è stato premuto dall'utente e, se non si tratta di uno dei normali tasti di navigazione, passa il fuoco al primo controllo successivo in grado di riceverlo.
A questo punto creiamo un controllo che eredita dal TextBox standard e scrive automaticamente questo javascript.
using System; using System.Web.UI; using System.Web.UI.WebControls; using System.ComponentModel; namespace MyWebControls { [ToolboxData("<{0}:TextBoxEx runat=server></{0}:TextBoxEx>")] public class TextBoxEx : System.Web.UI.WebControls.TextBox{ public TextBoxEx() : base(){ FAutoTab = false; } private bool FAutoTab; private const string SMONKEYUP = "SMONKEYUP"; public bool AutoTab{ get { return FAutoTab; } set { FAutoTab = value; } } protected override void OnPreRender(EventArgs e) { if (FAutoTab){ string szFunction = "<script language=\"javascript\"> " + "function Tab(AInput, AEvent){ " + "var KeyCode = (navigator.appName.indexOf(\"Netscape\") != -1) ? AEvent.which : AEvent.keyCode; " + "var NavKeys = [0,8,9,16,17,18,27,35,36,37,38,39,40,46]; " + "var obj; " + "if(AInput.value.length >= AInput.maxLength && !KeyInNavKeys(NavKeys, KeyCode)) { " + "obj = AInput.form[(GetFieldIndex(AInput)+1) % AInput.form.length]; " + "while (obj.type == 'hidden'){ " + "obj = AInput.form[(GetFieldIndex(obj)+1) % AInput.form.length]; " + "} " + "obj.focus(); " + "} " + "function KeyInNavKeys(ANavKeys, AKeyCode) { " + "var found = false, i = 0; " + "while(!found && i < ANavKeys.length) " + "if(ANavKeys<i> == AKeyCode) " + "found = true; " + "else " + "i++; " + "return found; " + "} " + "function GetFieldIndex(AInput) { " + "var j = -1, i = 0, found = false; " + "while (i < AInput.form.length && j == -1) " + "if (AInput.form<i> == AInput) j = i; " + "else i++; " + "return j; " + "} " + "} " + "</script>"; if (!Page.IsClientScriptBlockRegistered(SMONKEYUP)){ Page.RegisterClientScriptBlock(SMONKEYUP, szFunction); } } } protected override void AddAttributesToRender(HtmlTextWriter writer) { base.AddAttributesToRender (writer); if (AutoTab) writer.AddAttribute("onKeyUp", "Tab( this, event )"); } } }
Al controllo viene aggiunta una proprietà denominata AutoTab di tipo bool che segnala se il tab automatico va attivato. Nell'evento OnPreRender viene renderizzato lo script sul client e nell'evento AddAttributesToRender viene effettuato il collegamento tra il TextBox e lo script; il tutto ovviamente solo se l'AutoTab è attivo.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Eseguire del codice personalizzato al click di una checkbox in Blazor
Effettuare il tracing asincrono delle chiamate a un'applicazione ASP.NET Core
Eseguire lo shutdown pulito di un'applicazione ASP.NET Core
.NET Conference Italia 2020
Registrare un servizio generico nella dependency injection di ASP.NET Core
Testare le impostazioni CORS di un'applicazione ASP.NET Core
L'agenda di #netconfit è online => https://aspit.co/netconfit-20 3 track, tante sessioni e una keynote speciale di @shanselman per la più importante conferenza in lingua italiana su .NET! Vi aspettiamo il 24/11. Iscrizioni sempre aperte! #donet #aspnet #netconf
Registrare un servizio generico nella dependency injection di ASP.NET Core
I più letti di oggi
- Utilizzare le proprietà Init-only per inizializzare una proprietà in C# 9
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!
- Modificare automaticamente la Wiki da una pipeline YAML con Azure DevOps
- Chiamare direttamente un numero di telefono con HTML5
- Scale your (AKS) cluster, Luke!
- Welcome to Container&DevOps Day!
- Docker 101
- Visual Basic 2019