Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
TextMate's "cmd-T" functionality in a web app
Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
assets
lib
spec
tasks
.gitignore
MIT-LICENSE
README.textile
Rakefile
VERSION
init.rb
install.rb
super_finder.gemspec
uninstall.rb

README.textile

SuperFinder

TextMate’s “cmd-T” functionality right in your ruby on rails application. Results in the popup come from models you choose. Almost everything can be re-defined to match your needs.

I strongly suggest you to check our demo application to see how it looks.

Pre-requisities

ActiveRecord as ORM, jQuery and jQuery boxy plugin.

Installation

For now, only installation as a plugin is available.
Even if there are multiple steps to pass before using it, the installation is pretty simple.

script/plugin install git://github.com/did/super_finder.git

Then, in your config/routes.rb, just add at the end of your file the following statement:

SuperFinder::Routes.draw(map)

Register an new observer in config/environment.rb (or add it to your existing observers list). This observer is responsible for sweeping the cache.

config.active_record.observers = 'super_finder/cache_sweeper'

Define the behavior of the plugin by creating an initializer file (initializers/super_finder.rb for instance)

SuperFinder::Initializer.run do |config|
  config.models = [
    { :klass => Project, :column => :title },
    { :klass => Person, :column => :nickname }
  ]
end

Next, inside your application layout, just before the closing BODY tag, add this:

<%= super_finder_tag %>

Include the javascript and stylesheets files (do not forget to include jQuery as well):

<%= stylesheet_link_tag 'super_finder' %>
<%= javascript_include_tag 'boxy', 'super_finder' %>

Finally, put into your application.js

	
$(document).ready(function() {
	new SuperFinder({ button: $('#your-button a') })	
});

_Note: button is optional since we set up a shortcut (ALT-T)

That’s it !!!

Usage

There are 2 ways to display the popup and begin to search for something

  • Press ALT and t in your browser.
  • if you provide a css selector for button (see previous section), just click the button

Then, it’s pretty straigth forward, type some letters and use your keyboard arrows to select your item. Once you’re done, press ENTER.

You may want to change the color assigned to a label. Just add the following lines in one of your stylesheet files

div#superfinder li.project label { background-color: #64992c; }
div#superfinder li.task label { background-color: #5a6986; }
div#superfinder li.person label { background-color: #ec7000; }
div#superfinder li.account label { background-color: #5229a3; }

How it works ?

Thru its own controller, SuperFinder generates on the fly a js file storing by model all the records it found.
It means some important things:

  • It best fits for small collections of records. Not to fetch all the customers of an important e-commerce back-office.
  • Authentication and before_filter constraints can be applied. It prevents not authorized people to sneak at data.

The javascript output is just a single statement; it assigns the previous collection to a global javascript variable.
Then, a jquery uses this variable to emulate the same behaviour of the TextMate’s “cmd-T” functionality

More settings

Instead of writing hundred or thousands lines, I prefer to show you some examples:

Simple one

SuperFinder::Initializer.run do |config|
  config.models = [
    { :klass => Project, :column => :title },
    { :klass => Person, :column => :nickname }
  ]
end

Let’s say you have a project in db whose title is “Ruby on Rails” and id is 42. If you type, “ru” in the popup, “Ruby on Rails” will appear and if you press ENTER, you will be redirected to project_url(42).
Simple, isn’t it ?

I18n

For each entry displayed in the popup, a little label precising the model type is also displayed as well.
By default, SuperFinder will find the translation of activerecord.models. and if it’s missing humanize the model class name. But you can also define it !

SuperFinder::Initializer.run do |config|
  config.models = [
    { :klass => Project, :label => 'My fancy projects', :column => :title },
    { :klass => Task, :label => Proc.new { |controller| "blablabla" }, :column => :title },
    { :klass => Person, :column => Proc.new { |p| p.full_name } }
  ]
end

Urls

When pressing enter, you are redirected to the url of the selected entry. For each model, you can define your own url strategy.

SuperFinder::Initializer.run do |config|
  config.url = {
    :name_prefix  => 'admin',
    :action       => :edit # by default, :show
  }
  config.models = [
    { :klass => Project, :column => :title, :url => { :action => :show, :name_prefix =>nil } },
    { :klass => Task, :column => :title },
    { :klass => Person, :column => :nickname, :url => Proc.new { |controller, person| controller.my_url(person) } }
  ]
end

Generated urls will be:

  • project_url()
  • edit_admin_task_url()
  • edit_admin_task_url()
  • my_url()

Scoping / finder

Sometimes, one of your model is scoped and bound to an account for instance. The scoper object is generally retrieved from the controller based on subdomain.
SuperFinder allows you to use the scoper to find entries.

SuperFinder::Initializer.run do |config|
  config.scoper = {
    :column_id => :account_id,
    :getter => :current_account # name of controller method returning the scoper instance
  }
  config.models = [
    { :klass => Project, :column => :title },
    { :klass => Person, :column => :nickname, :scoper => false }
    { :klass => Task, :column => :title, :finder => Proc.new { |controller| Task.active.all } }
  ]
end

Controller filtering

Of course, you do not want bad people sneak at your data. No problems, here is the solution

SuperFinder::Initializer.run do |config|
  config.before_filters = [:must_be_authenticated]
  config.models = [
     { :klass => Project, :column => :title },
     { :klass => Person, :column => :nickname }
  ]
end

Note: beforefilters does not work in development mode for some class reloading issues.

Demo

A big thank you at Heroku’s people for their awesome service.

http://superfinder.heroku.com

Tests / Bugs / Evolutions

The plugin is fully tests with rspec (unit / functional tests). Into the plugin folder, type

rake

You may find bugs, sure you will actually. If you have time to investigate and solve them, just apply the classic procedure (fork, fix, test and submit).

For evolutions, you’re welcome to suggest your ideas. Contact me at didier at nocoffee dot fr.

Copyright © 2010 NoCoffee, released under the MIT license

Something went wrong with that request. Please try again.