Thursday, June 06, 2013

Add custom method to jQuery Form Validation plugin

We have used JQuery form validation plugin many times like in "contact us" forms. Problem occurs when any field has a hint text specified. For example, suppose "firstname" text input field has a hint-text "Enter firstname here". When this plugin validates for  emptiness, the value "Enter firstname here" successfully passes the test but this is not right.

In such situations we would require to add custom validation method to jQuery Validator plugin.

I am showing one "contact us" form with 2 required fields "firstname" and "lastname". Here is the code and HTML.

<script>
  $(document).ready(function(){
   
    // Contact Form Submission Handler
    $("#contactUsForm").validate(
    {
    messages:
    {
         firstname: "Enter your firstname",
         lastname:  "Enter your lastname",
        },
   
    submitHandler: function(form)
    {
      jQuery.ajax(
      {
        url: form.action,
        type: form.method,
        data: $(form).serialize(),
        success: function(response)
        {
          if( response == "1") // Success
          {
            // Reset the form
            document.getElementById("contactUsForm").reset()
          }
          else // Failure
          {
            // Do stuff when failed
          }
       }           
     });
    }
     });
  });
</script>

<form id='contactUsForm' method="post">

<input type="text" name="firstname"  id="firstname" class="required">
<input type="text" name="lastname" id="lastname" class="required">
<input class="form-element" name="Submit" value="Submit" type="submit">

</form>


JQuery validation plugin needs class='required' to be added to the required fields. The messages parameters holds all error messages to be shown for each element specified. When the Submit button is clicked, the form is validated through the validation plugin. Error messages are shown if  required fields are empty. If any "email" field is given class='required email', then that field would be checked for both emptiness and email format. But what if the fields have hint-text as shown below? These fields get validated and they pass in empty testing which should not be the case.

<input type="text" name="firstname" id="firstname" value='Your First Name' onfocus="javascript:if(this.value=='Your First Name') this.value='';" onblur="javascript:if(this.value=='') this.value='Your First Name';" >

<input type="text" name="lastname" id="lastname" value='Your Last Name' onfocus="javascript:if(this.value=='Your Last Name') this.value='';" onblur="javascript:if(this.value=='') this.value='Your Last Name';">


To manage such situations we need to add some custom methods to the jQuery Validator object as shown below. We also need to add new Rule to it.

<script>
  $(document).ready(function(){
   
    // Our NEW custom method   
    jQuery.validator.addMethod("rem_default_val", function(value, element)
    {
       // Default Value Check for firstname
       if(element.value == "Your First Name" && element.name == "firstname")
       { jQuery('#firstname').focus(); return false; }

       // Default Value Check for lastname
       if(element.value == "Your Last Name" && element.name == "lastname")
       { jQuery('#lastname').focus(); return false; }
      
    });
   
   
    // Contact Form Submission Handler
    $("#contactUsForm").validate(
    {
    // Define a new Rule
    rules:
    {
       firstname: "required rem_default_val",
       lastname: "required rem_default_val",
    },
   
    messages:
    {
         firstname: "Enter your firstname",
         lastname:  "Enter your lastname",
        },
   
    submitHandler: function(form)
    {
      /// .... AJAX form submissions
    }
     });
  });
</script>


Notice that class='required' may not be required if we add 'required' as a rule. We also add a method called rem_default_val() as a rule which means elements have to pass this validation method which is defined using addMethod() function.

New rules have been defined here ::

rules:
{
   firstname: "required rem_default_val",
   lastname: "required rem_default_val",
}


Our new custom validation method rem_default_val() tests default values in elements and returns FALSE if certain predefined values or hint-text or default text found.

jQuery.validator.addMethod("rem_default_val", function(value, element)
{
  // Default Value Check for firstname
  if(element.value == "Your First Name" && element.name == "firstname")
  { jQuery('#firstname').focus(); return false; }

  // Default Value Check for lastname
  if(element.value == "Your Last Name" && element.name == "lastname")
  { jQuery('#lastname').focus(); return false; }

});


This way, we can validate a form with elements having hint texts in them.

Dynamic Script Loading using jQuery


We have already seen how dynamic Javascript can be inserted to the HTML document using Javascript in my previous article. Here we would see how we can get the same task done using jQuery getScript() method. This function actually loads a script from the SERVER using ajax method and then executes it. It has the following syntax :

jQuery.getScript( URL_for_script, load_success_callback( data, status, xhr ) );

The 2nd argument is optional. We can use .fail() and .done() methods with it as failure and success callbacks respectively. Let's write a small program which loads a script which is a function.

<script src='js/jquery-latest.js'></script>

<script>
// Define a variable in global scope
var click_times = 1;

// Load scripts dynamically
function load_script()
{
  jQuery.getScript("js/test.js")
 
  // SUCCESS callback
  .done(function(){
    jQuery("#status_div").html('Script Loaded');
  })
 
  // FAIL callback
  .fail(function(){
    jQuery("#status_div").html('Script Failed');
  });

}
</script>

<input type='button' value='Load Script' onclick='load_script()'>
<input type='button' value='This does not work' id='inactive_button'>
<div id='status_div'></div>


We have 2 buttons -- 'Load Script' and 'This does not work' and a DIV with id 'status_div'.


The 'This does not work' button remains inactive initially. Now when we click the 'Load Script' button, it loads a test.js file whose contents is given below ::

// Add a click event to the inactive button
jQuery('#inactive_button').on('click', function(){

// It can access global Variable also
if( click_times == 1)
 {
   // Change BUTTON TEXT only once
   jQuery(this).val('This Now WORKS !!');
 }

// Alert
alert('This button is now active, Clicked : ' + click_times + ' times');

// Increase number of click value
click_times++;

});


We used jQuery on() method to attach a "click" event to the button. So, every time the button is clicked, it alerts the message mentioning total number of clicks it got so far. Below is the screenshot :




The done() method attached to getScript() updates the DIV 'status_div' with status message. It can be done away with in below shown method ::

jQuery.getScript("js/test.js", function(data){
 
    // SUCCESS callback
    jQuery("#status_div").html('Script Loaded:' + data);
  })
 
   // FAIL callback
  .fail(function(){
    jQuery("#status_div").html('Script Failed');
  });


This code does the same stuff; however it also inserts the text received in ajax response in the div.

The only problem with the above code is that, it repeatedly attach events to the button 'inactive_button' if the "Load Script" button is clicked more than once. Assigning new procedure to 'click' event of any button does not remove the previous methods, the new procedures are just appended to the previous procedures. So, we can add a single line at the top of test.js like this to achieve that ..

// Remove the old attached events
jQuery('#inactive_button').off('click');

Monday, June 03, 2013

Dynamic Javascript Insertion

We can create dynamic script element using the simple DOM methods. We have discussed how setting element's innerHTML property fails to execute the inserted scripts at runtime. Let us check out a simple DOM method to load an external js file. Changing "src" property of any <script> element on the runtime does not work on all browses. This has been discussed at the end of this article.

<html>
<head id='header'>
<script> 
function load_script()
{
  // Get the ID of head
  var p = document.getElementById("header");
 
  // Create new script element
  var scr = document.createElement("script");
 
  // Define src
  scr.setAttribute("src","sample.js");
 
  // Append the script to header
  p.appendChild( scr );

}
</script>
</head>

<body>
<div id="mydiv">Click the button to load a script <br />
<input type="button" onclick="load_script()" value="Load Script">
</div>
</body>
</html>


The function load_script() dynamically inserts a <script> element inside the header section, and then setting up "src" property and appending the new <script> to <header> element loads and executes the external js file 'sample.js'.

Using this method we can dynamically call some server pages and get the feedback in native JavaScript code and get it executed.

We have already seen in my previous article that inserting a piece of JavaScript code in a DIV using DIV's innerHTML property does not work. To get some JS code executed, we either need to call eval() method or use the general DOM method to create Script element itself. Let's check out an Ajax example where the feedback is received in native Javascript and we are following the DOM methods to create new script element on the document.

<script>
function call_ajax()
{
 // XHR Object
 var xhr = new XMLHttpRequest();

 // CallBack on Success
 xhr.onreadystatechange = function(){
 
  if(xhr.readyState == 4 && xhr.status == 200)
  {
    // Create new script element
    var scr = document.createElement("script");

    // Create a TEXT node with Ajax Response
    var c = document.createTextNode( xhr.responseText );

    // Append the code to script
    scr.appendChild( c );

    // Append the script to document body
    document.body.appendChild( scr );
  }

 };

 // REQUEST to find_city.php with param zip=10001
 xhr.open("GET",'find_city.php?zip=10001', true);
 xhr.send();
}
</script>

<input type='button' value='Load Script thru Ajax' onclick='call_ajax()'>

<span id='city'></span>


In the above example we are sending a call to find_city.php with a zip parameter. Now, find_city.php searches a DB with given zip code, and returns the result in a native JS (in text format) as shown below.

search_result = 'New York, NY'; document.getElementById('city').innerHTML = search_result; 

Now, our JS code create a Script element with the above Ajax response and appends it to the document body. As a result, the above function gets executed which changes the content of the span (id=city). Check the screenshot below.




The screenshot shows that the ajax response text has been successfully inserted in the span element after clicking the button.

Now, suppose, the ajax response is a function call like this ::

put_search_result ( 'New York, NY', 'city_div') ;

the function "put_search_result" should have been defined prior to making the ajax call. However, we can make the function name dynamic and vary between function calls as shown in example below.

<script>
function call_ajax()
{

 // Define random no.
 var random = Math.floor( Math.random() * 10000 );

 // Define the dynamic function name
 var call_back_fn_nm = "call_back_" + random;

 // Define an anonymous function with body
 var func = function(response){ document.getElementById('city').innerHTML = response;  } ;

 // Link up dynamic function name & body
 eval(call_back_fn_nm + " = func");


 //// AJAX SECTION 
 var xhr = new XMLHttpRequest();

 xhr.onreadystatechange = function(){
 
  if(xhr.readyState == 4 && xhr.status == 200)
  {
    var p = document.getElementById('script_div');
    // Below line is IMPORTANT

    eval( xhr.responseText );
  }

 };

 xhr.open("GET",'find_city.php?zip=10001&callback=' + call_back_fn_nm, true);
 xhr.send();
}
</script>


The above program has some significant and interesting points to notice :

i. We dynamically create a function name like "call_back_1234" and assign it to variable "call_back_fn_nm". We want to fire call_back_1234() after we receive the ajax response. Suppose that 1234 was generated as a random nunber.
ii. Secondly we define an anonymous function and store it in variable func.
iii. Most important statement is call to eval(call_back_fn_nm + " = func"); which is finally evaluated to "call_back_1234 = func" which assigns the anonymous function to a variable call_back_1234 in global scope. This means we can always call call_back_1234(). We can't make a statement like "
call_back_1234 = func" and execute it without the help of eval().
iv. Next we call the server page find_city.zip with zipcode and callback function name as parameters like this ::
    find_city.php?zip=10001&callback=call_back_1234
v. The server simply returns the response in text format :: call_back_1234( 'New York, NY' );
vi. The statement eval( xhr.responseText ); simply evaluates the response and gives a call to call_back_1234( 'New York, NY' ) which inserts the text  'New York, NY' inside the span (id='city').

On many cases, web services are received in JSON object wrapped in a function call like this :

call_back_123456789( {state : 'NY', city : 'New York', zip : '10001'} );

In these situations, our solution would work provided we define the call-back function prior to the webservice call.

Such Dynamic script insertion may create and append lots of dynamic <script> tags on the document body. We could have used another method ...

<script id='dyn_src'></script>

<script>
// Dynamically changes the src property of a script element
function search_result()
{
  document.getElementById('dyn_src').src = 'find_city.php?zip=10001&calback=call_back'
}

// Function body for call back function
function call_back(city_name)
{
  document.getElementById('city').innerHTML = city_name;
}
</script>



The response of find_city.php is received as :: call_back('New York, NY') which is executed when we change the src property of the script element inside the search_result() function. So, calling search_result() function would change the content of the span element. Unfortunately this method works well in IE only.


We can use jQuery getScript() method to load a piece of JS code and execute it dynamically. This has been discussed here.

Adding BookMarks Through Javascript

Whenever we like a page on web, we can bookmark it for future consult. We need to hit CTRL+D keystrokes to bring the bookmark dialogue and after we click on "Ok" button, the current URL is saved in browser bookmark list. In IE, it gets listed in Favorites listings. Here we would be bringing the Save Bookmark dialogue box on screen though JavaScript code. Check it out ...

<script>
function bookmark_me(sURL,sTitle)
{
 // IE
 if ( window.external && document.all)
 {
  window.external.AddFavorite (sURL,sTitle);
 }
 // Now for firefox
 else if (window.sidebar) 
 {
   window.sidebar.addPanel(sTitle,sURL,'');
 }
  // Opera
 else if(window.opera)
 {
   var p = document.createElement("a");      
   p.setAttribute("title", sTitle);
   p.setAttribute('rel','sidebar');
   p.setAttribute('href','http://google.com');
   p.setAttribute('onclick','return false;');
   p.click();
   return false;
 }
}
</script>

<a rel='sidebar' href="javascript:;" onclick="bookmark_me('http://google.com','Google')">BookMark Me !!</a>


My version of firefox (v.21) has access to window.external, hence we had to use document.all check for IE. Chrome does not allow adding favorites/bookmarks though JavaScript. The "rel='sidebar'" in the above link is a must for it to work in Opera (my version is 12.15).

Friday, May 31, 2013

innerHTML Property in HTML Elements

With this property, we can get or set the inner HTML/Contents of any elements. We have the following HTML ::

<div id='myDiv'></div>

Now if we write the following script, it successfully inserts a new HTML inside the above DIV. And this works on all versions of browsers.

<script> 
var p = document.getElementById("myDiv");
// Set the innerHTML
p.innerHTML = "<p>This is a nice day</p>";
</script>

 

Problem starts when we try to insert <link> or <style> elements through this innerHTML property. However, <link> tag should appear inside the <head> tag. So, let's re-write our program as shown below ..

<html>
<head id='header'>
<script> 
function load_style()
{
  var p = document.getElementById("header");
  var t = p.innerHTML;
  p.innerHTML =  "<link href='style.css' rel='stylesheet' >" + t;
}
</script>
</head>

<body>
<div id="mydiv">This is a sample DIV. Click the button to make this DIV Red
<input type="button" onclick="load_style()" value="Load Style">
</div>

</body>
</html>

 



The <head> element contains a script which inserts a new <link> tag inside the <head> and as a result, a stylesheet is loaded at run time. Check that the DIV contents change to red when the "Load Style" button is clicked. This works perfectly on all browsers but shows error on IE. Similar error occurs in IE when we try to insert new HTML inside any <tbody> element. For IE, "The innerHTML property is read-only on the col, colGroup, frameSet, html, head, style, table, tBody, tFoot, tHead, title, and tr objects" - ;MSDN. This has been done for security puposes. So, we need to use DOM methods to insert this new <link> tag inside the <head> element. Check the new implementation below ::

<script> 
function load_style()
{
  var p = document.getElementById("header");
 
  /* Create New link element */
  var t = document.createElement("link");

  /* Set href and rel property */
  t.setAttribute('href','style.css');
  t.setAttribute('rel','stylesheet');

  /* Append it to head tag */
  p.appendChild( t );
}
</script>


The above solution works on all browsers including IE7 and IE8. This dynamically loads a stylesheet and applies it.

Let's load some Javascripts using innerHTML property. Try the following function :

<script>
function load_script()
{
  var p = document.getElementById("header");
  var t = p.innerHTML;
  p.innerHTML =  "<script>alert('This is a nice day');</script>" + t;
}
</script>


The above function does not work because of malformed Javascript due to the existence of "</script>" word used inside the function body. Browser thinks that the script ends there. So the rest part " + t }" are assumed to be HTML and printed on screen. So, we would correct that first. Check out the implementation below ::

<html>
<head id='header'>
<script> 
function load_script()
{
  // Get the ID of <head>
  var p = document.getElementById("header");
  var t = p.innerHTML;
  p.innerHTML =  "<script>alert('This is a nice day');</scri" + "pt>" + t;
}
</script>
</head>

<body>
<div id="mydiv">This is a sample DIV. Click the button to load a script <br />
<input type="button" onclick="load_script()" value="Load Script">
</div>
</body>
</html>


Notice how the "</script>" has been written as "</scri" + "pt>" to tell JavaScript engine that this is just a string. The above code successfully inserts a new <script> node on all browser [Except IE] but does not execute the script. IF we insert the <script> tag in any other elements like DIV or P, it would have worked in IE also, but the code would still behave as a plain text.

However, dynamically adding a script to DIV or P etc elements does not make the new script work on any browser. However in IE, we can see a different bahaviour if we use the keyword "defer" on <script> tag.

<html>
<head id='header'>
<script> 
function load_script()
{
  // Get the ID of DIV
  var p = document.getElementById("mydiv");
  var t = p.innerHTML;

  // We use defer keyword
  p.innerHTML =  "<script defer>alert('This is a nice day');</scri" + "pt>" + t;
}
</script>
</head>

<body>
<div id="mydiv">This is a sample DIV. Click the button to load a script <br />
<input type="button" onclick="load_script()" value="Load Script">
</div>
</body>
</html>


The above code works on IE only. As soon as we click on the 'Load Script' button, a script tag with alert() function call is inserted in the "mydiv" DIV element and the script is executed.The keyword "defer" means the loading of JS is deferred.

So, we need to use DOM methods to insert a script.

<script>
function load_script()
{
  // Get the ID of head
  var p = document.getElementById("header");
 
  // Create new script element
  var scr = document.createElement("script");
 
  // Define Code Body
  var code = "function d(){ var sum = 0; "   +
     "  for(var i=1; i<=10; i++ )  sum += i;" +  

     "  alert('The Sum is : ' + sum );} d();" ;
        
  // Create a TEXT node
  var c = document.createTextNode(code);

  // Append the code to script
  scr.appendChild( c );

  // Append the script to header
  p.appendChild( scr );

}
 
</script> 

The above code successfully inserts a script at runtime inside the <head> tag. The script contains definition of a user-defined function d() which calculates sum of first 10 natural numbers and shows the sum on screen. And then we call the function d(). As a result, when we click on the "Load Script" button, the new script is appended to <head> element, the d() function is evaluated and run; so we see a message "The Sum is : 55" popping up on screen.

innerHTML property treats the inserted javascript statements as plain text. However, we can use eval() function to make those statements back to Javascript. Check the example below ..

<script> 
function load_script()
{
  eval( document.getElementById("mydiv").innerHTML  );
}
</script>

<div id="mydiv">function sum(a,b){alert (a+b);}</div>
<input type="button" onclick="load_script()" value="Load Script">
<input type='button' value = 'Get Sum' onclick='sum(1,2)'>


The purpose is, when the "Load Script" button is clicked, the content of the DIV is parsed and evaluated and as a result function sum() is registered, hence when then "Get Sum" button is clicked, the sum(1,2) function should get executed. But problem is this does not work as eval() maintains the scope for the code body it parses. Hence, the sum() function is registered inside the load_script() function only, hence not accessible form outside the parent function load_script(). So, if we change the DIV content as shown below, a function is registered in global scope and can be accessed from anywhere.

<div id="mydiv">sum = function(a,b){alert (a+b);}</div>

Here, we create a sum() function in the global scope. Hence the "Get Sum" button now works and shows us a message containing sum of 1 and 2.

We can receive block of Javascript statements in Ajax Response, put those statement texts in any DIV or span or other elements through innerHTML property of that element and then use eval() method to parse and evaluate them to do some automated job.


Check my next article "Dynamic JS Insertion" where I have discussed some more on this.

Wednesday, May 29, 2013

String Reversing with C

We need to write a C program which would reverse every word in a given sentence. For example if the given string is "India is my country", the resultant output would be "aidnI si ym yrtnuoc".

Going to solve the whole problem right now, let's try a small string reversing program which would reverse whole of a given string instead of reversing each word in it.

#include "stdio.h"
#include "string.h"
main()
{

  char str[35] = "Program" ;
 
  /* Print Before Reversing */
  printf("\n str : %s\n",str);

  /* reverse in Place */
  str_rev(str);

  /* Print AFter Reversing */
  printf("\n Reversed str : %s\n",str);
}

/* String Reversing Function.  It does
   not work on a copy of the string

*/
str_rev( char *str)
{
  int count = strlen(str);
  int j = 0, k=count-1, l = 0;
  char ch;
  while( l < count/2)
  {
      /* character swapping */
      ch = str[j];
      str[j] = str[k];
      str[k] = ch;
     
      /* Counters */
      j++; k--; l++;
    }
}


The Output :: "margorP"

Now check how the str_rev function works. To reverse a word "Program" to "margorP", we need a loop which would run from 0 index to the exactly middle of the string.

Word length : 7 [ index 0 to 6 ]
1st pass : swap between position 0 and 6 => mrograP
2nd pass : swap between position 1 and 5 => maogrrP
3rd pass : swap between position 2 and 4 => margorP

The character at position 3 does not need to be swapped with anything. See that we have already achieved the target, hence we need to stop here, if we go ahead, the swapping will again take place like this

4th pass : swap between position 3 and 3 => margorP
5th pass : swap between position 4 and 2 => maogrrP
6th pass : swap between position 5 and 1 => mrograP
7th pass : swap between position 6 and 0 => Program

The last 4 passes would get the original string "Program" back which we do not want. Hence, we need to run the main loop till half of the length of the string. The statement "while( l < count/2)" inside str_rev() function does just that. The function str_rev() takes a pointer to a string which means the string is updated in place. It does not work on a copy of the string.

Next, we would try to identify and print each word in a given string.

#include "stdio.h"
#include "string.h"
main()
{

  char str[35] = "  C   is   Nice   " ;
  int i,len, letter_found ;

  len = strlen(str);
  i = 0 ;
 
  while(1)
  {
    /* This Loop below only work if it
       is a non-whitespace character

    */
    letter_found = 0;

    while(str[i] && str[i]!=' ')
    {
      printf("[%c]",str[i]);
      i++;
     
      /* Set a flag that we found some letters */
      letter_found = 1;
    }
   
    /* Break if string ends */
    if( str[i] == '\0' )
     break;
    i++;
   
    /* Print a Newline after a word is printed */
    if(letter_found) printf("\n");

  }
  
}


The output of above program is :

[C]
[i][s]
[N][i][c][e]

The above program beautifully ignores all whitespaces and shows only the non-whitespace characters found inside the string. We need the inner loop to go through a single word and print it completely. After the inner loop ends, we check for string termination and if the string does not end here we again start at the beginning of outer loop. The outer loop while(1) keeps us going with printing every word and only when the string termination character '\0' is found, we break out.

Within the inner loop, we can copy every single word to another temp array and then reverse that temp array and print.

#include "stdio.h"
#include "string.h"
main()
{

  char str[35] = "  C   is   Nice   " ;
  char temp[35];
  int i, j, letter_found ;

  i = 0 ;
  /* Outer Loop Starts */ 
  while(1)
  {
   
    j = 0;
    letter_found = 0;

    /* This Loop below only work if it
       is a non-whitespace character

    */
   
    while(str[i] && str[i]!=' ')
    {
      /* Copy to temp Array */
      temp[j++] = str[i++];
     
      /* Set a flag that we found some letters */
      letter_found = 1;
    }

    /* terminate the "temp" string */
    temp[j] = 0;

    /* a word is found */
    if(letter_found)
    {

        /* Reverse the "temp" string */
        str_rev(temp);

        /* PRINT the "temp" string */
        printf("[%s]",temp);
    }
   
    /* Break if string ends */
    if( str[i] == '\0' )
     break;
   
    /* Counter */
    i++;

  }
  
}

/* Our old String Reversing function */
str_rev( char *str)
{

  int count = strlen(str);
  int j = 0, k=count-1, l = 0;
  char ch;
  while( l < count/2)
  {
      /* character swapping */
      ch = str[j];
      str[j] = str[k];
      str[k] = ch;
     
      /* Counters */
      j++; k--; l++;
    }
}



The output is given below :

[C][si][eciN]

The code above is quite self-explanatory. We put all the read characters in array "temp" and then calling our old function str_rev() on it. 


Next, the final goal, let's reverse all words within a given string. So, we won't take help of any temp array in this. To reverse a word, we need to know its start position and end position and then we would apply the logic we used in str_rev() earlier. Check out the implementation below ::

#include "stdio.h"
main()
{

  char str[35] = "    AB ABC     ABCD  ABCDE   " ;
  int i, j, k, l, letter_found, start_pos, end_pos ;

  i = 0 ;

  /* Outer Loop Starts */ 
  while(1)
  {
   
    letter_found = 0;

    /* This Loop below only work if it
       is a non-whitespace character

    */
   
    while(str[i] && str[i]!=' ')
    {
      if( letter_found == 0 )
      {
        /* Set a flag that we found some letters */
        letter_found = 1;
       
        /* Capture the start position */
        start_pos = i;
      }
      i++;
    }

    /* a word is found */
    if(letter_found)
    {

        /* Capture the end position */
        end_pos = i-1;

        /* NOW REVERSE */
        int count = end_pos - start_pos + 1;
        char ch;
        j = start_pos, k=end_pos; l = 0;

        while( l < count/2)
        {
          /* character swapping */
          ch = str[j];
          str[j] = str[k];
          str[k] = ch;
         
          /* Counters */
          j++; k--; l++;
        }
       
    }
   
    /* Break if string ends */
    if( str[i] == '\0' )
     break;
   
    /* Counter */
    i++;

  } /* Outer Loop Ends */

  /* Now PRINT The original String */
  printf("\n [%s]",str);
  
}


The output is shown below ::
[    BA CBA     DCBA  EDCBA   ]

The stating and trailing whitespaces are maintained as this reverses each word in a given string ignoring the whitespaces.

Tuesday, May 28, 2013

String trimming with C

Trimming means removing whitespaces from beginning and end of a string. First we would write a function which removes all trailing whitespaces from a given string.

The logic is ::

i) Scan a string from right end in a loop
ii) If a whitespace found at location n and location n-1 holds any non-whitespace, then we put a '\0' NULL character there and stop.
iii) Otherwise for every whitespace, we replace it with a NULL character.

#include"stdio.h"
#include"string.h"
main()
{
  char str[35] = "  India  is my   country  " ;
 
  /* TRIM end whitespaces */
  right_trim(str); 
 
  /* Print After right Trimming*/
  printf("\n %s",str);
}


/* Right Trim function definition */
right_trim(char *str)
{
  int i,len;
  len = strlen(str);
  i = len - 1;
 
  /* Make sure STRING is not empty */
  if( len > 0 )
  {

       /* This Loop scans the string from end */
       while(str[i])
       {
         /* If a space is found at nth position
            and n-1 position holds a character
*/
         if( str[i] == ' ' && str[i-1]!=' ' && i > 0 )
         {
           str[i] = 0;

           /* BREAK THE LOOP - Important*/
           break;
         }
         else if( str[i] == ' ' )
         {
            str[i] = 0;
         }
               
         i--;
       }
   
   }
}


The right_trim() function takes a pointer to a string which means it works on the original string, not a copy of it. There is a main loop which scans a given string from right end and it places a NULL character at any position if the following conditions satisfy..

a. If any whitespace is found and its previous character is a non-whitespace, then we can assume that it is end of the word/string, hence we put a NULL character at that position.

Suppose we have a string "PHP  " (2 whitespaces at the end) with character 'P' at index 0 and ' ' (space) at index 3 and 4. When the loop scans the string from the end (From index 4), in the first pass, the condition "str[i] == ' '" is evaluated to be true, hence a NULL is placed at position 4. In the second pass the condition " str[i] == ' ' && str[i-1]!=' ' && i > 0 "  becomes true and null character is placed at position 3 making the string "PHP". After this point, we should break out of the loop.

For another example string "Nice PHP  " (2 spaces at the end), after it puts '\0' at 8th position when condition " str[i] == ' ' && str[i-1]!=' ' && i > 0" (i=8) satisfies, if we don't break the loop, it satisfies the similar condition at position 4 and puts a '\0' at 4th position making the string "Nice" which is not what we want.

b. The else part's condition  str[i] == ' ' is equally important to right-trim empty string like  "    ". It continuously places a '\0' on every occurrence of whitespaces.

Now check out how to left-trim a given string like "   NICE PHP   " with 3 whitespace at both front and end. Here is the logic ::

i)Start scanning the string from beginning
ii) If a position has whitespace (" ") and next character is a non-whitespace, break the loop. That is the valid starting point of the string. We can copy from this position into another array or the same array
iii) Else we keep putting 0 in every position if it is a whitespace.

The step (iii) is for trimming empty strings like "  " (2 whitespaces). Now check the implementation below ..
   
#include"stdio.h"
#include"string.h"
main()
{

  char str[35] = "  NICE PHP  " ;
 
  /* TRIM beginning whitespaces */
  left_trim(str); 
 
  /* Print After LEFT Trimming */
  printf("\n %s",str);
}


/* LEFT Trim function definition */
left_trim(char *str)
{
  int i,len, copy_flag=0;
  len = strlen(str);
  i = 0;
 
  /* Make sure STRING is not empty */
  if( len > 0  )
  {

       /* This Loop scans the string from beginning */
       while(str[i])
       {
         /* If a space is found at nth position
            and n+1 position holds a character
*/
         if( str[i] == ' ' && str[i+1]!=' ' && i < len-1 )
         {

           /* Set the FLAG to denote that Shifting/Copying is required */
           copy_flag = 1; 

           /* BREAK THE LOOP - Important */
           break;
         }
         else if( str[i] == ' ' )
         {
            str[i] = 0;
         }
               
         i++;
       }
   
   }
   

   /* LEft Shifting is required */
   if( copy_flag )
   {
      /* i+1 holds valid start of the string as
         prior to that, all position holds whitespaces

      */
      int fpos = i+1;
      int target_pos = 0;
     
      /* start shifting the string towards left */
      while( str[fpos] )
      {
        /* Write/Shift */
        str[target_pos] = str[fpos];

        target_pos++;
        fpos++;
      }
     
      /* Denote new ending */
      str[target_pos] = 0;

   }

}


The loop while(str[i]) determines where the first non-whitespace character appears within the string. If any such non-whitespace character is found, its location is stored and we beak out the loop with a flag set to denote that the array values need to be shifted towards left. Then we shift the array towards left. If any non-whitespace character is not found, '\0' is inserted at every position which does not cause any harm. For example a string is "  NICE PHP  " (with 2 spaces at the beginning and end), in the 2nd pass of the loop the string becomes "0 NICE PHP  " as the first position gets a '\0' due to the code block :

else if( str[i] == ' ' )
{
  str[i] = 0;
}


The above condition satisfies when the i has a value of 0. But it does not harm because rest of the string "NICE PHP  " are shifted towards left and such NULL characters are over-written.

This was a very lengthy approach, let's take another small approach to left trim a given string. Here we would keep on left shift array characters until the first character becomes a non-whitespace character. Check the implementation below.

#include"stdio.h"
#include"string.h"
main()
{

  char str[35] = "  NICE PHP  " ;
 
  /* TRIM beginning whitespaces */
  left_trim(str); 
 
  /* Print After LEFT Trimming */
  printf("\n %s",str);
}


/* LEFT Trim function definition */
left_trim(char *str)
{
        int i=0, j , len;
      
       /* This Loop scans only the 1st position */
       while(  strlen( str ) > 0 && str[0] == ' ')
       {
           len = strlen( str );
           /* Put a NULL at 0 position */
           str[0] = '\0';

           /* LEFT Shift array characters */
           j = 1;
           while( str[j] )
           {
             str[j-1] = str[j];
             j++;
           }
         
           /* Denote End of the string */
           str[j-1] = 0;
           
       }
}


The 2nd approach requires less lines of code and easy to understand. The output is "NICE PHP  ".

Monday, May 27, 2013

Generate RSS feed with PHP

Generating RSS feed with PHP is vey easy. We need to maintain the basic RSS XML format in the output.

<?xml version='1.0' encoding='UTF-8'?>
<rss version='2.0'>
<channel>
<title> Any Title</title>
<link> Any URL </link>
<description> Any Description </description>
<lastBuildDate> Last Build Date</lastBuildDate>
<atom:link href="http://example.com/rss.xml" rel="self" type="application/rss+xml" />
<language>en-us</language>

<item>
<title> Item1 Title</title>
<link> Item1 URL </link>
<description> Item1 Description </description>
</item>

<item>
<title> Item2 Title</title>
<link> Item2 URL </link>
<description> Item2 Description </description>
</item>

</channel>
</rss>


The above XML shows two feed items enclosed within "<item>" tags and each item has its own "title", "link" and "description" tags. The whole item-node construct is enclosed in <channel> and <rss> tags which is important. The "<atom:link ...." tag is totally optional and it's href property should hold the URL of current feed. Using such "<atom:link>" tag has some advantage of being portable and easier to cache. RSS 2.0 requires "title", "link" and "description" tags to be present in the output whereas Atom 1.0 requires "id","title", "link", "author", "updated" elements.

Now, suppose we have a DB table called 'article' with fields 'title', 'url' and 'description' and 'content' fields. We would be making a simple SELECT query, then iterate though the rows and create the final XML as displayed in the PHP program below ::

<?php
// Database Stuffs
$con = mysql_connect("localhost","root","");
mysql_select_db("test");
$sql = "Select title, url, description from article";
$res = mysql_query($sql);

$xml_data = "";

// MAIN LOOP starts
while( $row = mysql_fetch_array($res))
{
  $xml_data .= "<title>". htmlentities($row['title']) ."</title>";
  $xml_data .= "<link>". htmlentities($row['url']) ."</link>";
  $xml_data .= "<description>". htmlentities($row['description']) ."</description>";
}

// Set the output document type through header() function
header("Content-Type: application/rss+xml; charset=utf-8");

// Next, GENERATE the RSS Content
echo '<?xml version="1.0" encoding="utf-8"?>';
echo '<rss version="2.0">';
echo '<channel>';
echo '<title> All Article Listings</title>';
echo '<link>http://www.example.org/aticle-listing-rss.php</link>';
echo '<description>Get Listing of all Articles</description>';
echo '<lastBuildDate>' . date('d M Y h:i:s ') . '+0000' . '</lastBuildDate>';
echo '<language>en</language>';

// Render the DB content
echo $xml_data;

// Concluding Tags
echo '</channel>';
echo '</rss>';
?>


The above code is very simple and easy to understand. However some output characters like single quote or ampersand can cause error. That's why we have used htmlentities() function to convert them to HTML compatible. After we create an RSS feed this way, we may get it checked by validator.w3.org. The output on firefox is shown below ::



If we want to include any article images in the output we can do it two ways :

$xml_data .= "<description>". htmlentities("<a href='". $row['link'] ."'><img src='". $row['image'] ."'></a>") ."</description>";

We created the <img> tag enclosed in an anchor tag to linkify the image. We used htmlentities() function to make these data not available for XML parsing. Characters like "<" and "&" are illegal in XML elements. htmlentities() function would convert <img> to "&lt;img&gt;" which then would not be parsed as XML node. But browser can still build the <img> tag and show the corresponding image on screen in the output.

Similar effect we can achieve through using "CDATA". Check the code below.

$xml_data .= "<description>"  . "<![CDATA[<a href='". $row['link'] ."'><img src='". $row['image'] ."' ></a>]]>" . "</description>";

A CDATA section within XML document starts with "<![CDATA[" and ends with "]]>" and hence it can not contain the string "]]>". Nested CDATA section are also not allowed. Texts like Javascript code should be placed inside CDATA section in XML document.

Download: Fast, Fun, Awesome

Tuesday, May 21, 2013

Fun using css "background-position"


Last week I had checked a beautiful demo of a moving background here and I decided to shell out my own version. Check the image below to learn what I was upto.




The above graphic was done by modifying the background picture position of a DIV using Javascript.

It has four buttons at the bottom, if we click on the "<" button, the digits seem to flow from right to left; by clicking on the '^' button, the digits seem to flow from bottom to top etc. How the whole stuff actually works is described below.

a. First we create an image of digits. Example image is given here..



b. Second, we create a PNG image where the text "PHP" section is totally transparent. Example image is given here..In the picture below, some part is transparent, hence nothing is seen on browser. 


c. We take a DIV with same hight and width as of the PNG image mentioned in step (b) above.
d. We set the background image of the above DIV to the digits image we created in step (a)
e. Now if we change the background-position of the background image of the DIV in a constant manner, the above animation can be achieved.

We set the background image of the DIV through CSS, but we change the "background-position" through Javascript as shown below.

document.getElementById("scrollDiv").style.backgroundPosition = '10px 13px';

The value '10px 13px' defines x-position and y-position of the image. If we increase constantly the y-position from 13px, it would cross the height of the image and hence the image would be gone away and the animated effect would stop. That's why we use "repeat" while setting the background image for the DIV. This would repeat the background image even when we cross the image height/width limit. However, we have put a check in our JS logic that when during scrolling the background image, if any x-position or y-position values are crossing their limit, they are reset to 0.

The Javascript works the following way ::
a. When a button is clicked, we call use-defined scroll() function with a parameter denoting the direction.
b. scroll() function sets a timer so that scr_oll() function is called every 50 milliseconds.
c. The scr_oll() also takes the direction value as a parameter. This function reads the existing background-position style attribute (initially '0px 0px' or '0% 0%') from the DIV. It then clears the 'px' or '%' characters from that value, extracts correct x-pos and y-pos values, then does some maths to set a new value to that background-position style attribute of the DIV. We also check if the x-pos/y-pos values remain within range;

Check the implementation below.

<html>
<head>
<script>
var max_bottom = 300; // Image height of digits.jpg
var max_right  = 599; // Image width of digits.jpg
var timer = '';       // For timer

function scroll(dir)
{
  // Clear any Old Interval if exists
  clearInterval( timer );
  // Set new Interval
  timer = setInterval( function () { scr_oll(dir); }, 50 );
}

// Main function which scrolls the background image
function scr_oll(dir )
{

 // GEt existing background-position
 var backp_css = document.getElementById("scrollDiv").style.backgroundPosition;

 // Remove spl chars
 backp_css = backp_css.replace(/%/g,'');
 backp_css = backp_css.replace(/px/g,'');

 // Split to get xpos and ypos values
 var arr = backp_css.split(" ");

 // Scrolling from top to bottom
 if(dir == 1)
 {
   // For top-to-bottom scroll, we would
   // incerase the ypos value by 1
   var ypos = parseInt(arr[1]) + 1;
  
   // If crossing the maximum, reset
   if( ypos > max_bottom ) ypos = 0;
  
   // Build the final CSS string
   var css_str = arr[0] + 'px ' + ypos + 'px';
 }

 // Scrolling from bottom to top
 if(dir == 3)
 {
   // For bottom-to-top scroll, we would
   // decerase the ypos value by 1
   var ypos = parseInt(arr[1]) - 1;
  
   // If crossing the minimum low, reset
   if( ypos < 0 ) ypos = max_bottom;
  
   // Build the final CSS string
   var css_str = arr[0] + 'px ' + ypos + 'px';
 }

 // Scrolling from right to left
 if(dir == 2)
 {
   // For right-to-left scroll, we would
   // decerase the xpos value by 1
   var xpos = parseInt(arr[0]) - 1;
  
   // If crossing the minimum low, reset
   if( xpos < 0 ) xpos = max_right;
  
   // Build the final CSS string
   var css_str = xpos + 'px ' + arr[1] + 'px';
 }

 // Scrolling from left to right
 if(dir == 4)
 {
   // For left-to-right scroll, we would
   // incerase the xpos value by 1
   var xpos = parseInt(arr[0]) + 1;
  
   // If crossing the minimum low, reset
   if( xpos > max_right ) xpos = 0;
  
   // Build the final CSS string
   var css_str = xpos + 'px ' + arr[1] + 'px';
 }

 // Set new background-position
 document.getElementById("scrollDiv").style.backgroundPosition = css_str;
}
</script>
</head>

<body>



<!-- We set the background Image to the DIV -->
<div id='scrollDiv' style="background:url('digits.jpg');height:250px;width:300px;border:0px solid tomato">
 <img src='php.png' style='display:block'>
</div>

<!-- Direction Buttons -->
<input type='button' value='<' title='Left' onclick='scroll(2)'>
<input type='button' value='>' title='Right' onclick='scroll(4)'>
<input type='button' value='˄' title='Top' onclick='scroll(3)'>
<input type='button' value='˅' title='Bottom' onclick='scroll(1)'>

</body>
</html>


Copy-paste the above code and supply the images used, this would run on all browsers.

The scroll() function clears any previous timer set, by calling clearInterval() function. It is necessary otherwise n number of timer might get created and force the browser to execute all of them at the same interval.