Home > .net 3.5, AJAX, c#, JavaScript, Microsoft, Visual Studio 2008, Volta > AJAXing in .NET – #2 – Pure JavaScript and AJAX Framework JavaScript

AJAXing in .NET – #2 – Pure JavaScript and AJAX Framework JavaScript

January 7, 2008

This is the second in the three part series looking at “AJAXing” technologies for .NET developers.

Post 1:

  • Example #1 – Plain ASP.NET Page with PostBacks
  • Example #2 – ASP.NET AJAX with UpdatePanels

Post 2 (this post):

  • Example #3 – Standard HTML and JavaScript
  • Example #4 – ASP.NET AJAX Framework and JavaScript

Post 3 (this post):

  • Example #5 – Nikhil Kothari’s Script#
  • Example #6 – Microsoft Labs Live Volta

In these two examples, we’ll take a look at the differences of JavaScript programming—between “standard” JavaScript and using the methods and objects provided by the ASP.NET AJAX Framework, but without using the actual server-side controls.

#3. Standard HTML and JavaScript

The next example is a classic—clean HTML and a JavaScript function.  This is a standard HTML page without any “fancy” .NET or framework technologies.  How does this compare to .NET?

In our header, there’s a simple JavaScript function to handle the OnChange event of the drop down list:

<script type=”text/javascript” language=”javascript”>

function LoadPhoto()

{

PhotoPreview.style.display = ‘block’;

       PhotoPreview.src = Images/ + PhotoList.value;

}

</script>

Next, our HTML.

<select id=”PhotoList” onchange=”LoadPhoto()”>

<option label=”ABCs – Blocks” value=”abc_blocks.jpg” />

       <option label=”ABCs – Chalkboard #1″ value=”abc_board.jpg” />

       <option label=”ABCs – Chalkboard #2″ value=”abc_board2.jpg” />

       <option label=”Graduation” value=”capandgown.jpg” />

</select>

<br /><br />

<img id=”PhotoPreview” style=”display: none; src=”” />

As we can see from the Fiddler capture, the HTML, of course, is EXTREMELY thin here and, since postback events are not firing, the page ever reloads, simply loads the resources (in this case, images) as necessary.  In addition, the images are cached, so additional downloading isn’t necessary..

  1. HTML Code: 8 + 2 4 JavaScript function lines (see below).
  2. I may be a bit older, but this is how it “used” to be done, so it’s readable to me.  For those unfamiliar with JavaScript may be turned off by it.
  3. IE 7 and Safari (*shocked*) work, however, Opera and FireFox are broken.  See details below.
  4. As you’ll read below, managing compatibility between JavaScript functionality on each platform is a HASSLE and can be a major turn off for DIY JavaScript AJAX.

Details for Compatibility Issues:

IE 7 and Safari actually render correctly because they use the “label” property from HTML 4.0 for option boxes.  FireFox and Opera turn out blank.  To have options in those browsers, we’ll need to place the text in the body of the tag. 

<option label=”ABCs – Blocks” value=”abc_blocks.jpg”>
ABCs – Blocks
</option>

That fixes Opera, but FireFox is still broken.  Why?  Because FireFox can’t read the DOM directly, you have to populate each element into a variable and manipulate the variable.  Updating our JavaScript to the following code will fix the problem.  Also, since this method works in all the OTHER browsers, this would be the “preferred” method to accomplish this.

var photoPreview = document.getElementById(‘PhotoPreview’);

var photoList = document.getElementById(‘PhotoList’);

 

photoPreview.style.display = ‘block’;

photoPreview.src = ‘Images/’ + photoList.value;

While this code works, you can run into challenges for browsers that do not yet support getElementById.

#4. ASP.NET AJAX Framework and JavaScript

In our last example, browser compatibility was the most challenging pitfall to overcome.  If we want to write our own JavaScript, but would like the padding of a framework, we can use the ASP.NET AJAX framework without all the fancy server-side controls.

When we add a new AJAX Web Form, a single control is added, the ScriptManager.  In this example, we’re not going to use UpdatePanels, but simply access the objects provided for us by the ScriptManager.

The JavaScript in our Header:

<script type=”text/javascript”>     

function LoadPhoto() {    

       $get(‘PhotoPreview’).style.display = ‘block’;

       $get(‘PhotoPreview’).src = ‘Images/’ + $get(‘PhotoList’).value;

}

</script>

And the HTML:

<asp:ScriptManager ID=”ScriptManager1″ runat=”server” />

<select id=”PhotoList” onchange=”LoadPhoto()”>

<option label=”ABCs – Blocks” value=”abc_blocks.jpg”>

              ABCs – Blocks</option>

<option label=”ABCs – Chalkboard #1″ value=”abc_board.jpg”>

              ABCs – Chalkboard #1</option>

<option label=”ABCs – Chalkboard #2″ value=”abc_board2.jpg”>

              ABCs – Chalkboard #2</option>

<option label=”Graduation” value=”capandgown.jpg”>

              Graduation</option>

</select>

<br /><br />

<img id=”PhotoPreview” style=”display: none; src=”” />

The $get alias simply returns browser-compatible JavaScript for getElementById.  You can read more about how this alias works on Irena Kennedv’s blog.  The short is that this alias will generate the correct code based on the browser.

The Fiddler logs are nearly identical to the plain JavaScript; however, the .aspx page is a bit heavier.

  1. HTML Code: 9 + 2 JavaScript function lines.
  2. Aside from familiarization with the aliases and framework functions in JavaScript, this code is nearly identical to the
  3. The only difference at this point is that the code allows us to access the $get alias and, most importantly, cross-browser compatibility handled by the framework—not you.
  4. Past the bit of losing “update panels”, this is a nice middle ground between pure JavaScript and pure server-side AJAX Framework.

This methodology also has another benefit: you can directly access web services (.asmx) from your JavaScript client code.  For more information on this topic, read Calling Web Services from Client Script.  I haven’t done a lot with this yet, but have a few notes sitting around to give it a try and see how it compares when reading actual data across the wire.

  1. marcelo
    January 7, 2008 at 11:08 pm

    bueno les dejo un link sobre donde existe una extensa bibliografia sobre ajax:
    http://vagos.es/showthread.php?p=2035665
    y por si les interesa otro sobre Servicios web y SOA
    http://www.vagos.es/showthread.php?t=285783

  2. January 8, 2008 at 7:33 am

    Interesting article. I’m going to have to check out the specs on the label attribute for an option tag (this is the first I’ve heard of it in 7 years of web dev)

    I also noted that the $get method used, has a flaw in the implementation, in that it does NOT handle IE’s bugs with document.getElementById() As a service to your readers I think it is important to be aware of the bugs, and ideally workaround them until this core method is patched, or better yet IE fixes their bugs.

    See these bug reports for details:
    http://webbugtrack.blogspot.com/search/label/152
    http://webbugtrack.blogspot.com/search/label/154

    In short, IE will return the wrong elements in certain situations, which can and will cause issues when your application starts to get a bit complex (which is also the time that debugging it becomes a nightmare too!๐Ÿ˜‰

  3. January 8, 2008 at 8:11 am

    @marcelo – Nice list of all the AJAX books out there; thanks!

  4. January 8, 2008 at 8:21 am

    @Henry – I first found the label attribute hounding through Microsoft SharePoint code, but it’s been mostly IE specific. The example here simply demonstrated that (Safari support was truly shocking–I didn’t expect it to work).

    For information on the spec, you can find it on W3C here:

    http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.6

    From the page:

    label = text [CS]
    This attribute allows authors to specify a shorter label for an option than the content of the OPTION element. When specified, user agents should use the value of this attribute rather than the content of the OPTION element as the option label.

    As you said, the flaws are in IE and Opera’s implementation of getElementById, not the AJAX Framework alias $get, which is very unfortunate.

    I’ll be honest that I wasn’t aware that JavaScript WAS case sensitive in any browser–I’ve always assumed that functionality was broke all around. Similar to most other scripting languages, I’ve simply avoided same-named variables.

    Very good to know, however, and to keep an eye out while debugging!

  5. Nathon
    January 8, 2008 at 10:46 am

    @David,

    Wow, I can’t believe that label is actually in the HTML 4.x specs, and that IE supports it, and Firefox doesn’t… I’m speechless!

    (Although, after reading it, and knowing what the value attribute is for, the label doesn’t make sense?… unless qualified with “display the label, ONLY when the .innerText of the option element will not fit”) IMHO.

    JavaScript most certainly is CaSe Sensitive! (and many would argue that any “real” language “must” be)

    As you likely read, the case-sensitivity is only 1 issue, the matching on non-valid elements with a matching name attribute is the real big issue. I use the workaround in all my projects now, after this one bit me big time in a production application.

    Finally, looking at the original source code in your example, the option tags have an .innerText value matching the label attribute… thus would show the same value either way? Am I missing something here, or was the source code updated?๐Ÿ˜‰

    Hmm, actually I guess I have one last comment… what is the bit in your notes about Firefox not being able to read the DOM directly?… I’ve never had any issues here, can you explain what did/didn’t work here?๐Ÿ˜‰

  6. January 8, 2008 at 1:37 pm

    @Nathon- The spacing, I believe, is where SharePoint uses it the most on forms and such–at least that’s where I’ve seen it. The more I think about it, the more I need to dig through the HTML of some .net pre-gen’ed controls and see which is applied. Hmmm.

    Re: JavaScript being case sensitive–totally agreed and noted; I’ve just never ran into an issue before with two elements with the same ID, but different casing. I sat and worked up a few examples to prove it to myself and, yeah, it breaks. Heh, how annoying, but nice to know.๐Ÿ™‚ My prior assumption is now altered.

    Re: Option Tags — You’ll notice the HTML right at the top of the example doesn’t have innerText, just the label. I could remove the label attribute with the innerText, but just left it for now.

    Re: FireFox — IE, Opera, and Safari are able to parse the following code block directly… they don’t need to break them out into variables; whereas, for some reason, FireFox seems to require it. Now, I’ll admit that what IE, Opera, and Safari are doing may be non-standard and FireFox is standardized, but it’s a notable difference.


    function LoadPhoto()
    {
    PhotoPreview.style.display = โ€˜blockโ€™;
    PhotoPreview.src = โ€˜Images/โ€˜ + PhotoList.value;
    }

    The pro to this is that Visual Studio 2008’s intellisense automagically picks up elements on the page and populates them with their properties. The con, obviously, is that it doesn’t seem to work with FireFox; it throws the error that PhotoPreview is not defined.

    So, a better wording may be that FireFox can read the DOM directly, but not directly by the element’s Id; you must first place the required element into a variable.

  1. January 8, 2008 at 2:28 pm
Comments are closed.
%d bloggers like this: