I’ve been trying to design a widget for my rails app and unfortunately find myself lacking in Javascript skills…
I was able to create a widget based on the short guide from this blog: http://www.eduvoyage.com/2008/8/3/widget-with-rails
But what I need is a little different from what they describe.
If you had a digg or tweetmeme-like application with votes for a particular article, how could you create a widget to display the votes?
Let’s say that an article model has a name, a link and a votes_counter.
This is what I tried:
In the articles controller:
def index
@article = Article.find_by_link("#{request.url}")
respond_to do |format|
format.js
format.html
end
end
In index.js.erb:
var txt = ''
txt += "<div id='article_widget'>";
txt += "<h2>Article vote count:</h2>";
txt += "<%= escape_javascript(@article.votes) %>";
txt += "</div>";
document.write(txt);
The problem I’m getting is that the @article turns out to be nil. To figured out what was wrong I added this bit of code to my javascript file:
txt += "<%= escape_javascript(request.url) %>";
The result on the screen was: http://localhost:3000/articles.js. Obviously I wouldn’t be able to use the find_by_link method when it just returns the path of the javascript file. What I’d like in the find_by_link method is the current url in the browser.
Or is there a better way to do this?
Is there a way to let my rails app know exactly which article is being referenced?
Many widgets actually run two pieces of code: Something like this:
Widget code on client site:
widget.js:You could then access it in Rails by using
params[:url]andparams[:title]This is not a complete solution as your second script would not have context as to where to place the widget. Most of the big ones (digg, tweetmeme) use
document.writebut I have a personal aversion to using it.If I were building this whole thing, I would probably have an empty div with an id be part of the widget code you have the user copy, or I might use
document.writein the firstjsfile to write out a holdingdivthat the second script can populate viagetElementById.One final word of warning: Be sure to clean the URL before matching. You don’t want
http://domain.comandhttp://domain.com/providing two different matches.