Class: Gridify::Grid

Inherits:
Object
  • Object
show all
Includes:
Assertions
Defined in:
lib/gridify/grid.rb,
lib/gridify/grid_view.rb,
lib/gridify/grid_finder.rb,
lib/gridify/grid_options.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Assertions

#assert_exclusive_keys, #assert_valid_keys

Constructor Details

#initialize(klass, *args, &block) ⇒ Grid

todo: change this so klass is optional, decouple from active record



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/gridify/grid.rb', line 14

def initialize( klass, *args, &block )
  #debugger
  options = args.extract_options! # => args.last.is_a?(Hash) ? args.pop : {}
  assert_exclusive_keys( options, :only, :except)
  
  @resource = klass.to_s.tableize.pluralize
  @name = args.first || :grid
  
  # non-persistent options
  # generate model unless explicitly say no
  build_model = options.delete(:build_model) == false ? false : true
  only = options.delete(:only)
  except = options.delete(:except)
  col_presets = options.delete(:columns)
  
  # assign options
  update options
  
  # build columns from ActiveRecord model (klass)
  if klass.present? && build_model
    @model = build_columns klass, only, except, col_presets
  end
  
  instance_eval(&block) if block
  #(note instance_eval cannot access things outside its scope; otherwise do this:
  #yield self if block_given?
end

Instance Attribute Details

#search_rulesObject

current search/filter rules, as hash



4
5
6
# File 'lib/gridify/grid_finder.rb', line 4

def search_rules
  @search_rules
end

#search_rules_opObject

current search/filter rules, as hash



4
5
6
# File 'lib/gridify/grid_finder.rb', line 4

def search_rules_op
  @search_rules_op
end

Instance Method Details

#arranger_options(type) ⇒ Object

read-only



159
160
161
# File 'lib/gridify/grid_options.rb', line 159

def arranger_options(type) #read-only       
  (arranger[type] if arranger.is_a?(Hash)) || {}
end

#arranger_typeObject

read-only



151
152
153
154
155
156
157
# File 'lib/gridify/grid_options.rb', line 151

def arranger_type #read-only
  if arranger.is_a?(Hash)
    arranger.keys
  else
    Array(arranger)
  end
end

#collapsibleObject



181
182
183
# File 'lib/gridify/grid_options.rb', line 181

def collapsible
  @collapsible || @collapsed
end

#column(name, options = {}) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/gridify/grid.rb', line 47

def column( name, options={} )
  name = name.to_s
  klass = resource.classify.constantize
  # TODO: set edit options based on ar_column 
  # TODO: edit
  # TODO: handle file input types
  # TODO: custom input types 
  if col = columns_hash[name]
    # update an existing column
    col.update options
    
  elsif ar = klass.columns.detect {|c| c.name==name}
    #debugger
    # create column from database schema
    edit = editable && 
      # only edit accessible attributes
      (klass.accessible_attributes.nil? || klass.accessible_attributes.include?(ar.name))
    args = {
      :ar_column => ar,
      :name => ar.name,
      :value_type => ar.type,
      :searchable => searchable,
      :sortable => sortable,
      :editable => edit
    }.merge(options)
    columns << GridColumn.new( args)
    
  else
    # create column from scratch
    args = {
      :name => name,
      :value_type => :string,
      :searchable => searchable,
      :sortable => sortable,
      :editable => edit
    }.merge(options)
    columns << GridColumn.new( args)
  end
end

#column_modelObject



91
92
93
# File 'lib/gridify/grid.rb', line 91

def column_model
  columns.collect {|col| col.properties }
end

#column_namesObject



87
88
89
# File 'lib/gridify/grid.rb', line 87

def column_names
  columns.collect {|col| col.name.titleize }
end

#columns_hashObject

normally we need to keep columns an ordered array, sometimes its convenient to have a hash



96
97
98
# File 'lib/gridify/grid.rb', line 96

def columns_hash
  columns.inject({}) {|h, col| h[col.name] = col; h }
end

#current_scopeObject

return find args (scope) for current settings



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/gridify/grid_finder.rb', line 26

def current_scope
  #debugger
  find_args = {}
  if sort_by.present? && col = columns_hash[sort_by]
    if case_sensitive || !([:string, :text].include?(col.value_type))
      find_args[:order] = "#{sort_by} #{sort_order}" 
    else
      find_args[:order] = "upper(#{sort_by}) #{sort_order}" 
    end
  end
  if rows_per_page.present? && rows_per_page > 0
    find_args[:limit] = rows_per_page
    offset = (current_page.to_i-1) * rows_per_page if current_page.present?
    find_args[:offset] = offset if offset && offset > 0
  end
  cond = rules_to_conditions
  find_args[:conditions] = cond unless cond.blank?
  find_args
end

#data_formatObject



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/gridify/grid_options.rb', line 222

def data_format
  if @data_format || @data_format==false #explicit false for no param
    @data_format
  elsif resource && data_type == :xml
    {
      :root        => resource,
      :page        => resource+'>page',
      :total       => resource+'>total_pages',
      :records     => resource+'>total_records',
      :row         => resource.singularize,
      :repeatitems => false,
      :id          => :id
    }
  elsif resource && data_type == :json
    {
      :root        => resource,
      :page        => 'page',
      :total       => 'total_pages',
      :records     => 'total_records',
      :row         => resource.singularize,
      :repeatitems => false,
      :id          => :id
    }
  end
end

#data_typeObject



218
219
220
# File 'lib/gridify/grid_options.rb', line 218

def data_type
  @data_type || :xml
end

#dom_idObject



131
132
133
# File 'lib/gridify/grid_options.rb', line 131

def dom_id
  @dom_id || "#{resource}_#{name}"
end

#encode_records(records, total_count = nil) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/gridify/grid_finder.rb', line 54

def encode_records( records, total_count=nil )
  #debugger
  klass = resource.classify.constantize
  total_count ||= klass.count
  total_pages = total_count / rows_per_page + 1
  #TODO: :only => [attributes], :methods => [virtual attributes]
  case data_type
  when :xml then
    xml = records.to_xml( :skip_types => true, :dasherize => false ) do |xml|
      if rows_per_page > 0
        xml.page          current_page
        xml.total_pages   total_pages
        xml.total_records total_count
      end
    end
    
  when :json then
    #debugger
    data = { resource => records }
    if rows_per_page > 0       
      data.merge!( 
        :page => current_page, 
        :total_pages => total_pages, 
        :total_records => total_count 
      )
    end
    
    save = ActiveRecord::Base.include_root_in_json
    ActiveRecord::Base.include_root_in_json = false
    json = data.to_json
    ActiveRecord::Base.include_root_in_json = save
    json

  #others...
  else #nop ?
    records.to_s
  end
end

#error_containerObject



256
257
258
# File 'lib/gridify/grid_options.rb', line 256

def error_container
  @error_container || '.errorExplanation'
end

#error_handlerObject



248
249
250
# File 'lib/gridify/grid_options.rb', line 248

def error_handler
  @error_handler || 'gridify_action_error_handler'
end

#error_handler_return_valueObject



252
253
254
# File 'lib/gridify/grid_options.rb', line 252

def error_handler_return_value
  error_handler ? error_handler : 'true;'
end

#find(params) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/gridify/grid_finder.rb', line 46

def find( params )
  #debugger
  update_from_params params
  find_args = current_scope
  klass = resource.classify.constantize
  records = klass.send( finder, :all, find_args )
end

#find_and_encode(params) ⇒ Object



93
94
95
# File 'lib/gridify/grid_finder.rb', line 93

def find_and_encode( params )
  encode_records( find( params ) )
end

#finderObject



118
119
120
# File 'lib/gridify/grid_options.rb', line 118

def finder
  @finder || :find
end

#jqgrid_optionsObject



135
136
137
# File 'lib/gridify/grid_options.rb', line 135

def jqgrid_options
  @jqgrid_options || {}
end

#member_params(params) ⇒ Object

grid doesnt nest attributes inside the resource could change this behavior in jqGrid, see grid.postext.js ?

http://www.trirand.com/jqgridwiki/doku.php?id=wiki:post_data_module


101
102
103
# File 'lib/gridify/grid_finder.rb', line 101

def member_params( params )
  params.inject({}) {|h, (name, value)| h[name] = value if columns_hash[name]; h }
end

#pagerObject

pager layer



186
187
188
189
190
191
# File 'lib/gridify/grid_options.rb', line 186

def pager
  case @pager
  when String then @pager
  when true then dom_id+'_pager'
  end
end

#paging_choicesObject



197
198
199
# File 'lib/gridify/grid_options.rb', line 197

def paging_choices
  @paging_choices || [10,25,50,100]
end

#paging_controlsObject



193
194
195
# File 'lib/gridify/grid_options.rb', line 193

def paging_controls
  @paging_controls.nil? ? true : @paging_controls
end

#resizableObject



143
144
145
146
147
148
149
# File 'lib/gridify/grid_options.rb', line 143

def resizable
  return false if @resizable == false
  rs = { "minWidth" => 150, "minHeight" => 80 }
  rs.merge!({ "handles" => 's' }) if width_fit == :fluid
  rs.merge!( @resizable ) if @resizable.is_a?(Hash)
  rs
end

#restfulObject


attribute defaults and special value handling (sure it’d be easier to initialize defaults using a hash but we want nil to mean the jqGrid default - might be true - and not pass a value at all)



114
115
116
# File 'lib/gridify/grid_options.rb', line 114

def restful
  @restful==false ? false : true
end

#rows_per_pageObject



206
207
208
209
210
211
212
213
214
215
216
# File 'lib/gridify/grid_options.rb', line 206

def rows_per_page
  #debugger
  # all rows when pager controls or rows per page are off
  if !pager || paging_controls==false || @rows_per_page==false || @rows_per_page==-1
    -1
  elsif @rows_per_page.nil?
    paging_choices.first
  else
    @rows_per_page
  end
end

#searchableObject



122
123
124
# File 'lib/gridify/grid_options.rb', line 122

def searchable
  @searchable==false ? false : true
end

#select_rowsObject



163
164
165
166
167
168
169
# File 'lib/gridify/grid_options.rb', line 163

def select_rows
  if @select_rows
    @select_rows
  else
    pager && (view_button || edit_button || delete_button)
  end
end

#sortableObject



126
127
128
# File 'lib/gridify/grid_options.rb', line 126

def sortable
  @sortable==false ? false : true
end

#titleObject

header layer



172
173
174
175
176
177
178
179
# File 'lib/gridify/grid_options.rb', line 172

def title
  case @title
  when String then @title
  when true then resource.titleize
  else          
    ('&nbsp;' if collapsible || collapsed) #show header with blank title
  end
end

#to_javascript(options = {}) ⇒ Object


generate the grid javascript for a view options:

:script => true generates <script> tag (true)
:ready  => true generates jquery ready function (true)


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/gridify/grid_view.rb', line 11

def to_javascript( options={} )
  options = { :script => true, :ready => true }.merge(options)
  
  s = ''
  if options[:script]
    s << %Q^<script type="text/javascript">^       
  end

  s << js_helpers

  if options[:ready]
    s << %Q^jQuery(document).ready(function(){^    
  end
  
  s << jqgrid_javascript(options)
              
  if options[:ready]
    s << %Q^});^ 
  end
  if options[:script]
    s << %Q^</script>^
  end
  s     
end

#to_jsonObject



37
38
39
# File 'lib/gridify/grid_view.rb', line 37

def to_json
  jqgrid_properties.to_json_with_js
end

#to_s(options = {}) ⇒ Object

alias :to_s, :to_javascript



42
43
44
# File 'lib/gridify/grid_view.rb', line 42

def to_s( options={} )
  to_javascript( options )
end

#update(options) ⇒ Object



42
43
44
45
# File 'lib/gridify/grid.rb', line 42

def update( options )
  options.each {|atr, val| send( "#{atr}=", val )}
  # exception "invalid option..."
end

#update_from_params(params) ⇒ Object

finds records based on request params e.g. params from jqGrid

:_search      do search (true/false)  ["false"]
:sidx         sort index (column to search on)  [""]
:sord         sort direction (desc/asc)  ["asc"]
:nd           ?
:rows         number of items to get   ["20"]
:page         page number (starts at 1) ["1"]


16
17
18
19
20
21
22
23
# File 'lib/gridify/grid_finder.rb', line 16

def update_from_params( params )
  params.symbolize_keys!
  params_to_rules params
  self.sort_by       = params[:sidx] if params[:sidx]
  self.sort_order    = params[:sord] if params[:sord]
  self.current_page  = params[:page].to_i if params[:page]
  self.rows_per_page = params[:rows].to_i if params[:rows]
end

#urlObject

data



202
203
204
# File 'lib/gridify/grid_options.rb', line 202

def url
  @url || "/#{resource}"
end

#width_fitObject



139
140
141
# File 'lib/gridify/grid_options.rb', line 139

def width_fit
  @width_fit || :fluid
end