Sunday, July 5, 2009

Ajaxified Will Paginate

I added the will_paginate plug-in for my rails 2.3.2 application but quickly found that there was no way I could ajaxify it. So I made a renderer of my own by modifyind some code. It was fun and effective.

The will_paginate.rb file inside config/initializers look like this..


class PaginationListLinkRenderer < WillPaginate::LinkRenderer

def to_html
links = @options[:page_links] ? windowed_links : []

links.unshift(page_link_or_span(@collection.previous_page, 'previous', @options[:previous_label]))
links.push(page_link_or_span(@collection.next_page, 'next', @options[:next_label]))

html = links.join(@options[:separator])
@options[:container] ? @template.content_tag(:ul, html, html_attributes) : html
end

protected

def windowed_links
visible_page_numbers.map { |n| page_link_or_span(n, (n == current_page ? 'current' : nil)) }
end

def page_link_or_span(page, span_class, text = nil)
text ||= page.to_s
if page && page != current_page
page_link(page, text, :class => span_class)
else
page_span(page, text, :class => span_class)
end
end

def page_link(page, text, attributes = {})
if @options[:ajax].nil?
return @template.content_tag(:li, @template.link_to(text, url_for(page)), attributes)
else
return @template.content_tag(:li, @template.link_to(text,'#', :onclick => ajax_url_for(page)), attributes)
end
end

def ajax_url_for(page)
return @options[:fn_name]+'("'+ (page.to_s) +'")'
end

def page_span(page, text, attributes = {})
@template.content_tag(:li, text, attributes)
end

end

WillPaginate::ViewHelpers.pagination_options[:renderer] = 'PaginationListLinkRenderer'
WillPaginate::ViewHelpers.pagination_options[:previous_label] = 'Prev'
WillPaginate::ViewHelpers.pagination_options[:next_label] = 'Next'


The ajax_url_for page gives the javascript to be called for the link. The options added are


:ajax => true (to signify that it is an Ajax request)
:fn_name => some_function_name (The Javascipt function which has the Ajax call)


The view is a partial which requires these local variables to be passed


A collection of paginated records using will_paginate's Model.paginate(:page => page)
A base_url which has the url to which the page parameter should be added.
The container which should be populated after the Ajax call.


The partial looks like this ...


<script type="text/javascript"><br />var access_page_for_paginate = function(page_no){<br /> <%= remote_function(:update => container, :url => base_url, :with => '"page="+page_no') %><br />}<br /></script>
<div class="pagination_container">
<%= will_paginate collection, :ajax => true, :base => base_url,
:container => container, :fn_name => 'access_page_for_paginate' %>
</div>


And the partial is called like this ..


<%= render :partial => 'partials/ajax_paginate',
:locals => {:collection => @feeds, :base_url => show_service_url, :container => 'profile_all'} %>

Wednesday, June 24, 2009

The Face of the Web

It changes everyday. Trends change and so does the people who use them. We have all seen what a simple application like twitter did to the community. It made the community addicted to it. And millions of people find it important to use this service as a medium of communication. I still remember the incident when twitter was able to save a life.

The term 'service' is a very subtle but important thing to note here. Saumitri helped me understand the true role of an application. An application can be a utility or a service. Utility is something a user would come for a specific purpose. He might or might not choose to return to the application. But a service is something that pulls the user and makes him do stuff with the application. The success of twitter lies in the fact that it is a service. And this service has a large amount of marketting, driven by the common user. People who are part of this application sell the application. They are fully in control of what they want to publish, which might be even advertising themselves, and they have a greater reach.

Now applications like twitpic have solved something that twitter did not have. Store a picture in twitpic and we will post a link to your twitter account. Twitter having an open API made things easier. Think of the time when twitter would allow you to attach images from the main application itself. Twitpic becomes irrelevant. Twitpic for me is then a utility. It uses something and routes traffic into the application. Intelligent and effective but for a short term.

Most of those great applications, if you notice, have a very simple idea as their core. They facilitate a certain action and they render them in a unique style. Once we get used to a style, it is pretty hard to revert or use another one. The crux is not to develop UI intensive applications which serve multiple purposes, but to have an application simple enough which fulfils a purpose in a simple fashion.

These kinds of ideas are hard to come by. They just click at once. I am on the look out for an idea that would change my world and one that would leave a footprint on the net.

Tuesday, June 16, 2009

Search search search

I was wondering how searching 'dineshvasudevan' in those search engines would result. Attached are some results from Google, Yahoo and Bing.

I have a blog of my own and I expect it to come up some where on the first page. It comes up for Google and Yahoo. But for some ODD reason Bing does not even have it on any of the pages. Thats a load of crap.

My Linked In profile comes up for Google and Yahoo but not for Bing. Very bad indeed.

Slideshare seems to be a very popular site for all the three. Thats good.

My twitter profile comes up on the first page for Google, on the second page for Yahoo. I get other people's twitter pages when I search me on Bing. HAHAHA .

Google has a suggest option where as Yahoo includes the result and asks me if I want them excluded. Bing does nothing of that sort.


--

--

Saturday, May 16, 2009

Jira Again

Its been some time since I have worked on Jira. Creating plugins and modifying Java/Velocity Template/jsp code was what I used to do earlier. It was fun earlier when you start of learning new things and understand the structure of the excellent code written for Jira. But then the work becomes monotonous and you feel that you have more to give. After having finished with Enthiosys but developing some high end stuff based on SVG, javascript and HTML, I was asked to do some work on Jira.

The idea is a simple one. try to build something that would let users chat about some Jira issue and then log the chat into the Jira issue as comments. :) . Simple as it sounds, I had to set up a Jabber server. I used the excellent OpenFire as the server. The LDAP credentials for the company, I managed to obtain and then configured it so that all the users of the company could log in. Jira 3.13.4 was downloaded and I managed to connect to LDAP as well with the help of Indraneel.

Then came the difficult part. The application which was to be in AIR. I first thought to try to build it using flash. Actionscripting is something that I could do. But to have frames build movie clips is something that I could not do. I was good with HTML and Javascript and thought I would do it my way using HTML Ajax. I decided to build the required files to communicate with Jira and Jabber in flash so that I could use them in HTML using the window.runtime object provided by Adobe AIR.

Jira offers 2 ways of external communication. SOAP and XML RPC. I downloaded a bunch of those classes which facilitated the SOAP communication, because SOAP was well documented and XML RPC was crude, but did not have much luck getting information from Jira. The envelope and the structure of the xml was not being detected by the class for some reason. I had success with XML RPC and decided to go on with that.

The communication with Jabber was done with the excellent XIFF library. It is one of the best libraries that I have seen but is a little less in documentation. That is ok as long as it has all the necessary stuff required to develop.

I tried compiling the libraries into swf files, but for some reason they were not included in the file. I had just used an import statement. Ashish suggested to use a function and after using a function which initiated the class, I managed to get all the libraries for access. Event listeners were something that needed to be taken care of. At first the idea was to call Javascript from the Actionscript but the sand box had restrictions. This made me create event handlers in javascript and attach then using javascript. That worked fine.

With all the things setup, the next step was to build the interface. The interface would be simple with a list of contacts, an option to search, find and add contacts and chat with a contact. To create a native window with the chat was the next big step. I managed to populate the list of contacts with online and offline contacts (this list would change as and when the user logs in).

The native window creation according to the chat was tricky. It was tricky because to show the window was not a big deal, but to load chats in it was a pretty big deal. The handle for the window must be maitained by the main window and the chats must be sent as well. As of now I am working on this and I hope Ill make progress.