This space is available to any ComponentArt employee to write about anything.

Major input control Gotcha


Short Story:

This will not work:
<ComponentArt:NumberInput runat="server" ID="MyNumberInput" />
<input type="button" value="+" onclick="MyNumberInput.increaseValue();" />
<input type="button" value="-" onclick="MyNumberInput.decreaseValue();" />

This is how to correct it:
<ComponentArt:NumberInput runat="server" ID="MyNumberInput" />
<input type="button" value="+" onclick="window.MyNumberInput.increaseValue();" />
<input type="button" value="-" onclick="window.MyNumberInput.decreaseValue();" />


Long Story:

This will work:
<ComponentArt:NumberInput runat="server" ID="MyNumberInput" />
<input type="button" value="+" onclick="increase();" />
<script type="text/javascript">
  function increase()
  {
    MyNumberInput.increaseValue();
  }
</script>

But, as mentioned before, this:
<ComponentArt:NumberInput runat="server" ID="MyNumberInput" />
<input type="button" value="+" onclick="MyNumberInput.increaseValue();"/>
will instead produce a JavaScript error: MyNumberInput.increaseValue is not a function

But isn't that the exact same code?? What is going on?

It turns out that in the second case "MyNumberInput" is not referring to the client-side NumberInput object. Instead it is referring to a DOM element of the same name.

Like most ComponentArt controls, input controls create a number of client-side DOM elements and JavaScript objects.
In this particular example, with a NumberInput named MyNumberInput:
In JavaScript, the most important object is named MyNumberInput, and is an instance of client-side class ComponentArt.Web.UI.NumberInput.
In the DOM, there are a number of different elements, including a text input with the id MyNumberInput.

This results in a very unusual naming conflict. Normally, when you write MyNumberInput in client-side code, you expect it to refer to the global JavaScript object of that name. And it does. Except when the code is running in the event handler of an HTML tag. Then MyNumberInput refers to the DOM element with that id. Which is probably not what you want.

To avoid ambiguity, you can use window.MyNumberInput to refer to the JavaScript object, and document.getElementById('MyNumberInput') to refer to the DOM element.

So why don’t we fix this? Well, it turns out that there is no real bug here.
First of all, this is not a design that is unique to ComponentArt input controls. In fact, most ComponentArt controls produce JavaScript objects and DOM elements with matching identifiers, for a number of reasons. What is different with input controls is that the DOM element in question happens to be a form element. This triggers the naming conflict.
However, having these matching identifiers turns out to be needed for the input controls to work smoothly with ASP.NET’s client-side validation, which is a very important feature.
So it is unlikely that we will be able to "fix" this. Instead, just please keep this gotcha in mind.

Share this post: email it! | bookmark it! | digg it! | reddit!

Posted by: Jovan
Posted: Tuesday, October 14, 2008 8:17 AM


Comments

Greg said:

Would it work to do what is really best practice anyway and for us to name our fields and variables better than that? "NumberInput1" tells me nothing about the field. "MilesPerHour" or "GumballCount" would avoid the naming conflict if I read you right...
# October 15, 2008 5:37 AM

Jovan said:

No, the problem would still stand.  Whichever identifier you pick, the control will create a client-side JavaScript object of the same name and a DOM element with the same id.  Almost all ComponentArt controls work like that.

That's a good point though, I'll rename "NumberInput1" above to "MyNumberInput".  I think that will make it a little clearer.

# October 15, 2008 8:54 AM

Greg said:

Thanks for clarifying the code and how your components work...much clearer to me now! Thanks for blogging about it too. I can see myself getting caught by this at some point without your help.
# October 15, 2008 7:02 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Blogs On This Site
Thoughts on web user interfaces and component development.
Ramblings of a web control developer.
Web.UI news and more
Next weeks guest: A dog and a baby dog!
I'm in your base, killing your dudes.
Absurdity is it's own message.
Musings of an ex Java developer
im in ur page, hackin ur codez
ComponentArt in the Community
... and the program ran happily ever after.

This Blog