Wednesday, October 31, 2012

Javascript Event Bubbling 2

I have already discussed the issues related to Event Bubbling behaviour in various browsers in article "Javascript Event Bubbling". I just have another small example of such event bubbles shown below.


HTML
-------  

<div>
   <a href="javascript:alert('ANCHOR clicked')">
     <span style='font-weight:bold' onclick="alert('SPAN clicked');">SPAN</span> Anchor
   </a>
</div>

The output of above HTML is shown below.















The text "Anchor" is appearing inside the Anchor tag . When it is clicked , "ANCHOR clicked" message is shown. But when an child element of this anchor, a span element with text "SPAN" is clicked, the message "SPAN clicked" message is shown as span element's click event is fired. Next, span element's parent is an Anchor tag which has "click" event defined also. Due to Event Bubbling effect, "click" event of the Anchor tag is also fired and as a result, both the messages "SPAN clicked" and "ANCHOR clicked" are alerted on screen one by one. If the anchor tag had a parent element with its own click event, that would have also been fired in the same process. 

To prevent this, we can make a small change in the above HTML as shown below.

<div>
   <a href="javascript:alert('ANCHOR clicked')">
     <span style='font-weight:bold' onclick="alert('SPAN clicked'); return false;">SPAN</span> Anchor
   </a>
</div>

We have appended a "return false;" statement to the "onclick" property of the Span element. And by doing this, the control does not pass form child's triggered event to parent's similar event. The above solution ran perfectly on Chrome, Firefox and IE 6,7,8,9.

Javascript Event Bubbling


I have a Div element with a small Span element inside it, on my webpage. I have attached two alerts against the click event of each elements. The code snippet and screen-shot is given below.

HTML
-------
<div onclick="javascript:alert('Outer DIV Clicked')">
     <span onclick="javascript:alert('Inner Span Clicked')">?</span>
</div>

Problem :: 
When we click on anywhere within the Div element, the message "Outer DIV Clicked" is shown, but when we click on the inner question mark icon [inside the Span element], "click" events of both the elements [Span and Div] are sequentially fired and as a result the following messages are shown on screen one by one.

Inner Span Clicked
Outer DIV Clicked















At first, the click event of Span is fired, then same event of outer Div is fired. This type of incident is called event bubbling. We can stop this kind of behaviour in the following way.

Solution :: 
We need to re-write the Span element as the following way

<span onclick="span_click(event)">?</span>

and we need to write the "span_click" function as shown below.

<script>
function span_click(e)
{
  if (!e) var e = window.event;
  e.cancelBubble = true;   // for IE
  if (e.stopPropagation) 
    e.stopPropagation();   // for Firefox 
  alert('Inner Span Clicked');
}
</script>

By manipulating the "cancelBubble" property available with IE browser and calling stopPropagation() method in Firefox browser, we can stop this event bubbling. Just check this out.

Find more on Event Bubbling in next article "Javascript Event Bubbling 2"

Javascript FadeOut


Situation :: I have two small question mark icons on my page and when clicked, each of those icons shows related tooltip help text in a DIV and that DIV fades away in some seconds. The scenario can be better understood from the picture below.


As stated, when the 1st icon is clicked, the corresponding tooltip text is displayed and the other tooltip text is immediately hidden.











If we use fadeout() function of jQuery, we need to write the HTML and JS as shown below.

HTML 
-------
<!-- Creating the two question mark icons as displayed in the picture. -->
<span onclick = 'display_help(1); return false;'>?</span>
<span onclick = 'display_help(2); return false;'>?</span>

<!-- ToolTips, Iniatially made hidden -->
<div id='consumer_tips' style="background-color:#FFA130;width:130px;font-size:12px;color:#1658A2;display:none;padding:5px">As a Consumer, you can accept various offers from Merchants.</div>

<div id='merchant_tips' style="background-color:#FFA130;width:130px;font-size:12px;color:#1658A2;display:none;padding:5px">As a Merchant, you can offer various goodies to Consumers.</div>


JavaScript
-------------
function display_help(type)
{
  // Show FIRST TIP and FadeOUT 
  if( type == 1 )       
  { j("#merchant_tips").hide();
    j("#consumer_tips").show().fadeOut(15000);
  }

  // Show SECOND TIP and FadeOUT
  if( type == 2 )      
  { j("#consumer_tips").hide(); 
    j("#merchant_tips").show().fadeOut(15000); 
  }
}


Testing Scenario:: We have the following scenario.

1. We click on the 1st icon, 1st tooltip is shown and it starts to fade out. 2nd tooltip is made hidden.

2. We click on the 2nd icon, 1st tooltip is made hidden, the 2nd tooltip is shown and it starts to fade out.

3. We click on the 1st icon again, 2nd tooltip is hidden. 1st tooltip is shown again.

Problem ::  
If we repeat the above stated processes quickly, we'll see that the third process [stated in point 3 above] is showing first DIV in faded condition. This happens due to the timer which started the fading in first process [stated in point 1]. This timer is still in function because it has not timed-out yet as we had gone through the clicks very fast. The picture below is showing the faded effect.















Solution :: We can fix the issue by writing our own Javascript timer function. Our objective will be as follows ::

1. When 1st icon is clicked, we set a flag to 1; we start a timer for fading out; when the opacity of the tooltip DIV reaches below 0 we hide the DIV completely

2. When we click on the 2nd icon, we set another flag to 1 and clear the first flag and first timer; similarly the second DIV is made hidden when its opacity goes below 0;

3. When we again click the 1st icon, the related flag and timer are set whereas the flag and timer for second icon/toolbar are all cleared.

The code is given below .. 

<script type='text/javascript'>
function display_help( type )
{
  // Show Consumer TIPs and FadeOUT
  if( type == 1 ) 
  {   
      // Hide 2nd DIV
      j("#merchant_tips").hide();
      // Show 1st DIV
      j("#consumer_tips").show();
      // Set flag related to 1st icon
      tip1 = 1; op1 = 1.0;  
      // Clear old timer for fading 
      clearTimeout( timer1 );
      // Call the fade_out function 
      fade_out("consumer_tips", 1);  
  }
  // Show Merchant TIPS and fadeOut 
  if( type == 2 )  
  { 
     // Hide 1st DIV
     j("#consumer_tips").hide(); 
     // SHow 2nd DIV
     j("#merchant_tips").show(); 
     // Set flag related to 2nd icon/DIV
     tip2 = 1; op2 = 1.0;
     // Clear old timer for fading
     clearTimeout( timer2 );
     // Call the fade_out function
     fade_out("merchant_tips", 2);  
  }
}

// Fade_Out function, which sets timer for changing the Opacity of a DIV. 
// Lower the opacity, more faded the element looks. 

function fade_out(div_id, mode)
{
  // FOR 1st DIV/Icon  
  if(mode == 1 && tip1 == 0 ) 
  {
    clearTimeout( timer1 );
    return;
  }
  
  // FOR 1st DIV/Icon  
  // Consumer tips is fading Out
  if( mode == 1 && tip1 == 1 ) 
  {
    // Setting the timer
    timer1 = setTimeout( function(){ fade_out(div_id, mode); }, 100 );
    
    // Set the Opacity
    j("#" + div_id).css("opacity", op1);
    
    //Decrease the opacity
    op1 -= .01;
    
    // If opacity goes below 0, clear the timer
    if(op1 < 0 )
    {  
       // Clear the timer
       clearTimeout( timer1 ); 
       tip1 = 0;  
       j("#" + div_id).css("display", "none"); 
    }
  }
  
  // FOR 2nd DIV/Icon  
  if(mode == 2 && tip2 == 0 )
  {
    clearTimeout( timer2 );
    return;
  }
  
  // FOR 2nd DIV/Icon  
  // Merchant tips is fading Out
  if( mode == 2 && tip2 == 1 ) 
  {
    // Setting the timer
    timer2 = setTimeout( function(){ fade_out(div_id, mode); }, 100 );
    
    // Set the opacity
    j("#" + div_id).css("opacity", op2);
    
    // Decrease the opacity
    op2 -= .01;
    
    // If opacity goes below 0, clear the timer
    if(op2 < 0 )
    {  clearTimeout( timer2 ); 
       tip2 = 0;  
       j("#" + div_id).css("display", "none"); 
    }
  }
}    
</script>  

Friday, October 26, 2012

Printing Special Characters in HTML

HTML has alternative coding for showing special characters. 

For example :

"&nbsp;" is equivalent to having a space
"&copy;"  is equivalent to copyright sign

When we write "&copy" in our HTML, browser renders the corresponding copyright sign in the screen.

But problem is, how to print the word "&copy" itself on the screen? 

Here is the solution :
"&amp;copy;

Write the above code and this would do just the thing we want to achieve.

Saturday, October 20, 2012

Email validation in Javascript

We can check whether an given email address is ok or not through the regular expression show below.

<script type='text/javascript'>
// RegExp Pattern
var pattern = /^[a-zA-Z]+[a-zA-Z0-9_]*@[A-Z0-9a-z]+(\.){1,1}[a-zA-Z]{2,3}$/ ;


// Email to check
var email = "a@a.com";

// Show the result
console.log( pattern.test(email) );
</script>

The above code will print 'true' in your browser console. Let's dissect the regular expression to understand it more clearly.

1. ^[a-zA-Z]+     => means, the Input must start with character a through z in small/capital letters
2.[a-zA-Z0-9_]*  => means, characters and digits and underscore may or may not appear next. 
3. @         => '@' character must appear next
4. [A-Z0-9a-z]+  => means, character, digits will appear next, minimum 1 character/digit is must
5. (\.){1,1} => then, there must be a dot (.)... {1,1} means minimum 1 times and maximum 1 times respectively
6. [a-zA-Z]{2,3}$  => means, a series of character,digits will appear at the end of the input, but that series will have minimum 2 and maximum 3 characters/digits

Numeric Data validation in Javascript

To check whether a user-given number is numeric, we can test it with a regular expression pattern. 

Problem :: Suppose, on a webpage, there is a textbox where user needs to input valid numeric data. That data has to be greater than zero also. 

Solution :: We can write a javascript function as given below.

<script type='text/javascript'>
function test_numeric($data)
{
 // Define Regular Expression Pattern 
 var $pattern = /^[0-9]+(\.)?[0-9]+$/;

 // Test the pattern
 $result = $pattern.test( $data );

 // Input data is matching our expected pattern 
 if( $result ) 
 {
   // Now check if Data is Positive
   if( parseFloat( $data ) > 0 )
     return parseFloat( $data );
   else
     return 0;

 }
 // Input data does not match our expected pattern
 else 
 {
    return 0;  
 }
}
</script>

The above function returns the floating representation of input data when the Input data is valid or matches our given pattern. If it does not match the pattern, 0 is returned.

Now let's simplify the regular expression /^[0-9]+(\.)?[0-9]+$/ 
1. ^[0-9]+  => means the Input data should start with digits 0 to 9, 1 or more digits may appear.
2. (\.)?    => means the character dot (.) may or may not appear at all
3.  [0-9]+$  => means the input data ends with digit[0-9] sequence and may have 1 or more digits in it.

Another point, we need to discuss here. The above regular expression will pass "0009" as a valid input. That's why we have returned floating point representation of  the original number by using the statement :: 

return parseFloat( $data );

The above statement would return "9" if the input was "0009".

Friday, October 19, 2012

Self Join in mySql

I have a scenario where a table is required to be joined with itself. This process is called self-join.

Say, We have a table called 'category' with the following column structure.



cat_idcat_nameparent_id
1parent10
2parent20
3child11
4child22
5sub-child13
6sub-child24


The table above has a parent-child relationship among rows. For example, category "parent1" has a child "child1" and again "child1" has a child named "sub-child1".

The table might have more such entries i.e "sub-child1" can have multiple children under it and even those children can have n number of children added under it. 

Problem is, how to get the tree for top-most category "parent1" ?

We need to use self-join techniques to solve this issue. Below is the SQL which will fetch all the children of "parent1".

SELECT t.cat_name as cat1, m.cat_name as cat2, l.cat_name as cat3 FROM category t
left join (select * from category ) as m on t.cat_id = m.parent_id
left join (select * from category ) as l on m.cat_id = l.parent_id
where t.cat_name = 'parent1';

Here, we have left joined the category table with itself twice as we wanted to find out 3rd level children. Using only "join" would not do the proper searching, because that will miss out those second level category names which don't have any children under it. Plain "join" returns data only if there is a match where as "Left Join" would return parent category name even if there is no match for any children.

If we were to search for only 1 level of children, we would have used the following query :

SELECT t.cat_name as cat1, m.cat_name as cat2 FROM category t
left join (select * from category ) as m on t.cat_id = m.parent_id where t.cat_name = 'parent1';

To find all the category names which have immediate children and each of those children has atleast one sub-children under it we can use the following SQL :


SELECT t.cat_name as cat1, m.cat_name as cat2, l.cat_name as cat3 FROM family as t, family as m, family as l 
where t.cat_id = m.parent_id and  m.cat_id = l.parent_id and t.cat_name = 'parent1'

Backticks in INSERT Query in PhpMyAdmin

I just want to share an experience while trying INSERT SQL query in MySql. I was working on MySQL server version: 5.5.16.

I have one employee details table called "emp" which has the following fields..
emp_id, emp_name, emp_sal, emp_address, emp_tel

The field names are quite self-explanatory. I faced problems when I wanted to inserted a row with only emp_id and emp_name values. 

INSERT into emp ("emp_id","emp_name") values("php-002","Chandan");

The above statement fell flat on its face. MySQL gave me an error saying syntax error.  However, I had corrected the statement by using backtick operator as a wrapper for field names. This is shown below.

INSERT into emp (`emp_id`,`emp_name`) values("php-002","Chandan");

Even if I leave the field names without applying any wrapper, it still works.

INSERT into emp (emp_id,emp_name) values("php-002","Chandan");

Hope this post was useful.

Get first and last day of current month in PHP

To achieve this we need to create a DateTime object and then use the modify() method to change the timestamp as shown in the code snippet below.

<?php
// Create Object

$d = new DateTime( date("Y-m-d",strtotime('now') ) );

// Change the timestamp in 'd' object
$d->modify('first day of this month');

// Format the date according to FORMAT passed
echo $d->format('Y-m-d 00:00:00');

// Again change the timestamp in 'd' object
$d->modify('last day of this month');

// Format the last day of the month
echo $d->format('Y-m-d 23:59:59');
?>

The above code is quite self-explanatory. 

1. Php date() function takes timestamp as 2nd parameter and strtotime() reads the first parameter as a date and converts it to a timestamp.

2. The DateTime object's modify() method is used to alter the timestamp. It can accept various English-like strings like "+1 day", "-1 month", "first day of this month"


Monday, October 01, 2012

Javascript Date Validation check

Suppose you have a contact form on your website, which job hunters will fill up during Job application. In that form, they must fill up the DOB text input.

We need to check ::

1. Date given is in correct format :: dd-mm-yyyy is maintained
2. Date is actually a correct data, date such as '29-02-1978' will be discared

We take the following actions for the points above respectively::

1. We use a regular expression to check the formatting of the date
2. We use Javascript Date() function feature for achieving the correct date

Check the code below, we have written a function called date_validation() which takes a date and returns true if it is a valid date, returns false otherwise.

<script type="text/javascript">
function date_validation(user_date)
{
// Use a RegEX pattern to check formatting
var patt = /^[0-9]{1,2}-[0-9]{1,2}-[0-9]{4,4}$/;

// If the input string's format is okay
if( patt.test(user_date) )
{

// Extract Day Month Year from user input
var p = user_date.split(/-/);
var a_year  = p[2];
var a_month = p[1];
var a_day   = p[0];


// Create a new Date Object with each part
// Date() object does not hold original data
// if the Date is wrong
var t_d = new Date(a_year, a_month - 1, a_day);

// Now check
if( t_d.getDate() == a_day && t_d.getMonth() == (a_month - 1) && t_d.getFullYear() == a_year )
{
   // Date is Okay
   return true;
}
else
{
   return false;
}
}
}

console.log( date_validation("29-2-1978") ); // False

console.log( date_validation("29-2-1976") ); // True
</script>

The code above is quite self-explanatory. Still, let's discuss some parts of it.


1.  We used a RegEX pattern to validate the user input. So the patt.test() returns true if the input is as per our expectation.

2. Next we extract date, month and year info from the user input by calling a split function. Split accepts Regular Expression as its arguments. So the pattern /-/ means we wanted to split it by the character hyphen (-). After the split, each part is stored in an array.

3. Next we create a Date object with these date, month and year information. In Javascript, month starts from 0, hence to mean February (month : 2), we need to use 1 (2-1).  

For example, if we want to create a date object with date : 29-2-1978, we need to provide

// January is 0, Feb is 1 etc
var test_date = new Date(1978, 1, 29); 

Javascript Date() function has a feature, if we want to create a Date object with an invalid date, it changes to a different valid date. For example, the above line will generate an object with date "1-3-1978" as "29-2-1978" does not exist on calendar. But if we used a valid date, the object gets created with that valid date only.

So, with the following lines ::

if( t_d.getDate() == a_day && t_d.getMonth() == (a_month - 1) && t_d.getFullYear() == a_year )

... we just checked whether the entered date is changing or not, if changes, it means that entered date is invalid. So, if the date is valid, this function returns true and false in other cases.

Check out some other validation techniques using Javascript in articles Email Validation in JavascriptNumeric Data validation using Javascript

To know basic Javascript Regular Expression Patterns, see Article Basic Regular Expression Patterns I