Sunday, September 4, 2011

Extremely Flexible jQuery Color Picker – ExColor

Extremely Flexible jQuery Color Picker – ExColor:

ExColor is a jQuery plugin for enabling users to select colors from a Photoshop-like color picker.

It is attached to <input> fields and can be activated by simply calling a single-line function.

The color picker's design is so flexible as every element used in the picker comes with 10 different design options to select from.

Also, a web-based editor helps choosing each design element, their colors and various other options to create a unique look.

jQuery ExColor Color Picker Plugin

Special Downloads: Ajaxed Add-To-Basket Scenarios With jQuery And PHP Free Admin Template For Web Applications jQuery Dynamic Drag’n Drop ScheduledTweets

How to Create Automatic Image Montage with jQuery

How to Create Automatic Image Montage with jQuery:

Arranging images in a montage like fashion can be a challenging task when considering certain constraints, like the window size when using fullscreen, the right image number to fill all the available space or also the size of the images in use.

With Automatic Image Montage with jQuery you can automatically create a montage, either for a liquid container or a fixed size container (including fullscreen), with the option to fill all the gaps.

automatic-image-montage

Requirements: jQuery Framework Demo: http://tympanus.net/Development/AutomaticImageMontage/ License: License Free

Shuffle Letters Effect: a jQuery Plugin

Shuffle Letters Effect: a jQuery Plugin:

In this short tutorial we will be making a jQuery plugin that will shuffle the text content of any DOM element – an interesting effect that can be used in headings, logos and slideshows.

The Code

The first step is to write the backbone of our jQuery plugin. We will place the code inside a self-executing anonymous function, and extend $.fn.

assets/js/jquery.shuffleLetters.js

(function($){

	$.fn.shuffleLetters = function(prop){

		// Handling default arguments
		var options = $.extend({
			// Default arguments
		},prop)

		return this.each(function(){
			// The main plugin code goes here
		});
	};

	// A helper function

	function randomChar(type){
		// Generate and return a random character
	}

})(jQuery);

Next we will turn our attention to the randomChar() helper function. It will take a type argument (one of “lowerLetter“, “upperLetter” or “symbol“) and return a random character.

function randomChar(type){
	var pool = "";

	if (type == "lowerLetter"){
		pool = "abcdefghijklmnopqrstuvwxyz0123456789";
	}
	else if (type == "upperLetter"){
		pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	}
	else if (type == "symbol"){
		pool = ",.?/\\(^)![]{}*&^%$#'\"";
	}

	var arr = pool.split('');
	return arr[Math.floor(Math.random()*arr.length)];
}

We could have used a single pool string for all types of characters, but this will do for a better effect.

The Plugin In Action

The Plugin In Action

Now lets write the body of the plugin!

$.fn.shuffleLetters = function(prop){

	var options = $.extend({
		"step"	: 8,	// How many times should the letters be changed
		"fps"	: 25,	// Frames Per Second
		"text"	: "" 	// Use this text instead of the contents
	},prop)

	return this.each(function(){

		var el = $(this),
			str = "";

		if(options.text) {
			str = options.text.split('');
		}
		else {
			str = el.text().split('');
		}

		// The types array holds the type for each character;
		// Letters holds the positions of non-space characters;

		var types = [],
			letters = [];

		// Looping through all the chars of the string

		for(var i=0;i<str.length;i++){

			var ch = str[i];

			if(ch == " "){
				types[i] = "space";
				continue;
			}
			else if(/[a-z]/.test(ch)){
				types[i] = "lowerLetter";
			}
			else if(/[A-Z]/.test(ch)){
				types[i] = "upperLetter";
			}
			else {
				types[i] = "symbol";
			}

			letters.push(i);
		}

		el.html("");			

		// Self executing named function expression:

		(function shuffle(start){

			// This code is run options.fps times per second
			// and updates the contents of the page element

			var i,
				len = letters.length,
				strCopy = str.slice(0);	// Fresh copy of the string

			if(start>len){
				return;
			}

			// All the work gets done here
			for(i=Math.max(start,0); i < len; i++){

				// The start argument and options.step limit
				// the characters we will be working on at once

				if( i < start+options.step){
					// Generate a random character at this position
					strCopy[letters[i]] = randomChar(types[letters[i]]);
				}
				else {
					strCopy[letters[i]] = "";
				}
			}

			el.text(strCopy.join(""));

			setTimeout(function(){

				shuffle(start+1);

			},1000/options.fps);

		})(-options.step);

	});
};

The plugin will take either the contents of the DOM element it was called on, or the text property of the object passed as an argument. It then splits the string into characters and determines the type of each one. The shuffle function then uses setTimeout() to call itself and randomize the string, updating the DOM element on each step.

When you head on to the demo you will see that you are able to type your own text and test it out. Here is how I did it:

assets/js/script.js

$(function(){

	// container is the DOM element;
	// userText is the textbox

	var container = $("#container")
		userText = $('#userText');

	// Shuffle the contents of container
	container.shuffleLetters();

	// Bind events
	userText.click(function () {

	  userText.val("");

	}).bind('keypress',function(e){

		if(e.keyCode == 13){

			// The return key was pressed

			container.shuffleLetters({
				"text": userText.val()
			});

			userText.val("");
		}

	}).hide();

	// Leave a 4 second pause

	setTimeout(function(){

		// Shuffle the container with custom text
		container.shuffleLetters({
			"text": "Test it for yourself!"
		});

		userText.val("type anything and hit return..").fadeIn();

	},4000);

});

The fragment above also shows how you can use the plugin and the custom text parameter.

Pop From Top Notification

Pop From Top Notification:

Have you seen that design pattern where a notification pops down from the top of the browser window, then slides away? We can rock that in pure CSS.

View Demo Download Files

We'll just make a div:

<div id="note">
  You smell good.
</div>

Then we'll style it and put it on the top of the screen:

#note {
  position: absolute;
  z-index: 101;
  top: 0;
  left: 0;
  right: 0;
  background: #fde073;
  text-align: center;
  line-height: 2.5;
  overflow: hidden;
  -webkit-box-shadow: 0 0 5px black;
  -moz-box-shadow:    0 0 5px black;
  box-shadow:         0 0 5px black;
}

Let's animate it

With a keyframe animation, we can "hide" it above the browser window and bring it down for a short while:

@-webkit-keyframes slideDown {
  0%, 100% { -webkit-transform: translateY(-50px); }
  10%, 90% { -webkit-transform: translateY(0px); }
}
@-moz-keyframes slideDown {
  0%, 100% { -moz-transform: translateY(-50px); }
  10%, 90% { -moz-transform: translateY(0px); }
}

Er... let's consider other browsers quick

But let's consider browsers that don't have transforms and animations for a second. For those, we'd want to default to just showing the notification bar at all times, with the ability to dismiss it.

So we'll make a custom build of Modernizr to test for transforms and animations, load that up, then we can write CSS to test for those features and only fire off the animations if we're in a browser that supports them.

.cssanimations.csstransforms #note {
  -webkit-transform: translateY(-50px);
  -webkit-animation: slideDown 2.5s 1.0s 1 ease forwards;
  -moz-transform:    translateY(-50px);
  -moz-animation:    slideDown 2.5s 1.0s 1 ease forwards;
}

The 1.0s in there is the delay before the animation runs. Best to wait a minute to make the notification more noticeable.

Now we'll add a close button into the HTML:

<div id="note">
  You smell good. <a id="close">[close]</a>
</div>

And a tiny bit of JavaScript at the bottom of the page so that the non-supporting browsers can close the notification.

<script>
close = document.getElementById("close");
close.addEventListener('click', function() {
 note = document.getElementById("note");
 note.style.display = 'none';
}, false);
</script>

Look ma, no libraries.

Since we don't need that close button in browsers that do support the animations, we'll hide it:

.cssanimations.csstransforms #close {
display: none;
}

For the record, this should work OK on mobile browsers (tested Mobile Safari). There is no fixed positioning used here, only absolute, and that's going to be less of a problem moving forward anyway (might want to consider making it fixed so even if the user is scrolled down the page they'll get it).

Enjoy

View Demo Download Files

Pop From Top Notification is a post from CSS-Tricks

Thursday, November 18, 2010

Signature Pad – A jQuery Plugin For Accepting Signatures Online

Signature Pad – A jQuery Plugin For Accepting Signatures Online:

Signature Pad is a jQuery plugin which transforms an HTML form into a canvas where users can draw their signatures.

It has 2 modes:

  • TypeIt mode where the user’s signature is automatically generated as HTML text and styled with @font-face from the input field where the name is typed.
  • DrawIt mode where the users can draw their signatures on the canvas element.

Signature Pad jQuery Plugin

The signature submitted is stored as a JSON array which makes re-generating it possible.

And, the plugin doesn't need to be used as its name suggests, you can ask users to draw anything and store it easily.

Special Downloads:

Related posts:

Parse RSS Feeds and Display Images with Lumebox

Parse RSS Feeds and Display Images with Lumebox:

The Lumebox is an Open-Source Lightbox clone written as a JavaScript jQuery plugin with a few added features. One of the main features is that it can parse RSS feeds just as easily as displaying images.

The Lumebox also searches the post or page for links leading to images (and RSS-feeds) and opens them in a popup instead of following them. The Lumebox was written using jQuery 1.4.3. The Lumebox plugin is released under the GNU GPL.

lumebox

Requirements: jQuery Framework Demo: http://anders.zakrisson.se/projects/lumebox/ License: GPL License

Related Posts

Wednesday, September 29, 2010

Ajax-Enable Standard Websites: jQuery Ajaxy

Ajax-Enable Standard Websites: jQuery Ajaxy

jQuery Ajaxy is a plugin which enables us to convert a standard website into an Ajaxed one with no hassles.

It has built-in support for URL hash changes, AJAX form submits or AJAX links.

jQuery Ajaxy

The usage of the plugin is so easy: the ordinary links and forms are upgraded into Ajax requests by just adding a CSS classname.

As the URL addresses change on every request, users can browse with browser back-forward buttons and URLs will stay SEO-friendly.

The plugin also gives the ability to control your web applications state manually through your code for advanced circumstances.

Special Downloads:

Related posts

Orbit – A Slick jQuery Image Slider Plugin

Orbit – A Slick jQuery Image Slider Plugin

Most jQuery image sliders hover at around 8 kbs for minified versions, and around 15kbs or more for uncompressed development files, but what if there was a way to keep the simple fades, slides, and a couple other nifty bits, but strip the bloated and corny diagonal-cross fades or spiral dissolves.

Orbit is a killer jQuery plugin that lets you create a simple, effective and beautiful slider for images of any size, and even includes some parameters for making awesome captions and a sweet timer.

slick-gallery

Requirements: jQuery Framework Demo: http://www.zurb.com/playground/jquery_image_slider_plugin License: MIT License

Friday, September 17, 2010

Easy jQuery Image Cropping with imgAreaSelect

Easy jQuery Image Cropping with imgAreaSelect

imgAreaSelect is a jQuery plugin for selecting a rectangular area of an image. It allows web developers to easily implement image cropping functionality, as well as other user interface features, such as photo notes like those on Flickr.

imgAreaSelect is highly configurable and customizable with CSS styling. Keyboard support for moving and resizing the selection. It works in all major browsers, including Firefox 2+, Opera 9.5+, Google Chrome, Safari 3+, and Internet Explorer 6+.

image-crop

Requirements: jQuery Framework Demo: http://odyniec.net/projects/imgareaselect/ License: MIT, GPL License

Google Powered Site Search with jQuery

Google Powered Site Search with jQuery

By far one of the most requested features by Tutorialzine’s readers, is building a site-wide search. One way to do it, is to build it yourself from the ground up. That is, to use a server-side language like PHP and run search queries on your database, displaying the results to the user.

Another way is to use the services of the one search engine that already knows everything about everyone. Yep, you guessed it. In this tutorial we are using Google’s AJAX Search API, to create a custom search engine, with which you can search for web results, images, video and news items on your site.

The HTML

Lets start with the HTML markup. From the new HTML5 doctype, we move on to defining the title of the document and including the stylesheet to the head section of the page.

search.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Google Powered Site Search | Tutorialzine Demo</title>

<link rel="stylesheet" type="text/css" href="styles.css" />

</head>
<body>

<div id="page">

  <h1>Google Powered Site Search</h1>

  <form id="searchForm" method="post">
      <fieldset>

          <input id="s" type="text" />

          <input type="submit" value="Submit" id="submitButton" />

          <div id="searchInContainer">
              <input type="radio" name="check" value="site" id="searchSite" checked />
              <label for="searchSite" id="siteNameLabel">Search</label>

              <input type="radio" name="check" value="web" id="searchWeb" />
              <label for="searchWeb">Search The Web</label>
          </div>

          <ul class="icons">
              <li class="web" title="Web Search" data-searchType="web">Web</li>
              <li class="images" title="Image Search" data-searchType="images">Images</li>
              <li class="news" title="News Search" data-searchType="news">News</li>
              <li class="videos" title="Video Search" data-searchType="video">Videos</li>
          </ul>

      </fieldset>
  </form>

  <div id="resultsDiv"></div>

</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>

In the body section, we have the main container element – the #page div. The form inside it, acts not only as a search form, but as a container as well. It has CSS3 rounded corners and a darker background color applied to it, which makes it more easily distinguishable from the rest of the page.

Inside the form is the text input box, after which comes the radio group for searching on the current site / the web, and the four search type icons, organized as an unordered list. Lastly we include jQuery and our scripts.js, which is discussed in the last step of this tutorial.

Google Powered Site Search

Google Powered Site Search

The CSS

The CSS styles reside in styles.css. Only the more interesting parts are included here.

styles.css – Part 1

#searchForm{
/* The search form. */
background-color:#4C5A65;
padding:50px 50px 30px;
margin:80px 0;
position:relative;

-moz-border-radius:16px;
-webkit-border-radius:16px;
border-radius:16px;
}

fieldset{
border:none;
}

#s{
/* The search text box. */

border:none;
color:#888888;
background:url('img/searchBox.png') no-repeat;

float:left;
font-family:Arial,Helvetica,sans-serif;
font-size:15px;
height:36px;
line-height:36px;
margin-right:12px;
outline:medium none;
padding:0 0 0 35px;
text-shadow:1px 1px 0 white;
width:385px;
}

As mentioned above, the form’s functions are not limited to only submitting data, but also to act as a regular container element. This keeps the markup on the page to a minimum, while still providing rich functionality.

The text input box, #s, is styled with a background image and padding, so that the text does not cover the magnifying glass.

styles.css – Part 2

.icons{
list-style:none;
margin:10px 0 0 335px;
height:19px;
position:relative;
}

.icons li{
background:url('img/icons.png') no-repeat;
float:left;
height:19px;
text-indent:-999px;
cursor:pointer;
margin-right:5px;
}

/* Styling each icon */

li.web{ width:15px;}
li.web.active,
li.web:hover{ background-position:left bottom;}

li.images{ width:22px; background-position:-18px 0;}
li.images.active,
li.images:hover{ background-position:-18px bottom;}

li.news{ width:14px; background-position:-44px 0;}
li.news.active,
li.news:hover{ background-position:-44px bottom;}

li.videos{ width:17px; background-position:right 0;}
li.videos.active,
li.videos:hover{ background-position:right bottom;}

span.arrow{
/* The little arrow that moves below the icons */

width:11px;
height:6px;
margin:21px 0 0 5px;
position:absolute;
background:url('img/arrow.png') no-repeat;
left:0;
}

/* The submit button */

#submitButton{
background:url('img/buttons.png') no-repeat;
width:83px;
height:36px;
text-indent:-9999px;
overflow:hidden;
text-transform:uppercase;
border:none;
cursor:pointer;
}

#submitButton:hover{
background-position:left bottom;
}

In the fragment above, you can see that the search type icons all share a single background image. It is offset with background position so the appropriate part of it is shown, for both the default and the hover state.

The same technique is used for the submit button. Its text is hidden with a negative text-indent, and buttons.png is shown as its background, with the top part of the image visible by default and the bottom on hover.

styles.css – Part 3

/* Web & news results */

.webResult{ text-shadow:1px 1px 0 #586a75;margin-bottom:50px;}
.webResult h2{
background-color:#5D6F7B;
font-size:18px;
font-weight:normal;
padding:8px 20px;

/* Applying CSS3 rounded corners */
-moz-border-radius:18px;
-webkit-border-radius:18px;
border-radius:18px;
}
.webResult h2 b{ color:#fff; }
.webResult h2 a{ color:#eee;border:none;}
.webResult p{ line-height:1.5;padding:15px 20px;}
.webResult p b{ color:white;}
.webResult > a{ margin-left:20px;}

/* Image & video search results */

.imageResult{
float:left;
height:170px;
margin:0 0 20px 40px;
text-align:center;
width:150px;
}
.imageResult img{ display:block;border:none;}
.imageResult a.pic{
border:1px solid #fff;
outline:1px solid #777;
display:block;
margin:0 auto 15px;
}

/* The show more button */

#more{
width:83px;
height:24px;
background:url('img/more.png') no-repeat;
cursor:pointer;
margin:40px auto;
}

#more:hover{
background-position:left bottom;
}

In the last fragment, we style the results. Although we show four types of search results – web, news, images and video, these are only styled by the two classes above – .webResult and .imageResult. Lastly, we style the #more button, which is dynamically added to the page by jQuery depending on the results returned by Google.

jQuery & JSONp Google API Site Search

jQuery & JSONp Google API Site Search

The jQuery

As mentioned in the beginning, this app uses Google’s AJAX Search API. Google do provide their own JavaScript library, but if you choose to use it, you are constrained with their UI. While functional, it may not be what you want to offer your visitors. This is why, in this tutorial, we are using the “naked version” by issuing JSONp calls with jQuery directly to their API.

Before we start discussing the jQuery code, lets have a glimpse at what data Google makes available to us, after we run a search with the API.

Sample Result From Google’s API

{
  "GsearchResultClass": "GwebSearch",
  "unescapedUrl": "http://tutorialzine.com/2010/02/html5-css3-website-template/",
  "url": "http://tutorialzine.com/2010/02/html5-css3-website-template/",
  "visibleUrl": "tutorialzine.com",
  "cacheUrl": "http://www.google.com/search?q=cache:_NSLxH-cQMAJ:tutorialzine.com",
  "title": "Coding a <b>CSS3</b> & <b>HTML5</b> One-Page Website Template | Tutorialzine",
  "titleNoFormatting": "Coding a CSS3 & HTML5 One-Page Website Template | Tutorialzine",
  "content": "Feb 16, 2010 <b>...</b> Here we are using the new version of HTML.."
}

A search run through their API would return the same set of result that you’d normally get directly from their site. The difference is that here we get a JavaScript array populated with objects like the one above. Each of these objects holds the type of search, a title, a URL, and text from the page that contains the terms we are searching for.

Using the GsearchResultClass property, we can determine how to display the information, as you will see in a moment. This search app supports only web, image, news and video searches but you can see a complete list of the available types of searches in Google’s AJAX search documentation.

script.js – Part 1

$(document).ready(function(){

var config = {
 siteURL  : 'tutorialzine.com', // Change this to your site
 searchSite : true,
 type  : 'web',
 append  : false,
 perPage  : 8,   // A maximum of 8 is allowed by Google
 page  : 0    // The start page
}

// The small arrow that marks the active search icon:
var arrow = $('<span>',{className:'arrow'}).appendTo('ul.icons');

$('ul.icons li').click(function(){
 var el = $(this);

 if(el.hasClass('active')){
  // The icon is already active, exit
  return false;
 }

 el.siblings().removeClass('active');
 el.addClass('active');

 // Move the arrow below this icon
 arrow.stop().animate({
  left  : el.position().left,
  marginLeft : (el.width()/2)-4
 });

 // Set the search type
 config.type = el.attr('data-searchType');
 $('#more').fadeOut();
});

// Adding the site domain as a label for the first radio button:
$('#siteNameLabel').append(' '+config.siteURL);

// Marking the Search tutorialzine.com radio as active:
$('#searchSite').click();

// Marking the web search icon as active:
$('li.web').click();

// Focusing the input text box:
$('#s').focus();

$('#searchForm').submit(function(){
 googleSearch();
 return false;
});

$('#searchSite,#searchWeb').change(function(){
 // Listening for a click on one of the radio buttons.
 // config.searchSite is either true or false.

 config.searchSite = this.id == 'searchSite';
});

The config object holds general configuration options, such as the site URL, a start page (used in the pagination), and the default type of search (a web search). Google only allows us to select 8 results at a time, which is enough for web searches, but not so for images. Lets hope that Google will raise this limit in the future.

When the form is submitted, jQuery calls our googleSearch() function, which you can see below.

To integrate the search into your website, just replace the siteURL property of the config object, with that of your own site URL.

script.js – Part 2

 function googleSearch(settings){

 // If no parameters are supplied to the function,
 // it takes its defaults from the config object above:

 settings = $.extend({},config,settings);
 settings.term = settings.term || $('#s').val();

 if(settings.searchSite){
  // Using the Google site:example.com to limit the search to a
  // specific domain:
  settings.term = 'site:'+settings.siteURL+' '+settings.term;
 }

 // URL of Google's AJAX search API
 var apiURL = 'http://ajax.googleapis.com/ajax/services/search/'+settings.type+
     '?v=1.0&callback=?';
 var resultsDiv = $('#resultsDiv');

 $.getJSON(apiURL,{
  q : settings.term,
  rsz : settings.perPage,
  start : settings.page*settings.perPage
 },function(r){

  var results = r.responseData.results;
  $('#more').remove();

  if(results.length){

   // If results were returned, add them to a pageContainer div,
   // after which append them to the #resultsDiv:

   var pageContainer = $('<div>',{className:'pageContainer'});

   for(var i=0;i<results.length;i++){
    // Creating a new result object and firing its toString method:
    pageContainer.append(new result(results[i]) + '');
   }

   if(!settings.append){
    // This is executed when running a new search,
    // instead of clicking on the More button:
    resultsDiv.empty();
   }

   pageContainer.append('<div class="clear"></div>')
       .hide().appendTo(resultsDiv)
       .fadeIn('slow');

   var cursor = r.responseData.cursor;

   // Checking if there are more pages with results,
   // and deciding whether to show the More button:

   if( +cursor.estimatedResultCount > (settings.page+1)*settings.perPage){
    $('<div>',{id:'more'}).appendTo(resultsDiv).click(function(){
     googleSearch({append:true,page:settings.page+1});
     $(this).fadeOut();
    });
   }
  }
  else {

   // No results were found for this search.

   resultsDiv.empty();
   $('<p>',{
    className : 'notFound',
    html  : 'No Results Were Found!'
   }).hide().appendTo(resultsDiv).fadeIn();
  }
 });
}

The googleSearch() function sends a JSONp request to Google’s API, generates the markup of the results, and inserts it into the #resultsDiv div. It can either empty that div beforehand (if we are making a fresh search) or append the results (this happens when we click the “More” button).

Both paths follow the same logic – a new .pageContainer div is created for each set of results (this div has a bottom border, so it is easier to distinguish one page of results from the next) and an object of the result class (you can see this class below), is initialized and its markup is appended to the pageContainer.

Web Search Results

Web Search Results

script.js – Part 3

 function result(r){

 // This is class definition. Object of this class are created for
 // each result. The markup is generated by the .toString() method.

 var arr = [];

 // GsearchResultClass is passed by the google API
 switch(r.GsearchResultClass){

  case 'GwebSearch':
   arr = [
    '<div class="webResult">',
    '<h2><a href="',r.url,'">',r.title,'</a></h2>',
    '<p>',r.content,'</p>',
    '<a href="',r.url,'">',r.visibleUrl,'</a>',
    '</div>'
   ];
  break;
  case 'GimageSearch':
   arr = [
    '<div class="imageResult">',
    '<a href="',r.url,'" title="',r.titleNoFormatting,
    '" class="pic" style="width:',r.tbWidth,'px;height:',r.tbHeight,'px;">',
    '<img src="',r.tbUrl,'" width="',r.tbWidth,'" height="',
    r.tbHeight,'" /></a>','<div class="clear"></div>',
    '<a href="',r.originalContextUrl,'">',r.visibleUrl,'</a>',
    '</div>'
   ];
  break;
  case 'GvideoSearch':
   arr = [
    '<div class="imageResult">',
    '<a href="',r.url,'" title="',r.titleNoFormatting,'
    " class="pic" style="width:150px;height:auto;">',
    '<img src="',r.tbUrl,'" width="100%" /></a>',
    '<div class="clear"></div>','<a href="',
    r.originalContextUrl,'">',r.publisher,'</a>',
    '</div>'
   ];
  break;
  case 'GnewsSearch':
   arr = [
    '<div class="webResult">',
    '<h2><a href="',r.unescapedUrl,'">',r.title,'</a></h2>',
    '<p>',r.content,'</p>',
    '<a href="',r.unescapedUrl,'">',r.publisher,'</a>',
    '</div>'
   ];
  break;
 }

 // The toString method.
 this.toString = function(){
  return arr.join('');
 }
}
});

This function acts as the constructor of the result class. It takes the object which was returned from Google’s API (which you saw at the beginning of the jQuery step) and initializes arr according to the value of GsearchResultClass. Notice that arr is assigned an array instead of a string. This is a bit faster than multiple concatenations of a string together.

At the bottom of the class, we have the toString() method. It basically calls the array’s internal join method, turning it into a string. toString() is a magical method, which is implicitly called on line 38 of script.js – Part 2.

With this our own Google Powered Search Engine is complete!

Conclusion

Configuring this app to search your site is really simple. Just change the siteURL property of the config object in script.js. There are many ways how you can improve this example. Not all the data that comes from Google is currently displayed. You could also use the filetype: search modifier to look for specific types of files.