Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Sunday, 5 May 2013

How to compare start and end time in JavaScript

Think of a form where we have entries for start and end time. There obviously we need to check that the end time should be after start time. Here at this point we will need to compare time and preferably that in client side(using Javascript).

In Javascript comparing date is quite simple. Just create date object of the dates and then using comparison operator you can compare the dates. But this is not that simple when it comes to compare two time strings. Javascript does not provide any direct way to compare time.

So I just found out a way to do so. Please take a look.

Here I am assuming that we have got time to compare in 24 hours format. So we do have time as hh:mm:ss or in some other format. First get the hour, minute and second part of this using string functions. And then go for the coding below. And if you don't have time in 24 hour format and its in 12 hour format as 06:30AM, then better convert it to 24 hour format, other wise it's hard to compare two time in 12 hour format.
 
//Set the extracted part of the time to variables. 
// If you dont have the second part then set it to 0.

 var startHour = extractedStartHour;
 var startMinute = extractedStartMinute;
 var startSecond = extractedStartSecond;

 var endHour = extractedEndHour;
 var endMinute = extractedEndMinute;
 var endSecond = extractedEndSecond;

 //Create date object and set the time to that
 var startTimeObject = new Date();
 startTimeObject.setHours(startHour, startMinute, startSecond);

 //Create date object and set the time to that
 var endTimeObject = new Date(startTimeObject);
 endTimeObject.setHours(endHour, endMinute, endSecond);

 //Now we are ready to compare both the dates
 if(startTimeObject > endTimeObject)
 {
 alert('End time should be after start time.');
 }
 else
 {
 alert('Entries are perfect.');
 } 

Saturday, 15 December 2012

JavaScript Mistakes You Must Avoid

If you are new to JavaScript and you write raw JavaScript or use any framework (jQuery, Mootools, Dojo, YUI) with it, you must avoid few mistakes. Actually these are my experiences when I was learning JavaScript.

Equality Operator

You may know that in js, two operators are used for comparing values. First is == (two equal signs). This operator compare the values but it doesn’t compare the data type of operands. For example if first operand is 1 and the second is true, the result will be true.
if( 1 == true ) {
    //this code will run
}
Here are more examples.
1 == "1"        //true
"true" == true  //false
1 == true       //true
"0" == 0        //true
"" == 0         //true
" " == 0        //true
"Str" == false  //false
"Str" == true   //false
 
Some of the results are unexpected specially for those who don’t know how JavaScript evaluates == operator. Actually every operand (no matter what data type it has) is converted to Number data type before comparison.

Consider the first example (1 == “1″). The first operand is already a number so no conversion occurs. Second operator is string so it’s converted or parsed to number. Now the second operator “1″ (string) is converted to 1 (number).

In the second example (“true” == true) is false because if the string contain characters other than digits, convertion to number will return NaN which means Not a Number. If anything is compared with NaN, comparison will always return false.

You can check what value will be returned after conversion to number using the Number constructor. Following are some tests in Firebug.

Number tests

Now you maybe wondering how === operator works. Equality operator (with 3 equal signs) in JavaScript compare not only the value of operands, but also the data type. If the data type of operands is different, it will always return false. Both the data type and value of operands must be same in order to make the condition true.

4 === 4         //true
"2" === 2       //false
1 === true       //false
"true" === true //false

Not Assigning null to Reference Types

It’s common mistake that many js developers don’t assign null value to variables of reference types (object or Array) when there use is finished. Take a look at following example.

var arr = [1, 2, 3];
 
//perform some processing on arr
 
//assign null to arr when its use is finished
arr = null;
 
The benefit of assigning null to reference types is that the garbage collector of js engine automatically reclaims the memory used by that variable. Remember that this is specially important for variables whose scope is large like global variables. Local variables are automatically destructed when they are out of scope (specially js engines with Mark and Sweep garbage collector).

Reference Variable Initialization

Never try to initialize multiple reference variables (like object and array) in a single assignment statement. This can be better understood using an example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var arr1 = [1, 2, 3]
  , arr2 = ['a', 'b', 'c'];
 
//reset both arrays
arr1 = arr2 = [];
 
//add a single item in arr2 and arr1
arr2.push( 32 );
arr1.push( 10 );
 
//print both arrays and you will see same result
//OUTPUT: 10, 32
alert( arr1.join() );
alert( arr2.join() );
 
On line 1 and 2, two arrays are created. Then those arrays are reinitialized with blank array in a single statement on line 5. The problem with this statement is that now both arrays (arr1, arr2) are pointing to same array in the memory. So changes in one will automatically be reflected in the other.

On line 8, integer 32 is added in arr2 and on line 9, integer 10 is added in arr1. To check the output of both arrays, join method is called on each of them on lines 13 and 14. Note that both arrays contain same values.

Don’t Forget Keyword var

In JavaScript you can declare variables with keyword var. But it also allows you to use variables without any declaration. There’s a very critical difference between these two ways of using variables. Consider the following example.

function createVar() {
	var myVar = 'local';
};
 
alert( myVar ); //output: undefined
 
As you can see from the above example when a variable is declared with keyword var, it’s not accessible in the outer scope. Let’s change this example to define a variable without var in function.
 
function createVar() {
	myVar = 'local';
};
 
alert( myVar ); //output: local

Note that a variable defined without keyword var in function is also accessible from the global scope. In other words var makes the variable local. So becareful when using variables in JavaScript. Always declare your variables using keyword var before using them.

Not Using Event Delegation

Attaching event handler is simple in JavaScript. For example following code adds a click handler to anchor tag having id myLink.

document.getElementById('myLink').addEventListener( 'click', function() {
   //you code goes here...
}, false );
 
Now suppose you want to add a click handler to all the td elements in table. Are you going to write a handler for each td in table?

<table id="myTable">
   <tbody>
      <tr>
         <td>1, 1</td>
	 <td>1, 2</td>
      </tr>
 
      <tr>
         <td>2, 1</td>
	 <td>2, 2</td>
      </tr>
   </tbody>
</table>
 
Here event delegates help us. In our case we will attach a single click event handler to myTable and within that we will check to see if a td element is clicked or not. In this way we don’t have to write and attach event handlers to every td in table. Such kind of handler is known as event delegate. Here’s the code for it.

document.getElementById( 'myTable' ).addEventListener( 'click', function( e ) {
      if( e.target && e.target.nodeName == 'TD' ) {
         console.log( e.target.innerHTML );
 
         //to access id
         //console.log( e.target.id );
 
         //to access className
         //console.log( e.target.className );
      }
   }, false );

innerText VS innerHTML

New js developers are often confused between innerHTML and innerText properties. Both innerHTML and innerText are used with element objects. innerHTML gets the html code inside the element and innerText gets the text inside the element.

innerHTML working

The dark gray background in Html is actually the output of innerHTML property. Note that the Html tags (in our case <p>) are also included in the output.
Let’s take a look at innerText example.

innerText working
As you can see from the above example that innerText gets the text inside the element (without html tags).

Adding Nodes in Bulk

It’s common in JavaScript to append list of nodes to some element in DOM. For example you may want to append a list of names to ul received from server using Ajax call. One way of doing this is shown below.

window.onload = function() {
//ul element - <ul id="list"></ul>
var list = document.getElementById( 'list' );
 
var item = null;
 
//suppose this json is returned from ajax call
var ajaxResponse = [
    { 'name' : 'Haiku' },
    { 'name' : 'Linux' },
    { 'name' : 'OS X' },
    { 'name' : 'Windows' }
];
 
//add all names in ajaxReponse to documentFragment
for( var i in ajaxResponse ) {
    item = document.createElement( 'li' );
    item.appendChild( document.createTextNode( ajaxResponse[ i ].name ) );
    list.appendChild( item );
}
} //end onload
 
/*
..:: OUTPUT ::..
<ul id="list">
<li>Haiku</li>
<li>Linux</li>
<li>OS X</li>
<li>Windows</li>
</ul>
*/

The problem with this method is that each time the item is appended to list in "for in" loop, the DOM gets updated immediately. This hurts performance because DOM manipulation is costly process.

“DocumentFragment is light weight version of document and it has no visual representation on the web page.”
The same output can be achieved using DocumentFragment. DocumentFragment is light weight version of document and it has no visual representation on the web page. Following is the example to append list items using DocumentFragment.

window.onload = function() {
    //create DocumentFragment
    var documentFragment = document.createDocumentFragment();
 
    var list = document.getElementById( 'list' ); //<ul id="list"></ul>
    var item = null;
 
    //suppose this json is returned from ajax call
    var ajaxResponse = [
	{ 'name' : 'Haiku' },
	{ 'name' : 'Linux' },
	{ 'name' : 'OS X' },
	{ 'name' : 'Windows' }
    ];
 
    //add all names in ajaxReponse to documentFragment
    for( var i in ajaxResponse ) {
	item = document.createElement( 'li' );
	item.appendChild( document.createTextNode( ajaxResponse[ i ].name ) );
	documentFragment.appendChild( item );
    }
 
    //append all items in documentFragment to list
    list.appendChild( documentFragment );
}

DOM Manipulation using innerHTML

Never use arithmetic assignment operator (+=) with innerHTML to add new markup. Whenever you change innerHTML, DOM updation occurs (Browser redraws the markup). So adding new markup using += operator (specially in a loop) decreases performance.
var container = document.getElementById( 'container' );
 
for( var i = 1; i <= 10; ++i ) {
    container.innerHTML += 'Item ' + i + '<br />';
}
Always use a temporary variable to store the markup you want to assign to innerHTML as shown below.
var container = document.getElementById( 'container' )
  , str = '';
 
for( var i = 1; i <= 10; ++i ) {
    str += 'Item ' + i + '<br />';
}
 
container.innerHTML += str;

Saturday, 27 October 2012

How to Find ASP.NET Control and get/Set values of Controls in ASP.NET using JavaScript


At a time there becomes a requirement to get/set the values of controls in our project. We can get/set the values of controls through programming or by using JavaScript. If we just have to perform a get/set operation we can do it by simply using JavaScript.

Scenario I

Let's consider a scenario where I've 2 textboxes named TextBox1 and TextBox2 and I need to set the value of a particular textbox in the other textbox on the same page.

I can simply do it programmatically with the following line.

TextBox2.Text=TextBox1.Text;

The same part of code can be done by using JavaScript:

document.getElementById('<%=TextBox2.ClientID%>').value=document.getElementById('<%=TextBox1.ClientID%>').value

or

document.forms[0]["TextBox2"].value=document.forms[0]["TextBox1"].value;

Note: Provided that the pages are just normal web page and don't have any master page applied to it.

Scenario II

Now consider a scenario if we have a master applied on a particular web page and we want to get/set the value of a particular control within the same web page.

For doing this activity we'll create a sample master page. The following is the code for the master page.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="TopLevel.master.cs" Inherits="TopLevel" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Untitled Page</title>
    <style type="text/css">
        .style1
        {
            width: 4%;
        }
        .style2
        {
            width: 1274px;
        }
    </style>
</head>
<
body>
 <form id="form1" runat="server">
<table style="width:100%;">
        <tr>
            <td align="right" colspan="3">
                <asp:Image ID="Image1" runat="server" ImageUrl="~/images/AdvWorksLogo.gif" />
            </td>
        </tr>
        <tr>
            <td class="style1">
                <asp:Image ID="Image2" runat="server" ImageUrl="~/images/AdvWorksSideBar.gif" />
            </td>
            <td valign="top" class="style2">
        <asp:ContentPlaceHolder id="pageContent" runat="server">
            <p>
                <br />
            </p>
            <p>
            </p>
            <p>
            </p>
            <p>
            </p>
           
        </asp:ContentPlaceHolder>
            </td>
            <td style="width: 10%">
                &nbsp;</td>
        </tr>
        <tr>
            <td align="right" colspan="3">
                <asp:Label ID="Label1" runat="server"
                    Text="&lt;b&gt;Copyright&amp;copy;2011@AdventureWork.com&lt;/b&gt;"></asp:Label>
            </td>
        </tr>
    </table>
    </form>
</body>
</
html>

Following is the source code for the Test.aspx apge.

<%@ Page Language="C#" MasterPageFile="~/TopLevel.master" AutoEventWireup="true" CodeFile="Test1.aspx.cs" Inherits="Test1" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="pageContent" Runat="Server">
    <script type="text/javascript">
    function getData()
    {
        /*
        Here your this method of setting the value will not work because in our current web page we donot have a form tag we have a content tag
        which is inside the master page. So our form tag will reside on master then how do i access/set the value through this method.
            document.forms[0]["TextBox2"].value=document.forms[0]["TextBox1"].value;
        */
        document.getElementById('<%=TextBox2.ClientID %>').value=document.getElementById('<%=TextBox1.ClientID %>').value;
          /*
          OR
              var a = document.getElementById('<%= "ctl00_pageContent_TextBox1" %>').value;
            document.getElementById('<%= "ctl00_pageContent_TextBox2" %>').value = a;
          */     
    }
</script>
    <table style="width: 40%;">
        <tr>
            <td>
                Enter Your Name :
            </td>
            <td>
              <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            </td>
            </tr>
            <tr>
            <td colspan="2" align="center">
                   <asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="getData()" />
            </td>
            </tr>
        <tr>
            <td>Your Name is :</td>
            <td>
                <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox></td>
        </tr>
    </table>
</asp:Content>

NOTE : In case you want to access a master page control on the child page you can use the following code.

document.getElementById('<%=Page.MasterPage.FindControl("pageContent").FindControl("TextBox2").ClientID %>').value=document.getElementById('<%=Page.MasterPage.FindControl("pageContent").FindControl("TextBox1").ClientID %>').value

Hope you've liked the article.