apotomo-datatable 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # Apotomo-Datatable
2
+ Rails Gem for generating jQuery Datatables with extremely minimal configuration
3
+
4
+ Built on the Apotomo widget gem
5
+
6
+ Pacaged with jQuery Datatables version 1.9.4
7
+
8
+ Datatables may be rendered within a view (like a partial) or as javascipt for AJAX implementation
9
+
10
+ ## Usage
11
+
12
+ ### Gemfile
13
+ gem 'apotomo-datatable'
14
+ gem 'haml'
15
+
16
+ ### Simple use case for a given model/controller
17
+
18
+ #### items_controller.rb
19
+ has_widgets do |root|
20
+ root << datatable=widget('apotomo/datatable',:datatable)
21
+ end
22
+
23
+ #### Embedding with an HTML view
24
+ ##### view/items/index.html.haml
25
+ =render_widget :datatable,:display
26
+
27
+ #### AJAX rendering
28
+ ##### view/items/index.html.haml
29
+ %div#parentDiv
30
+ =link_to "Create table", items_path+'.js?template[parent]=parentDiv', :remote=>true, :title=>"Create table"
31
+ ##### view/items/index.js.haml
32
+ =render_widget :datatable,:display
33
+
34
+ ### Passing options from various points
35
+
36
+ #### items_controller.rb
37
+ root << datatable=widget('apotomo/datatable',:datatable,
38
+ :widget=>{}, #widget options (the model is derived from the controller name by default, but may be passed here as :model=>Model)
39
+ :template=>{:footer=>true}, #template options
40
+ :plugin=>{:sScrollY=>150} #plugin options, see: http://datatables.net/usage/options
41
+ )
42
+
43
+ def index
44
+ respond_to do |format|
45
+ format.html
46
+ format.js {render :script=>true}
47
+ end
48
+ end
49
+
50
+ # By defaultathe widget will query the model on its own
51
+ # If apotomo_datatable_datasource is defined, Apotomo::DatatableWidget.datasource will use this to populate
52
+ # The hash provided, which is expected to be standard search results from an ActiveRecord query, is encapsulated in a hash expected by jquery datatables
53
+
54
+ def apotomo_datatable_datasource(filter)
55
+ Item.find(:all,filter)
56
+ end
57
+
58
+ #### view/items/index.html.haml
59
+ %h1="Apotomo Datatable Example"
60
+
61
+ %h2="Rendered as HTML"
62
+ =render_widget :items_datatable,:display,:plugin=>{:sScrollY=>100,:bScrollCollapse=>true},:template=>{:id=>'html_datatable'}
63
+
64
+ %h2="Rendered via AJAX"
65
+
66
+ %div#parentDiv1
67
+ =link_to "Create table from options set in the URL", items_path+'.js?template[parent]=parentDiv1&plugin[sScrollY]=100', :remote=>true
68
+
69
+ :javascript
70
+ var plugin_options={sScrollY: 50, iDisplayStart: 20};
71
+
72
+
73
+ %div#parentDiv2
74
+ =link_to "Create table from options defined in javascript variable", items_path+'.js?template[plugin_options]=plugin_options&template[parent]=parentDiv2&template[id]=datatable_2', :remote=>true
75
+
76
+ #### index.js.haml
77
+ =render_widget :items_datatable,:display,:widget=>{},:template=>{:footer=>true},:plugin=>{:sScrollY=>150}
78
+
79
+
80
+ ## Options
81
+
82
+ The @options hash includes sub-hashes for the widget, templates and client-side plugin
83
+ @options={:widget=>{...}, :template=>{...}, :plugin=>{...}}
84
+
85
+ Default options are generated and merged with controller-provided options in Apotomo::DatatableWidget.set_options
86
+
87
+ Default options may be overridden from the controller, view, by URL parameters and by a client-side javascript hash, as seen in the example above, with the client-side javascript hash taking the highest precedence
88
+ client_side_options -> url_param_options -> view_options -> controller_options -> default_options
89
+
90
+ URL parameters may only define template and plugin options. Defining widget options from the URL would present a security hole
91
+
92
+ The client-side hash may only define plugin options. Since this hash is not passed to the server template and widget options would never be seen
93
+
94
+ $.extend(@options[:widget].to_json,client_side_options) constitutes the arguments passed to the datatable initialization function.
95
+ See http://datatables.net/usage/options for options. As such, any option specified in the jquery datatables API may be set in this sub hash
96
+ Note: Server-side processing is not yet supported
97
+
98
+ By default, :id, :created_at and :updated_at columns are excluded from display.
99
+ Pass the [:template][:excluded_columns] option to exclude more
100
+ Pass the [:template][:included_columns] option to include excluded columns
101
+
102
+ ## Current Status
103
+
104
+ The above examples will load a functional datatable, with sorting and global filtering working
105
+ Basic tests for loading and sorting are implemented. Sorting tests fail when plugin[bServerSide]=true since that is not implemented yet
106
+ Template for column-based filters started, but not yet complete or functional
107
+
108
+ ## TODO
109
+
110
+ Implement server-side sorting and filtering
111
+ Expand feature tests
112
+ Implementing the other base features
113
+ Move on to implementing plugins
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'ApotomoDatatable'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
29
+ require 'rspec/core'
30
+ require 'rspec/core/rake_task'
31
+ desc "Run all specs in spec directory (excluding plugin specs)"
32
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
33
+ task :default => :spec
34
+
35
+ =begin
36
+
37
+ Rake::TestTask.new(:test) do |t|
38
+ t.libs << 'test'
39
+ t.test_files = FileList['test/**/*_test.rb']
40
+ t.verbose = true
41
+ end
42
+
43
+
44
+
45
+ Bundler::GemHelper.install_tasks
46
+ =end
@@ -0,0 +1,11 @@
1
+ require 'apotomo/datatable_widget'
2
+ require 'apotomo-datatable/railtie'
3
+ module ApotomoDatatable
4
+ class Engine < Rails::Engine
5
+ # loads views from 'cell/views' and NOT from 'app/cells'
6
+ # config.paths.add 'app/cell_views', :with => 'cell/views'
7
+
8
+ # appends 'lib/my_cells_view_path' to this Railtie view path contribution
9
+ # config.paths['app/cell_views'] << 'lib/apotomo/datatable'
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ require "rails/railtie"
2
+
3
+ module ApotomoDatatable
4
+ class Railtie < ::Rails::Railtie
5
+ # rake_tasks do
6
+ # load "apotomo/apotomo.rake"
7
+ # end
8
+
9
+ # As we are a Railtie only, the routes won't be loaded automatically. Beside that, we want our
10
+ # route to be the very first (otherwise #resources might supersede it).
11
+ # initializer 'apotomo.prepend_routes', :after => :add_routing_paths do |app|
12
+ # app.routes_reloader.paths.unshift(File.dirname(__FILE__) + "/../../config/routes.rb")
13
+ # end
14
+
15
+ # Include a lazy loader via has_widgets.
16
+ # initializer 'apotomo.add_has_widgets' do |app|
17
+ # ActionController::Base.extend Apotomo::Rails::ControllerMethodsLoader
18
+ # end
19
+
20
+ initializer 'apotomo-datatable.setup_view_paths', :after => 'apotomo.setup_view_paths' do |app|
21
+ Apotomo::DatatableWidget.setup_view_paths!
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module ApotomoDatatable
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ /default apotomo-datatable view
2
+ -if @merged_options[:widget][:model]
3
+ %table{:id=>@merged_options[:template][:id],:class=>"display dataTable"}<>
4
+ -if @merged_options[:template][:header]
5
+ %thead<>
6
+ =render({:state=>:head_foot},@merged_options,:header);
7
+ %tbody<>
8
+ -if !@merged_options[:plugin][:sAjaxSource] and !@merged_options[:plugin][:aaData]
9
+ -@merged_options[:widget][:datasource].call().each do |item|
10
+ %tr<>
11
+ -item.attributes.each do |key,value|
12
+ -if !@merged_options[:template][:excluded_columns].include?(key.to_sym) or @merged_options[:template][:included_columns].include?(key.to_sym)
13
+ %td<>=value
14
+ -if @merged_options[:template][:footer]
15
+ %tfoot<>
16
+ =render({:state=>:head_foot},@merged_options,:footer);
17
+ -if !@merged_options[:params][:format]
18
+ :javascript
19
+ postInit(function() {
20
+ #{@init_datatable_js}
21
+ });
22
+ -"#{@merged_options[:plugin].inspect}"
23
+ -else
24
+ ="No Model Defined"
25
+
@@ -0,0 +1,2 @@
1
+ $("##{@merged_options[:template][:parent]}").append("#{@html}");
2
+ != "#{@init_datatable_js}"
@@ -0,0 +1,22 @@
1
+ %tr<>
2
+ -merged_options[:widget][:model].columns_hash.each_pair do |name,column|
3
+ -if !@merged_options[:template][:excluded_columns].include?(name.to_sym) or @merged_options[:template][:included_columns].include?(name.to_sym)
4
+ %th<>
5
+ - if merged_options[:template][section].respond_to?(:each_pair)
6
+ - inputs=merged_options[:template][section][name]
7
+ - unless inputs
8
+ - inputs=merged_options[:template][section][:default]
9
+ - else
10
+ - inputs=merged_options[:template][section]
11
+ - unless inputs.respond_to?(:each)
12
+ - inputs=[inputs]
13
+ - inputs.each do |opt|
14
+ - case opt
15
+ - when :label
16
+ =name
17
+ - when :input
18
+ %br<>
19
+ %input{:onclick=>"event.stopPropagation();"}<>
20
+ - when :select
21
+ %br<>
22
+ %select{:onclick=>"event.stopPropagation();"}<>
@@ -0,0 +1,303 @@
1
+ require 'apotomo'
2
+ #include Rails.application.routes.url_helpers
3
+
4
+ =begin
5
+ Apotomo-Datatables
6
+
7
+ Basic usage with default options:
8
+
9
+ Gemfile
10
+ gem 'apotomo-datatables'
11
+
12
+ items_controller.rb
13
+ root << items_datatable=widget('apotomo/datatable',:items_datatable)
14
+
15
+ index.html.haml
16
+ #render as HTML like a partial
17
+ =render_widget :items_datatable,:display
18
+
19
+ #render via AJAX
20
+ %div#parentDiv
21
+ =link_to "Create table from options set in the URL", items_path+'.js?template[parent]=parentDiv, :remote=>true
22
+
23
+ index.js.haml #used to render via AJAX
24
+ =render_widget :items_datatable,:display
25
+
26
+ =end
27
+
28
+ class Apotomo::DatatableWidget < Apotomo::Widget
29
+ DEFAULT_VIEW_PATHS << File.expand_path('../../', __FILE__)
30
+
31
+ responds_to_event :data #Used by sAjaxSource plugin option
32
+ responds_to_event :display
33
+ responds_to_event :test_evt, :with => :test_evt, :passing => :root
34
+
35
+ after_initialize do
36
+ ## set default options and those based on options provided in the has_widgets call in the controller
37
+ set_options(options)
38
+ @test_val=0
39
+ end
40
+
41
+ def test_val
42
+ @test_val
43
+ end
44
+
45
+ def increment_test_val
46
+ @test_val=@test_val+1
47
+ end
48
+
49
+ def test_evt(event)
50
+ if @merged_options[:widget][:controller].respond_to?(:apotomo_datatable_event)
51
+ @evt_test=@merged_options[:widget][:controller].apotomo_datatable_event(event)
52
+ end
53
+ end
54
+
55
+ def merged_options
56
+ @merged_options
57
+ end
58
+
59
+ def display(view_options={})
60
+ if view_options && view_options.respond_to?('each_pair')
61
+ ## merge options provided by the render_widget method call in the view
62
+ @merged_options.deep_merge!(view_options)
63
+ end
64
+
65
+ ## merge options from the URL params
66
+ merge_url_param_options(params)
67
+ process_boolean_options
68
+
69
+ ##Build json string to pass plugin options to the client
70
+ ##and command to merge with client-side plugin_options if provided
71
+ datatable_options=@merged_options[:plugin].to_json
72
+ if @merged_options[:template][:plugin_options]
73
+ datatable_options="$.extend(#{datatable_options},#{@merged_options[:template][:plugin_options]})"
74
+ end
75
+
76
+ #make sure :header and :footer are arrays
77
+ if @merged_options[:template][:header] && ! @merged_options[:template][:header].respond_to?('each') then @merged_options[:template][:header]=[@merged_options[:template][:header]] end
78
+ if @merged_options[:template][:footer] && ! @merged_options[:template][:footer].respond_to?('each') then @merged_options[:template][:footer]=[@merged_options[:template][:footer]] end
79
+
80
+
81
+ @init_datatable_js= "$(\"##{@merged_options[:template][:id]}\").dataTable(#{datatable_options});"
82
+
83
+ #this is just a test firing an event
84
+ @evt_test='empty'
85
+ self.fire :test_evt
86
+ if @merged_options[:params][:format]=='js'
87
+ #TODO: search the app's widget path for this template before using the default version
88
+ @html=render_to_string :file => File.expand_path('../../apotomo/datatable/display_html', __FILE__)
89
+ #escape double quotes and new lines, then make string safe so it's rendered properly
90
+ @html=@html.gsub(/[\n\r]/,' ').gsub(/"/,'\\\\"').html_safe
91
+ render :view=>:display_js
92
+ # render (replace :view=>:display_html, :selector=>'div#parent')+@init_datatable_js
93
+ else
94
+ render :view=>:display_html
95
+ # render :view=>File.expand_path('./datatable/display_html', __FILE__)
96
+ # render :view=>'app/widgets/apotomo/datatable/display_html'
97
+ end
98
+ end
99
+
100
+
101
+ # def view_for_state(state)
102
+ # "app/widgets/apotomo/datatable/#{state}"
103
+ # end
104
+
105
+ def datatable_init_vars
106
+ end
107
+
108
+ def head_foot(merged_options,section)
109
+ render :locals=>{:merged_options=>merged_options,:section=>section}
110
+ end
111
+
112
+ def data
113
+ is_searching = (params[:sSearch] and params[:sSearch].length>0)
114
+ @records=datasource
115
+ @data={
116
+ :iTotalRecords=>@merged_options[:widget][:model].count,
117
+ :iTotalDisplayRecords=>is_searching ? @records.count : @merged_options[:widget][:model].count,
118
+ :aaData=>@records
119
+ }
120
+ render text: @data.to_json
121
+ end
122
+
123
+ def datasource
124
+ #datatable passes something like
125
+ #"sEcho"=>"1", "iColumns"=>"5", "sColumns"=>"", "iDisplayStart"=>"0", "iDisplayLength"=>"10", "mDataProp_0"=>"id", "mDataProp_1"=>"text", "mDataProp_2"=>"created_at", "mDataProp_3"=>"updated_at", "mDataProp_4"=>"like", "sSearch"=>"", "bRegex"=>"false", "sSearch_0"=>"", "bRegex_0"=>"false", "bSearchable_0"=>"true", "sSearch_1"=>"", "bRegex_1"=>"false", "bSearchable_1"=>"true", "sSearch_2"=>"", "bRegex_2"=>"false", "bSearchable_2"=>"true", "sSearch_3"=>"", "bRegex_3"=>"false", "bSearchable_3"=>"true", "sSearch_4"=>"", "bRegex_4"=>"false", "bSearchable_4"=>"true", "iSortCol_0"=>"0", "sSortDir_0"=>"asc", "iSortingCols"=>"1", "bSortable_0"=>"true", "bSortable_1"=>"true", "bSortable_2"=>"true", "bSortable_3"=>"true", "bSortable_4"=>"true"
126
+ filter={}
127
+ is_searching = (params[:sSearch] and params[:sSearch].length>0)
128
+ if is_searching
129
+ filter[:conditions]=[@merged_options[:widget][:model].column_names.join(' LIKE :sSearch OR ')+' LIKE :sSearch',{:sSearch=>"%#{params[:sSearch]}%"}]
130
+ end
131
+ if params[:iDisplayStart] and params[:iDisplayLength]
132
+ filter[:limit]=params[:iDisplayLength]
133
+ filter[:offset]=params[:iDisplayStart]
134
+ end
135
+ if @merged_options[:widget][:controller].respond_to?('apotomo_datatable_datasource')
136
+ @records=@merged_options[:widget][:controller].apotomo_datatable_datasource(filter)
137
+ else
138
+ @records=@merged_options[:widget][:model].find(:all,filter)
139
+ end
140
+ return @records
141
+ end
142
+
143
+ def create
144
+
145
+ end
146
+
147
+ def edit
148
+
149
+ end
150
+
151
+ def update
152
+
153
+ end
154
+
155
+ def destroy
156
+
157
+ end
158
+
159
+ def set_options(controller_options)
160
+ =begin
161
+ Options:
162
+
163
+ The @merged_options hash includes primary keys for the widget, templates and client-side plugin
164
+ @merged_options={:widget=>{...}, :template=>{...}, :plugin=>{...}}
165
+
166
+ Default options are generated in Apotomo::DatatableWidget.set_options
167
+
168
+ Default options may be overridden from the controller, view, by URL parameters and by a client-side javascript hash, as seen in the example above,
169
+ with the client-side javascript hash taking the highest precedence
170
+ client_side_options -> url_param_options -> view_options -> controller_options -> default_options
171
+
172
+ URL parameters may only define template and plugin options. Defining widget options from the URL would present a security hole
173
+ The client-side hash may only define plugin options. Since it is not passed to the server, template and widget options would be irrelevant
174
+
175
+ $.extend(@merged_options[:widget].to_json,client_side_options) constitutes the arguments passed to the datatable initialization function.
176
+ See http://datatables.net/usage/options for options. As such, any option specified in the jquery datatables API may be set in this sub hash
177
+
178
+
179
+ =end
180
+ #initialize @merged_options, which will contain the final merged hash of options
181
+ @merged_options={:widget=>{},:template=>{},:plugin=>{}}.with_indifferent_access
182
+
183
+ #make sure options (passed by controller in has_widgets) has the basic hash structure
184
+ controller_options=controller_options.respond_to?(:each_pair) ? controller_options : {}.with_indifferent_access
185
+ controller_options=@merged_options.deep_merge(controller_options)
186
+ controller=parent_controller
187
+ if match=/(\w+?)sController/.match(controller.class.name.to_s)
188
+ controller_model_name=match[1]
189
+ end
190
+
191
+ #get model first since it is used to build other default options
192
+ model=nil
193
+ if controller_options[:widget].has_key?(:model)
194
+ if controller_options[:widget][:model].respond_to?("columns_hash")
195
+ model=controller_options[:widget][:model]
196
+ end
197
+ elsif controller_model_name
198
+ #derive the model from the controller name
199
+ if defined?(controller_model_name) && eval(controller_model_name+'.respond_to?("columns_hash")')
200
+ model=eval(controller_model_name)
201
+ end
202
+ end
203
+ if model==nil then
204
+ raise "Cannot use apotomo-datatable without a model. Either pass a model in the has_widgets method call or make sure a model exists with a name corresponding to the controller from which has_widgets is called"
205
+ end
206
+
207
+ default_options={
208
+ :widget=>{
209
+ :name=>"#{model.name}DatatableWidget",
210
+ :model=>model,
211
+ :controller=>controller,
212
+ :datasource=>self.method(:datasource),
213
+ :test_option=>'default'
214
+ },
215
+ :template=>{
216
+ #The header and footer have the same set of options.
217
+ #Each may contain multiple rows. Each row may define an array of options for each cell
218
+ #:header=
219
+
220
+ #Each may be a single value, an array or a hash
221
+ #If a single value or array, all columns are rendered with the provided options in order
222
+ #If a hash, each key should match column field names. Each key-value is a value or array as above
223
+ #single value or array options are: nil: ommited, label: label, input: input column filter, select: select column filter
224
+ # :header=>{:default=>:label,:name=>[:label,:input],:value=>[:label,:input]},
225
+ :header=>{:default=>:label},
226
+ :footer=>nil,
227
+ :id=>"#{model.name}Datatable",
228
+ :excluded_columns=>[:id,:created_at,:updated_at], #set to a list of field names to exclude from display
229
+ :included_columns=>[], #set to a list of columns to include even if they are excluded in :excluded_columns
230
+ :test_option=>'default'
231
+ },
232
+ :plugin=>{
233
+ :iDisplayStart=>0,
234
+ :bProcessing=>true,
235
+ :bJQueryUI=>true,
236
+ :test_option=>'default'
237
+ }
238
+ }.with_indifferent_access
239
+ default_options[:plugin][:aoColumns]=[]
240
+ model.column_names.each do |name|
241
+ default_options[:plugin][:aoColumns].push({'mDataProp'=>name})
242
+ end
243
+
244
+ # merge default options with options provided by the controller
245
+ @merged_options=default_options.deep_merge(controller_options)
246
+ @merged_options[:params]=params
247
+ end
248
+
249
+ def merge_url_param_options(url_param_options)
250
+ #:widget options are not accepted from URL parameters - accepting them would be a security hole
251
+ if url_param_options.has_key?(:template) && url_param_options[:template].respond_to?('each_pair')
252
+ @merged_options[:template].deep_merge!(url_param_options[:template])
253
+ end
254
+ if url_param_options.has_key?(:plugin) && url_param_options[:plugin].respond_to?('each_pair')
255
+ @merged_options[:plugin].deep_merge!(url_param_options[:plugin])
256
+ end
257
+ end
258
+
259
+ def process_boolean_options
260
+ #some options accept boolean options to indicate the default value (true) or undefined (false or nil)
261
+ #these must be processed after options from all sources have been merged
262
+ #Some true values are converted to default parameters for the plugin
263
+ #Some false values are deleted from the hash to allow the plugin to apply its own default options
264
+
265
+ ## if options[:plugin][:sAjaxSource] is boolean or nil, derive default if true and delete option value from controller
266
+ if @merged_options[:plugin].has_key?(:sAjaxSource)
267
+ sAjaxSource_bool=make_bool(@merged_options[:plugin][:sAjaxSource])
268
+ if sAjaxSource_bool
269
+ @merged_options[:plugin][:sAjaxSource]=url_for_event(:data)
270
+ unless @merged_options[:plugin].has_key?(:bServerSide)
271
+ @merged_options[:plugin][:bServerSide]=true # User server-side processing: http://datatables.net/ref#bServerSide
272
+ end
273
+ else
274
+ @merged_options[:plugin].delete(:sAjaxSource) #delete false or nil value to prevent invalid option from passing to plugin
275
+ end
276
+ end
277
+ ## profide column mapping if using ajax or aaData
278
+ ## provide aaData if requested
279
+ if sAjaxSource_bool || @merged_options[:plugin][:aaData]==true
280
+ if @merged_options[:plugin][:aaData]==true
281
+ records=datasource
282
+ @merged_options[:plugin][:aaData]=records
283
+ end
284
+ else
285
+ @merged_options[:plugin].delete(:aoColumns)
286
+ end
287
+ @merged_options[:plugin][:sAjaxSourceBOOL]=sAjaxSource_bool
288
+ end
289
+
290
+ def make_bool(val)
291
+ if !!val==val
292
+ return val
293
+ else
294
+ if val.is_a?(String) && val.downcase=="true"
295
+ return true
296
+ else
297
+ return false
298
+ end
299
+ end
300
+ end
301
+ end
302
+
303
+