Activescaffold Big Screen Touch Devices

Leave a comment

Well, it was only a question of time till one of my clients request better support for bigscreen touch devices such as iPad or some of these new Android tablets.
Have you every tried activescaffold with an iPad? Close Icon is too small, hover is nt supported, record actionlinks are not optimized for touch input…

We are facing at least two issues:

  1. We have to detect touch devices and apply improved css
  2. For some of these devices we have to fix hover issue

Activescaffold uses a new before_filter to identify touch devices, currently it just supports apple devices, but it can be easily overwritten:

def check_input_device
  if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod|iPad)/i]
    session[:input_device_type] = 'TOUCH'
    session[:hover_supported] = false
  else
    session[:input_device_type] = 'MOUSE'
    session[:hover_supported] = true
  end if session[:input_device_type].nil?
end

In addition two new helper methods are provided:

def touch_device?
  session[:input_device_type] == 'TOUCH'
end

def hover_via_click?
  session[:hover_supported] == false
end

And finally we added a new html class “as_touch” to activescaffold’s main div element to be able to apply different css stylings in case of a touch device.

At the end we improved activescaffold’s touchability a lot, it s not perfect but far better than before.

Hope that helps, wish you all a great weekend.

ActiveScaffold: FieldSearch Column Overrides

4 Comments

ActiveScaffold is quite powerful, but sometimes it might not fit your needs. That s why activescaffold offers you many options to extend/change activescaffold s features to your needs.
I would like to talk about FieldSearch Column Overrides today, as an example how you may extend activescaffold.

We will use my howto application as a starting point: howto installation.

Please activate field_search and human conditions in players controller:

active_scaffold :player do |conf|
  conf.actions.exclude :search
  conf.actions.add :field_search
  conf.field_search.columns = [:date_of_birth]
  conf.field_search.human_conditions = true
end

If you start the application you may try fieldsearch. date_of_birth is using activescaffold’s default date search ui.
Let s assume we have a special requirement and we would like to show a select box showing all existing date_of_birth values.

How to do that? It s really quite simple and it takes as only three steps:

search column override

Responsible for rendering our specific search_ui.

players_helper.rb
def date_of_birth_search_column(record, html_options)
  selected = html_options.delete :value
        
  players = Player.select('distinct date_of_birth').except(:order).order('date_of_birth DESC').all
  select_options = players.collect do |player|
    [ l(player.date_of_birth), player.date_of_birth ]
  end
  options = { :selected => selected,
                  :include_blank => as_(:_select_)}
  select(:record, :date_of_birth, select_options, options, html_options)
end

human condition column override

Responsible for rendering a special human condition.

players_helper.rb
def date_of_birth_human_condition_column(value, options)
  "#{Player.human_attribute_name(:date_of_birth)} = #{I18n.l(controller.class.condition_value_for_datetime(value, :to_date))}"
end

condition_for column override

Responsible for generating our special sql condition.

players_controller.rb
def self.condition_for_date_of_birth_column(column, value, like_pattern)
  ["#{column.search_sql} = ?", column.column.type_cast(value)]
end

My example used an override for one specific column, however you may as well override an existing search_ui type (such as :select or :multiselect) or just create your own search_ui type….

ActiveScaffold: singular polymorphic association inline actionlink

3 Comments

Quite a complicated subject for a post. 🙂 Hope at least some of you have an idea about the topic of this post.
Activescaffold supports concept of an inline actionlink, which is basically just a list column as a hyperlink. Out of the box it is used for associations to have a one click path to associated records. Unfortunetly, it was nt supported for singular polymorphic associations and in one of my projects I was missing this feature. I had to implement a log feature using a database as store. Each log statement should include a reference to the source. source was a perfect candidate for a polymorphic association.
I just had to extend activescaffold to support singular polymorphic assocation inline actionlinks.

I ve prepared a simple example app including invoice and applog model for those of you who are interesting in trying out.

Setup Example Application

  1. Download: one_step_active_scaffold
  2. Download: polymorphici_blog.rb and rename it to model_setup.rb
  3. Execute following command: ruby one_step_activescaffold.rb polymorphic_app jquery
  4. cd polymorphic_app
  5. rails s
  6. http://localhost:3000/invoices
  7. Create new invoice with a log entry
  8. http://localhost:3000/app_logs

ActiveScaffold: actions_for_association_links supporting list

9 Comments

Many of you know already that you may configure your inline actionlinks for singular associations columns.
Possible action values are :new, :show, :edit.

Let me show you a simple example. You would like to show “new” form in case player has nt got any team assigned and in case a team is assigned you would like to show “show” form

class PlayersController < ApplicationController
  active_scaffold :player do |conf|
    ....
    conf.columns[:team].actions_for_association_links = [:new, :show]
    ....
  end
end

I m using it quite often, however sometimes I was missing the option to show list view. That s why you have the following options these days: :new, :show, :edit and :list.

class PlayersController < ApplicationController
  active_scaffold :player do |conf|
    ....
    conf.columns[:team].actions_for_association_links = [:new, :list]
    ....
  end
end

Try it out. It s a shortcut for the user, all available information and actions for association model is just one click away and it s inline.

ActiveScaffold: Actionlink Parameters

4 Comments

A real quick one for today.

We will take a closer look at which options you have to pass addional url params to action_links.
My example is based upon my post: ActiveScaffold Confirmation of Actionlinks

Static Parameters

A static parameter is a simple key-value pair inside of a hash you may define for your actionlink:

class PlayersController < ApplicationController
  active_scaffold :player do |conf|
    ....
    conf.action_links.member.add 'fire', :confirm => 'are_you_sure', :type => :member, :method => :put, :position => false, :ignore_method => :ignore_fire_action?, :parameters => {:static => 'static'}
    ....
  end
end

Reload players controller in your browser and you see the new parameter ‘static’ attached to each fire action_link.

Dynamic Parameters

Static Parameters are nice, but well they are static.
However, it s also possible to do dynamic one s a s well and actually it s quite easy.

class PlayersController < ApplicationController
  active_scaffold :player do |conf|
    ....
    conf.action_links.add 'fire', :confirm => 'are_you_sure', :type => :member, :method => :put, :position => false, :ignore_method => :ignore_fire_action?, :parameters => {:static => 'static'}, :dynamic_parameters => Proc.new {{:dynamic => random_number}}
    ....
  end
end

We ve added the following to our action_link definition: :dynamic_parameters => Proc.new {{:dynamic => random_number}}
A simple Proc Object which is returning a hash including a key ‘dynamic’ with a value… random_number…. ??
Let me explain: our Proc object is called in scope of your helpers, which means you have access to any helper methods.
Therefore we define a helper method ‘random_number’ in our players_helper:

players_helper.rb
module PlayersHelper
  def random_number
    400 + rand(100)
  end
end

Wish you a great weekend.

ActiveScaffold: Single Table Inheritance (STI)

6 Comments

Today, I would like to show you an improved way to manage Single Table Inheritance with ActiveScaffold. It s a real time safer.
STI Models should hopefully have a big overlap of attributes, which is the base assumption for my implementation of STI in ActiveScaffold.

Basically, we will show an index view of parent sti controller, in which member actions such as edit, show,delete are linking to corresponding specific sti controller. Create link opens a popup menu showing the different sti models.

That s the concept let s try it out. I will use an example from the book: “Agile Web Development with Rails” written by Dave Thomas and David Heinemeier Hansson.
That example consist of the following models:

  1. Person (sti_parent)
  2. Customer
  3. Employee (Parent of Manager)
  4. Manager

It s quite tedious to set up an application with these models, therefore we will shorten that process.

Setup Example Application

  1. Download: one_step_active_scaffold
  2. Download: sti_blog.rb and rename it to model_setup.rb
  3. Execute following command: ruby one_step_activescaffold.rb sti jquery

Great, we ve prepared our example application, now we have to configure our controllers

Controller Inheritance

ActiveScaffold configuration can be inherited, which is quite useful for sti, because many columns are shared.

class CustomersController < PeopleController
class EmployeesController < PeopleController
class ManagersController < EmployeesController

Definition of column set for each Controller

We have to define for each controller, which columns we would like to use. Please note that we do not have to define anything specific for manager controller because it should use same settings as employee controller.

class PeopleController < ApplicationController
  active_scaffold :person do |conf|
    conf.columns = [:type, :name, :email]
  end
end 
class CustomersController < PeopleController
  active_scaffold :customer do |conf|
    conf.columns = [:type, :name, :email, :balance]
    conf.update.columns = [:name, :email, :balance]
    conf.create.columns = [:name, :email, :balance]
  end
end
class EmployeesController < PeopleController
  active_scaffold :employee do |conf|
     conf.columns = [:type, :name, :email, :boss, :department]
     conf.update.columns = [:name, :email, :boss, :department]
     conf.create.columns = [:name, :email, :boss, :department]
  end
end 

Parent Controller STI Child Models

One last step, we have to tell the parent controller, which sti_models he should be able to manage.

class PeopleController < ApplicationController
  active_scaffold :person do |conf|
    ....
    conf.sti_children = [:employee, :customer, :manager]
    ....
  end

Our Application is ready, start the server and go to: localhost:3000/people.

Hopefully, you will benefit as much as I did.

ActiveScaffold Gem

Leave a comment

Yes, ActiveScaffold is a available as gem. I think it s a great step forward and it will be easier than ever to integrate activescaffold into your projects. Finally, we ve managed to get it up and running and I would like to thank Chris Shoemaker for his contribution to this project.

Let me introduce to you the different options you have to integrate activescaffold into your project:

  1. Plugin
    rails plugin install git://github.com/vhochstein/active_scaffold.git -r 'rails-3.0'
    
  2. Gem
    gemfile:
    gem active_scaffold_vho
    
  3. Gem linked to git repository using rails 3.0
    gemfile:
    gem 'active_scaffold_vho', :git => 'git://github.com/vhochstein/active_scaffold.git', :branch => 'rails-3.0'
    
  4. Gem linked to git repository using rails 3.1 (not working)
    gemfile:
    gem 'active_scaffold_vho', :git => 'git://github.com/vhochstein/active_scaffold.git'
    

I ve updated One-Step-Install to use third option as a default and if you do not have git installed it will use second option.

All activescaffold plugins have been gemified as well:

Older Entries Newer Entries