Monday, 21 September 2015

document.write() overwrites the entire page

document.write is a function which basically outputs whatever is given to it. But sometimes, improper usage may overwrite the entire page depending on where it is being called.

For e.g.,

<html>
<head></head>
<body>
<p>The current date and time is,
<script type="text/javascript">
document.write((new Date()).toString());
</script>
</p>
</body>
</html>

Output: The current date and time is, Sun Sep 20 2015 01:23:01 GMT+0530 (India Standard Time)

In the above example, document.write() has been used to output content directly into the page as it’s being rendered.

If document.write() is called after the page has been completely loaded, the content
overwrites the entire page (existing DOM), as shown in the following example:

<html>
<head></head>
<body>
<p>The current date and time is,
<script type="text/javascript">

window.onload = function(){
    document.write((new Date()).toString());
}
</script>
</p>
</body>
</html>

In the above example, document.write() is called after the page has been completely loaded by using the window.onload event handler.
So, the text:

"Sun Sep 20 2015 01:23:01 GMT+0530 (India Standard Time)"

is only rendered, overwriting the text:

"The current date and time is,"

Similar incident occurs with jQuery $(document).ready()

It's better to avoid document.write. You may use document.createElement instead.

Wednesday, 4 December 2013

Generate a unique alphanumeric string by checking against the database in PHP

<?php

//function to generate n character alpha-numeric string.

function alphamumeric($length=12) {
   $charset = '1234567890abcefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
   return substr(str_shuffle($charset), 0, $length);
}

//assuming we are storing the generated ids in the column 'id' of table 'tbl_ids' in database 'test'

$mysqli=new mysqli('localhost','root','root','test');

do{

$num=alphamumeric(16);
$query="SELECT count(id) FROM tbl_ids WHERE id='$num'";
$result=$mysqli->query($query);
$row=$result->fetch_row();
$found=$row[0];

}while($found == 1);

echo 'Unique Id='.$num;

?>

For the Id to be unique you must check it with the database or file where you are storing the Ids (collision check). Otherwise, you can't be sure that the currently generated value is unique.

After the do-while loop ends, the variable $num gives you a 16 character unique id.

Please note that in the code

   $charset = '1234567890abcefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';

1234567890 has been repeated three times.This is just to increase the probability of 'numeric characters' relative to 'non-numeric characters' in the generated value. If you use 1234567890 only once, you will notice that there are mostly non-numeric characters generated.

Monday, 2 September 2013

jQuery form validation using jquery.validate.min.js

<html>
<head>
<style type="text/css">

.error, .notice, .success{padding:.1em; margin-bottom:1em; border:2px solid
#ddd}
.error{background:#FBE3E4; color:#8a1f11; border-color:#FBC2C4}
.notice{background:#FFF6BF; color:#orange; border-color:#FFD324}
.success{background:#E6EFC2; color:#264409; border-color:#C6D880}

</style>
<script src="jquery.js"></script>
<script src="jquery.validate.min.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function()
{
    $("#contact-form").validate({
       rules:{
              username:"required",
              userid:"required",
              useremailid:{required:true,email:true},
              usermobile:{required:true,digits:true,rangelength:[10,10]},
              userage:{required:true,digits:true,min:18,max:100},
              userpass:{required:true,rangelength:[6,10]},
              confpass:{required:true,equalTo:'#userpass'},
              country:{required:true,countrylist:["India"]},
              city:{required:true,citylist:["Kolkata","Chennai","Mumbai","New Delhi"]},
              langs:{required:true,langcount:[2]},
              ambition:{rangelength:[10,20]},
              vcode:{required:true,verify:true},
               
        }, //end rules
         messages:{
                usermobile:{required:"Please enter your mobile number",digits:"Please enter a valid mobile number",rangelength:"The mobile number must have exactly 10 digits"},
                confpass:{required:"Please enter the password again",equalTo:"The passwords do not match"},
                langs:{required:"Tick the languages you know"},
                ambition:{rangelength:"Should be 10 to 20 characters"},
                vcode:{required:"Please enter verification code"},
            },//end messages
           
       errorPlacement:function(error, element)
                      {
           if ( element.is(":radio") || element.is(":checkbox")) 
              {
                 error.appendTo( element.parent());
              } else 
                 {
                  error.insertAfter(element);
                 }
                     }//end errorPlacement
        });
       
        $.validator.addMethod("countrylist",function(value,element,params)
        {
           return this.optional(element)||   

                   value.toLowerCase()== params[0].toLowerCase();
        },"You must be an Indian citizen");
       
        $.validator.addMethod("citylist",function(value,element,params)
        {
            return this.optional(element) || 
            value.toLowerCase()==params[0].toLowerCase() ||
            value.toLowerCase()==params[1].toLowerCase() ||
            value.toLowerCase()==params[2].toLowerCase() ||
            value.toLowerCase()==params[3].toLowerCase() ;
        },$.format("You must stay in one of {0},{1},{2} or {3}"));
       
        $.validator.addMethod("langcount",function(value,element,params)
        {
            $langcount=$("form input:checkbox:checked").length;
           
            return this.optional(element) || $langcount>=params[0];
        },$.format("You must know at least {0} languages"));
       
        $.validator.addMethod("verify",function(value,element,params)
        {
            var total=parseInt($('#no1').val()) + parseInt($('#no2').val());
           
            return this.optional(element) || parseInt(value)==total;
        },$.format("Verification failed..please try again"));
       
        $('input:radio[name=pmtmeth]').change(function(){
       
            if($(this).val()=='cheque')
            {
                $('#chequeno').attr('readonly',false);
                $('#chequeno').rules('add',"required digits");
                $('#chequeno').rules('add',{messages:        {required: "Please enter cheque number",digits:"Invalid Cheque number. Should be digits only"}});               
            }
            else
            {
                $('#chequeno').attr('readonly',true);
                $('#chequeno').rules('remove',"required digits");
                $('#chequeno').val('');
                $('#chequeno').removeClass('error');
                $('label[for=chequeno]').remove();
               
            }
           
        });
       
});

</script>
</head>
<body>
<form id="contact-form">
Name<br />
<input type="text" name="username" value="" />
<br />UserId<br />
<input type="text" name="userid" value="" />
<br />EmailId<br />
<input type="text" name="useremailid" value="" />
<br />Mobile No<br />
<input type="text" name="usermobile" value="" />
<br />Age (must be between 18 and 100)<br />
<input type="text" name="userage" value="" />
<br />Country<br />
<input type="text" name="country" value="" />
<br />City<br />
<input type="text" name="city" value="" />
<br />Password (6 to 10 characters)<br />
<input type="password" id="userpass" name="userpass" value="" />
<br />Confirm Password<br />
<input type="password" name="confpass" value="" />
<br /><br />Languages Known
<div>
<input type="checkbox" name="langs" value="Bengali">English
<input type="checkbox" name="langs" value="English">Spanish
<input type="checkbox" name="langs" value="Hindi">French
</div>
<br />Your Ambition<br />
<textarea name="ambition"></textarea>
<br /><br />Payment Method
<input type="radio" name="pmtmeth" value="cash" checked="checked">Cash</input>
<input type="radio" name="pmtmeth" value="cheque">Cheque</input>
<br />Cheque No<input type="text" name="chequeno" id='chequeno' value="" readonly="true"/>
<br /><br />Enter Verification Code
<input type="text" name="no1" id="no1" value="5" size="2"/> + <input type="text" name="no2" id="no2" value="7" size="2"/> = <input type="text" name="vcode" value="" size="2"/>
<br /><br />
<input type="submit" name="btnSubmit" value="SAVE" />
</form>
</body>
</html>

Friday, 16 August 2013

Variable scope in JavaScript

In JavaScript, variables can be declared in two ways, implicit declaration and explicit declaration.

var x;

This was an explicit declaration. The keyword var indicates the next symbol is a new identifier in the current scope.

x = 100;

This was an implicit declaration. There is no need to always explicitly define a variable before using it. A variable can be implicitly defined by simply referring to it without using the var keyword.

The second piece of code assigns the variable to the global scope, meaning it will be accessible by all blocks,  functions, and statements. In general, it is better to avoid implicit variables.

Now, let us come to Variable Scope. The scope of a variable refers to the portions of the program where it can be directly accessed. 

When variables are defined explicitly, they are accessible by all parts of the program, so they have global  scope . If a variable’s scope is limited to its function, it has local scope . The scope to which a variable  belongs is called its context.

<script type="text/javascript">
var os = "Windows";

function myOs()
{
  var os = "Linux";
  document.write(os + "<br />");
}

myOs();
document.write(os + "<br />");
</script>


The output of the above code is:

Linux
Windows

The output above is a matter of variable scoping. When the function myOs() is called, the interpreter first checks whether there is a variable 'os' defined in the local scope (the function context). If it doesn’t find it, it moves up the hierarchy of scopes until it reaches the global scope (the window object in a browser), checking along the way. If instead it actually does find this variable declared in the local scope, it uses that one instead of any others of the same name that might appear higher up in the scope chain.

In the above example, since a variable 'os' is declared within the function, it is used and the global variable 'os' remains untouched.

<script type="text/javascript">
var os = "Windows";

function myOs()
{
  os = "Linux";  //no var here
  document.write(os + "<br />");
}

myOs();
document.write(os + "<br />");
</script>


The output of the above code is:

Linux
Linux

In the last code snippet, the variable 'os' inside the function myOs() is not declared explicitly in the local scope. So, the global scope is used thus reassigning the global variable 'os'.


Wednesday, 17 July 2013

Convert a JSON text into a JavaScript object

To convert a JSON text (i.e. a string formatted as JSON) into a JavaScript object, use  the eval() function.

Approach 1:


In this approach you should surround the JSON with parentheses. The reason for the parentheses is so the eval statement treats the text as an object initializer, rather than some other type of code.

var jsonstr='{"name":"Adis","age":25,married:false}';
var jsobj=eval("(" + jsonstr + ")");


OR

Approach 2:

The second approach is to include the variable assignment as the left side of the expression and the JSON as the right, within the eval method:

var jsonstr='{"name":"Adis","age":25,married:false}';
eval("var jsobj=" + jsonstr);

Monday, 24 June 2013

Dynamic image resize function maintaining aspect ratio

$img-width = Image width
$img-height = Image height
$cont-width = Width of the display container
$cont-height = height of the display container



function  calculate($img-width,$img-height,$cont-width,$cont-height)
{
    $adjusted=array($img-width,$img-height);
    $ratio=$img-width/$img-height;

    if($img-width>$cont-width || $img-height>$cont-height)
    {
        $adjusted[0]=$cont-width;
        $adjusted[1]=$adjusted[0]/$ratio;
       
        if($adjusted[1] > $cont-height)
        {
            $adjusted[1]=$cont-height;
            $adjusted[0]=$adjusted[1]*$ratio;
        }
    }
    return $adjusted; // adjusted[0]=required width, adjusted[1]=required height
}



If image width and image height are both less than those of the container then we need no resizing. But resizing is required if any one or both of image width and image height exceeds those of the container.

So, adjustment begins if:

if($img-width>$cont-width || $img-height>$cont-height)

Within the if condition we don't know which one exceeds. Might be width, or might be height or both of them. Whatever may be the case, we have to reduce the image size to fit into the container, but at the same time maintaining aspect ratio. That's why we have calculated the ratio as :


$ratio=$img-width/$img-height;

During reduction, a time will come when an exceeded dimension becomes equal to that of the container. Let's assume that this is the width. So,

$adjusted[0]=$cont-width; // $adjusted[0] is the required width

Hence, at this time, maintaining aspect ratio the image width should be:

$adjusted[1]=$adjusted[0]/$ratio; // $adjusted[1] is the required height

But, at this point we are not sure whether the calculated height fits in the height of the container. So, check by: 

if($adjusted[1] > $cont-height)

If the above is true, then our adjustment was incorrect. We must adjust the height first and then the width:

$adjusted[1]=$cont-height;
$adjusted[0]=$adjusted[1]*$ratio; // to maintain the ratio

Wednesday, 9 May 2012

Implementing polymorphism using the Strategy Design Pattern in PHP

The Strategy pattern is used to separate an object from its algorithms. The core idea of the pattern is the OOP principal of polymorphism. More explicitly, a Strategy pattern is a group of algorithms encapsulated inside classes that are made interchangeable so the algorithm can vary depending on the class used. Strategies are useful when you would like to decide at run time when to implement each algorithm. They can be used to vary each algorithm’s usage by its context.
The Strategy pattern has three main components: the Strategy, the Concrete Strategy, and the Context. The strategy is a common interface that ties together all supported algorithms. Usually this class is abstract. The concrete strategy is the implementation class where the logic for each different algorithm lives in the group. The context is the object that ties a concrete strategy to a particular code flow.


Advantage of the strategy pattern
As mentioned earlier, the motive behind the strategy pattern is to separate an object from its algorithms. Removing the algorithms from the host class and putting them in a separate class, enables the host to concentrate on its own job. Otherwise, the host will get messy with all the algorithms in itself with lot of if-else or switch-case statements.
Here’s an example.
Suppose a car renting service charges its customers differently at different situations – sometimes based on kilometers travelled, sometimes on hours of travel, and sometimes on a combination of both, depending on festive seasons, off-seasons etc.
There’s a billing class in the application which prepares the bill for the customer. Now the payable amount part needs a lot of calculations based on the type of charge, distance and hours of travel resulting in a lot of if-else or case statements. Addition of more billing algorithms results in inclusion of more if-else statements. To make the situation better, we simply encapsulate each faring algorithm in a separate class and depending on the context at runtime, we decide which algorithm to choose. Addition of another faring algorithm is done by simply adding another class i.e. extending the abstract class FareStrategy.

<?php
abstract class FareStrategy
{
    abstract function calculateFare($kms, $hrs);
}

class HourlyFareStrategy extends FareStrategy
{
    private $normalHours=8;
    private $normalHourRate=250;
    private $additionalHourRate=200;
   
    function calculateFare($kms, $hrs)
    {
        if($hrs > $this->normalHours)
        {
            $fare=($this->normalHours*$this->normalHourRate)+(($hrs-$this->normalHours)*$this->additionalHourRate);
            return $fare;
        }
        else
        {
            $fare=$hrs*$this->normalHourRate;
            return $fare;
        }       
    }
} //end class HourlyFareStrategy

class KmsFareStrategy extends FareStrategy
{
    private $normalKms=100;
    private $normalKmRate=15;
    private $additionalKmRate=13;
   
    function calculateFare($kms, $hrs)
    {
        if($kms>$this->normalKms)
        {
            $fare=($this->normalKms*$this->normalKmRate)+(($kms-$this->normalKms)*$this->additionalKmRate);
            return $fare;
        }
        else
        {
            $fare=$kms*$this->normalKmRate;
            return $fare;
        }
    }
}//end class KmsFareStrategy

class FaringContext
{
    private $_fareStrategy;
   
    public function __construct(FareStrategy $fareStrategy)
    {
        $this->_fareStrategy=$fareStrategy;
    }
   
    public function getFare($kms,$hrs)
    {
        return $this->_fareStrategy->calculateFare($kms,$hrs);
    }
} //end class FaringContext

//main program

$context=new FaringContext(new HourlyFareStrategy());
$fare=$context->getFare(120,6);
echo $fare;

echo '<br />';

$context=new FaringContext(new KmsFareStrategy());
$fare=$context->getFare(120,6);
echo $fare;

?>

document.write() overwrites the entire page

document.write is a function which basically outputs whatever is given to it. But sometimes, improper usage may overwrite the entire page d...