Helping ASP.net programmers with that unavoidable JavaScript

AID: 2606
  • Status: Published

1860 points

Awards
  • Community Pick
This article is for ASP.net programmers with little experience in JavaScript.

As an ASP.net programmer, probably you have noticed that writing JavaScript code is an important part of your daily work.  This is a fact.  In today’s world, when ultra-fast running is a requirement in all applications, including (of course) web applications, doing the most possible tasks in JavaScript – and taking advantage of execution of those tasks in the client browser - will relieve a lot of server workload.

The bad news are that writing JavaScript (specially good & simple JavaScript) is not easy.  JavaScript code syntax is complex, especially for VB programmers that had never written code in C or C# languages and are not familiar with case-sensitive source code or case-sensitive strings management.  And Visual Studio’s Intellisense doesn’t work as well in JavaScript as in server code (this has been improved in VS2008, but in VS2005 JavaScript Intellisense is almost nonexistent).

Hence the need for a good JavaScript code base library.  There are many ways in which we can minimize the difficulty in writing JavaScript code.  The purpose of all this is to write a good JavaScript code base library (usually called “common.js”) to include in all or almost all of the ASP.net pages that we develop.

Naturally, each one of us will have a preference on which of these facilities will help us more on writing JavaScript.  I’ll focus this article on 3 ways to attack the problem: all-purpose utility functions, extending JavaScript native objects, and writing wrappers for HTML elements.

All-purpose utility functions

Simply by browsing the web, you’ll find a lot of utility functions that will make your life much easier when writing JavaScript. Here’s a sample:

function $() {
    var elements = new Array();
    for (var i = 0; i < arguments.length; i++) {
        var element = arguments[i];
        if (typeof element == 'string')
	        element = document.getElementById(element);
        if (arguments.length == 1)
	        return element;
        elements.push(element);
    }
    return elements;
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

Select allOpen in new window



Are you bored of writing document.getElementById – that looong and awful function name-? Well, then try $().

var anyObject = $( 'id_of_the_object' );
                                    
1:

Select allOpen in new window



This $() function not only simplifies the way that you get reference to objects, but also extends the way that you can do it, by accepting as arguments not just object identifiers, but event variables that are not established yet.

var firstObject = $('id_of_the_object');
var secondObject = $('id_of_another_object');
var manyObjects = $('the_third_object', 'the_fourth_object', firstObject, secondObject);
                                    
1:
2:
3:

Select allOpen in new window



Now manyObjects is an array of the four objects specified as arguments (note that two arguments are identifier strings and the other two arguments are variables referencing objects).

This function has turned into being my most used function since it came to my life.  I found it in this blog entry: http://www.dustindiaz.com/top-ten-JavaScript/. This URL is a unbeatable starting point to find useful JavaScript functions suitable to be in an honored place in our common.js library.

Extending JavaScript native objects

Another amazing thing that we can do to simplify our life with JavaScript is extend its native objects.  This lets us provide them with new and exciting features that in many cases will seem like those existing in .net objects.  As an example, we are going to extend the native JavaScript String object with this new function: startsWith().  Sound familiar? Yes, it’s a native .net function of the .net’s System.String object, and it’s wonderful when we can make JavaScript strings provide us with the same and useful functionality.

Extending a JavaScript native object is as easy as this:
native_type.prototype.your_new_function = function([arguments]) {
    // your JavaScript code here
    // in here, the “this” object refers to the variable in which you call the function
}
                                    
1:
2:
3:
4:

Select allOpen in new window


As an example:
String.prototype.startsWith = function(chars) {
    // return true when the substring of the string, starting at 0
    // and taking chars.length of length be equal to chars
    return (this.substr(0,chars.length) == chars);
}
                                    
1:
2:
3:
4:
5:

Select allOpen in new window


As strings are case-sensitive in JavaScript, you can even improve the function to make it case-insensitive:
String.prototype.startsWith = function(chars,ignoreCase) {
    if(ignoreCase==true) {
        return (this.toLowerCase().substr(0,chars.length) == chars.toLowerCase());
    } else {
        return (this.substr(0,chars.length) == chars);
    }
}
                                    
1:
2:
3:
4:
5:
6:
7:

Select allOpen in new window


Well, I have shown you the way.  Now imagine extending the JavaScript objects in multiple ways: string objects with startsWith(), endsWith(), contains(), ltrim(), rtrim(), trim()… imagine the possibilities with the limited and nothing-easy-to-manage JavaScript Date object!  This is an endless world waiting to be explored by you.  Indisputably, extending native JavaScript objects is a must-have in your common.js.

Writing wrappers for HTML elements

Finally we’ll discuss another approach to the JavaScript problem that will let us save hours and hours of our limited (and precious) time: the writing of wrappers for HTML objects.

Take this simple example: in JavaScript, we need to get a reference to a list object and add one element to the list.

This is the native JavaScript way:
//---------------------------- get a reference to the list object
var list = document.getElementById( 'id_of_the_list' );
//---------------------------- Create the new option and give it text and value
var newOption = document.createElement( 'option' );
newOption.text = 'the text';
newOption.value = 'the value';
//---------------------------- Add the new option to the list object
list.options.add(newOption);
                                    
1:
2:
3:
4:
5:
6:
7:
8:

Select allOpen in new window



Yeah, I know that, as with almost all in JavaScript, it can be much simplified as this:
//---------------------------- get a reference to the list object
var list = document.getElementById( 'id_of_the_list' );
//---------------------------- add the new option
list.options[list.length] = new Option( 'the text', 'the value' );
                                    
1:
2:
3:
4:

Select allOpen in new window


But even in that way, this is much more readable and pleasant to write:
var list = new ListControl( 'id_of_the_list' );
list.add( 'the text', 'the value' );
                                    
1:
2:

Select allOpen in new window


As you might deduce from that previous code, we have created a ListControl JavaScript class that acts as a wrapper of the native HTML <select> tag.  

We can provide this ListControl class with naturally named methods and utilities that will make the work with select objects much easier.  This is the listing of my complete ListControl class, that I use often in my pages:

function ListControl(id) {
    //get a reference to the list control (using, of course, the $() function)
    var _base = $(id);
    
    //this function is to show/hide the list control wrapped, or get its visible state
    //usage:
    //alert(listControlObject.visible());
    //listControlObject.visible(false);
    this.visible = function(newValue) {
        if(newValue==undefined) {
            return (_base.style.display != 'none');
        } else {
            _base.style.display = (newValue==true) ? '' : 'none';
        }
    }
    
    //this function is to enable/disable the list control wrapped, or get its enabled state
    //usage:
    //alert(listControlObject.enabled());
    //listControlObject.enabled(false);
    this.enabled = function(newValue) {
        if(newValue==undefined) {
            return (!_base.disabled);
        } else {
            _base.disabled = (!newValue);
        }
    }
    
    //this function is to get the number of elements contained in the list
    this.count = function() {
        return _base.options.length;
    }
    
    //this function is to clear all the elements from the list
    this.clear = function() {
        while(_base.options.length > 0) {
            _base.options.remove(0);
        }
    }
    
    //this function is to add a new element to the list. The index argument is optional;
    //if not supplied, the new element adds at the end of the list
    this.add = function(text,value,index) {
        var oItem = document.createElement('option');
        oItem.text = text;
        oItem.value = value;
	    
        if((index==undefined) || (index==null)) {
            try {
                _base.add(oItem,null);
             } catch (e) {
                _base.add(oItem,_base.length);
            }
        } else {
            _base.add(oItem,index);
        }
    }
    
    //this function is to remove an element from the list based on its zero-based position
    this.remove = function(index) {
        _base.options.remove(index);
    }
    
    //this function is to get a concrete element based on its zero-based position. The function
    //returns the native Option javasacript object, so we can access to text, value, and so on
    this.item = function(index) {
        return _base.options[index];
    }
    
    //this function is to sort alphabetically the elements in the list. Note that this will only
    //work well when elements are text-unique and value-unique
    this.sort = function() {
        var texts = new Array();
        for(var k=0;k<_base.options.length;k++) {
            texts[k] = _base.options[k].text;
        }
        texts.sort();
        var values = new Array();
        for(var k=0;k<texts.length;k++) {
            values[k] = this.valueOf(texts[k]);
        }
        this.clear();
        for(var k=0;k<texts.length;k++) {
            this.add(texts[k],values[k]);
        }
    }
    
    //this function is to retrieve the text that corresponds to a concrete value
    this.textOf = function(value) {
        for(var k=0;k<_base.options.length;k++) {
            if(_base.options[k].value==value) {
                return _base.options[k].text;
            }
        }
        return null;
    }
    
    //this function is to retrieve the value that corresponds to a concrete text
    this.valueOf = function(text) {
        for(var k=0;k<_base.options.length;k++) {
            if(_base.options[k].text==text) {
                return _base.options[k].value;
            }
        }
        return null;
    }
    
    //this function is to know when the list contains any element with the specified text
    this.containsText = function(text) {
        for(var k=0;k<_base.options.length;k++) {
            if(_base.options[k].text==text) {
                return k;
            }
        }
        return -1;
    }
    
    //this function is to know when the list contains any element with the specified value
    this.containsValue = function(value) {
        for(var k=0;k<_base.options.length;k++) {
            if(_base.options[k].value==value) {
                return k;
            }
        }
        return -1;
    }
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:

Select allOpen in new window


Please refer to the comments in the listing for detailed documentation of how to use the object.

Conclusion

Well, as I said previously, I have shown you the way.  Now it’s up to you to create yor own common.js (or whatever you want to name it) and start to code JavaScript easier and faster.  These are only three ways to do it,  I'm sure that you can find a lot more, but only with these three ways you have a good starting point to find utility functions, to extend JavaScript objects and to create useful HTML object wrappers.

Good luck and happy programming!
Asked On
2010-03-03 at 23:54:49ID2606
Tags

ASP.net

,

javascript

Topic

JavaScript

Views
785

Comments

Add your Comment

Please Sign up or Log in to comment on this article.

Join Experts Exchange Today

Gain Access to all our Tech Resources

Get personalized answers

Ask unlimited questions

Access Proven Solutions

Search 3.2 million solutions

Read In-Depth How-To Guides

1000+ articles, demos, & tips

Watch Step by Step Tutorials

Learn direct from top tech pros

And Much More!

Your complete tech resource

See Plans and Pricing

30-day free trial. Register in 60 seconds.

Loading Advertisement...

Top JavaScript Experts

  1. leakim971

    511,289

    Sage

    2,168 points yesterday

    Profile
    Rank: Genius
  2. mplungjan

    291,279

    Guru

    2,800 points yesterday

    Profile
    Rank: Savant
  3. nap0leon

    195,491

    Guru

    0 points yesterday

    Profile
    Rank: Sage
  4. Proculopsis

    182,948

    Guru

    0 points yesterday

    Profile
    Rank: Sage
  5. COBOLdinosaur

    157,309

    Guru

    0 points yesterday

    Profile
    Rank: Genius
  6. chaituu

    130,684

    Master

    0 points yesterday

    Profile
    Rank: Sage
  7. Ray_Paseur

    130,217

    Master

    330 points yesterday

    Profile
    Rank: Savant
  8. tommyBoy

    125,345

    Master

    0 points yesterday

    Profile
    Rank: Genius
  9. StingRaY

    114,318

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  10. DaveBaldwin

    80,081

    Master

    336 points yesterday

    Profile
    Rank: Genius
  11. ansudhindra

    79,054

    Master

    2,000 points yesterday

    Profile
    Rank: Wizard
  12. ChrisStanyon

    62,768

    Master

    800 points yesterday

    Profile
    Rank: Sage
  13. hielo

    61,266

    Master

    0 points yesterday

    Profile
    Rank: Savant
  14. HainKurt

    59,030

    Master

    0 points yesterday

    Profile
    Rank: Genius
  15. BuggyCoder

    54,739

    Master

    0 points yesterday

    Profile
    Rank: Sage
  16. mroonal

    54,339

    Master

    10 points yesterday

    Profile
    Rank: Sage
  17. tagit

    54,093

    Master

    1,600 points yesterday

    Profile
    Rank: Genius
  18. gurvinder372

    52,824

    Master

    10 points yesterday

    Profile
    Rank: Genius
  19. basicinstinct

    52,586

    Master

    0 points yesterday

    Profile
    Rank: Genius
  20. JonNorman

    45,158

    2,200 points yesterday

    Profile
    Rank: Master
  21. Lalit-Chandra

    44,420

    0 points yesterday

    Profile
    Rank: Master
  22. xmediaman

    36,450

    3,800 points yesterday

    Profile
    Rank: Guru
  23. kozaiwaniec

    33,100

    0 points yesterday

    Profile
    Rank: Guru
  24. Kravimir

    32,700

    0 points yesterday

    Profile
    Rank: Genius
  25. designatedinitializer

    32,300

    0 points yesterday

    Profile
    Rank: Master

Hall Of Fame