Javascript/Ajax/JQuery « Intelligrape Groovy & Grails Blogs

Archive for the ‘ Javascript/Ajax/JQuery ’ Category

Simulating Static behaviour for Object Properties in JavaScript

Posted by on February 1st, 2013

We were facing problem at time of creating Static properties in any Object in JavaScript as there is not any direct method to create static properties. For example if we want to create a static property in an array object and we want it to be same for every other object without storing the property in objects by which object’s size will not increased and actual static property is stored in another place which is accessed by every object. In the process we created following method to get Static like behavior  in JavaScript.


(function () {
   var statics = {};
   Array.prototype.static = function (name, value) {
     if (!Boolean(value)) {
       return statics[name];
     }
     else {
       statics[name] = val;
     }
   }
 })(); //this method will create a static method in Array's prototype by calling which any object can get and set the value of static element.

 [].static("first","hello");
 [].static("out","this is static");
 var array = [10,20,30]
 console.log(array.static("first")); // prints "hello"
 console.log(array.static("out")); // prints "this is static"

Shreyance Jain
shreyance@intelligrape.com

Removing duplicate elements from an array using reduce() method

Posted by on February 1st, 2013

We can use reduce() method for removing duplicate elements from an array. For this, I have added a method called unique() in the prototype of Array class which make use of reduce(). Parameters in the reduce() method are a callback function and an optional initial value which could be anything like array, map etc.

Example:

Array.prototype.unique= function ()
{
  return this.reduce(function(previous, current, index, array)
   {
     previous[current.toString()+typeof(current)]=current;
     return array.length-1 == index ? Object.keys(previous).reduce(function(prev,cur)
       {
          prev.push(previous[cur]);
          return prev;
       },[]) : previous;
   }, {});
};

console.log([2,5,"4", 9,4,2,7,2].unique());

Output:

[ 2, 5, '4', 9, 4, 7 ]

Here what we have done is, defined a callback function in arguments of reduce()and initial value as an empty map. In that callback method,we are pushing unique key value pairs in the map thereby eliminating the duplicate elements and Object.keys() gives us all those unique keys. The nested reduce() method is for returning the key values in the form of an array.

This code will also handle the case, in which user enter a string and an integer with same value like- “4″ and 4 in this example. typeof() method is concatenated with current.toString() so that different type of values can be identified separately.

Try it on online node console www.node-console.com

Difference between call() and apply() method of JavaScript

Posted by on January 30th, 2013

Many people get confused with these two functions in JavaScript, most of the time people think that we can pass an object in apply() and access it with this which is not possible with the call() method. But that is not the case, let’s see an example which will make it more clear.

Using call() method:

(function sum(a,b,c) {
 var i, k=0;
 var num = arguments.length;
 for (i = 0; i < num; i++) {
 k+= arguments[i];
 }
 console.log(this.toString()); //prints body of the function passed i.e., test()
 console.log(k); //prints the sum in console
 this(); // this will call the test() function passed to sum
 return k; //returns sum

}).call(function test() {
 console.log(10); //prints 10 in console
 },10,100);

Using apply() method:

 (function sum(a,b) {
    var i, k=0;
    var num = arguments.length;
    for (i = 0; i<num; i++) {
        k+= arguments[i];
    }
    console.log(this.toString()); //prints body of the function passed i.e., test()
    console.log(k);               //prints the sum in console
    this();             // this will call the test() function passed to sum
    return k;           //returns sum

}).apply(function test() {
       console.log(10); //prints 10 in console
    },[10,100,200,200]);

Try it online at Node Console

So the basic difference between both the methods is that in call() method we have to pass comma separated arguments and in apply() method we have to pass an array. If you have any queries then do let me know in comments section below.

“this” keyword in JavaScript

Posted by on December 20th, 2012

There are four patterns of invocation in JavaScript:
1. The method invocation pattern.
2. The function invocation pattern.
3. The constructor invocation pattern.
4. The apply invocation pattern.

1. The Method Invocation Pattern:
When a function is stored as a property of an object, we call it a method. When a method is invoked, this is bound to that object.

var employee = { 
	salary: 25000, 
	increaseSalary: function(inc) { 
		this.salary += inc || 5000; 
	} 
}; 
employee.increaseSalary(); 
document.writeln(employee.salary);

2. The Function invocation Pattern:
When a function is not the property of an object, this is bound to the global object.

employee.setBonus = function () { 
	var that = this; 
	var countBonus = function (inc) { 
		that.salary += inc || that.salary*0.5; 
	}; 
	countBonus(); 
}; 
employee.setBonus(); 
document.writeln(employee.salary);

3. The Constructor Invocation Pattern:
If a function is invoked with a new prefix, then a new object will be created with a hidden link to the value of the function’s prototype member, and this will be bound to that new object. If the function was invoked with the new prefix and the return value is not an object, then this (the new object) is returned instead.

var Person = function (name) { 
	this.name = name; 
	this.getName = function () { 
		return this.name; 
	}; 
}; 
var newPerson = new Person("Amit Thakkar"); // this will refer to newly created Object.
document.writeln(newPerson.getName()); // Amit Thakkar

4. The Apply Invocation Pattern:
The apply method takes two parameters. The first is the value that should be bound to this. The second is an array of parameters.

var vigil = { 
	name:"Vigil" 
}; 
document.writeln(newPerson.getName.apply(vigil)); // Vigil

Here this is referring to vigil object and there will not be any run-time error even when the number of arguments and the number of parameters do not match. If there are too many argument values, the extra argument values will be ignored. If there are too less argument values, the undefined value will be substituted for the missing values. So here second parameter will be undefined.

Amit Kumar
amit.kumar@intelligrape.com
in.linkedin.com/in/amitkumar0110
twitter.com/amit_kumar0110
More Blogs by Me

Using Yahoo Query Language (YQL) to Monitor a Web Page

Posted by on October 27th, 2012

I keep on experimenting on new things. So this time I thought of experimenting on something which I can use in my daily routine. I regularly visit a deals webpage. So, I thought of making an android mobile app for my android device that can track the deals webpage and notifies me whenever a new deal is added.

The deals website does not provide any api or service by which I can accomplish this. The only way to accomplish this task was to scrap the deals page and monitor it for changes.(I know scraping of other’s webpage is illegal, but its OK if we are doing it for the purpose of learning.)

One possible solution was to use a server side script that scraps the web page and stores its hash. So, in subsequent scraps, if the hash changes, that means the web page content has been changed. If it is so, it returns true otherwise it returns false. We periodically call the script from the phonegap app using jquery ajax call. Thus, when true is returned, it notifies me of the change in web page content and hence I get to know that a new deal is posted. The only problem with this approach is, We need to have extra resources like a server of our own where our script is hosted.

The other solution is to use Yahoo Query Language(YQL). By this solution, we will neither need server of our own nor the script. We just need to write a Yahoo Query and pass it along with the url provided by Yahoo. It is executed on Yahoo server and result(which is the complete html of the page in json format) is returned. In my case, I have created Yahoo Query from the javascript code. The query returns the deals web page content in json format(we can configure it to return result in other formats like xml also). We can then calculate its hash using javascript and store it in phone’s local storage. In subsequent scraps we just need to compare the already stored hash with the newly calculated hash to know if the content has been changed or not. Quite Simple! Let’s see how to implement it in code.

        function poll(url) {
            var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + url + '"') + '&format=json&callback=?';
            jQuery.getJSON(yql, function (data) {
                if (data) {
                    var newHashCode = JSON.stringify(data.query.results.body).hashCode(); 
                    //implementation of hashCode method is shown later
                    var oldHashCode = window.localStorage.getItem("dataHash");
                    if (oldHashCode) {
                        if (!(oldHashCode == newHashCode)) {
                            alert(url + " changed!");
                        }
                    }
                    window.localStorage.setItem("dataHash", newHashCode);
                }
            });
        }

Here, we pass the url of the web page which we want to monitor to the poll() function.
The variable yql stores the entire url which contains the address of yahoo page which will be hit and our yahoo query containing the url of webpage which we want to monitor. YQL has a simple MySQL query like syntax.

'select * from html where url="' + url + '"'

means select the entire html page of specified url. We can be as specific as we want in selecting page content.

Here is the implementation of hashCode method. The following code will inject hashCode method to every string. You can find its explanation here.

String.prototype.hashCode = function () {
            var hash = 0;
            if (this.length == 0) return hash;
            for (i = 0; i < this.length; i++) {
                ch = this.charCodeAt(i);
                hash = ((hash << 5) - hash) + ch;
                hash = hash & hash;
            }
            return hash;
};

Final step is to call the poll() function periodically to test for changes in webpage.

$(function () {
            document.addEventListener("deviceready", onDeviceReady, true);
});

function onDeviceReady() {
            setInterval("poll('www.eample.com')", 300000);
}

Here we are calling the poll() function every 5 minutes and passing it the url to be monitored.
I just used one small query of YQL. It has a lot more to offer. You can explore it in more detail here.
You can see the content returned from a particular url by writing your query at YQL Console.

I found YQL quite interesting. Hope you will find it interesting too.

Regards

Raj Gupta
raj.gupta@intelligrape.com
@rajdgreat007

Setting count bubble in jQuery mobile Accordian Head

Posted by on October 18th, 2012

Sometimes we want to show count bubble in Accordion head that is different from the what jQuery mobile provides by default.

To add count bubble to Accordian head, we use following piece of code:

</pre>
<h2>Heading<span class="ui-li-count">10</span></h2>
<pre>

But it doesn’t give us the desired output and it looks like following:



If we want to set count bubble in Accordian head as per our use case , we have to add following css:


.ui-collapsible-heading .ui-btn-text{ display:block;}
.ui-collapsible-heading .ui-li-count { position: absolute; font-size: 11px; font-weight: bold; padding: .2em .5em; top: 50%; margin-top: -.9em; right: 10px;  border-radius: 1em 1em 1em 1em; background: linear-gradient(#FFFFFF, #F1F1F1) repeat scroll 0 0 #EEEEEE;  border: 1px solid #CCCCCC; color: #222222;font-weight: bold;text-shadow: 0 1px 0 #FFFFFF; }

After making the changes, our Accordian head looks like following:

Count Bubble after fix

Hope it helps.:)
Rajan Shergill
rajan@intelligrape.com
https://twitter.com/RajanShergill3

AngularJS : Implementing Routes And Multiple Views

Posted by on October 12th, 2012

We have already seen the concept of routes and multiple views in my previous blog. Now let’s see how to implement it in code.

To implement the concept of routing in AngularJS, we need to create modules. Inside a module config, we can define routes.

File : js/modules.js
angular.module('videoModule', []).
  config(['$routeProvider', function($routeProvider) {
  $routeProvider.
	when('/videos', {templateUrl: 'videoList.html',   controller: VideoController}).
	when('/videos/:videoId', {templateUrl: 'videoDetail.html', controller: VideoDetailController}).
      	otherwise({redirectTo: '/videos'});
}]);

Here ‘videoModule’ is the name of the module. Inside the config Api function, we inject the $routeProvider service, which is used to specify routes.
In each route, we have three things :
1. URL received (eg. ‘/videos’)
2. templateUrl – The html template to load for the url received
3. controller- The controller function that the templateUrl will use
Thus, the first route in the module defined in line 5 above states that, when the relative url ‘/videos’ is received, load the videoDetail.html template into the layout page(main.html) and use the properties and methods defined in the controller function VideoController.

Here is how our new module is used.

File : main.html
<!Doctype html>
<html ng-app="videoModule">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<script type="text/javascript" src="js/modules.js"></script>
<script type="text/javascript" src="js/controllers.js"></script>
<style type="text/css">
	li{list-style:none;float:left;padding:20px;}
	a{text-decoration:none;}
</style>
</head>
<body>
	<div ng-view></div>
</body>
</html>

We tell the application to use our new module by using ng-app=”videoModule”. Then we included the modules.js file and controllers.js(will show later) file by using the script tag. In body, we use ng-view attribute. It allows the appropriate template to be inserted into place when a particular url is received. The template to be inserted is decided by the routing that we have defined in our module. For example, as per routes defined by ‘videoModule’, if url ‘main.html/videos’ is received, template videoList.html is rendered inside the div containing the ng-view attribute.

We will also need two controller functions- VideoController and VideoDetailController. It’s a good idea to put all our controller functions in a separate file.

File : js/controllers.js
function VideoController($http,$scope){
	$http.get('videoList.json').success(function(videoList) {
		$scope.data = videoList;
	});
}

function VideoDetailController($scope,$routeParams,$http){
	$http.get('video'+$routeParams.videoId+'Detail.json').success(function(videoDetail) {
		$scope.data = videoDetail;
	});
}

The function VideoController() will fetch list of videos from a json file and assign that list to a local variable. The template videoList.html then uses that local variable to show list of videos.

Now, we need two templates –
1. videoList.html – To show the list of videos. When user clicks on any of the video, he will be taken to detail page for that video.
2. videoDetail.html – This will show details of the video

File : videoList.html
<div>
	<ul>	
		<li ng-repeat="datum in data">
			<a href="#/videos/{{datum.id}}">{{datum.name}}</a>
		</li>
	</ul>
</div>

File : videoDetail.html
<img ng-src="{{data.thumbUrl}}" />
<br />Name : {{data.name}}
<br />Id : {{data.id}} 
<br />Views : {{data.views}}
<br />Comments : {{data.comments}}

When the application starts, the page main.html is loaded. According to route definitions specified in videoModule, it will match the route ‘otherwise’ and thus user will be redirected to ‘main.html#/videos’. The corresponding template videoList.html will be loaded into main.html. Thus user will see a list of videos. When user clicks on a video, for example video with id 2, the resulting url will be ‘main.html#/videos/2′. This url corresponds to route ‘/videos/:videoId’, where the value of videoId=2. Thus the template ‘videoDetail.html’ is loaded into the main.html. The value of videoId can be retreived from route ‘/videos/:videoId’ by using the $routeParams.videoId as shown in the videoDetailController function. This function simply fetches data of the selected video from its json file and assigns it to a local variable, which is then used by the videoDetail.html template to show details of video. For example if videoId=2, then the json file from which data will be fetched is video2Detail.json.

That was just a small example illustrating concept of routes and multiple views in AngularJS. I will be back with more.

    Read Further on AngularJS Series

  1. AngularJS : A “Write Less Do More” JavaScript Framework
  2. AngularJS : Updating a Label Dynamically with User Input
  3. AngularJS : Adding Items to a JavaScript List and updating corresponding DOM Dynamically
  4. AngularJS : Text Suggestions
  5. AngularJS : Sorting objects on various attributes
  6. AngularJS : Fetching data from the server
  7. AngularJS : Multiple Views, Layout Template and Routing
  8. AngularJS : Implementing Routes And Multiple Views

Regards

Raj Gupta
raj.gupta@intelligrape.com
@rajdgreat007

Getting started with knockout.js

Posted by on September 26th, 2012

Recently, I learnt something very new e.g. Knockout.js. It is quite a advanced form of javascript. It just simplifies the structure of the javascipt in your application. It basically follows MVVM pattern(Model View View Model). It is quite fast and easy to use as comparison to jquery.

Some of it’s key features are :-

1. Declarative bindings
2. Automatic UI refresh
3. Free, open source (MIT license)
4. Pure JavaScript — works with any web framework
5. Supports all mainstream browsers
6. Templating(Quickly generate sophisticated, nested UIs as a function of your model data)

I’ll be covering the very basics of it in this article. In this, you need to deal with KO’s (Knockout objects). These are used to bind data with your model objects.

For using it add knockout-x.y.z.js in your application. Now, Moving towards how to use it :-
For example, Declaring model as below :-
E.g

  var firstModel = {
    empName: 'Gaurav',
    empWeight: 72
};

Then we need to create view for this e.g.

 Weight of emp <span data-bind="text: empName"> is <span data-bind="text: empWeight"> kgs.

Here KO wil bind the model object to these data-bind attribute and you will get the required details. But, this will not display the data as such, You need to activate the KO’s for binding the data.
e.g

<script>
  ko.applyBindings(firstModel);
</script>

After this you will be having the desired results.e.g Weight of emp Gaurav is 72 kgs.

So, You can see the declarative data binding of knockout.js. It is having lot more features. I’ll come up with all those.
Just give it a try. :)

Thanks & Regards,
Robin Sharma,
Intelligrape.
@er.robinsharma

AngularJS : Multiple Views, Layout Template and Routing

Posted by on September 26th, 2012

Need For Multiple Views

In all previous examples which i used on AngularJS, there was only a single view, i.e. the view displaying the list of youtube videos. Now let’s say we wan’t to display a detail page when a video is clicked. On the detail page, we will display more details about the video like author name, comments etc. In this blog, we will see, how we can use the concept of multiple views in AngularJS.

Layout Template
When we talk about multiple views, we will definitely come across various resources that are used by all the views. For example the AngularJS library will be used by all the views. Thus, we collect all such resources which will be shared by all the views and put them in a file called “layout template”. Grails users can think it as equivalent to main.gsp file.

Routing
In AngularJS, routing is provided by $routeProvider which provides the $route service. We use this service to wire the requested url with the controller and view. For a particular url, we can specify which controller and corresponding view would be used by using this service.

How services are injected?
In AngularJS, there are module definitions that contain service providers. These providers are responsible for instantiating the services. When an application starts, all the AngularJS modules are loaded and all service providers contained in these modules are registered. When we ask for a service(eg. $route) by mentioning it as an argument in the controller function, AngularJS delegates our request to its dependency injector. The injector then inject the requested service into the controller function after it is instantiated by the corresponding service provider.

In future blogs, we will see how these features are implemented in code to support multiple views in AngularJS.
Have Fun. :)

    Read Further on AngularJS Series

  1. AngularJS : A “Write Less Do More” JavaScript Framework
  2. AngularJS : Updating a Label Dynamically with User Input
  3. AngularJS : Adding Items to a JavaScript List and updating corresponding DOM Dynamically
  4. AngularJS : Text Suggestions
  5. AngularJS : Sorting objects on various attributes
  6. AngularJS : Fetching data from the server
  7. AngularJS : Multiple Views, Layout Template and Routing
  8. AngularJS : Implementing Routes And Multiple Views

Regards
Raj Gupta
raj.gupta@intelligrape.com
@rajdgreat007

Tags:

JavaScript: Currying in JavaScript

Posted by on September 25th, 2012

Hi,

 

Currying is a very simple and useful concept in JavaScript. Here we can set the context of the function to any object or variable.

 

So let us study this concept using the practical examples and code as follows:

//Let us first create a function "curry"
function curry(thisObject, func){
    return function(){
          return func.apply(thisObject, arguments);
   };
}

//Lets make a function in which we have delegated the this arg. Such that this function is executed in the context of some other object.
var myCurriedFunction = curry("This is a string object, it will be the 'this' object", function(){
    alert(this);
});

//Now lets call the function:
myCurriedFunction(); //will alert "This is a string object, it will be the 'this' object"

 

 

Hope it Helps!
Kushal Likhi