Meet Netzke::GridPanel

Here's an instance of GridPanel, which by default provides for:

  • multiline CRUD-operations inside the grid itself
  • multi-record editing and adding records via a form
  • context menu
  • support for Rails validations
  • pagination
  • sorting
  • search filters (per column)
  • extended search (configurable, see the last widget below)
  • automatic column type detection (e.g. "salary" is a number column)
  • persistent on-the-fly configuration of the columns ("move", "resize" and "hide"-operations)
  • Code (in the view):

    netzke :bosses, 
      :class_name => "GridPanel", 
      :model => 'Boss'
    

    Result:

    Control over columns

    If you need more control over which columns to display and how, you can provide :columns option:

      netzke :bosses_custom_columns, 
        :class_name => "GridPanel", 
        :model => 'Boss', 
        :ext_config => {
          :rows_per_page => 20, 
          :title => "Bosses",
          :width => 400
        },
        :columns => [:id, # id should always be included and is by default hidden
          :last_name, 
          {:name => :salary, :editable => false, :label => "$", :renderer => 'usMoney'}, 
          {:name => :email, :width => 180}]
    

    Result:

    Model-wide configuration, associations, Rails validations and "virtual" columns

    Here's an example that demonstrates:

  • how GridPanel handles one-to-many associations
  • usage of "virtual" attributes (model's instance methods)
  • how to specify per model which columns should be picked up by grid, and how to preconfigure them
  • Rails' validations in action
  • # Model
    class Clerk < ActiveRecord::Base
      belongs_to :boss
    
      validates_presence_of :first_name
      validates_presence_of :last_name
    
      # a virtual attribute
      def name
        "#{last_name}, #{first_name}"
      end
    
      # another virtual attribute
      def updated
        updated_at > 5.minutes.ago
      end
    end
    
    # Declare and configure attributes specifically for GridPanel
    module Netzke::ModelExtensions
      class ClerkForGridPanel < Clerk
        # Virtual attribute defined in the model
        netzke_attribute :name, :renderer => "uppercase", :width => 200
        
        # Preconfigure a "real" attribute
        netzke_attribute :salary, :renderer => "usMoney"
        
        # Set the scopes for bosses listed in the association column
        netzke_attribute :boss__last_name, :editor => {:xtype => :combobox, :scopes => [["salary_greater_than", 95000]]}
        
        # Specify which columns and in which order to show
        netzke_expose_attributes :id, :name, :first_name, :last_name, :updated_bulb, :email, :salary, :boss__last_name      
        
        # Virtual attribute defined below (thus only to be shown in GridPanels)
        netzke_attribute :updated_bulb, :width => 40, :label => "<div class='bulb-off' />", :tooltip => "Recently updated"
        
        def updated_bulb
          bulb = updated ? "on" : "off"
          "<div class='bulb-#{bulb}' />"
        end
      end
    end
    
    # In the view:
    netzke :clerks, 
      :class_name => "GridPanel", 
      :model => 'Clerk'
    

    Result:

    Permissions

    You can specify which actions are allowed for this grid
    netzke :bosses_with_permissions, 
      :class_name => "GridPanel", 
      :model => 'Boss', 
      :ext_config => {
        :prohibit_update => true,
        :prohibit_delete => true
      }
    

    Result:

    A word about the security: it's not only about disabling buttons. Even if the user manages to submit a prohibited operation, the server side of the widget will block the attempt.

    Configuring the bars

    You can easily customize the bottom bar, or even move the actions to the top bar.

    netzke :clerks_with_custom_bottom_bar,
        :class_name => 'GridPanel',
        :model => 'Clerk',
        :ext_config => {
          :bbar => nil,
          :tbar => [{
            :menu => [:add, :edit, :apply, :del], :text => "Edit inline", :icon => "/images/icons/table.png"
          },{
            :menu => [:add_in_form, :edit_in_form], :text => "Edit in form", :icon => "/images/icons/application_form.png"
          }]
        }
    

    Result:

    Dynamic configuration

    Real power of the Netzke framework lies in its baked-in dynamic configurability. GridPanel and FormPanel from netzke-basepack provide interface to its configuration options. In real-life application these options are automatically stored per user/role, and can be quickly changed by the administrator with the help of masquerading. GridPanel below is configured to provide access to its configuration panel (click the "gear" tool on the right top of it) - use it to change different functional and representational aspects of this GridPanel instance. Besides that, the FormPanel-based forms for creating/editing records inherit the configuration mode, hence they are also configurable. And, finally, the search form is configurable as well: you can specify which criteria for search as you wish.

    Code:

    netzke :configurable_clerks, :class_name => "Wrapper", :item => {
      :class_name => "GridPanel", 
      :model => 'Clerk',
      :ext_config => {
        :mode => :config, # here we enable the configuration mode
        :title => "Configurable clerks"
      }
    }
    

    We wrap the grid up so that after changing its configuration it can be automatically reloaded without the need to reload the page. Btw, this touches another powerful concept behind the Netzke framework: ability to easily nest widgets.

    Result:

    Get the code

    Netzke framework consists of 2 Rails plugins/Ruby gems: netzke-core and netzke-basepack. Get them on the GitHub along with the source code for this demo: http://github.com/skozlov

    The news about Netzke development and more tutorials on http://blog.writelesscode.com

     

     

    --- The following links alter test data (the page will be reloaded):

    regenerate test data

    reset configs (e.g. columns configurations, permissions, etc )