widget_list 1.1.7 → 1.1.8

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/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