Archive for the 'UI' Category
will_paginate and Ajax pagination 
September 2nd, 2008
One thing that I’ve been using a lot is will_paginate and it’s derivatives, such as merb_paginate, ultraminx and ultrasphinx. One problem that I noticed with merb_paginate was that it didn’t want to use the restful paths in the merb app that I was using. This was rather annoying, since I was trying to make my merb app almost entirely restful, except for the home controller. So, instead of using paginator, I decided that I wanted to add ajax pagination.
The first step that needs to be done is to create a create and delete js view. This is extremely basic. I have some code that does this in one of my github repositories. Namely, the sparty_server code.
In the controller, uncomment this line as usual. We are going to be sending back json:
provides :xml, :yaml, :js
Then create the following *.js.erb files:
index.js.erb
var events = "";
<%= partial "widgets", :with => @widgets %>
<%= partial "shared/paginate", :items => @widgets %>
$jQ(”#main_eventlist”).empty();
$jQ(”#main_eventlist”).append(events);
$jQ(”.pagination”).empty();
$jQ(”.pagination”).append(navigation);
Note that you should really make this so that it uses your jQuery variable. Here, we’re not using noConflict. noConflict should almost always be used, since you most likely will be using a non-jQuery item with your software. We also created two partials, namely one that just lists the lists. This could be used for anything that will update inside a div. The other thing that we created is a pagination partial, which is just a string definition.
This is pretty obvious. This just uses the methods present in all will_paginate derived objects to determine which page is present. One thing that we found is that we don’t always have access to all the methods and attributes, which is why it looks rather odd.
Here’s the javascript code that does the pagination:
var prevPaginate = function(id)
{
items = id.split('_')[1];
current_page = id.split(’_')[2];
next_page = parseInt(current_page) - 1;
next_page_key = “#page_” + next_page;
uri = parseMerbUri(window.location.href);
good_uri = window.location.href.split(”#”)[0];
next_page_key = good_uri + next_page_key;
hist.add(next_page_key);
query_string = uri + “?page=” + next_page;
if(next_page > 0)
{
jQuery.get(query_string, function(data){eval(data);});
return false;
}
}
var nextPaginate = function(id)
{
items = id.split(’_')[1];
current_page = id.split(’_')[2];
next_page = parseInt(current_page) + 1;
uri = parseMerbUri(window.location.href);
good_uri = window.location.href.split(”#”)[0];
next_page_key = good_uri + “#page_” + current_page;
hist.add(next_page_key);
query_string = uri + “?page=” + next_page;
jQuery.get(query_string, function(data){eval(data);});
return false;
}
Of course, we have a method that parses the URI so that we are going to the right resource. This is important for nested resources to do this, since we want to display the correct results. We also use the Nitobi history in this case because we want the back button to use the pagination, and not go back to the previous page in the history.
I’m going to make this more generic in the next couple of weeks and post the code to the blog, however this should be rather trivial for anyone to do once they know how will_paginate works and how to use the json data that it sends back.
Posted in Ruby, UI | No Comments »
Mesh Wireless goes to the Mainstream, (maybe) 
September 10th, 2007
I have a hobby of hacking the firmware on the Linksys WRT54G. I originally started doing it because I wanted to learn about how Embedded Linux worked, and I thought it was cool that it could run Linux. That’s how I got introduced to the Community Wireless movement.
Basically, the problem with the DIY Community Wireless hacking is that you’d have to either take off the shelf routers, flash them (and void your warantee) and then hope that you got something working. Then you can write applications for it like WifiDog, or various Mesh Networking Applications such as Optimised Link State Routing. This was great, but it ran into two big problems:
- It’s hard to convince someone to run a hacked Linksys router in their home, because it looks sketchy
- You’re at the whim of the manufacturer, who may not like that you can extend your hardware, or may change the hardware randomly or End of Life(EOL) it because they can make something that is cheaper.
In fact, the original Linksys WRT54G was changed after Version 4.0 to run vxworks because it took less processing power, voltage and memory to do what they wanted than they needed from their prior cookie-cutter design. Also, Netgear also discontinued the WGT634U because of similar logic. The reason I mention the WGT634U router is because that is what MIT Roofnet originally used to build the prototypes for what is now Meraki Mesh.
After BarCamp and talking to Boris at Bryght, I decided to buy some Meraki hardware. Now, I was expecting some unmarked boxes, and the devices to be large, but I was very suprised to find a branded box, like what you would find in FutureShop, and a very small device. Not only that, but it is extremely user friendly. I was also impressed with the range of the device. I put one in my Window at my apartment, and it seems to have a 100m (about 300 ft) range. Now, this is important, since the way mesh works is that you put a bunch of mesh nodes out into the world, and they route between each other to the nearest gateway node, the node with the least latency.
When I compare the Meraki out-of-the-box solution to the alternative, which is the Freifunk OLSR, there’s really no comparison for how easy it is to use. I think that Meraki has a very interesting project and it’s worth testing out. The main advantage of us testing out mesh is obvious, since we can facilitate a test bed for Ajax components in mobile devices right outside our window. With the release of the iPhone and the iPod touch (more importantly the iPod Touch, since we’re in Canada), content that is dynamic, and takes advantage of both geography, as well as the various user agents, is critical to providing a user experience like nothing else.
With more and more mobile devices equipped with Wifi for mass adoption, it just makes sense to at least play with the stuff. I’ll have pictures up here soon of us playing with the hardware!
Posted in FtN, General, Linux, UI, mesh | 1 Comment »
Nitobi Grid on Rails - Part 1 
July 5th, 2007
Even though we’re doing a lot of work in Ruby on Rails, and we blog about it a lot, we don’t sell a back-end for it. So the question that people may ask is how do we use our Components with Rails?
Here’s some information on how I’m using Rails with the current version of Grid. In Rails, you can use Builder to create XML, so the first thing that I am going to create is a grid controller. In that grid controller, I define a getHandler method, which looks like this:
def getHandler
if params[:SortColumn].nil?
@tblcustomer_pages, @tblcustomers = paginate :tblcustomers, :per_page => params[:PageSize].to_i
else
@tblcustomer_pages, @tblcustomers = paginate :tblcustomers, :per_page => params[:PageSize].to_i , :order => params[:SortColumn] + ” ” + params[:SortDirection]
end
render :layout => false
end
What this does is use the paginate function to do some pagination of the table. We set the PageSize using the Nitobi Grid’s PageSize paramater, and we use the SortColumn and the SortDirection coming into the function from the grid to determine the column sorting.
I then have a view (rxml) that looks like this:
xml.instruct! :xml, :version => “1.0″
xml.root(:fields => “CustomerName|ContactName”, :keys => “CustomerName|ContactName”) {
for tblcustomer in @tblcustomers
xml.e(:a => tblcustomer.CustomerName,:b =>tblcustomer.ContactName, :xk => tblcustomer.CustomerID)
end
}
This is very basic. I’m just starting out with builder, so I don’t have the Error Handler here. I suppose that I should have that there, but I don’t know what will happen if its nil. (I suspect it will break). That’s definitely something I’m going to have to ask around about.
And, I make sure that I have the getHandler set in the Grid Definition like this:
gethandler=”getHandler/”
Of course, I make sure to include grid and toolkit. Once this is all done, I have a grid that can load. I still have to get the savehandler working on Rails, but this should be enough to get started with Rails. If I find any interesting interactions with Grid, Toolkit and Prototype, I’ll post them here.
Posted in Grid, Rails, UI | 1 Comment »
This isn’t directly work related, but this is the coolest thing I ever made!!!! 
June 24th, 2007
I just finished hacking a bunch of Infrared LED lights, and here is a picture of the results:
So, this is a picture of my hand. This picture was taken by an off the shelf webcam that I modified to only pick up IR light. My hand is touching a piece of acrylic which has LEDs lighting the edges of it. When my hand touches the Acrylic, this causes the tips of my hand and the heel of my palm to form white blobs which can then be tracked by software. This is called FTIR. I now have a multi-touch interface, similar to the Microsoft Surface sitting at my home. The best part about it is that it’s cost me less than $400 to make. This touch screen is very similar to what Jeff Han is doing at his company, Perceptive Pixel.
This is mentioned on this blog because I think this changes everything. This is evident because of the upcoming release of the iPhone, which is also multi-touch. I think with devices like the table that I built (using instructions from multitouch.nl), Microsoft Surface and the iPhone, onclick may become antiquated. Of course someone already made something for Flash, so I guess that means that Adobe is already prepared for this, but what about the rest of us??
It’s definitely food for thought. I’ll be posting updates about the table to this blog, so stay tuned!
Posted in UI | No Comments »