Estábamos desarrollando una aplicación web para un Iphone. Esta web es una tienda y, como tal, tiene un formulario de entrada de datos a la hora de hacer el pago.
Realmente estábamos haciendo una aplicación web pero adaptada con ciertos estilos para que tenga un "Iphone feeling", así que los controles del formulario eran controles de .NET de toda la vida (además, lo de "de toda la vida" era literal, ya que el framework en que se ejecuta es el 1.1).
Sin embargo, el cliente quería que el textbox de introducción del número de la tarjeta de crédito fuese numérico, es decir, que al seleccionarlo apareciese el teclado sólo con números en el iphone (por defecto aparece el teclado alfanumérico).
Empezamos por buscar cómo podríamos hacer esto en un HTML control, y googleando encontramos que podemos indicar el atributo type para que muestre un tipo de teclado u otro:
<input type='tel'/>
<input type='number'/>
<input type='email'/>
<input />
Esto es correcto, pero… ¿Cómo lo aplicamos a un control de .NET? Evidentemente, no podemos ponerle un atributo "type". Y evidentemente, cuando añadimos un textbox .NET nos hará el renderizado en HTML como un control "type=text".
La solución es extender la clase TextBox y sobreescribir el método de renderizado.
Sin embargo, aún queda un paso más, ya que no podemos borrar los atributos que no son nuestros directamente de la colección "Attributes".
Si hiciésemos esto:
this.Attributes.Remove("type");
Para luego añadir el atributo type:
this.Attributes.Add("type", "number");
No obtendríamos el resultado esperado, ya que no podemos borrar ese parámetro.
La solución que se nos ocurrió fue hacer un replace dentro del objeto writeruna vez el método render del padre ha sido llamado:
protected
override
void Render(System.Web.UI.HtmlTextWriter writer)
{
StringWriter stringWriter = new StringWriter();
HtmlTextWriter source = new HtmlTextWriter(stringWriter);
base.Render(source);
writer.Write(stringWriter.ToString().Replace("type=\"text\"", "type=\"" + _contentType + "\""));
}
Este es el ejemplo completo:
public
class NumberTextBox:TextBox
{
private
string _contentType;
public
string ContentType
{
get
{
return _contentType;
}
set
{
_contentType = value;
}
}
public NumberTextBox()
{
}
protected
override
void Render(System.Web.UI.HtmlTextWriter writer)
{
StringWriter stringWriter = new StringWriter();
HtmlTextWriter source = new HtmlTextWriter(stringWriter);
base.Render(source);
writer.Write(stringWriter.ToString().Replace("type=\"text\"", "type=\"" + _contentType + "\""));
}
Y esto cómo se usaría el control:
<cc:NumberTextBox cssclass="ipTextfieldAllWidth" runat="server" id="Zip" ContentType="number" />