Class: Gridify::Grid

Inherits:
Object
  • Object
show all
Includes:
Assertions
Defined in:
lib/jquery/gridify/grid.rb,
lib/jquery/gridify/grid_view.rb,
lib/jquery/gridify/grid_finder.rb,
lib/jquery/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
41
42
# File 'lib/jquery/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(:colModel)
  col_include = options[:colInclude]
  row_actions = options[:rowActions]

  # assign options
  update options

  # build columns from ActiveRecord model (klass)
  if klass.present? && build_model
    @model = build_columns(klass, only, except, col_presets, col_include, row_actions)
  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/jquery/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/jquery/gridify/grid_finder.rb', line 4

def search_rules_op
  @search_rules_op
end

Instance Method Details

#ajax_grid_optionsObject



162
163
164
# File 'lib/jquery/gridify/grid_options.rb', line 162

def ajax_grid_options
  @ajax_grid_options || {}
end

#arranger_options(type) ⇒ Object

read-only



186
187
188
# File 'lib/jquery/gridify/grid_options.rb', line 186

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

#arranger_typeObject

read-only



178
179
180
181
182
183
184
# File 'lib/jquery/gridify/grid_options.rb', line 178

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

#collapsibleObject



210
211
212
# File 'lib/jquery/gridify/grid_options.rb', line 210

def collapsible
  @collapsible || @collapsed
end

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



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
86
87
# File 'lib/jquery/gridify/grid.rb', line 49

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)
    colModel << GridColumn.new(args)

  else
    # create column from scratch
    args = {
        :name => name,
        :value_type => :string,
        :searchable => searchable,
        :sortable => sortable,
        :editable => edit
    }.merge(options)
    colModel << GridColumn.new(args)
  end
end

#column_modelObject



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

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

#column_namesObject



89
90
91
# File 'lib/jquery/gridify/grid.rb', line 89

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

#columns_hashObject

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



98
99
100
# File 'lib/jquery/gridify/grid.rb', line 98

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

#current_scopeObject

return find args (scope) for current settings



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/jquery/gridify/grid_finder.rb', line 34

def current_scope
  #debugger
  find_args = {}
  find_args[:include] = colInclude if colInclude
  if sort_by.present? && col = columns_hash[sort_by]
    if (sort_by.include? ".")
      # Workaround for :include and nested attributes
      field = sort_by.split('.', 2)
      if field.length == 2
        self.sort_by = field[0].pluralize + "." + field[1]
      end
    end
    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 total_rows.present? && total_rows > 0
    find_args[:limit] = total_rows
    offset = (current_page.to_i-1) * rows_per_page if current_page.present?
    find_args[:offset] = offset if offset && offset > 0
  elsif 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



257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/jquery/gridify/grid_options.rb', line 257

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',
        :records => resource+'>records',
        :row => resource.singularize,
        :repeatitems => false,
        :id => :id
    }
  elsif resource && data_type == :json
    {
        :root => resource,
        :page => 'page',
        :total => 'total',
        :records => 'records',
        :row => resource.singularize,
        :repeatitems => false,
        :id => :id
    }
  end
end

#data_typeObject



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

def data_type
  @data_type || :json
end

#dom_idObject



144
145
146
# File 'lib/jquery/gridify/grid_options.rb', line 144

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

#encode_records(records, userdata = nil, total_count = nil) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/jquery/gridify/grid_finder.rb', line 75

def encode_records(records, userdata=nil, 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
      if colInclude
        xml = records.to_xml(:include => colInclude, :skip_types => true, :dasherize => false) do |xml|
          if rows_per_page > 0
            xml.page current_page
            xml.total total_pages
            xml.records total_count
          end
        end
      else
        xml = records.to_xml(:skip_types => true, :dasherize => false) do |xml|
          if rows_per_page > 0
            xml.page current_page
            xml.total total_pages
            xml.records total_count
          end
        end
      end
    when :json
      #debugger
      data = {resource => records}
      if rows_per_page > 0
        data.merge!(
            :page => current_page,
            :total => total_pages,
            :records => total_count
        )
      end
      data.merge!(:userdata => userdata) if userdata
      save = ActiveRecord::Base.include_root_in_json
      ActiveRecord::Base.include_root_in_json = false
      if colInclude
        json = build_json(data);
      else
        json = data.to_json
      end
      ActiveRecord::Base.include_root_in_json = save
      json
    #others...
    else #nop ?
      records.to_s
  end
end

#error_containerObject



297
298
299
# File 'lib/jquery/gridify/grid_options.rb', line 297

def error_container
  @error_container || '.errorExplanation'
end

#error_handlerObject

def serialize_grid_data

  @serialize_grid_data || {}
end


289
290
291
# File 'lib/jquery/gridify/grid_options.rb', line 289

def error_handler
  @error_handler || 'gridify_action_error_handler'
end

#error_handler_return_valueObject



293
294
295
# File 'lib/jquery/gridify/grid_options.rb', line 293

def error_handler_return_value
  error_handler ? error_handler : 'true;'
end

#find(params) ⇒ Object



68
69
70
71
72
73
# File 'lib/jquery/gridify/grid_finder.rb', line 68

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

#find_and_encode(params) ⇒ Object



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

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

#finderObject



128
129
130
# File 'lib/jquery/gridify/grid_options.rb', line 128

def finder
  @finder || :find
end

#grid_viewObject



148
149
150
# File 'lib/jquery/gridify/grid_options.rb', line 148

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

#inline_editObject


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)



120
121
122
# File 'lib/jquery/gridify/grid_options.rb', line 120

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

#inline_edit_handlerObject



124
125
126
# File 'lib/jquery/gridify/grid_options.rb', line 124

def inline_edit_handler
  @inline_edit_handler || 'null'
end

#jqgrid_optionsObject



152
153
154
# File 'lib/jquery/gridify/grid_options.rb', line 152

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


134
135
136
# File 'lib/jquery/gridify/grid_finder.rb', line 134

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

#pagerObject

pager layer



215
216
217
218
219
220
221
222
# File 'lib/jquery/gridify/grid_options.rb', line 215

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

#paging_choicesObject



228
229
230
# File 'lib/jquery/gridify/grid_options.rb', line 228

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

#paging_controlsObject



224
225
226
# File 'lib/jquery/gridify/grid_options.rb', line 224

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

#resizableObject



170
171
172
173
174
175
176
# File 'lib/jquery/gridify/grid_options.rb', line 170

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



232
233
234
# File 'lib/jquery/gridify/grid_options.rb', line 232

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

#rows_per_pageObject



241
242
243
244
245
246
247
248
249
250
251
# File 'lib/jquery/gridify/grid_options.rb', line 241

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



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

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

#select_rowsObject



190
191
192
193
194
195
196
# File 'lib/jquery/gridify/grid_options.rb', line 190

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

#sortableObject



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

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

#sortable_rowsObject



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

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

#titleObject

header layer



199
200
201
202
203
204
205
206
207
208
# File 'lib/jquery/gridify/grid_options.rb', line 199

def title
  case @title
    when String
      @title
    when true
      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
35
36
37
38
39
40
41
42
43
# File 'lib/jquery/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">
    var lastsel_#{dom_id};
    ^
  end

  s << js_helpers

  if options[:ready]
    s << %Q^
    $(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



45
46
47
# File 'lib/jquery/gridify/grid_view.rb', line 45

def to_json
  jqgrid_properties.to_json_with_js
end

#to_s(options = {}) ⇒ Object

alias :to_s, :to_javascript



50
51
52
# File 'lib/jquery/gridify/grid_view.rb', line 50

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

#tree_gridObject

TreeGrid



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

def tree_grid
  @tree_grid || false
end

#update(options) ⇒ Object



44
45
46
47
# File 'lib/jquery/gridify/grid.rb', line 44

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
24
25
26
27
28
29
30
31
# File 'lib/jquery/gridify/grid_finder.rb', line 16

def update_from_params(params)
  params.symbolize_keys!
  params_to_rules params
  self.data_type = params[:datatype] if params[:datatype]
  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]
  self.total_rows = params[:total_rows].to_i if params[:total_rows]
  if tree_grid
    self.nodeid = params[:nodeid].to_i if params[:nodeid]
    self.n_level = params[:n_level].to_i if params[:n_level]
    self.n_left = params[:n_left].to_i if params[:n_left]
    self.n_right = params[:n_right].to_i if params[:n_right]
  end
end

#urlObject

data



237
238
239
# File 'lib/jquery/gridify/grid_options.rb', line 237

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

#width_fitObject



166
167
168
# File 'lib/jquery/gridify/grid_options.rb', line 166

def width_fit
  @width_fit || :fluid
end