Parsing RSS Feeds via Googles JS Feed API

So far we parsed our feeds with the acts_as_feed Rails plugin but as long as you only want to show them to users, there is an easier alternative: Googles JS Feed API!

Result

rss feed through google rss api

rss feed through google rss api

(The Example uses jQuery)
Example

<script type="text/javascript" src='http://jqueryjs.googlecode.com/files/jquery-1.3.1.js'></script>
<script type="text/javascript" src='http://www.google.com/jsapi?key=YOUR_API_KEY'></script><script>
google.load("feeds", "1");
$(function(){
  var feed = new google.feeds.Feed("http://rathershort.weblo.gg/rss.xml");
  feed.load(function(result) {
    if (result.error)return;
    $feed = $('#feed_entries');
    for (var i = 0; i < 3; i++) {
      var entry = result.feed.entries[i];
      $feed.append(
        '<div class="home_container_item">'+
          '<h3><a href="'+entry.link+'">'+entry.title.truncate(25)+'</a></h3>'+
          '<div class="small_gray">'+entry.publishedDate.toDate().formatted()+'</div>'+
          '<div>'+entry.contentSnippet.truncate(60)+'</div>'+
          '<br>'+
        '</div>'
        );
      }
    });
  });

//DATE
Date.shortMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
Date.prototype.formatted = function(){
  return this.getDate()+' '+Date.shortMonths[this.getMonth()]+' '+this.getFullYear();
};

//STRING
String.prototype.toDate = function(){
  var d = new Date();
  d.setTime(Date.parse(this));
  return d;
};

String.prototype.truncate = function(to_length){
  if(to_length >= this.length)return this;
  return this.substring(0, to_length-3)+'...';
};
</script>

Unobtrusive Autocomplete Rails Plugin

Auto complete solution, with customizable results (return just the word or word+id…) and no framework dependency, just use a plain text_field + class=> autocomplete and every autocomplete libary you like (included: jQuery).

autocomplete

# Controller
class UserController < ApplicationController
  autocomplete_for :user, :name
end

#Customized....
autocomplete_for :user, :name do |items,method|
  render :text => items.map{|item| "#{item.send(method)} -- #{item.id}"}.join("\n")
end

# View
<%= f.text_field :auto_user_name, :class => 'autocomplete', 'autocomplete_url'=>autocomplete_for_user_name_users_path %>

# Routes
map.resources :users, :collection => { :autocomplete_for_user_name => :get}

#JS
#any library you like
#(includes examples for jquery jquery.js + jquery.autocomplete.js + jquery.autocomplete.css )
jQuery(function($){//on document ready
  //autocomplete
  $('input.autocomplete').each(function(){
    var input = $(this);
    input.autocomplete(input.attr('autocomplete_url'));
  });
});

#Model(input/output association)
class User
  find_by_autocomplete('name')
end
class Post
  autocomplete_for('user','name') # auto_user_name= + auto_user_name
end
.

Not as thought free as the default version, but gives you a lot more control.

script/plugin install git://github.com/grosser/simple_auto_complete.git
README

jqUnit the jQuery Test Framework

My last project used jsUnit, but after some searching around, i found a great alternative: jqUnit!

It is a simple wrapper around the jQuery testrunner, so it is possible to run it with any library. And it is jsUnit compatible, so you can reuse all old tests.

Other features:

  • simple, just write test(‘it should find ids’,function(){ok(true)})
  • very light syntax ok(value,msg), equal(actual,expected,msg)…
  • DOM reset after every test
  • clean output, that can be opened/closed by clicking test-names
  • real user interaction ca be simulated with triggerEvent

Download Source and Demo
Demo Testsuite

Event delegation with almost any Selector

Always reapply the events to the DOM objects when they are inserted or loaded? NO MORE!

There are 3 solutions out there at the moment, jQuery listen, jQuery intercept both by event delegation addict Ariel Flesler and LiveQuery a plugin that reapplys all rules to every new DOM element loaded.

(Event delegation = every div.onclick will reach the parents of the div and can be captured there without binding directly to the div)

Listen and intercept both have a very limited selector choise, ‘a.b’ or ‘a#hello’. LiveQuery can be used rather thoughtfree but comes at a load-time-price for every existing/new element.

I like delegation more, but the selector choise is too limited. So here comes my
‘intercept any selector’ hack!

$.intercept(‘table td div.hello a#click :input’,’click’,fn) will bind your Event to the document, and run on every click of ‘table td…’. The lower you bind, the higher the performance cost(needless event checking)
$(‘table’).intercept(‘td div.hello a#click :input’,’click’,fn) will be faster…

As long as the DOM element you bound your events to is not replaced, all events will continue to work. This approach works best for few(and slow) rules that match many elements. There is no initial performance cost, so your page will load fast.

Only when a event is triggered the checking is done, and can be costly if you used a lot of events or a often triggered event (mouseover…).

The code you need to make it happen is here(insert into intercept.js):

  ...
    for( selector in handlers ){
      if( selector == 'self' && e.target == this || $.intercept.matches($target,selector))
        ret = handlers[selector].apply(this, arguments) !== false && ret;
    }
    return ret;
  };

  /**
   * Walk the element backwards and see if the selector matches (before reaching the document)
   * @see https://pragmatig.wordpress.com/2008/03/08/event-delegation-with-almost-any-selector/
   */
  $.intercept.matches = function(obj,selector){
    var root_reached = false;
    var words = selector.split(' ').reverse();
    for(i in words){
    	do{
    	  //match found?
    	  if(obj.is(words[i])){
    		  obj=$(obj.parent());
    		  break;
  	    }
    	  obj=$(obj.parent());
    	  root_reached = obj.get(0) == document;
      }while(!root_reached);
  	  if(root_reached)return false;
    }
    return !root_reached;
  };