Referencing the DOM

One of the most annoying pieces of code I've ever had to write over and over is this:

document.getElementById("my_element")

It's long, it's annoying, and the Intellisense for it sucks. Not to mention, if the id of the element isn't aptly named, it might be hard to understand what "my_element" is actually referring to. Span? Text input? Table? Heck if I know!

Because of this, NinJa provides a  means of referencing the DOM by using of reference functions. Reference functions are more of "syntax sugar" that makes the code more readable and, more importantly, provides accurate Intellisense for the code at hand.

Reference functions always begin with a dollar sign ($). For the sake of compatibility with other frameworks, NinJa does not use $ alone as a function. Instead it uses $<insert object type>("<id here>").  object type is any of the elements that natively exist in NinJa and id here being the id of the element. So how do we use this in our code? Le't say we want to create a real time clock for our page. We have the following html code:

<body>
    <span id="clock"></span>
</body>

Note, we are excluding the script tags needed and assuming they are provided. Notice that we don't provide a class to span. Classes are really meant for CSS references, not JavaScript referencing, so we stick to the id attribute. Now lets see to code to make the clock display the current time.

$Span("clock").Text(DateTime.Now().GetTime().ToString());

First off, DateTime is a static object type that represents Dates and Times in a similar fashion as the .NET framework. DateTime.Now() gets the current datetime and GetTime() gets the time portion of the date as a TimeSpan and ToString() returns a standard display of time in HH:MM:SS format (applies only to the TimeSpan objects).

Here we use the reference function $Span(). This indicates we are reference a span element in the HTML dom. In all reality we could just as easily used $Element() or even $TextBox(), the code does the same thing. However, the Intellisense for NinJa is driven by the proper reference function used. By using $Span(), Intellisense is provided that lists functions and fields specific to span tags. Where as if we used $TextBox(), we would be given functions for an input tag of type text such as Text(), Focus(), etc and these functions don't really exist for span tags and would throw errors on execution.

$Element is a generic reference function and exposes only functions common to all html element objects. Other generic reference functions include $Input for general form inputs (select, input, textarea) and $Content for elements that normally contain child elements (span, div, td, etc).

There are other reference functions that exist for non-element objects. These specifically provide a way to get Intellisense for objects that cannot have their types derived, such as parameters on functions. Here's an example:

function limitString(s, n) {
    s = $String(s);
    return s.Substring(0, n);
}

Here we use the reference function $String. Intellisense has no way of knowing what the types for s and n will be. However, by using s = $String(s), we are telling Intellisense that s will be a string object. So when we type "s." we will receive Intellisense for strings.

.NET ID Obfuscation

This isn't as big of a problem if you're using ASP.NET 4.0 and static ids for your pages, but for those who cannot afford the luxury, there is a solution! NinJa has built in support for referencing ID's that have been obfuscated by ASP.NET's unique id naming scheme. Let's say you have the following code:

<asp:Panel ID="Panel1" runat="server">
    <asp:Label ID="clock" runat="server" />
</asp:Panel>

We all know what will be produced in the HTML:

<div id="Panel1">
    <span id="Panel1_clock"></span>
</div>

What if this appearing in a master page? What if it's user control? We really don't want to have to view the page then set the id that way.

That's where NinJa comes in. Ninja creates various reference aliases for references that contain underscores. When using a reference function, such as $Span, if you provide the id, it checks against a table of possible id's until it finds the right one and returns the given object. In this example we can us $Span("clock") since NinJa created an alias of "clock" to refer to "Panel1_clock". 

For those elements with the same id in parents with different ids, this is where you can use the "." syntax to traverse the tree to find the correct element. Let's say this snippet was in a user control and the following HTML was generated by ASP.NET:

<div id="Control1">
    <span id="clock"></span>
</div>
<div id="Control2">
    <span id="clock"></span>
</div>
<div id="Control3">
    <span id="clock"></span>
</div>

As you can see, there are three elements named "clock". How can we reference correct one? $Span("parent.child"). When a string contains a period, each part is treated as a parent in the tree and finds the id as a child in the parent. You can have as many levels as you want, but this will ensure that you retrieve the element you truly want.

Finally, if the element simply can't be found, the reference function will return null.

Last edited Jun 13, 2012 at 3:49 PM by dahrkdaiz, version 2

Comments

No comments yet.