2

I have a custom TextBox control designed for accepting currency values. I call it the CurrencyTextBox. It renders as <input type="text" .../> but the issue is I need it to render <input type="currency" .../>. Note - In case you're wondering, "currency" is not a standard type, it is a custom type.

Here's a sample of some code. It all works fine apart from this one issue.

public class CurrencyTextBox : TextBox
{
    protected override void OnPreRender(EventArgs e)
    {
        //I have some code in here to render client side scripts
    }

    protected override void Render(HtmlTextWriter writer)
    {
        writer.AddAttribute("onfocus", "__ctbFocus(this);");
        writer.AddAttribute("onkeydown", "return __ctbKeyDown(this);");
        writer.AddAttribute("onkeypress", "return __ctbKeyPress(this);");
        writer.AddAttribute("onchange", "return __ctbChange(this)");


        //I have more code here which adds several more attributes

        base.Render(writer);

    }
}

I'm struggling to work out how to change the "type" attribute from the rendered markup. I want to change text="type" to say text="currency". It's easy enough just to add the attribute, as in

writer.AddAttribute("text", "currency")

but it still renders ' type="text" '. So I tried the following

Attributes.Remove("type");

but that doesn't work, it just doesn't do anything.

Perhaps I need to use

protected override void RenderAttributes(HtmlTextWriter writer)

but I can't work out exactly what the code should be or where it should go.

Matt
  • 195
  • 1
  • 4
  • 12
  • Type is something reserved so browsers can infer the "type" of input (Button, Text, etc.). Why not create your own attribute like: format, mask, inputStyle that matches what you want. type="Text" inputStyle="currency" – Ryan Ternier Sep 19 '11 at 16:59

4 Answers4

3

I've never heard of an input type called 'Currency' Are you sure you're doing the right thing, I'm pretty sure most browsers would have no idea how to render it..

http://www.w3schools.com/html/html_forms.asp

http://www.w3schools.com/html5/html5_form_input_types.asp

Of course, the easiest way is just to overwrite the Render (like you've done), but instead of calling it's base.Render, just provide the full implementation.

NotMe
  • 87,343
  • 27
  • 171
  • 245
1

I know the question is old but I just came here after a quick Google search so I'll add some details for the next visitors:

I tried to override the Render method that way, and it worked well

public class NumberInput : System.Web.UI.WebControls.TextBox
{
    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        writer.AddAttribute("type", "number");

        base.Render(writer);
    }
}

Maybe something changed with the .Net version since the question. I'm using ASP.Net on .Net 4 today.

David
  • 270
  • 1
  • 11
0

I looked at System.Web.UI.WebControls.TextBox in reflector and the AddAttributesToRender method has:

writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");

So you are left with two possible choices. 1. You can completely override the AddAttributesToRender method, or 2. You can create your own HtmlTextWriter type that ignores the "type" attribute in the AddAttribute(..., ...) method and pass that into the AddAttributesToRender function.

I don't really like option 1, but option two would look something like:

protected override void AddAttributesToRender(HtmlTextWriter writer)
{
   HtmlTextWriter coolWriter = new MyCoolHtmlTextWriter(writer);
   base.AddAttributesToRender(coolWriter);
}

Also, I found these links helpful:

ASP.NET: how to remove 'name' attribute from server controls?

Removing Attributes on Rendering WebControl

Community
  • 1
  • 1
Sam
  • 26,946
  • 12
  • 75
  • 101
  • Thanks for your reply. The problem is I end up with the attribute being rendered twice - type="text" type="currency". I want to lose "type='text'" and keep "type='currency'" – Matt Sep 19 '11 at 18:23
  • Both of the solutions I offered above should only output it once. I think completely overriding the `AddAttributesToRender` function would be too much work, but I really liked the idea of creating a custom HtmlTextWriter and modifying the behavior of the `AddAttribute(...,...)` function to discard attributes with name `HtmlTextWriterAttribute.Type` and value "text" (do ignore case on this comparison). Really you could just make that check, and if it doesn't have that name ("type") with the value "text" you could just call the super. Looks like you found something that works for you though. – Sam Sep 30 '11 at 17:28
0

Eventually I have found an answer elsewhere so I'll share it here. It might be considered a little hacky but for my purposes it is fine. Essentially, I render the control to a StringBuilder, modify the HTML (hacky?), then output the modified HTML.

So, in the "Render" method (as shown in my question), REPLACE the following line

base.Render(writer);

with this code -

//change type="text" to type="currency"
var sbHTML = new StringBuilder();
var swHTML = new StringWriter(sbHTML);
HtmlTextWriter htwHTML = new HtmlTextWriter(swHTML);
base.Render(htwHTML);
sbHTML.Replace("type=\"text\"", "type=\"currency\"");
writer.Write(sbHTML.ToString());
Matt
  • 195
  • 1
  • 4
  • 12