widget_list 1.1.7 → 1.1.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,8 +1,12 @@
1
1
  # WidgetList
2
2
  ====================
3
3
 
4
+ ****
5
+
4
6
  ## Introduction
5
7
 
8
+ ****
9
+
6
10
  This is my first gem ever!
7
11
 
8
12
  I feel like there are not very good lists in ruby/rails and/or dont care to find any because nothing will compare to widget_list's implementation.
@@ -11,31 +15,50 @@ In rails you have will_paginate and other ones like it using the ActiveRecord ap
11
15
 
12
16
  * A sleek ajaxified list
13
17
  * Supports *ALL Databases (Haven't tested everything yet though, I am sure there are tweaks for each DB). mysql, postgres, oracle and sqllite tested (basic example)
14
- * Full sorting ASC/DESC of list via ajax
18
+ * Full sorting ASC/DESC and paging/limits of list via ajax
15
19
  * Easily add row level buttons for each row
16
20
  * Custom tags to pass to be replaced by actual data from each column/value
17
- * Search bar/Ajax searching
21
+ * Automatic wildcard search support as well as CSV numeric parsing of when to perform a LIKE search or an IN statement on the primary keys
18
22
  * Column mappings and names
23
+ * Drill down link helper functions to allow user to click and filter the list by the particular record value
19
24
  * Checkboxes for each row for custom selection and mass actions
20
25
  * Session rememberance for each list/view of what was last sorted, which page the person was on, the limit and search filters
21
- * Ability to set a cool custom HTML arrow which draws a hidden DIV intended for someone to put custom widgets inside of to pass new filters to the list before it executes
26
+ * Ability to set a custom HTML arrow which draws a hidden DIV intended for someone to put custom widgets inside of to pass new filters to the list before it executes
22
27
  * Buttons for each row and areas on the bottom of the grid where you can add "Action buttons"
23
28
  * Export visible data as CSV
29
+ * Grouping/Predefined report filter feature
30
+
31
+ ****
24
32
 
25
33
  ## Screenshots
26
34
 
35
+ ****
36
+
27
37
  Main Example Loaded:
28
38
  ![](http://davidrenne.com/github/widget_list/main.png)
29
39
 
30
40
  Filter Drop Downs:
31
41
  ![](http://davidrenne.com/github/widget_list/filtered.png)
32
42
 
33
- Searching a row:
43
+ Searching a row (with wild card search):
34
44
  ![](http://davidrenne.com/github/widget_list/search.png)
35
45
 
46
+ Searching "name=asdf_18" (With ActiveRecord and Ransack hook):
47
+ ![](http://davidrenne.com/github/widget_list/ransack1.png)
48
+
49
+ Searching "name=asdf_18" and "sku<9000"(With ActiveRecord and Ransack hook):
50
+ ![](http://davidrenne.com/github/widget_list/ransack2.png)
51
+
52
+ Searching "name=asdf_18" and "sku < 9000" and "price > 67" (With ActiveRecord and Ransack hook):
53
+ ![](http://davidrenne.com/github/widget_list/ransack3.png)
54
+
55
+
56
+ ****
36
57
 
37
58
  ## Installation
38
59
 
60
+ ****
61
+
39
62
  Add this line to your application's Gemfile:
40
63
 
41
64
  ```ruby
@@ -49,15 +72,24 @@ Or install it yourself as:
49
72
  ```ruby
50
73
  $ gem install widget_list
51
74
  ```
75
+
76
+ ****
77
+
52
78
  ## Usage/Examples
53
79
 
80
+ ****
81
+
54
82
  You can either follow the below instructions or take a look at the changes here https://github.com/davidrenne/widget_list_example/commit/e4e8ab54edcf8bc4538b1850ee762c13bc6f5316
55
83
 
56
84
  I recommend if you use widget_list in production that you use config.consider_all_requests_local = true as errors will be handled but the base lists will still draw.
57
85
 
58
86
 
87
+ ****
88
+
59
89
  ## Feature Configurations
60
90
 
91
+ ****
92
+
61
93
  widget_list features and configurations primarily work by a single large hash passed to the constructor with the features you need for the given request which changes how the list is displayed or filtered.
62
94
 
63
95
  `name` - The unique name/id's of all the pieces that make up your widget list `default=([*('A'..'Z'),*('0'..'9')]-%w(0 1 I O)).sample(16).join`
@@ -154,6 +186,8 @@ widget_list features and configurations primarily work by a single large hash pa
154
186
 
155
187
  `listSearchForm` - Allows you to pass a custom form for the ARROW drop down for advanced searching `default=''`
156
188
 
189
+ `ransackSearch` - If you pass ModelName.search(params[:q]) ransack will show up in your advanced search `default=false`
190
+
157
191
  `columnStyle` - Column styles. KEY=column name VALUE= the inline style applied `default={}`
158
192
 
159
193
  `columnClass` - Column class. KEY=column name VALUE= the class name `default={}`
@@ -246,8 +280,11 @@ Style a row based on the value of the column.
246
280
 
247
281
  Go To http://localhost:3000/widget_list_examples/ruby_items
248
282
 
283
+ ****
284
+
249
285
  ### Example Calling Page That Sets up Config and calls WidgetList.render
250
286
 
287
+ ****
251
288
 
252
289
  ```ruby
253
290
  #
@@ -547,8 +584,12 @@ Style a row based on the value of the column.
547
584
  end
548
585
  ```
549
586
 
587
+ ****
588
+
550
589
  ## Contributing
551
590
 
591
+ ****
592
+
552
593
  1. Fork it
553
594
  2. Create your feature branch (`git checkout -b my-new-feature`)
554
595
  3. Commit your changes (`git commit -am 'Add some feature'`)
@@ -0,0 +1,10 @@
1
+ <div class="field">
2
+ <% local_assigns['ransack'].attribute_fields do |a| %>
3
+ <%= a.attribute_select %>
4
+ <% end %>
5
+ <%= local_assigns['ransack'].predicate_select %>
6
+ <% local_assigns['ransack'].value_fields do |v| %>
7
+ <%= v.text_field :value, :size => 10 %>
8
+ <% end %>
9
+ <%= link_to "remove", '#', class: "remove_fields" %>
10
+ </div>
@@ -0,0 +1,14 @@
1
+ <%= search_form_for local_assigns['search_object'], url: local_assigns['url'], method: :post, :authenticity_token => false do |f| %>
2
+
3
+ <%= f.condition_fields do |c| %>
4
+ <%= raw ActionController::Base.new.render_to_string(:partial => 'widget_list/condition_fields', :locals => { 'ransack' => c }) %>
5
+ <% end %>
6
+
7
+ <%
8
+ new_object = f.object.send "build_condition"
9
+ fields = f.send("condition_fields", new_object, child_index: "new_condition") do |c|
10
+ raw ActionController::Base.new.render_to_string(:partial => 'widget_list/condition_fields', :locals => { 'ransack' => c })
11
+ end
12
+ %>
13
+ <%= link_to("Add Conditions", '#', class: "add_fields", data: {id: "new_condition", fields: fields.gsub("\n", "")}) %>
14
+ <% end %>
data/lib/widget_list.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'ransack'
1
2
  require 'widget_list/version'
2
3
  require 'widget_list/hash'
3
4
  require 'widget_list/string'
@@ -192,6 +193,11 @@ module WidgetList
192
193
 
193
194
  @items = WidgetList::Widgets::populate_items(list,@items)
194
195
 
196
+ # If ransack is used
197
+ if @items['view'].class.name == 'ActiveRecord::Relation' && @items['ransackSearch'].class.name == 'Ransack::Search'
198
+ @items['ransackSearch'].build_condition if @items['ransackSearch'].conditions.empty?
199
+ end
200
+
195
201
  # current_db is a flag of the last known primary or secondary YML used or defaulted when running a list
196
202
  @current_db_selection = @items['database']
197
203
 
@@ -586,7 +592,7 @@ module WidgetList
586
592
  #
587
593
  # carryOverRequests will allow you to post custom things from request to all sort/paging URLS for each ajax
588
594
  #
589
- 'carryOverRequsts' => ['switch_grouping','group_row_id'],
595
+ 'carryOverRequsts' => ['switch_grouping','group_row_id','q'],
590
596
 
591
597
  #
592
598
  # Head/Foot
@@ -632,6 +638,7 @@ module WidgetList
632
638
  # Advanced searching
633
639
  #
634
640
  'listSearchForm' => '',
641
+ 'ransackSearch' => false,
635
642
 
636
643
  #
637
644
  # Column Specific
@@ -814,7 +821,7 @@ module WidgetList
814
821
  if key.include?(name)
815
822
  $_SESSION['list_checks'].delete(key)
816
823
  end
817
- } if $_SESSION.key?('list_checks')
824
+ } if $_SESSION.key?('list_checks') && !$_SESSION['list_checks'].nil? && !$_SESSION['list_checks'].empty?
818
825
 
819
826
  end
820
827
 
@@ -1022,9 +1029,6 @@ module WidgetList
1022
1029
  @templateFill['<!--HEADER_TXT_COLOR-->'] = @items['headerFontColor']
1023
1030
  @templateFill['<!--FOOTER_TXT_COLOR-->'] = @items['footerFontColor']
1024
1031
  @templateFill['<!--TITLE-->'] = @items['title']
1025
- @templateFill['<!--NAME-->'] = @items['name']
1026
- @templateFill['<!--JUMP_URL-->'] = WidgetList::Utils::build_url(@items['pageId'],listJumpUrl,(!$_REQUEST.key?('BUTTON_VALUE')))
1027
- @templateFill['<!--JUMP_URL_NAME-->'] = @items['name'] + '_jump_url'
1028
1032
  @templateFill['<!--CLASS-->'] = @items['class']
1029
1033
 
1030
1034
  if @totalRowCount > 0
@@ -1103,6 +1107,10 @@ module WidgetList
1103
1107
  @headerPieces['searchBar'] = WidgetList::Widgets::widget_input(list_search)
1104
1108
  @templateFill['<!--FILTER_HEADER-->'] = @headerPieces['searchBar']
1105
1109
 
1110
+ if @items['ransackSearch'] != false
1111
+ @templateFill['<!--RANSACK-->'] = ActionController::Base.new.render_to_string(:partial => 'widget_list/ransack_fields', :locals => { 'search_object' => @items['ransackSearch'], 'url' => '--JUMP_URL--'})
1112
+ end
1113
+
1106
1114
  end
1107
1115
 
1108
1116
  #
@@ -1171,6 +1179,11 @@ module WidgetList
1171
1179
  end
1172
1180
  end
1173
1181
 
1182
+ @templateFill['<!--NAME-->'] = @items['name']
1183
+ @templateFill['<!--JUMP_URL-->'] = WidgetList::Utils::build_url(@items['pageId'],listJumpUrl,(!$_REQUEST.key?('BUTTON_VALUE')))
1184
+ @templateFill['--JUMP_URL--'] = @templateFill['<!--JUMP_URL-->']
1185
+ @templateFill['<!--JUMP_URL_NAME-->'] = @items['name'] + '_jump_url'
1186
+
1174
1187
  rescue Exception => e
1175
1188
  out = '<tr><td colspan="50"><div id="noListResults">' + generate_error_output(e) + @items['noDataMessage'] + '</div></td></tr>'
1176
1189
  if !@templateFill.key?('<!--DATA-->')
@@ -1850,11 +1863,7 @@ module WidgetList
1850
1863
  end
1851
1864
 
1852
1865
  if WidgetList::List.get_db_type(items[:primary_database]) == 'oracle'
1853
- if $_REQUEST.key?('export_widget_list')
1854
- link = "#{items[:column_to_show]} #{WidgetList::List::is_sequel(items[:primary_database]) ? " as #{items[:column_alias]} " : ""}"
1855
- else
1856
- link = %[q'[<a style='cursor:pointer;color:#{items[:link_color]};' class='#{items[:column_alias]}_drill#{items[:column_class]}' onclick='#{items[:js_function_name]}("#{items[:drill_down_name]}", ListDrillDownGetRowValue(this) ,"#{items[:list_id]}"#{items[:extra_js_func_params]});#{items[:extra_function]}'>]' #{WidgetList::List::concat_string(items[:primary_database])}#{items[:column_to_show]}#{WidgetList::List::concat_string(items[:primary_database])}q'[</a><script class='val-db' type='text'>]' #{WidgetList::List::concat_string(items[:primary_database])} #{items[:data_to_pass_from_view]} #{WidgetList::List::concat_string(items[:primary_database])} q'[</script>]' #{WidgetList::List::concat_outer(items[:primary_database])} #{WidgetList::List::is_sequel(items[:primary_database]) ? " as #{items[:column_alias]} " : ""}]
1857
- end
1866
+ link = %[q'[<a style='cursor:pointer;color:#{items[:link_color]};' class='#{items[:column_alias]}_drill#{items[:column_class]}' onclick='#{items[:js_function_name]}("#{items[:drill_down_name]}", ListDrillDownGetRowValue(this) ,"#{items[:list_id]}"#{items[:extra_js_func_params]});#{items[:extra_function]}'>]' #{WidgetList::List::concat_string(items[:primary_database])}#{items[:column_to_show]}#{WidgetList::List::concat_string(items[:primary_database])}q'[</a><script class='val-db' type='text'>]' #{WidgetList::List::concat_string(items[:primary_database])} #{items[:data_to_pass_from_view]} #{WidgetList::List::concat_string(items[:primary_database])} q'[</script>]' #{WidgetList::List::concat_outer(items[:primary_database])} #{WidgetList::List::is_sequel(items[:primary_database]) ? " as #{items[:column_alias]} " : ""}]
1858
1867
  else
1859
1868
  if WidgetList::List.get_db_type(items[:primary_database]) == 'postgres'
1860
1869
  link = %['<a style="cursor:pointer;color:#{items[:link_color]};" class="#{items[:column_alias]}_drill#{items[:column_class]}" onclick="#{items[:js_function_name]}(''#{items[:drill_down_name]}'', ListDrillDownGetRowValue(this) ,''#{items[:list_id]}''#{items[:extra_js_func_params]});#{items[:extra_function]}">"' #{WidgetList::List::concat_string(items[:primary_database])}#{items[:column_to_show]}#{WidgetList::List::concat_string(items[:primary_database])}'</a><script class="val-db" type="text">' #{WidgetList::List::concat_string(items[:primary_database])} #{items[:data_to_pass_from_view]} #{WidgetList::List::concat_string(items[:primary_database])}'</script>' #{WidgetList::List::is_sequel(items[:primary_database]) ? " as #{items[:column_alias]} " : ""}]
@@ -1862,15 +1871,15 @@ module WidgetList
1862
1871
  link = %[#{WidgetList::List::concat_inner(items[:primary_database])}"<a style='cursor:pointer;color:#{items[:link_color]};' class='#{items[:column_alias]}_drill#{items[:column_class]}' onclick='#{items[:js_function_name]}(#{WidgetList::List::double_quote(items[:primary_database])}#{items[:drill_down_name]}#{WidgetList::List::double_quote(items[:primary_database])}, ListDrillDownGetRowValue(this) ,#{WidgetList::List::double_quote(items[:primary_database])}#{items[:list_id]}#{WidgetList::List::double_quote(items[:primary_database])}#{items[:extra_js_func_params]});#{items[:extra_function]}'>"#{WidgetList::List::concat_string(items[:primary_database])}#{items[:column_to_show]}#{WidgetList::List::concat_string(items[:primary_database])}"</a><script class='val-db' type='text'>"#{WidgetList::List::concat_string(items[:primary_database])} #{items[:data_to_pass_from_view]} #{WidgetList::List::concat_string(items[:primary_database])}"</script>"#{WidgetList::List::concat_outer(items[:primary_database])} #{WidgetList::List::is_sequel(items[:primary_database]) ? " as #{items[:column_alias]} " : ""}]
1863
1872
  end
1864
1873
  end
1865
-
1874
+
1866
1875
  if $_REQUEST.key?('export_widget_list')
1867
1876
  link = "#{items[:column_to_show]} #{WidgetList::List::is_sequel(items[:primary_database]) ? " as #{items[:column_alias]} " : ""}"
1868
1877
  end
1869
-
1878
+
1870
1879
  return link
1871
1880
 
1872
- end
1873
-
1881
+ end
1882
+
1874
1883
  def self.concat_string(primary)
1875
1884
 
1876
1885
  case WidgetList::List.get_db_type(primary)
@@ -1,5 +1,41 @@
1
1
  class Hash
2
2
 
3
+ def to_params
4
+ params = ''
5
+ stack = []
6
+
7
+ each do |k, v|
8
+ if v.is_a?(Hash)
9
+ stack << [k,v]
10
+ elsif v.is_a?(Array)
11
+ stack << [k,Hash.from_array(v)]
12
+ else
13
+ params << "#{k}=#{v}&"
14
+ end
15
+ end
16
+
17
+ stack.each do |parent, hash|
18
+ hash.each do |k, v|
19
+ if v.is_a?(Hash)
20
+ stack << ["#{parent}[#{k}]", v]
21
+ else
22
+ params << "#{parent}[#{k}]=#{v}&"
23
+ end
24
+ end
25
+ end
26
+
27
+ params.chop!
28
+ params
29
+ end
30
+
31
+ def self.from_array(array = [])
32
+ h = Hash.new
33
+ array.size.times do |t|
34
+ h[t] = array[t]
35
+ end
36
+ h
37
+ end
38
+
3
39
  # Merges self with another hash, recursively.
4
40
  #
5
41
  # This code was lovingly stolen from some random gem:
@@ -23,7 +23,11 @@ module WidgetList
23
23
  def self.build_query_string(args)
24
24
  q = []
25
25
  args.each { |k,v|
26
- q << k.to_s + '=' + URI.encode(URI.decode(v.to_s))
26
+ if v.class.name == 'Hash'
27
+ q << {k => v}.to_params
28
+ else
29
+ q << k.to_s + '=' + URI.encode(URI.decode(v.to_s))
30
+ end
27
31
  }
28
32
  q.join('&')
29
33
  end
@@ -1,3 +1,3 @@
1
1
  module WidgetList
2
- VERSION = "1.1.7"
2
+ VERSION = "1.1.8"
3
3
  end
@@ -771,3 +771,21 @@ jQuery(document).ready(function($) {
771
771
  });
772
772
  });
773
773
 
774
+ (function() {
775
+
776
+ jQuery(function() {
777
+ $('form').on('click', '.remove_fields', function(event) {
778
+ $(this).closest('.field').remove();
779
+ return event.preventDefault();
780
+ });
781
+ return $('form').on('click', '.add_fields', function(event) {
782
+ var regexp, time;
783
+ time = new Date().getTime();
784
+ regexp = new RegExp($(this).data('id'), 'g');
785
+ $(this).before($(this).data('fields').replace(regexp, time));
786
+ return event.preventDefault();
787
+ });
788
+ });
789
+
790
+ }).call(this);
791
+
@@ -766,7 +766,7 @@ ul#pagination li div.active
766
766
  /**
767
767
  * Search form
768
768
  */
769
- div#advanced-search-container ul.advanced-search-container-inline, div#advanced-search-container ul {list-style:none; margin:0px; padding:3px; height:51px; width:450px}
769
+ div#advanced-search-container ul.advanced-search-container-inline, div#advanced-search-container ul {list-style:none; margin:0px; padding:3px; width:450px}
770
770
  div#advanced-search-container ul.advanced-search-container-inline input.info-input, div#advanced-search-container ul input.info-input {font-size:11px}
771
771
  div#advanced-search-container ul.advanced-search-container-inline li {display:inline-block;width:428px; margin-top:4px;}
772
772
  div#advanced-search-container ul.advanced-search-container-inline li#required_message_inline {font-size:10px}
data/widget_list.gemspec CHANGED
@@ -23,7 +23,9 @@ Gem::Specification.new do |gem|
23
23
  # SEQUEL IS NOW OPTIONAL!! I am sure most people will be using ActiveRecord ORM
24
24
  # I am including it as a dependency just because it is easier to pull it down and have it available
25
25
  #
26
- gem.add_dependency('sequel', '3.42.0')
26
+ gem.add_dependency('sequel', '3.42.0')
27
+
28
+ gem.add_dependency('ransack', '0.7.2')
27
29
 
28
30
  gem.files = `git ls-files`.split($/)
29
31
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: widget_list
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.1.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-23 00:00:00.000000000 Z
12
+ date: 2013-04-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sequel
@@ -27,6 +27,22 @@ dependencies:
27
27
  - - '='
28
28
  - !ruby/object:Gem::Version
29
29
  version: 3.42.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: ransack
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.7.2
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.7.2
30
46
  description: An Advanced and flexible ajax data grid. Supports several databases where
31
47
  data is pulled from either using Sequel ORM (optional even though is a dependency),
32
48
  Active Record Models or Raw SQL.
@@ -50,6 +66,8 @@ files:
50
66
  - LICENSE.txt
51
67
  - README.md
52
68
  - Rakefile
69
+ - app/views/widget_list/_condition_fields.html.erb
70
+ - app/views/widget_list/_ransack_fields.html.erb
53
71
  - lib/extensions/action_controller_base.rb
54
72
  - lib/widget_list.rb
55
73
  - lib/widget_list/engine.rb