Archive

Archive for the ‘javascript’ Category

Yet another must have node.js module – underscore-cli

September 12, 2012 Leave a comment

If you love underscore.js and happen to be a CLI nut, you should not miss out underscore-cli, see

https://npmjs.org/package/underscore-cli

for details, or simply install via (assuming you are already using node.js)

sudo npm install -g underscore-cli

Test Drive:
curl https://api.github.com/users/midnightcodr|underscore print --color

Categories: javascript, node.js

Calling initialization function only once with this js trick

September 12, 2012 Leave a comment

There are times when an initialization function in a js object needs to be called only once. Here’s one of the solutions I came up with. When F.paint() is called, a check on the initialization tag (need_init) is performed. need_init remains undefined until init() is called for the first time.

The code:

var F=(function() {
	var self=this;

	var init=function() {
		console.log('Initialized.');
		self.need_init=false;
	}
	return {
		paint: function() {
			if(typeof self.need_init==='undefined') {
				init();
			}
			console.log('Now I am ready to paint.');
		}
	};
})();

F.paint();
F.paint();
F.paint();

Output from the above example:
Initialized.
Now I am ready to paint.
Now I am ready to paint.
Now I am ready to paint.

Enjoy coding.

Categories: javascript, Programming

backbone.js learning note [3]

May 14, 2012 Leave a comment

[ update 5/14/2012 ] This single page app is now available at http://whatsmyspeed.appspot.com/. Decided to go (back) with google app engine instead of heroku due to (initial start) performance reason.

I am definitely addicted to backbone.js and I just threw some backbone into the running speed calculator I wrote some time ago (with node.js):

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Speed Calculator</title>
	<style type="text/css">
		body { padding: 50px; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; }
		a { color: #00B7FF; }
		label {width:100px;font-weight:bold;display:block;float:left;}
		input[type="text"] {width:120px;margin-right:5px;}
	</style>
</head>
<body>
	<div id="container">
	   <p> 
		  <label>Distance</label>
		  <input id="distance" type="text" placeholder="distance in miles">
		</p>
		<p>
		  <label>Time</label>
		  <input id="time" type="text" placeholder="ex: 24:25, 01:45:17">
		</p>
		<p>
		  <label>Speed</label>
		  <input id="speed" type="text">
		</p>
	</div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
    <script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
	<script>
		var Speed=Backbone.Model.extend({
			defaults: {
				distance:0,
				time:0
			}
		});
		var SpeedView=Backbone.View.extend({
			el:$('body'),
			events: {
				'blur input#time': 'update_model',
				'blur input#distance': 'update_model'
			},
			initialize: function() {
				_.bindAll(this, 'render');
				this.model.bind('change', this.render);
			},
			update_model: function() {
				this.model.set({
					time: $('#time').val()
					,distance: $('#distance').val()
				});	
			},
			render: function() {
				$('#speed').val('');
				var dist_str=this.model.get('distance')
					, time_str=this.model.get('time')
				if( dist_str!='' && time_str!='' && !isNaN(dist_str) ) {
					var speed=this._calc_speed(dist_str, time_str);
					if(speed!=null) {
						$('#speed').val(speed.toFixed(3));
					}
				}
				return false;
			},
			_calc_speed: function(dist_str, time_str) {
				var dist_reg=/^([0-9]+(?:\.[0-9]+)?)$/
					, dist_res=dist_reg.exec( dist_str )
					, time_reg=/^(?:(?:(2[0-3]|[0-1]?[0-9])[:])?([0-5]?[0-9])[:])?([0-5]?[0-9](?:\.[0-9]+)?)$/
					, time_res=time_reg.exec( time_str );
				if(dist_res && time_res) {
					var hours=(time_res[1]||0)*1
						, minutes=(time_res[2]||0)*1
						, seconds=(time_res[3]||0)*1
					total_seconds=hours*3600+minutes*60+seconds;
					if(total_seconds>0) {
						return 3600*dist_res[1]/total_seconds;
					} else {
						return null;
					}
				}
				return null;
			}
		});
		var speed=new Speed();
		var speedview=new SpeedView({model:speed});
	</script>
</body>
</html>
Categories: backbone.js, javascript

backbone.js study note [2]

May 13, 2012 Leave a comment

Here’s an improved and complete example to the first learning note on backbone.js

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>stock price simple demo</title>
</head>
<body>
    <div id="data"></div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
    <script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>

    <script>
        var Stock=Backbone.Model.extend({
            defaults: {
                price: 123
            }
        });

        var StockList=Backbone.Collection.extend({
            model: Stock
        });

        var ItemView=Backbone.View.extend({
            tagName: 'li',
            initialize: function() {
                _.bindAll(this, 'render');
                this.model.bind('change:price', this.render);
            },
            render: function() {
                $(this.el).html('<span>'+this.model.get('price')+'</span>');
                return this;
            }
        });

        var stock1=new Stock({price:333});
        var stock2=new Stock({price:555.667});

        var StockView=Backbone.View.extend({
            el: $('#data'),
            initialize: function() {
                _.bindAll(this, 'render');
                this.collection=new StockList();
                this.collection.add(stock1);
                this.collection.add(stock2);
                this.render();
            },
            render: function() {
                $(this.el).append('<ul></ul>');
                _(this.collection.models).each( function(item) {
                    var itemview=new ItemView({model:item});
                    $('ul', this.el).append(itemview.render().el);
                }, this);
            }
        });
        var stockview=new StockView();
    </script>
</body>
</html>

To test what it does (so far this is the most impressive feature of backbone, the rendering is actually linked directly to the change of model), open a Javascript console (in Chrome or with Firebug in Firefox), and type

stock1.set({ price: 10 })
stock2.set({ price: 999 })

, pay attention to the changes on the page.

References:
http://arturadib.com/hello-backbonejs/docs/5.html

Categories: backbone.js, javascript

How to make an Ajax form without capturing key press event on the input element

May 13, 2012 Leave a comment

OK this is a very common task: build a form, collect user input and send to server for processing (through Ajax therefore upon response the page should remain the same). One of the ways to accomplish this is to bind the ajax handling function to both the submit button (or an anchor link)’s click event and the input field’s key press event (only when Enter key is pressed):

<!DOCTYPE html> 
<html>
<head>                  
    <meta charset="utf-8">                                               
    <title>submit test using onclick and onkeydown event</title>
</head>             
<body>
    Name:   <input type="text" name="user_name" value="" id="user_name" onkeydown="kp_handler();">
    <p><input type="button" value="Continue &rarr;" onclick="handle_submit();"></p>
    <script type="text/javascript">
        function kp_handler(evt) {
                if(!evt && window.event) evt=window.event;
                if(evt.keyCode==13) {
                    handle_submit();
                }   
        }           
        function handle_submit() {                      
            // you might want to do ajax here to submit data to the server
            // as a demo I just print the data to the client's browser
            var msg='You have entered '+ document.getElementById('user_name').value;
            try {
                console.log(msg);
            } catch (e) {
                alert(msg);
            }
        }
    </script>
</body>
</html>

However, a better approach is to do it through a dummy form enclosing the text input and submit button. The benefit of of this is the Enter key event is automatically handled by form’s onsubmit attribute hence there’s no need to capture the onkeydown event on the text input element (figuring whether the Enter key is pressed is messy as you can see from the first approch):

<!DOCTYPE html> 
<html>
<head>                  
    <meta charset="utf-8">                                               
    <title>submit test using only onsubmit event</title>
</head>             
<body>
    <form id="some_form" onsubmit="javascript: handle_submit(); return false;">
        Name:   <input type="text" name="user_name" value="" id="user_name">
    <p><input type="submit" value="Continue &rarr;" ></p>
    </form>
    <script type="text/javascript">
        function handle_submit() {
            // you might want to do ajax here to submit data to the server
            // as a demo I just print the data to the client's browser
            var msg='You have entered '+ document.getElementById('user_name').value;
            try {
                console.log(msg);
            } catch (e) {
                alert(msg);
            }
        }
    </script>
</body>
</html>

It’s worth noting that the return false statement has to be put at the end of the onsubmit attribute (moving it into handle_submit will result in the form submitting to the page itself).
Comments and feedbacks are welcome.

Categories: javascript

backbone.js learning note [1]

April 5, 2012 Leave a comment

Keep track of state change example:

    Stock = Backbone.Model.extend({
        defaults: {
            price: null,
        },
        initialize: function(){
            this.bind('change:price', function() {
                var px=this.get('price');
                console.log('price changed to: '+px);
            });
        },
        price_change: function(newprice) {
            this.set({price:newprice});
        }
    });

    var stock=new Stock({price:1234.55});
    stock.price_change(456);
    // the console output from the last line:
    // price changed to: 456

References:
http://backbonetutorials.com/what-is-a-model/

Categories: backbone.js, javascript

Howto: create javascript object without the “new” keyword (quick example)

March 11, 2012 2 comments
var Apple=function(type, color) {
    this.type=type;
    this.color=color;
    this.getInfo=function() {
        return "This is a "+color+' '+type+' apple.';
    };
    this.grow=function() {
        console.log('See a '+type+' apple needs to grow too.');
    };
    return this;
};

var myapple=Apple('honeycrip', 'red'); // new Apple ... works too
console.log(myapple.getInfo());
myapple.grow();

The new keyword can be omitted due to the use of return this line (10). Happy coding.

Categories: javascript
Follow

Get every new post delivered to your Inbox.