Cuando uno se adentra al mundo web directamente de mundo SmartClient (VB6, winforms) sin pasar antes por conocimiento de HTML, programar en ASP.NET no sea del todo razonable y lógico como diría Sr. Spock. Me preguntaba un amigo (y también en los grupos de noticias de asp.net) como validar un texbox multilinea con la propiedad Maxlength, más precisamente era un pedido de auxilio porque "no funcionaba"!
Vamos a un poco de logica difusa jee!, veamos un poco de renderizado en HTML de nuestros queridos controles Texbox SingleLine y Multiline
<asp:TextBox ID="txtSingleLine" runat="server" MaxLength="10"></asp:TextBox>
<asp:TextBox ID="txtMultiline" runat="server" MaxLength="10" TextMode="MultiLine"></asp:TextBox>
Se renderizan…
<input name="ctl00$txtSingleLine" type="text" value="" maxlength="10" id="ctl00_txtSingleLine" />
<textarea name="ctl00$txtMultiline" rows="2" cols="20" id="ctl00_txtMultiline"></textarea>
Aquí vemos dos cotroles HTML uno es un
input del tipo text y el otro un
textarea.
A propósito coloque de antemano la propiedad Maxlength del webcontrol Textbox pero solo lo renderiza en el control HTML correcto que es el en input
Aqui es el navegador quien utiliza esta propiedad/atributo del control para no permitir mas contenido que el especificado. Pero en cambio en el textarea no lo tenemos.. entonces que hacemos?
Como simular Maxlength en Texbox Multiline
Hasta ahora vemos que en el cliente tenemos un control HTML texarea, pero como restringir que el usuario solo pueda ingresar una cantidad de caracteres predefinidos o incluso validar este ingreso, vemos una serie de opciones que nos pueden ayudar
- Con Regular Expression Validator
- Con Custom Validator
- desde el servidor (con funcion en codebehind)
- en el cliente (con funcion js)
- Con Script js (sin controles de validación)
- Simular la propiedad Maxlength en el texarea/textbox multiline
OPCION 1: Regular Expression Validator
Haciendo uso de los controles de validación podemos validar en el cliente mediante expresiones regulares (que ese lenguaje para describir patrones de texto que muchas veces uno cree que lo hizo un Vulcano)
Ejemplo sencillo:
<asp:RegularExpressionValidator ID="revTexbox3" runat="server"
ErrorMessage="Debe ingresar hasta un maximo de 10 caracteres"
ValidationExpression="^([Ss]{0,10})$"
ControlToValidate="TextBox3"
Display="Dynamic"></asp:RegularExpressionValidator>
Las expresiones regulares son muy potentes pero se vuelven muy complejas… (solo el que la formulo a veces la entiende)
Por ejemplo si queremos solo numeros necesitariamos algo asi "^([d]{0,10})$"
Algunos Enlaces:
OPCION 2: Custom Validator
Aquí podemos utilizar tanto con código del lado del servidor como en el cliente (javascript)
2.1: Validar en el servidor, es decir en el postback se validará
<asp:CustomValidator ID="cvTexbox4" runat="server"
ErrorMessage="Debe ingresar hasta un maximo de 10 caracteres"
ControlToValidate="txtEjemplo4"></asp:CustomValidator>
y en el codebehind… un ejemplo simple
Protected Sub cvTexbox4_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles cvTexbox4.ServerValidate
Dim cantidadCaracteres As Integer = args.Value.Length
If cantidadCaracteres > 10 Then
args.IsValid = False
Else
args.IsValid = True
End If
End Sub
2.1: Validar en el cliente, seteando la propiedad ClientValidationFunction con la función js
Tenemos la definición del customvalidator
<asp:CustomValidator ID="CustomValidator1" runat="server"
ErrorMessage="Debe ingresar hasta un maximo de 10 caracteres"
ClientValidationFunction="ValidarTextoCantidad"
ControlToValidate="txtEjemplo5"></asp:CustomValidator>
La funcion js seria similar a esto
<script language="javascript" type="text/javascript">
function ValidarTextoCantidad(source, arguments){
var maxlength = 10;
if (arguments.Value.length==maxlength) {
arguments.IsValid=true
}else{
arguments.IsValid=false
}
}
</script>
OPCION 3: Mediante script JS (son controles de validación de ASP.NET)
Aquí tenemos un textbox multiline para agregarle eventos de JS y disparar una función
<asp:TextBox ID="txtEjemplo6" runat="server"
Height="88px" TextMode="MultiLine" Width="269px"></asp:TextBox>
Luego la funcion js, simple y dejo al criterio de cada uno agregar las acciones mas personalizadas, aqui solo presentamos un "molesto mensaje" y tambien "cortamos" el exceso de caracteres. Muy dictador
<script language="javascript" type="text/javascript">
function ValidarCaracteres(textareaControl,maxlength){
if (textareaControl.value.length > maxlength){
textareaControl.value = textareaControl.value.substring(0,maxlength);
alert("Debe ingresar hasta un maximo de "+maxlength+" caracteres");
}
}
</script>
Y como asociamos este js en los ventos onKeypress y onKeyUp ?
txtEjemplo6.Attributes.Add("onkeypress", " ValidarCaracteres(this, 10);")
txtEjemplo6.Attributes.Add("onkeyup", " ValidarCaracteres(this, 10);")
Logrando así que se dispare la función ValidarCaracteres cuando la necesitamos
OPCION 4: Simuladores…
Escribir realmente la propiedad Maxlength :) "simular la propiedad maxlength"
Este script me gusto por la idea, pero bueno no es del todo "valido" el HTML que hay que generar… pero esta bueno, veamos como funciona
(lo encontre aquí: http://www.quirksmode.org/dom/maxlength.html)
Necesitamos agregar al html control renderizado la propiedad que "no viene de fabrica" ;), que es maxlength, quedando así en el cliente:
<textarea id="text" name="text" maxlength="10"></textarea>
Como hacemos para agregar esta propiedad? Bien como en el paso 3 agregamos propiedades/atributos para generar eventos en js aqui lo mismo.
Teniendo un textbox en diseño simple:
<asp:TextBox ID="txtEjemplo7" runat="server"
Height="88px" TextMode="MultiLine" Width="269px"></asp:TextBox>
Agregamos el atributo que necesitamos
txtEjemplo7.Attributes.Add("maxlength", "10")
Hasta ahora se renderiza con un atributo que "no es legal" pero nos puede servir gracias a este script ingenioso
<script language="javascript" type="text/javascript">
function setMaxLength() {
var x = document.getElementsByTagName('textarea');
var counter = document.createElement('div');
counter.className = 'counter';
for (var i=0;i<x.length;i++) {
if (x[i].getAttribute('maxlength')) {
var counterClone = counter.cloneNode(true);
counterClone.relatedElement = x[i];
counterClone.innerHTML = '<span>0</span>/'+x[i].getAttribute('maxlength');
x[i].parentNode.insertBefore(counterClone,x[i].nextSibling);
x[i].relatedElement = counterClone.getElementsByTagName('span')[0];
x[i].onkeyup = x[i].onchange = checkMaxLength;
x[i].onkeyup();
}
}
}
function checkMaxLength() {
var maxLength = this.getAttribute('maxlength');
var currentLength = this.value.length;
if (currentLength > maxLength)
this.relatedElement.className = 'toomuch';
else
this.relatedElement.className = '';
this.relatedElement.firstChild.nodeValue = currentLength;
// not innerHTML
}
</script>
Ok.. pero donde lo llamo? y como?
Hay que agregarlo en el load de la pagina, es decir en el evento onload del body HTML
Y en ASP.NET como hago para generar este evento?
Primeramente tienes que convertir el tag body en un html control de asp.net… esto es simplemente agregar la propiedad runat="server" y también un identificador para poder accesarlo desde el codebehind
Vamos a nuesta pagina o al master y agregamos:
<body runat="server" id="body1">
Y desde la pagina donde necesitamos que este script se ejecute
Dim body1 As HtmlControl = Me.Master.FindControl("body1")
body1.Attributes.Add("onload", "setMaxLength();")
Y listo.. tenemos algo asi
Además nos agrega luego del textarea unas etiquetas para que el usuario visualice la cantidad de caracteres permitidos y los ingresados.
Descargar ejemplo
(si no puedes ver el enlace click aquí para descargar)
Espero que te sirva de ayuda o guía.
Enlaces: