Now go to jQuery homepage and execute the same code. Notice the difference in output. Why the difference?
Prototype adds additional methods to Array using Array.prototype . Those methods show up when you iterate through them. If you want to ignore methods added through Array.prototype then use this code.
In order to find if an element with id foo is present, one can do
How can you make the conditional statement shorter.
What is the output in this case. Notice that function bar is defined after the return statement.
What’s output in this case.
The result would be output 5 5 5 5 and all the four output will appear together in one shot. Then after 2 seconds another set of similar data would appear. This would continue forever.
Question is why do I see the output in one single shot and why do I see value 5 for all four cases.
Correct implementation would be
Above code would print 0 1 2 3 4 at an interval of 2 seconds.
What’s the output in this case.
What’s output in this case.
If I provide an array with certain values then how would you find the max value for that array.
This answer builds up on the answer provided in #7 .
You can try this but it will fail.
You can try this but it will fail too.
This will work
Following code has been tested with jQuery 1.3.2 version .
The super popular live method was added to jQuery 1.3 . It works just great. Except when it does not work. As per the documentation this method does not work in following cases: blur, focus, mouseenter, mouseleave, change, submit .
How binding events work in jQuery
In above case click event is bound to all the links in the document. jQuery stores such binding information as data attribute of the bound element. This is how I can access the list of all functions bound to an element.
If a new link is dynamically added then that new link will not get this click behavior. Tosolve this problem I can use live method.
Trying out live event
If I add a new a tag dynamically then that tag will automatically get the new click behavior. That’s great.
Just like the previous section, now I am going to find the events bound to a element. However when I execute following code I get undefined .
Why is that. In the previous section I showed that all the events bound to an element are stored as the data attribute of that element. Well, live is different. live events are not bound to the element directly. They are bound to the top level ‘document’. I can verify this by trying out this code
How does live method work
live methods do not set anything on elements directly. All the event handlers are set at the document level. It means that in order for live methods to work, event bubbling is required. If you don’t know what event bubbling is then read her . It also means that event should not be stopped while it is propagating to document. If event propagation is stopped then event handlers bound at the document level will never know about that event and live method will fail.
The strategy to let someone else deal with the event is called event delegation. You can read more about event delegation here .
When live method is called then a binding is done at the document level. Loosely translated this is what is basically happening.
As you can see when a click on p event bubbles all the way to the top then that event is captured by document and necessary action is taken if the target element matches.
It is clear that if the click event is stopped before it reaches document then live method will not work. I will show you an example.
Now you will notice that live is no more working.
live does not work when event bubbling is not supported
In the previous section I showed that when event does not bubble up to document then live fails. It means that all the events that do not bubble will not work. Which means that events like blur, focus, mouseenter, mouseleave, change and submit which do bubble in IE will not work in IE. However note that these events will continue to work in Firefox.
Above code will work in firefox but it will not work in IE.
Here is an example of an event that does not work in IE: onchange event.
To recap live method will not work in following cases:
live method works on event propagation, if an event is stopped while it is bubbling then live will not work.
IE does not support bubbling for certain events. live method on those events will not work in IE.
There is a way to get around to both the problems.
Brandon Aaron developed livequery plugin which was finally merged into jQuery as live method. livequery plugin solves both the problems listed above and the code works in IE too.
First step is to include this plugin
Now try this code.
livequery works because livequery ,unlike live, method does not do binding at the document level. livequery does binding at the element level. You can find that out by running following code.
Above code will produce result if I am using livequery. Above code will not produce any result if I am using live method.
The key piece of code in the plugin that makes all this work is
Every 20 milliseconds livequery runs all the bindings defined in livequery and then binds the matched element with the event.
By understanding the internals of how live and livequery are implemented, now you can choose to use livequery in certain cases where live will not work. Also it helps to understand how live actually works.
Live method finds elements and then throws it away. Not very efficient.
A typical use of live method is something like this.
As it has already been discussed a live method registers events at document level.
However when $('p').live(...) is evaluated then jQuery first goes and finds all the p elements. And then what does it do with those elements. Nothing. That’s right. jQuery throws away all those p elements which were just found without using them. What a waste.
If your application has a lot of live methods and this might slow down the performance of the application.
A better solution would have been to design an API like this one:
jQuery is flexible and I can create my own live method but it will add to the confusion. Another solution would be to make the call to live method without first finding all those p element. Here is how it can be done.
In the above case no element will be selected only to be thrown away. This is much better.
Seeing is believing
In the previous section, I showed how live method can be made to work without first selecting the elements. However a friend of mine asked me if I could conclusively prove that in the real live method a find is actually done. And in my solution a find call is not done.
Here I am showing you the overriding find method. In this method I am overriding the original find method. I will put a log message before passing the find method to the original method.
In the above case you will get message on firebug console confirming that find is indeed invoked when live method is called.
Also I had to comment out +process jsl-test.js at the very bottom. Now tell your plugin to to use this configuration file rather than the default one. Add the following line to your vimrc file.
This is the vim settings I use and it has been configured to take care of it. Just go to vimrc.local and change the path to your config file. Also don’t forget to remove " at the beginning of the line to uncomment it.
Now there is a need for function second to call function first. Try this and it will fail.
One way to fix this problem is to hardcode value foo inside the second function. Following code works.
Above code works but hardcoding the value of foo inside the object literal is not good. A better way would be to replace the hardcoded name with this .
All is good.
Also note that in order to invoke the returned function I have double ()() at the end.
Above code does not work. It did not work because this has changed. Now this in second function refers to the global object rather than referring to the foo object.
jQuery also allows developers to make use of custom events. How it is going to help us, we are going to see it shortly. First let’s take a look at a basic calendar application.
Code looks like this.
In the above case we have four methods. If all the implementation is filled out and helper methods are added then ,in total, we’ll have tons of methods.
And slowly, it’ll become difficult to see which methods act on the main element monthly_calendar_umbrella.
Let’s look at the same functionality if implemented using jQuery custom events.
First difference, you will notice is how nicely all the actions possible on the main element are laid out. In this case just one look at the code tells me that four actions can be performed on the main element. This was not so obvious from the first version of the code.
In this case, I am binding events such as ‘redrawFroMonth’ to the element. Obviously ‘redrawForMonth’ is not a native event such as ‘click’ or ‘submit’. This is what I mean by binding ‘custom events’ to elements. In this case ‘redrawForMonth’ is a custom event.
Now, the last part of the discussion is how to trigger custom events. Well, jQuery has a method called trigger .
Note that while binding a function is passed. The first parameter of that function is always an event handler. In the below example I am passing only one parameter even though the function takes two parameters: event handler element and the parameter I defined.
Let’s say that I have bound all the links to display an alert.
However it would be cool if there is a way to find all the click handlers associated with an element.
jQuery has data method which it uses internally to store information. jQuery uses data method to store all the handlers associated with an element. We could use this information to our advantage. Here I am trying to find out all the click handlers associated with the first link.
The output looks like this
jQuery.data method is also very useful if you want to store some information about an element. For example, in an application you need to store information about people. In the html page you are only displaying names. And when a name is clicked then you want to display age, hometown and the company they work for. You can store information about each user using jQuery.data and you can retrieve it when user name is clicked.
When you click on Java then you will get two alerts. That is because the click on element p will propagate outward and it will be caught by element div which has onclick trigger.
If you do not want the event to propagate then here is a way to stop it.
Stopping the default behavior
Converting a regular html link into an AJAX request is easy. One of the things you need to do is to return false so that the click operation does not perform its default behavior.
However there is another way to handle such cases. preventDefault stops the default behavior. The same code could be written as
In order to get around this security problem you can do any number of things including sending the Ajax request to your server which will get the JSON data from the eventsinindia.com API. Or use iframe. Both of these solutions are implemented and discussed in this article .
However in some cases JSONP solves this problem much more elegantly.
Before we discuss JSONP some basics ?
When the html page is loaded you will get an alert.
What is JSONP?
All the APIs should provide support for JSONP. Enabling JSONP support is easy if you are using Rails 2.3 or any Rack compliant framework. In Rails 2.3 all you need to do is stick this file in lib as jsonp.rb and then add one line to the environment.rb .
That’s it. Now you are providing support of JSONP with the keyword being callback.
I was hoping that I will get a dot after every two seconds. But that’s not what happens when you run the code. I see nothing for first 10 seconds then I see five dots in one shot. This is not what I wanted.
I started looking around at the documentation for IO class and found the method called sync= which if set to true will flush all output immediately to the underlying OS.
The reason why OS does not flush immediately is to minimize the IO operation which is usually slow. However in this case you are asking OS to not to buffer and to flush the output immediately.
Before you look at the next piece of code remember that defining a variable without the var prefix makes that variable a global variable.
What do you think would be the alert value first time? I thought it would be Angelina but the correct answer is undefined. That is because it does not matter where the variable is defined. As long as the variable is defined anywhere within a function then that variable will be set to undefined. It is when the statement is executed then the value of the variable changes from undefined to Jennifer.
What are we talking about
You can see that the main method that I want to expose to global namespace is showCalendar. However I am also exposing six other functions to global namespace. It means that if some user has declared a global namespace function named getCellID then my getCellID is going to collide with the user’s function. This is not good.
The above call to getCellID is currently being executed successfully. It means I have polluted the global namespace. I am going to fix it.
The solution is to put all the code inside a function. In a function all the variables and functions declared are scoped only to that function. Out of that function, inner functions cannot be used. Inside this function only one method showCalendar would be exposed.
Here is the solution.
In the above case the call to showCalendar was successful. However call to getCallID failed. That’s good. It means I am not polluting the global namespace.
If you notice carefully in the above case after declaring an anonymous function I am invoking that function by having () at the end. You can read more about self-invoking function here .
Example 1: Getting digit name
The goal is to read from an array and display the result. The first implementation is to put everything in Global namespace.
Above solution works. However creating a global variable names is not a good thing. You should create as less global variables as possible.
Moving to a function
Next step is to move the code to a function. In this case we will not have any global variable.
The above solution is very slow. Every single time the function is called the whole array is loaded. This solution works and most of the developers will settle with this one. However Closure can provide a better solution.
Better solution with Closure
Note that at after declaring the function the function is also getting invoked. This is a case of self invoking function. You can find out more about self invoking function here .
Example 2: Getters and Setters
Developers deal with getters and setters all the time. However creating a good getter and setter could be a little tricky. Here is one implementation
Above solution works and it’s nicely done.
Let’s look at another implementation.
This is a simple case of serially iterating through the items provided but the logic of deciding next element can be complex and it can be private.
I am learning jQuery and one of things I was struggling with is the plugin pattern. In jQuery world it is very common to wrap the major functionality of the application inside a plugin.
Here is a great article
The article did a great job of explaining the basics however it took me a while to understand the self-invoking functions.
self-invoking functions are anonymous functions declared on run time and then invoke it right then and there.
Since they are anonymous functions they can’t be invoked twice.
However they are a good candidate for initialization work which is exactly what is happening in the jQuery plugin pattern.
Declaring a function
A function can be declared in two ways:
In the end a variable named hello was created which is a function.
Please note that in the above case only the functions are declared. They are not invoked. In order to invoke the function we have to do this
How do we invoke an anonymous function. We need to call () on the anonymous function. But before that we need to wrap the whole command in (). Take a look at this
The final result is weird looking code but it works and that is how an anonymous function is declared and invoke on run time.
With this understanding now it becomes easier to see what is happening in this code
In the above case an anonymous function is being created. However unlike my anonymous function this anonymous function take a parameter and the name of this paramter is $. $ is nothing else but jQuery object that is being passed while invoking this function.
Rails makes it easy to adapt Restful architecture. All you have to do is following.
I started putting all pictures related activities in pictures_controller.rb .
In the beginning it was simple.
Slowly the application evolved.
The application started handling two different types of pictures.
There would be pictures for events and then there would be pictures of users using the system.
One can add comments to the event pictures but one can’t add comment to user pictures.
Slowly the requirement for event pictures grew vastly different from user pictures.
Sounds familiar. Right.
Initially controller takes on a few responsibilities but
slowly the controller starts taking a lot more responsibilities and then controller becomes huge.
The pictures controller was really huge and was fast becoming a mess and
specially writing test was getting very difficult.
Time had come to create two different controllers: one for event pictures and one for user pictures.
But wait. Lots of people would say that if we want to be restful then
there has to be one to one mapping between the model and the controller.
Model != resource
Being restful does not mean that there has be a one to one mapping between the model and the controller.
I am going to create a new controller called user_pictures_controller.rb
which will take on all the functionality related to users dealing with picture.
And this is going to be restful.
Above I have defined a resource called user_pictures.
To keep it simple this controller would do only three things.
display all the pictures of the user ( index )
allow user to upload pictures ( create )
allow user to delete a picture ( destroy )
That’s the general idea. In my application I have only three actions.
However in the interest of general discussion
I am going to show all the seven methods here.
Also for simplicity create in this case means adding a record (I am not showing multipart upload).
Here is the code for controller.
Another use case
Let’s talk about another example.
Let’s say that we have a model called Project
besides the regular functionality of creating, deleting, updating and listing projects,
one needs two more actions called enable and disable project.
Well the projects controller can easily handle two more actions called “enable” and “disable”.
However it is a good idea to create another controller called project_status_controller .
This controller should have only two actions - create and destroy.
destroy in this case would mean disabling the project
create would mean enabling the project.
I know it looks counter intuitive. Actions ‘enable’ and ‘disable’
seem simpler than “create” and “destroy”.
I agree in the beginning adding more actions to pictures controller looks easy.
However if we go down that path then it is a slippery slope and we do not know when to stop.
Compare that with the RESTful design of having only seven action : index, show, new, edit, create, update, destroy.
This limits what a controller can do and that’s a good thing.
This ensures that a controller does not take up too many responsibilities.
Creating another controller allows all the business logic which is not related to one of those
seven actions to be somewhere else.
One last example
Now that we have the ability to “enable” and “disable” pictures how about showing “only active”,
“only inactive” and “all” pictures.
In order to accomplish it once again we can add more actions to the pictures controller.
However it is much better to have two new controllers.
Some of you must be thinking what’s the point of having a controller for the sake
of having only one action.
Well the point is having code that can be changed easily and with confidence.
In this blog I tried to show that it is not necessary to have one to one mapping between model and controllers to be restful.
It is always a good idea to create a separate controller when the existing controller is burdened with too much work.
Rails exception handling depends on two factors and we are going to discuss both of them here.
When exceptions are handled by rescue_action_locally then we get to see the page with stacktrace. When exceptions are handled by rescue_action_in_public, we get to see the public/500.html or an error page matching the error code.
As you can see Rails uses two different methods consider_all_requests_local and local_request? to decide how exception should be handled.
consider_all_requests_local is a class level variable for ActionController::Base . We hardly pay attention to it but it is configured through files residing in config/environments
As you can see in development environment all the requests are considered local.
I have overridden the method local_request? but I am still not able to see public page when exception is raised.
That is a common question I see in the mailing list. As you can see the condition to decide how to handle exception is
In development environment consider_all_requests_local is always true as I showed before. Since one of the conditions is true Rails always handles the exception using rescue_action_locally .
I am running in production mode but I am still not able to see public/500.html page when I get exception at http://localhost:3000.
Same issue. In this case you are running in production mode so consider_all_requests_local is false but local_request? is still true because of localhost.
I want local_request? to be environment dependent
Recently I started using hoptoad and I needed to test how hoptoad will handle exception in production mode. However without any change local_request? was always returning true for http://localhost:30000 .
Then I stick following file under config/initializers
Now all request in production or in staging mode are treated as NOT local.
Now in both staging and production mode I get to see 500.html page even if I am accessing the application from http://localhost:3000 .