Community Pick: Many members of our community have endorsed this article.

Helping ASP.net programmers with that unavoidable JavaScript

Luis PérezSoftware Architect in .Net
CERTIFIED EXPERT
Software Architect in .Net C#, VB & ASP. Lover of Star Wars, MCU and Rock music. My greatest achievement in life: my 2 daughters.
Published:
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;
                      }

Open 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' );

Open 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);

Open 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
                      }

Open 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);
                      }

Open 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);
                          }
                      }

Open 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);

Open 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' );

Open 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' );

Open 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;
                          }
                      }

Open 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!
1
4,192 Views
Luis PérezSoftware Architect in .Net
CERTIFIED EXPERT
Software Architect in .Net C#, VB & ASP. Lover of Star Wars, MCU and Rock music. My greatest achievement in life: my 2 daughters.

Comments (1)

Michel PlungjanIT Expert
CERTIFIED EXPERT
Distinguished Expert 2023

Commented:
#1 asked question by ASP developers starting JavaScript is how to set the client ID in ASP so it can be retrieved again in JS.
Could you add that to your article?

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.