Category: JavaScript

My first Android App or how to develop an Android App using PhoneGap and jQuery?

Posted by – January 14, 2012

I always wanted to do mobile app. The problem is I don’t know Objective C or Java or C or C++ or have those ninja skills. But we live in 21st century. If I can write a script in Python or know jQuery I can write an Android App. My skills in JS are much better than in Python. So I decided to try PhoneGap. That doesn’t mean I will not be tinkering with Python. If you know how to instructions you can develop a small hello world app using PhoneGap and JavaScript in less than 15 minutes. I didn’t want to do a plain hello world app so I decided to take a step further. I decided to develop RSS reader for my blog. And I fired up eclipse. Here is what I did

  1. Set up a PhoneGap project, exactly as mentioned here http://phonegap.com/start#android.
  2. Created two folders under /assets/www folder, css and js.
  3. Moved phonegap.xx.js under js folder and also downloaded latest jQuery in this folder from here http://docs.jquery.com/Downloading_jQuery
  4. Created a CSS file named under base.css under css folder.
  5. Updated the reference to phonegap.xx.js and also linked jquery and css stylesheet in assets/www/index.html.
  6. I had done a jQuery driven RSS reader (Code here) and used the code with some modifications, here is the code:
    <!DOCTYPE HTML>
    <html>
    <head>
    <title>My Blog Feed Reader</title>
    <link rel="stylesheet" href="css/base.css" />
    <script type="text/javascript" charset="utf-8" src="js/phonegap-1.2.0.js"></script>
    <script type="text/javascript" charset="utf-8" src="js/jquery-1.6.4.js"></script>
    <script type="text/javascript" charset="utf-8">
    $( function() {
        var XMLURI = 'http://www.kumarchetan.com/blog/feed/';
        $.ajax({
            url: XMLURI,
            success: function(xml){
                setTimeout(
                function(){
                    var blogdescription = $(xml).find('channel description:first'),
    	                blogtitle = $(xml).find('channel title:first'),
    	                bloglink = $(xml).find('channel link:first'),
    	                blogdescription = blogdescription.text(),
    	                blogtitle = '<a href="' + bloglink.text() +'" class="bloglink">' + blogtitle.text() + '</a>',
    	                feedItem = '';
    	            $(xml).find( "item" ).each(
    	                function(){
    	                    var item = $(this),
    	                        title =  item.find('title').text(),
    	                        link =  item.find('link').text(),
    	                        description =  item.find('description').text(),
    	                        pubDate =  item.find('pubDate').text();
    	                    feedItem = feedItem + '<div class="feeditem">';
    	                    feedItem = feedItem + '<a href="' + link + '" class="feeditemlink">';
    	                    feedItem = feedItem + '<span class="feeditemtitle">' + title+ '</span>';
    	                    feedItem = feedItem + '</a>';
    	                    feedItem = feedItem + '<span class="feeditempubDate">' + pubDate + '</span>';
    	                    feedItem = feedItem + '<p class="feeditemdescription">' + description + '</p>';
    	                    feedItem = feedItem + '</div>';
    	            });
    	            $('#blogheader').html(blogtitle);
    	            $('#blogdescription').html(blogdescription);
    	            $('#content').append(feedItem);
    
                }
                , 5000);
            },
            error: function(){
            	$('#blogheader').html('<a href="http://www.youtube.com/watch?v=WUUptX0i55g#t=22s" class="bloglink">PC LOAD LETTER</a>');
            },
            dataType: "xml"
        });
        document.addEventListener("deviceready", onDeviceReady, false);
    });
    </script>
    </head>
    <body>
    	<div data-role="page" id="home">
    		<div data-role="header">
    			<h1 id="blogheader">Loading...</h1>
                <p id="blogdescription">This application requires a working internet connection.</p>
    		</div>
    		<div data-role="content" id="content">
    		</div>
    	</div>
    </body>
    </html>
  7. Modified /res/values/strings.xml
  8. Replaced stock Android icons with my own icons. I had to create folder named drawable in /res folder and placed my own icon.
  9. Then Run > Run As > Androidn Application.
  10. Voila!!!

I had to add sleep or delay or timeout as their was a glitch and I am unable to recall the web page that suggested to do it. Here is the GIT URL for project: https://github.com/kumarldh/My-Blog-Feed-Reader

Playing with YUI3

Posted by – March 1, 2011

I have been playing with YUI3 for a while. Some one with a background in prototype.js and jQuery will find YUI3 bit complicated. To me YUI always sounded like JS toolkit developed by some c++/Java programmer who hated web developers to the core. Well YUI3 tries to be friendly. It took me just 15 minutes to write down the following code:

<html>
<head>
<title>YUI says Hello World!</title>
</head>
<body id="doc-body">
<div id="rgbvalues"> </div>
<script src="http://yui.yahooapis.com/3.3.0/build/yui/yui-min.js" charset="utf-8"></script>
<script type="text/javascript">
//use node and event modules
YUI().use("node", "event", function(Y){
    var handleClick = function(e) {
        var docBody = Y.one("#doc-body"); //equivalent to $(element) in prototype and jQuery(element)
        var winHeight = docBody.get('winHeight');//get "viewport" height
        var winWidth = docBody.get('winWidth');//get "viewport" width
        var red = parseInt (e.pageX * (255/winWidth));
        var green = parseInt(e.pageY * (255/winHeight));
        var blue = parseInt (red*green*0.004);
        var bgstyle = "rgb("+red+","+green+"," +blue+")";
        docBody.setStyle("background-color", bgstyle);//same as $(element).setStyle() from prototype and jQuery(element).css()
        Y.one("#rgbvalues").set("innerHTML", bgstyle);//set innerHTML
    };
    Y.on("mousemove", handleClick, "#doc-body");
});
</script>
</body>
</html>

Easy!
As I am not so good at maths I wasn’t able to write a formula or function that could translate mouse motion into color values, so I simply wrote down my stupid conversion :) .

Method chaining

Posted by – October 2, 2010

I love the way CodeIgniter explains method chaining by saying.

Method chaining allows you to simplify your syntax by connecting multiple functions.

As explained above it simply lets you do things like

FileObject->OpenFile('FileName')->AppendLine('Hello World!')->CloseFile()

Its neat. But in PHP, you have to have PHP5.x. This wonderful thing is also available in JavaScript. From jQuery home page

$("p.neat").addClass("ohmy").show("slow");

How to do method chaining?
To have an object chain methods every method in that object must return a reference to itself. Easy. Example?

<?php
class MethodChainingExample{
	public function methodOne(){
		echo __METHOD__." \n";
		return $this;
	}
	public function anotherMethod(){
		echo __METHOD__." \n";
		return $this;
	}
	public function oneMoreMethod(){
		echo __METHOD__." \n";
		return $this;
	}
}
$example =  new MethodChainingExample;
$example->methodOne()->anotherMethod()->oneMoreMethod();

The Big Pipe – Faster Facebook

Posted by – July 20, 2010

Facebook is a big time killer. You can harvest farm without owning an inch of land, kill your buddies and still brag about it, save unknown species of zoo animals and poke any girl you know and she wont mind.
But Facebook is a case study for web developers like me. A typical Facebook page, depending on network and host, loads within 5 seconds. Facebook team has set this time to 2.5 seconds. Anything beyond 2.5 seconds is a big no no. For me it loads 19 CSS files, just one JS file, all in all a 50KB page w/out images. If you didnt pay attention to last line, it FB loads just one JS file and if you look at the byte size its just 10K file. Like I mentioned earlier Gzipped content is much lighter i.e. low byte size, it can be sent over network quickly. Facebook and every other website follows and compress the content they send over the network. But this is not all.
Before I move ahead, lets understand how a page is “rendered” in browser.

  • You send a request to FB servers.
  • FB server looks at your request and prepares a page, if you were logged in, it will send your profile page otherwise a nice login page. This job is done by PHP, MySQL, Apache and some in house tools developed by FB.
  • FB sends you back the page, the HTML
  • The browser reads or “parses” the HTML and finds out well it also needs CSS, images and JS and sends separate requests for these assets.

Now here is the tricky part. Browsers need all the possible assets that can affect the rendering of page and JS is one thing that can hide images, change CSS applied on an element, add text or can change the complete layout. So when browsers encounter a JS file they stop loading anything and concentrate only on JS. Till the time JS is not loaded and processed nothing else is done. This have been, more or less, same for nearly all the browsers till date. Web developers try to deceive browsers in many ways. The one way suggested by Yahoo! is to load JS at the bottom of page or develop the page in such a way that JS is loaded just before body tag is closed. This is not feasible in many cases. Say for example, on my webpage a menu appears in top header not in bottom of the page so it is rendered first and I need it to be active. There are way outs.

  • RequireJS
  • labJS
  • Load JS using AJAX
  • Create Script tag dynamically
  • Load scripts in iFrame
  • and others

Facebook employs some thing it calls a BigPipe. Interestingly FB divides its page into smaller chunks, named pagelets and every pagelet has its own JS associated with it. Have a look at following BigPipe fragment

<script> big_pipe.onPageletArrive({
 "id": "pagelet_nav_lite",
 "phase": 1,
 "is_last": false,
 "append": false,
 "display_dependency": [
 "pagelet_navigation"
 ],
 "bootloadable": {
 "editable-side-nav-js": [
 "CiNUi",
 "WTiBX",
 "Nahdv",
 "vstFf"
 ]
 },
 "css": [
 "p0tHf",
 "HOV0r",
 "FLbGk",
 "mWAGo",
 "e2Nmn"
 ],
 "js": [
 "CiNUi",
 "WTiBX",
 "k29le",
 "kJEXe",
 "5CZKw",
 "S4cYi",
 "3iRY2"
 ],
 "resource_map": {
 "e2Nmn": {
 "name": "css\/sprite\/autogen\/a2gtd9_duri.css",
 "type": "css",
 "nonblocking": 1,
 "src": "http:\/\/static.ak.fbcdn.net\/rsrc.php\/z8ZLB\/hash\/40d4o2t0.css"
 },
 "vstFf": {
 "name": "js\/ui\/xhp\/page\/editable_side_nav.js",
 "type": "js",
 "src": "http:\/\/static.ak.fbcdn.net\/rsrc.php\/z5QP6\/p\/hash\/eoj7km8p.js"
 }
 },
 "requires": [

 ],
 "provides": [

 ],
 "onload": [

 ],
 "onafterload": [

 ],
 "onpagecache": [

 ],
 "onafterpagecache": [

 ],
 "refresh_pagelets": [

 ],
 "invalidate_cache": [

 ],
 "content": {
 "pagelet_nav_lite": "HTML removed, view source your own FB profile page :-) "
 },
 "page_cache": true
})</script>

Further spying on the DOM using Firebug, I could see an iframe named “bootloader_iframe” which loads JS files.

BigPipe has really changed the way Facebook loads and works. Facebook is showing generosity and is sharing what it does. Unlike Yahoo! and Google, Facebook is not so much developer friendly and is not well known to share its knowledge. I hoping to see more documentation on BigPipe. Here is some info: http://www.facebook.com/notes/facebook-engineering/bigpipe-pipelining-web-pages-for-high-performance/389414033919

The JSON object was formatted using JSONLint.

Drop down menus with jQuery

Posted by – March 18, 2009

After attempting sliding menus with jQuery I developed drop down menus using lists.

Here is the code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html>
  <head>
  <title>Drop Down Menus With jQuery</title>
  <script type="text/javascript" src="js/jquery.js"></script>
  <script type="text/javascript">
  function mainmenu(){
  $("#nav ul" ).css({display: "none"}); // Opera Fix
  $("#nav>li" ).hover(
function(){
$(this).find('ul:first').css({visibility: "visible",display: "none"}).show(400);
},
function(){
$(this).find('ul:first').css({visibility: "hidden"});
});
}
$(document).ready(function(){
mainmenu();
});
</script>
<style type="text/css">
#nav, #nav ul{
margin:0;
padding:0;
list-style-type:none;
list-style-position:outside;
position:relative;
}
#nav>li{
float:left;
position:relative;
}
#nav>li>a{
font-size:12px;
font-family: arial;
color:#000000;
padding:5px;
text-decoration:none;
border: 1px solid #ddd;
background:#eee;
}
#nav ul {
position:absolute;
dispay:none;
}
#nav a{
display:block;
}
#nav>li>ul>li>a{
font-size:12px;
font-family: arial;
color:#000000;
padding:3px;
text-decoration:none;
border: 1px solid #aaa;
background:#bbb;
}
</style>
</head>
<body>
<ul id="nav">
<li><a href="">HTML</a></li>
<li><a href="#" >CSS</a>
<ul>
<li><a href="#">CSS 1</a></li>
<li><a href="#">CSS 2</a></li>
<li><a href="#">CSS 3</a></li>
</ul>
</li>
<li><a href="#" >Javascript</a>
<ul>
<li><a href="#">Mootools</a></li>
<li><a href="#">Prototype</a></li>
<li><a href="#">jQuery</a></li>
<li><a href="#">Yahoo! UI</a></li>
<li><a href="#">Dojo</a></li>
<li><a href="#">Mochi Kit</a></li>
</ul>
</li>
</ul>
</body>
</html>