ActiveScaffold Grouping actions

3 Comments

Sometimes I had the issue that my list view was configured with some action_links for nesting, crud actions and some additional ones. The resulting list view included a really huge action column on the right. The same sometimes happens for collection actions.

In my opinion a developer should be able to group these actions together to improve usability. If you agree, you will be happy because from now on Activescaffold offers that feature out of the box.

We will use my little howto application as usual.

First of all let s make sure that teams controller has a configured nested link.

class TeamsController < ApplicationController
  active_scaffold :team do |conf|
    ....
    conf.nested.add_link(:players) 
    ....
  end
end

Next we will create routing entries (conf/routes.rb) for a few dummy actions:

resources :teams do 
  as_routes 
  put :dummy1, : on => :collection 
  put :dummy2, : on => :collection 
  put :dummy3, : on => :collection 
  put :dummy1, : on => :member 
  put :dummy2, : on => :member 
  put :dummy3, : on => :member 
end 

Ok, that s it we ve prepared our application. Let s talk a little bit about the grouping of action_links.
Currently, if you want to add an action_link to your controller you do something like ‘conf.action_links << ….'. Internally, these are stored in an array. If list header is rendered all action_links of type 'collection' are selected and the same happens for type 'member' for each list row.

The grouping is achieved by changing the array to a tree structure. Leafs are representing action_links and nodes represent our groups. Two groups are automatically created: 'member' and 'collection'. I hope it s quite obvious why.

Let s start with the first example:
We would like to add all collection actions (create, search) to a group 'menu' for our teams controller.

class TeamsController < ApplicationController
  active_scaffold :team do |conf|
    ....
    conf.search.action_group = 'collection.menu' 
    conf.create.action_group = 'collection.menu' 
    ....
  end
end

If everything is working you should see a menu link at the top of your teams list view, which opens a "submenu" when hovering over it.

2. Example: We would like to group all member actions for all controllers (application_controller.rb).

ActiveScaffold.set_defaults do |conf| 
  conf.show.action_group = 'member.actions.crud' 
  conf.delete.action_group = 'member.actions.crud' 
  conf.update.action_group = 'member.actions.crud' 
  conf.nested.action_group = 'member.actions.nested'
end

3. Example: Adding collection actions to Teams Controller

class TeamsController < ApplicationController
  active_scaffold :team do |conf|
    ....
    conf.action_links.collection.custom do |group| 
      group.add 'dummy1', :confirm => 'are_you_sure', :type => :collection, :method => :put, :position => false
      group.level_2 do |group| 
        group.add 'dummy2', :confirm => 'are_you_sure', :type => :collection, :method => :put, :position => false 
      end 
      group.add 'dummy3', :confirm => 'are_you_sure', :type => :collection, :method => :put, :position => false 
    end 
    ....
  end
end

4. Example: Adding member actions to Teams Controller

class TeamsController < ApplicationController
  active_scaffold :team do |conf|
    ....
    conf.action_links.member.custom do |group| 
      group.add 'dummy1', :confirm => 'are_you_sure', :type => :member, :method => :put, :position => false
      group.level_2 do |group| 
        group.add 'dummy2', :confirm => 'are_you_sure', :type => :member, :method => :put, :position => false 
      end 
      group.add 'dummy3', :confirm => 'are_you_sure', :type => :member, :method => :put, :position => false 
    end 
    ....
  end
end

Wish you a great weekend.

Advertisements

ActiveScaffold FieldSearch with default search condition

11 Comments

Today I would like to introduce a new little feature for field search.
Let s assume you have a controller which shows lots of log entries and you would like to limit these log entries to the current day as a default, however if the user wants to take a look at older ones that should be also possible.

You might achieve that by using conditions_for_collection in your controller, but I think this is nt the right way.

The perfect solution for this requirement is a default field search condition. If user has nt specified a search condition we will use the default one.

Lets take a look how that might work. We do not have a log entry model, but howto app has a player model/controller.

Initially, We will setup our players controller to use fieldsearch and we will turn on human conditions:

class PlayersController < ApplicationController
  active_scaffold :player do |conf|
    conf.actions.swap :search, :field_search
    conf.field_search.human_conditions = true
  end
end

The following code will enable our default search condition:

  conf.field_search.default_params = {:salary => {"from"=>"400","to"=>"", "opt"=>"<"}}

I hope you except my excuse that there is nt a nice looking dsl to define a default search condition, but I ve decided to just use the format of the field search params sent by the field search form. The easiest why to get your required default_params value is by simply submitting the field search form and copying the params from your development log.
Our default search will only list players, which have a salary below 400.

That s already a cool thing, but let s assume you have a requirement to dynamically create a default search condition, e.g. specific to the current_user. That can be implemented by using a proc. I will show you with a quite stupid example, which will change our existing hard coded 400 to a random one.

Firstly, we have to add a method to our controller which returns a random number.

  def random_salary_limit
    400 + rand(100)
  end

Secondly, we have to adapt our existing default_params to use that random number method.

  conf.field_search.default_params = Proc.new { {:salary => {"from"=> random_salary_limit.to_s, "to"=>"", "opt"=>"<"}}}

You can try it out. If you click action link on the right-hand side of human condition in your list view you hopefully will see that human conditions will change after every click.

Thanks a lot for your attention and good luck.