Handling Thickbox and Facebox jQuery plugins with LiveQuery for AJAX

I found an interesting JQuery plugin to code painless AJAX modules.

It’s called LiveQuery which binds events/callbacks/plugins to the elements, will be loaded into DOM through AJAX requests.

Where to use LiveQuery?

We know that jQuery has most famous ready(); method that executes after DOM completion. So, what’s the point of LiveQuery?

Okay, let’s take an example.

We need to load some healthy amount of HTML elements using AJAX which includes hyperlinks, table, forms etc. and then we want to bind events to them. How would we achieve that?

Simple solution would be write a callback function.

$.get('ajax_url',serialize_params_map,function(data){
// manipulate data variable;
// execute callback to bind events;
});

We may think, it would be great we don’t have to attach manual callback after each and every ajax call and should be simple as

$(document).ready(
  function(){
  //execute callback to bind events;
  }
);

To understand my point more clearly, take a practical example.

  1. ThickBox Problem
    // thickbox.js (jQuery plugin)
    //on page load call tb_init
    $(document).ready(
      function(){
        //pass where to apply thickbox
        tb_init('a.thickbox, area.thickbox, input.thickbox');
        imgLoader = new Image();// preload image
        imgLoader.src = tb_pathToImage;
      }
    );

    Look at line6.
    It only executes one time when DOM get completed.

    What If we need to bind thickbox to new elements, inserted through AJAX request?

    One solution could be call tb_init(’..’) as “callback function” to every AJAX request

    $.get('ajax_url',serialize_params_map,function(data){
    // manipulate data
      tb_init('a.thickbox, area.thickbox, input.thickbox');
    //pass where to apply thickbox
    });

    or use LiveQuery ONLY ONCE i.e.

    Thickbox Demo

    $('a.thickbox').livequery(
      function(){
        tb_init('a.thickbox');
      }
    );

    So, what would above code do?
    It simulates $(document).ready(); function. Also observers for any “set of newly matched elements” inserted in DOM. So whenever “AJAX request” insert new elements in DOM, above function will bind thickbox to them.

  2. FaceBox Problem
    The same case with facebox… and could be with many more jquery plugins. To make facebox work properly with post loaded HTML elements, use…

    jQuery(document).ready(function() {
    $('a[rel*=facebox]').livequery(
      function(){
        $(this).facebox();
      });
    });

    instead of

    jQuery(document).ready(
      function($) {
        $('a[rel*=facebox]').facebox();
      }
    );

The conclusion is…

jQuery + painless AJAX modules => efficient use of LiveQuery.

Python coded GoogleMini SAYT (Search As You Type) run on Google App Engine

One of my client uses GoogleMini for search infrastructure. His entire site was coded in classic asp. I was hired for making some XSLT changes in frontend. GSA 6.0 has built in facility for query auto-completing. But googlemini doesn’t has such facility. So, Google Staff introduce SAYT (search as you type autocomplete) for googlemini and my client asked me to integrate SAYT with his googlemini. Google Mini SAYT is nothing but AJAX autocomplete script written in Javascript and PHP.

My client’s dedicated server is always heavily loaded with daily millions of page-views. So, SAYT was a kind of burden on his server by putting extra load as user keep sending request on every key stroke. Luckily I found Google App Engine, cloud computing infrastructure way cheaper as you can consume 1GB daily bandwidth free of cost. So then I converted GoogleMini SAYT php code into python and created a simple app engine code so we can host and run SAYT from Google Cloud Infrastructure.

# original file search-responder.php is Copyright (C) 2006 Google Inc. under Apache License, Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0

import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
from django.utils import simplejson

class RPCHandler(webapp.RequestHandler):

  def get(self):
    self.response.headers["Content-Type"] = "text/html; charset=UTF-8"
    self.response.headers["Cache-Control"] = "no-cache"
    self.response.headers.add_header("Expires", "Thu, 01 Dec 1994 16:00:00 GMT")
    # Get the data and the query
    self.data = self.GetData()
    self.query = self.request.get('query').strip().lower()
    # Build Response
    self.responseout = {}
    self.responseout["query"] = self.query
    self.responseout["results"] = self.GetResults()
    if len(self.responseout["results"]) == 1:
      self.responseout["autocompletedQuery"] = self.responseout['results'][0]['name']
    # Output response
    self.response.out.write("searchAsYouType.handleAjaxResponse(")
    self.response.out.write(simplejson.dumps(self.responseout))
    self.response.out.write(");")

  def GetData(self):
    data = []
    data_index = 1
    filedata = open("test-data.txt")
    for line in filedata:
      record = line.strip().split("|")
        if len(record) == 4:
          data.append(record)
    return data

  def GetResults(self):
    results = []
    data = self.data
    queryLength = len(self.query)
    for record in data:
      if record[0].lower().find(self.query,0,queryLength) != -1:
        result = {}
        result['name'] = record[0]
        result['type'] = record[1]
        result['content'] = record[2]
        result['moreDetailsUrl'] = record[3]
        result['style'] = 'expanded' if self.query == record[0].lower() else 'normal'
        results.append(result)
    return results

def main():
  application = webapp.WSGIApplication([('/rpc*', RPCHandler)], debug=True)
  util.run_wsgi_app(application)

if __name__ == '__main__':
main()

Save this code as search-responder.py file, and rest of work is similar to existing setup. Now to run this code from Google App Engine and modify your googlemini custom xslt frontend by these steps.

Note the step:-

<script src="http://localhost/sayt/search-as-you-type.js"></script>

<script>searchAsYouType.initialize(document.getElementById('sayt'), true);</script>

Modify with them with

<script src="http://your-app-engine-path/static_dir/search-as-you-type.js"></script>

<script>searchAsYouType.initialize(document.getElementById('sayt'), true);</script>

Save the Frontend XSLT and you are done.

Google WebMaster API (PHP) for submitting dynamic sitemaps

My New Photo Site has approximately 475 albums. Each album has manually coded RSS feeds. Now submitting that much RSS feeds, one by one, into Google Webmaster Tool’s interface is quiet painful.

So, I digged into Google’s GDATA API Code provided by Zend Framework. It’s very easy to submit google sitemap using php coding.

Steps:-
(1) Download Zend FrameWork
(2) Download GData API
(3) Write the code written @ end of the post into your php file & save it on path /demos/Zend/Gdata & run it.

Google needs RDF data tobe submitted to  https://www.google.com/webmasters/tools/feeds/www.yoursite.com/sitemap using POST request.

RDF format for submitting sitemaps is,

<atom:entry>
<atom:id>http://www.example.com/sitemap-index.xml</atom:id>
<atom:category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/webmasters/tools/2007#sitemap-regular'/>
<wt:sitemap-type>WEB</wt:sitemap-type>
</atom:entry>

You need to change http://www.yoursite.com/sitemap.xml with your sitemap location dynamically using php.

Above XML was creating some parsing errors before submitting POST request because it has no name-space.

So, I googled some different xml for submitting SiteMap,

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:wt="http://schemas.google.com/webmasters/tools/2007">
<id>http://www.yoursite.com/sitemap.xml</id>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/webmasters/tools/2007#sitemap-regular'/>
<wt:sitemap-type>WEB</wt:sitemap-type>
</entry>

So final php code became.

<?php

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Gapps');

// Provide Google Account Information
$email = 'youremail@gmail.com';
$passwd = 'xxxxxxxx';
$service      = 'sitemaps';

// Try to connect
try {
$client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, $service);
} catch (Zend_Gdata_App_CaptchaRequiredException $cre) {
echo 'URL of CAPTCHA image: ' . $cre->getCaptchaUrl() . "n";
echo 'Token ID: ' . $cre->getCaptchaToken() . "n";
} catch (Zend_Gdata_App_AuthException $ae) {
echo 'Problem authenticating: ' . $ae->exception() . "n";
}

add_sitemap($sitemap-location,$client);

function add_sitemap($sitemap-location,$client){
$xml ='<entry xmlns="http://www.w3.org/2005/Atom" xmlns:wt="http://schemas.google.com/webmasters/tools/2007"><id>'.$sitemap-location.'</id>';
$xml.="<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/webmasters/tools/2007#sitemap-regular'/><wt:sitemap-type>WEB</wt:sitemap-type></entry>";
$fdata = new Zend_Gdata($client);
$result=$fdata->post($xml,”https://www.google.com/webmasters/tools/feeds/http://yoursite%2Ecom%2F/sitemaps/”,null,”application/atom+xml”);
}

?>

Bollysite Goes Mobile

Bollysite Goes Mobile Now, browse bollysite at your fingertips on your mobile…for bollywood latest news, actor and actressesWe are pleased to enter into the mobile sphere by launching bollysite mobile version. It’s interactive and user friendly for easy navigation.

It’s easy and simple, just type www.bollysite.com into your mobile browser to experience bollysite. It is available on all WAP/GPRS enabled mobile phones.

Bollysite Movies featured on Google Code Blog

Here is a project.

Bollysite has lots of cool backend/frontend stuff  to give latest updated news as well as good User Interaction to the user.

Finally, one of my frontend engineering work Bollysite movies, get featured on Google Code Blog.

For every movies information, I didn’t have any image into my database. So, first I tried Flickr API to get relevant images to movies. But Flickr failed to deliver relevant images for old movies.

So, finally I try for Google Image Search API. First result on Google was relevant to every odd/old movies.

Then, I just needed to tweak API to get only first result. I could find that function google.search.ImageSearch.RawCompletion returns raw output.

So, I override that function with my custom function.

google.search.ImageSearch.RawCompletion = function(arg1,arg2,arg3,arg4){
if(typeof(arg2.results[0].tbUrl) != "undefined"){
movieImage = new Image();
movieImage.src = arg2.results[0].tbUrl; // Here first image will come
// now you can use movieImage.src to anywhere....
}
}
google.setOnLoadCallback(OnLoad);

So, now google powers every movie images to BollySite Movies

Bollysite goes Orkut (opensocial)

We proudly present Bollysite News as an Open Social Application.

bollysite_orkut.gif

You can add this application by following these steps.

  1. Goto orkut.com
  2. L.H.S see the Apps Box. Click edit
  3. Under add an application directly by its url box enter,http://news.bollysite.com/bollysite.news.orkut.xml
  4. Click Add Application.
  5. Click Save.


Facebox hack for Internet Explorer (IE 5,6,7)

Along with jQuery, we have used third party module facebox for hindi lyrics. During testing different browsers, I got problem with placement of facebox.

In internet explorer (IE 6 & 7) it got aligned left.

So, finally I tried some cross browser hack for it. I have done some little change in facebox.js

At the end of function,

$.facebox.reveal = function(data, klass) {

I have added followng line,

if(jQuery.browser.msie){
b = $("BODY").width();
pl = (b - $('#facebox .content')[0].offsetWidth)/2;
$('#facebox')[0].style.paddingLeft = pl;
}
}

Explanation:-

[1] If browser is Internet Explorer, it gets width of view port into b variable
[2] Now facebox width is $(’#facebox .content’)[0].offsetWidth
[3] So, required left padding is (total screen width - box with)/2
[4] $(’#facebox’)[0].style.paddingLeft = pl line properly aligns the facebox.

Now Hindi Lyrics is yours

We pleased to know you that now you can send lyrics to someone special to you. I love to dedicate love lyrics to my beloved, so I think why not to make such a module that can help other people to share their hearts’ thought.

Bollysite Lyrics Preview Main

Apart from that, we have added printer friendly version for hindi lyrics. So, on printed page you can get lyrics only.

Correct Lyrics

If you find any mistakes or errors in lyrics, feel to click correct it, it’s yours. We will review it & update lyrics accordingly.

Send Lyrics

So enjoy, Bollysite’s Hindi Lyrics

Team,
Bollysite

Bollysite News goes iGoogle

Friends,

Now you can get all the bollywood sites news on your google homepage ie. iGoogle.

igoogle
Add to iGoogle

Just click above Google icon to get bollysite add bollysite news widget to your iGoogle homepage.

Team,

Bollysite