hot-glue 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c984f13c5f9639c6cea9837c4266cf0e4e529e9adef1dffea257551ebd80f8cd
4
- data.tar.gz: ba87601c2e04556604a7900880f054fd67b95ee78c9113668664ffb591c0601f
3
+ metadata.gz: 54b2a13a1fb9740be4ca14f108d98b72d8f1250b6131389c5e1d2130f07578cb
4
+ data.tar.gz: 15010c5e7fb34e35503b5a43aa563159d52f19c0b36f690ff03d67b7f1468060
5
5
  SHA512:
6
- metadata.gz: f9b1228beb6639f671f2138c0b62a891060da18089e23cb1a9f0518b77b0002e2c38018b18df49525f0dcf6b2715c6ed3c4c415bca8d203c8afad0c5113fad88
7
- data.tar.gz: 34e37814fe29eb58097331279107b1b58a4e9dbb4f3f9887c0e5c6b095d484c8a893034d3dafeed2ffbd5350a3cbd7542ee7dba4ffbd0a149b04a4b6a936ab8c
6
+ metadata.gz: 7b4c9a3e48ea19199f95314a4f0bbff28ca7dfd5635c8ee34e3e2304944ad227d31cb359db1d7c4200f75336ebdb20133cfdb3c762cbe034590630e6d3051a0a
7
+ data.tar.gz: c6c26412000d4bfa3ee27571aa430a8cf7b1c6dc454c55254a618bd312a14f754088ddb2dd77cf485dd69f433d06fe985a6ba34242f3df47607f4a3955703653
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hot-glue (0.6.1)
4
+ hot-glue (0.6.2)
5
5
  ffaker (~> 2.16)
6
6
  kaminari (~> 1.2)
7
7
  rails (> 5.1)
@@ -139,7 +139,7 @@ GEM
139
139
  mini_mime (1.1.2)
140
140
  mini_portile2 (2.8.4)
141
141
  minitest (5.16.3)
142
- net-imap (0.4.5)
142
+ net-imap (0.4.7)
143
143
  date
144
144
  net-protocol
145
145
  net-pop (0.1.2)
data/README.md CHANGED
@@ -63,10 +63,14 @@ Instantly get a simple CRUD interface
63
63
  _If you are on Rails 6, see [LEGACY SETUP FOR RAILS 6](https://github.com/jasonfb/hot-glue/README2.md) and complete those steps FIRST._
64
64
 
65
65
  ## The Super-Quick Setup
66
+ https://jasonfleetwoodboldt.com/courses/stepping-up-rails/jason-fleetwood-boldts-rails-cookbook/hot-glue-quick-install-mega-script/
67
+ Copy & paste the whole code block into your terminal.
68
+ Remember, there is a small "Copy" button at the top-right of the code block.
69
+ Be sure to use your Node + Ruby version managers to switch into the Node & Ruby versions **before running the quick script**.
66
70
 
67
- https://jasonfleetwoodboldt.com/courses/stepping-up-rails/jason-fleetwood-boldts-rails-cookbook/
68
71
 
69
- Copy & paste the whole code block from each section into your terminal. Remember, there is a small "Copy" button at the top-right of each code block to help you copy & paste the script into your terminal.
72
+ For more of a step-by-step, see the full cookbook at:
73
+ https://jasonfleetwoodboldt.com/courses/stepping-up-rails/jason-fleetwood-boldts-rails-cookbook/
70
74
 
71
75
  These are the sections you need, you can ignore any others:
72
76
 
@@ -1064,6 +1068,73 @@ Both should be wrapped in quotation marks when specified in the command line, an
1064
1068
  (Notice the funky indentation of the lines in the generated code. Adjust you input to get the indentation correct.)
1065
1069
 
1066
1070
 
1071
+ ## Searching
1072
+
1073
+ ### `--search` (options: simple, set, false predicate, default: false)
1074
+
1075
+
1076
+ #### Set Search
1077
+ If you specify `--search` to `set`, you will get a whole bar across the top of the list with search fields for each field.
1078
+ Within the set, the search query is **_combinative_** ("and"), so records matching all criteria are shown as the **result set.**
1079
+ For date pickers and time pickers, you need the additional Stimulus.
1080
+ Install this with :
1081
+
1082
+ ```
1083
+ bin/rails generate hot_glue:set_search_interface_install
1084
+ ```
1085
+
1086
+ _Additional search option for Set Search_
1087
+ ##### `--search-fields=aaa,bbb,ccc,ddd,eee`
1088
+ to specify which fields you want to be searchable.
1089
+
1090
+
1091
+ ##### `--search-query-fields=aaa,ddd`
1092
+ to specify a list of strings only which will be taken out of the search set and presented in a singular query box (allowing search across multiple string fields)
1093
+
1094
+ ##### `--search-position=vertical`
1095
+ to specify vertical or horizontal (default: horizontal)
1096
+
1097
+ ##### `--search-clear-button` (no option)
1098
+ to specify whether to show a clear button to clear the whole search form at once (default: false)
1099
+
1100
+ ##### `--search-autosearch` (no option)
1101
+ to specify whether to automatically search when the user exit or changes any field (default: false)
1102
+
1103
+ examples:
1104
+ ```
1105
+ bin/rails generate Thing --include=name,description --search=set --search-fields=name,description
1106
+ ```
1107
+
1108
+ _Make a searchable table with two foreign keys (author_id and category_id) and a query field for title, including a clear button._
1109
+ ```
1110
+ bin/rails generate Articles --inclue=title,author_id,category_id --search=set --search-fields=title,author_id,category_id --search-query-fields=title --search-clear-button
1111
+ ```
1112
+
1113
+ _Make a searchable table with vertical position and autosearch on._
1114
+ ```
1115
+ bin/rails generate Inications --inclue=patient_id,drug_id,quantity --search=set --search-fields=patient_id,drug_id --search-position=vertical --search-autosearch
1116
+ ```
1117
+
1118
+
1119
+ Here's how you would add a search interface to Example #1 in the [Hot Glue Tutorial](https://school.jfbcodes.com/8188)
1120
+ ```
1121
+ bin/rails generate Book --include=name,author_id --search=set --search-fields=name,author_id
1122
+ ```
1123
+
1124
+
1125
+
1126
+
1127
+
1128
+ #### Predicate
1129
+ NOT IMPLEMENTED YET
1130
+ TODO: implement me
1131
+
1132
+
1133
+
1134
+
1135
+
1136
+
1137
+
1067
1138
 
1068
1139
  ## Special Features
1069
1140
 
@@ -1535,6 +1606,45 @@ These automatic pickups for partials are detected at buildtime. This means that
1535
1606
 
1536
1607
  # VERSION HISTORY
1537
1608
 
1609
+ #### D2024-01-15 - v0.6.3
1610
+
1611
+ ## Set Searching
1612
+
1613
+ ### `--search` (options: set, false default: false)
1614
+
1615
+ (Future options include simple, predicate)
1616
+
1617
+ A set search is a search form that allows you to search across multiple fields at once. It is a set of search fields, each of which is a search field for a single field.
1618
+
1619
+
1620
+ #### Set Search
1621
+ If you specify `--search` to `set`, you will get a whole bar across the top of the list with search fields for each field.
1622
+ Within the set, the search query is **_combinative_** ("and"), so records matching all criteria are shown as the **result set.**
1623
+ For date pickers, time pickers, and the clear form interaction, you need the additional Stimulus JS.
1624
+ Install this with :
1625
+
1626
+ ```
1627
+ bin/rails generate hot_glue:set_search_interface_install
1628
+ ```
1629
+
1630
+ _Additional search option for Set Search_
1631
+ ##### `--search-fields=aaa,bbb,ccc,ddd,eee`
1632
+ to specify which fields you want to be searchable.
1633
+
1634
+ ##### `--search-query-fields=aaa,ddd`
1635
+ to specify a list of strings only which will be taken out of the search set and presented in a singular query box (allowing search across multiple string fields)
1636
+
1637
+ ##### `--search-position=vertical`
1638
+ to specify vertical or horizontal (default: horizontal)
1639
+
1640
+ ##### `--search-clear-button` (no option)
1641
+ to specify whether to show a clear button to clear the whole search form at once (default: false)
1642
+
1643
+
1644
+
1645
+
1646
+
1647
+
1538
1648
  #### 2023-12-02 - v0.6.2
1539
1649
 
1540
1650
  • Fixes to typeahead when using Pundit.
@@ -5,28 +5,42 @@ module HotGlue
5
5
  (tz >= 0 ? "+" : "-") + sprintf('%02d',tz.abs) + ":00"
6
6
  end
7
7
 
8
- def datetime_field_localized(form_object, field_name, value, label, nothing = nil )
8
+ def datetime_field_localized(form_object, field_name, value, **args )
9
9
  current_timezone
10
- form_object.text_field(field_name, class: 'form-control',
11
- type: 'datetime-local',
12
- value: date_to_current_timezone(value, current_timezone)) + timezonize(current_timezone)
10
+
11
+ args = args.merge({class: 'form-control',
12
+ type: 'datetime-local' })
13
+
14
+ if !value.nil?
15
+ args[:value] = date_to_current_timezone(value, current_timezone) + timezonize(current_timezone)
16
+ end
17
+
18
+ form_object.text_field(field_name, args)
19
+
13
20
  end
14
21
 
15
22
 
16
- def date_field_localized(form_object, field_name, value, label, timezone = nil )
17
- form_object.text_field(field_name, class: 'form-control',
18
- type: 'date',
19
- value: value )
23
+ def date_field_localized(form_object, field_name, value, **args)
24
+
25
+ form_object.text_field(field_name, args.merge({class: 'form-control',
26
+ type: 'date',
27
+ value: value }))
20
28
  end
21
29
 
22
- def time_field_localized(form_object, field_name, value, label )
30
+ def time_field_localized(form_object, field_name, value, **args )
23
31
  current_timezone
24
- form_object.text_field(field_name, class: 'form-control',
25
- type: 'time',
26
- value: value && value.strftime("%H:%M"))
32
+
33
+ form_object.text_field(field_name, args.merge({class: 'form-control',
34
+ type: 'time',
35
+ value: value }))
27
36
 
28
37
  end
29
38
 
39
+
40
+
41
+
42
+
43
+
30
44
  def current_timezone
31
45
  # returns a TimeZone (https://apidock.com/rails/TimeZone) object
32
46
  if defined?(current_user)
@@ -104,6 +118,96 @@ module HotGlue
104
118
  modified_params
105
119
  end
106
120
 
121
+ def string_query_constructor(match, search)
122
+ if match.blank? || search.blank?
123
+ nil
124
+ else
125
+ case match
126
+ when 'contains'
127
+ "%#{search}%"
128
+ when 'is_exactly'
129
+ "#{search}"
130
+ when 'starts_with'
131
+ "#{search}%"
132
+ when 'ends_with'
133
+ "%#{search}"
134
+ else
135
+ nil
136
+ end
137
+ end
138
+ end
139
+
140
+ def enum_constructor(field_name, value, **args)
141
+ return nil if value.blank?
142
+ ["#{field_name} = ?", value]
143
+ end
144
+
145
+
146
+ def date_query_constructor(field, match, search_start, search_end)
147
+ if match.blank?
148
+ nil
149
+ elsif ['is_on', 'not_on'].include?(match) && search_start.blank?
150
+ nil
151
+ elsif ['is_on_or_after','is_between'].include?(match) && (search_start.blank? )
152
+ nil
153
+ elsif ['is_before_or_on'].include?(match) && (search_end.blank? )
154
+ nil
155
+ elsif ['is_between'].include?(match) && (search_start.blank? || search_end.blank? )
156
+ nil
157
+ else
158
+ case match
159
+ when 'is_on'
160
+ ["#{field} = ?", search_start]
161
+ when 'is_on_or_after'
162
+ ["#{field} = ? OR #{field} > ?", search_start, search_start]
163
+ when "is_before_or_on"
164
+ ["#{field} = ? OR #{field} < ?", search_end, search_end]
165
+ when "is_between"
166
+ ["#{field} BETWEEN ? AND ?", search_start, search_end]
167
+ when "not_on"
168
+ ["#{field} != ?", search_start]
169
+ end
170
+ end
171
+ end
172
+
173
+ def time_query_constructor(field, match, search_start, search_end)
174
+ if match.blank?
175
+ nil
176
+ elsif ['is_at'].include?(match) && search_start.blank?
177
+ nil
178
+ elsif ['is_ar_or_after', 'is_before_or_at', 'is_between'].include?(match) && (search_start.blank? || search_end.blank?)
179
+ nil
180
+ else
181
+ case match
182
+ when 'is_at_exactly'
183
+ ["EXTRACT(HOUR FROM #{field}) = ?
184
+ AND EXTRACT(MINUTE FROM #{field}) = ? ", search_start.split(":")[0], search_start.split(":")[1]]
185
+ # when 'is_at_or_after'
186
+ # ["#{field} = ? OR #{field} > ?", search_start, search_start]
187
+ # when "is_before_or_at"
188
+ # ["#{field} = ? OR #{field} < ?", search_end, search_end]
189
+ # when "is_between"
190
+ # ["#{field} BETWEEN ? AND ?", search_start, search_end]
191
+ end
192
+ end
193
+ end
194
+
195
+ def association_constructor(field, search)
196
+ unless search.blank?
197
+ ["#{field} = ?", search]
198
+ else
199
+ nil
200
+ end
201
+ end
202
+
203
+ def boolean_query_constructor(field, search)
204
+ unless search.blank?
205
+ ["#{field} = ?", search]
206
+ else
207
+ nil
208
+ end
209
+ end
210
+
107
211
  private
108
212
 
109
213
  def server_timezone_offset # returns integer of hours to add/subtract from UTC
@@ -1,5 +1,7 @@
1
1
  module HotGlueHelper
2
2
 
3
+
4
+
3
5
  def enum_to_collection_select(hash)
4
6
  hash.collect{|k,v| OpenStruct.new({key: k, value: v})}
5
7
 
@@ -149,4 +149,76 @@ class AssociationField < Field
149
149
 
150
150
  "<%= #{singular}.#{assoc}.try(:#{display_column}) || '<span class=\"content \">MISSING</span>'.html_safe %>"
151
151
  end
152
+
153
+
154
+ def search_field_output
155
+
156
+ assoc_name = name.to_s.gsub("_id","")
157
+ assoc = eval("#{class_name}.reflect_on_association(:#{assoc_name})")
158
+ if modify_as && modify_as[:typeahead]
159
+ search_url = "#{namespace ? namespace + "_" : ""}#{assoc.class_name.downcase.pluralize}_typeahead_index_url"
160
+
161
+ # \"q[0][#{name}_search]\"
162
+ # @q['0']['#{name}_search']
163
+ "<div class='typeahead typeahead--q_0_#{name}_search'
164
+ data-controller='typeahead'
165
+ data-typeahead-url-value='<%= #{search_url} %>'
166
+ data-typeahead-typeahead-results-outlet='#search-results'>
167
+ <%= text_field_tag \'q[0][#{name}_search]_query\', '', placeholder: 'Search #{assoc.plural_name}', class: 'search__input',
168
+ data: { action: 'keyup->typeahead#fetchResults keydown->typeahead#navigateResults', typeahead_target: 'query' },
169
+ autofocus: true,
170
+ autocomplete: 'off',
171
+ value: @q['0']['#{name}'] ? #{assoc.class_name}.find(@q['0']['#{name}']).try(:name) : \"\" %>
172
+ <%= f.hidden_field \'q[0][#{name}]\', value: @q['0']['#{name}_search'].try(:id), 'data-typeahead-target': 'hiddenFormValue' %>
173
+ <div data-typeahead-target='results'></div>
174
+ <div data-typeahead-target='classIdentifier' data-id=\"typeahead--q_0_#{name}_search\"></div>
175
+ </div>"
176
+ else
177
+ if assoc.nil?
178
+ exit_message = "*** Oops. on the #{class_name} object, there doesn't seem to be an association called '#{assoc_name}'"
179
+ exit
180
+ end
181
+
182
+ is_owner = name == ownership_field
183
+ assoc_class_name = assoc.class_name.to_s
184
+ display_column = HotGlue.derrive_reference_name(assoc_class_name)
185
+
186
+ if hawk_keys[assoc.foreign_key.to_sym]
187
+ hawk_definition = hawk_keys[assoc.foreign_key.to_sym]
188
+ hawked_association = hawk_definition[:bind_to].join(".")
189
+ else
190
+ hawked_association = "#{assoc.class_name}.all"
191
+ end
192
+
193
+ (is_owner ? "<% unless @#{assoc_name} %>\n" : "") +
194
+ " <%= f.collection_select(\"q[0][#{name}_search]\", #{hawked_association}, :id, :#{display_column}, {include_blank: true, selected: @q['0']['#{name}_search'] }, class: 'form-control') %>\n" +
195
+ (is_owner ? "<% else %>\n <%= @#{assoc_name}.#{display_column} %>" : "") +
196
+ (is_owner ? "\n<% end %>" : "")
197
+ end
198
+
199
+
200
+ # " "+
201
+ # "\n <%= f.select 'q[0][#{name}_match]', options_for_select([['', ''], ['is on', 'is_on'], " +
202
+ # "\n ['is between', 'is_between'], ['is on or after', 'is_on_or_after'], " +
203
+ # "\n ['is before or on', 'is_before_or_on'], ['not on', 'not_on']], @q[\'0\']['#{name}_match'] ), {} ," +
204
+ # "\n { class: 'form-control match', 'data-action': 'change->date-range-picker#matchSelection' } %>"+
205
+ # "\n <%= date_field_localized f, 'q[0][#{name}_search_start]', @q[\'0\'][:#{name}_search_start], autocomplete: 'off', size: 40, class: 'form-control', type: 'text', placeholder: 'start', 'data-date-range-picker-target': 'start' %>" +
206
+ # "\n <%= date_field_localized f, 'q[0][#{name}_search_end]', @q[\'0\'][:#{name}_search_end], autocomplete: 'off', size: 40, class: 'form-control', type: 'text', placeholder: 'end' , 'data-date-range-picker-target': 'end'%>" +
207
+ # "\n "
208
+ end
209
+
210
+
211
+ def where_query_statement
212
+ ".where(*#{name}_query)"
213
+ end
214
+
215
+ def load_all_query_statement
216
+ if modify_as && modify_as[:typeahead]
217
+ "#{name}_query = association_constructor(:#{name}, @q['0'][:#{name}])"
218
+ else
219
+ "#{name}_query = association_constructor(:#{name}, @q['0'][:#{name}_search])"
220
+ end
221
+ end
222
+
223
+
152
224
  end
@@ -78,4 +78,34 @@ class BooleanField < Field
78
78
  def label_class
79
79
  super + " form-check-label"
80
80
  end
81
+
82
+
83
+
84
+ def search_field_output
85
+ " <%= f.radio_button('q[0][#{name}_match]', '-1', checked: @q[\'0\']['#{name}_match']==-1 ? '' : 'checked', class: '#{@layout_strategy.form_checkbox_input_class}') %>\n" +
86
+ " <%= f.label('q[0][#{name}_match]', value: '-1', for: 'q[0][#{name}_match]_-1' ) %>\n" +
87
+
88
+ " <%= f.radio_button('q[0][#{name}_match]', '0', checked: @q[\'0\']['#{name}_match']==0 ? '' : 'checked', class: '#{@layout_strategy.form_checkbox_input_class}') %>\n" +
89
+ " <%= f.label('q[0][#{name}_match]_0', value: '#{modify_binary? && modify_as[:binary][:falsy] || 'No'}', for: 'q[0][#{name}_match]_0') %>\n" +
90
+ " <br /> <%= f.radio_button('q[0][#{name}_match]', '1', checked: @q[\'0\']['#{name}_match']==1 ? 'checked' : '' , class: '#{@layout_strategy.form_checkbox_input_class}') %>\n" +
91
+ " <%= f.label('q[0][#{name}_match]_1', value: '#{modify_binary? && modify_as[:binary][:truthy] || 'Yes'}', for: 'q[0][#{name}_match]_1') %>\n"
92
+
93
+
94
+ # "<%= f.select 'q[0][#{name}_match]', options_for_select([['', ''], ['contains', 'contains'], ['is exactly', 'is_exactly'], ['starts with', 'starts_with'], ['ends with', 'ends_with']], @q[\'0\']['#{name}_match'] ), {} , { class: 'form-control match' } %>"+
95
+ # "<%= f.text_field 'q[0][#{name}_search]', value: @q[\'0\'][:#{name}_search], autocomplete: 'off', size: 40, class: 'form-control', type: 'text' %>"
96
+ end
97
+
98
+
99
+ def where_query_statement
100
+ ".where('#{name} ILIKE ?', #{name}_query)"
101
+ end
102
+
103
+ def load_all_query_statement
104
+ "#{name}_query = boolean_query_constructor(@q['0'][:#{name}_match], @q['0'][:#{name}_search])"
105
+ end
106
+
107
+ # def code_to_reset_match_if_search_is_blank
108
+ # " @q['0'][:#{name}_match] = '' if @q['0'][:#{name}_search] == ''"
109
+ # end
110
+
81
111
  end
@@ -10,7 +10,7 @@ class DateField < Field
10
10
 
11
11
 
12
12
  def form_field_output
13
- "<%= date_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }') %>"
13
+ "<%= date_field_localized(f, :#{name}, #{singular}.#{name}, label: '#{ name.to_s.humanize }') %>"
14
14
  end
15
15
 
16
16
  def line_field_output
@@ -20,4 +20,24 @@ class DateField < Field
20
20
  <span class=''>MISSING</span>
21
21
  <% end %>"
22
22
  end
23
+
24
+ def search_field_output
25
+ " <div data-controller='date-range-picker' >"+
26
+ "\n <%= f.select 'q[0][#{name}_match]', options_for_select([['', ''], ['is on', 'is_on'], " +
27
+ "\n ['is between', 'is_between'], ['is on or after', 'is_on_or_after'], " +
28
+ "\n ['is before or on', 'is_before_or_on'], ['not on', 'not_on']], @q[\'0\']['#{name}_match'] ), {} ," +
29
+ "\n { class: 'form-control match', 'data-action': 'change->date-range-picker#matchSelection' } %>"+
30
+ "\n <%= date_field_localized f, 'q[0][#{name}_search_start]', @q[\'0\'][:#{name}_search_start], autocomplete: 'off', size: 40, class: 'form-control', type: 'text', placeholder: 'start', 'data-date-range-picker-target': 'start' %>" +
31
+ "\n <%= date_field_localized f, 'q[0][#{name}_search_end]', @q[\'0\'][:#{name}_search_end], autocomplete: 'off', size: 40, class: 'form-control', type: 'text', placeholder: 'end' , 'data-date-range-picker-target': 'end'%>" +
32
+ "\n </div>"
33
+ end
34
+
35
+
36
+ def where_query_statement
37
+ ".where(*#{name}_query)"
38
+ end
39
+
40
+ def load_all_query_statement
41
+ "#{name}_query = date_query_constructor(:#{name}, @q['0'][:#{name}_match], @q['0'][:#{name}_search_start], @q['0'][:#{name}_search_end])"
42
+ end
23
43
  end
@@ -34,7 +34,7 @@ class DateTimeField < Field
34
34
  end
35
35
 
36
36
  def form_field_output
37
- "<%= datetime_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }') %>"
37
+ "<%= datetime_field_localized(f, :#{name}, #{singular}.#{name}, label: '#{ name.to_s.humanize }' ) %>"
38
38
  end
39
39
 
40
40
  def viewable_output
@@ -48,4 +48,24 @@ class DateTimeField < Field
48
48
  <% end %>"
49
49
  end
50
50
  end
51
+
52
+ def search_field_output
53
+ " <div data-controller='date-range-picker' >"+
54
+ "\n <%= f.select 'q[0][#{name}_match]', options_for_select([['', ''], ['is on', 'is_on'], " +
55
+ "\n ['is between', 'is_between'], ['is on or after', 'is_on_or_after'], " +
56
+ "\n ['is before or on', 'is_before_or_on'], ['not on', 'not_on']], @q[\'0\']['#{name}_match'] ), {} ," +
57
+ "\n { class: 'form-control match', 'data-action': 'change->date-range-picker#matchSelection' } %>"+
58
+ "\n <%= datetime_local_field 'q[0]', '#{name}_search_start', {value: @q[\'0\'][:#{name}_search_start], autocomplete: 'off', size: 40, class: 'form-control', placeholder: 'start', 'data-date-range-picker-target': 'start' } %>" +
59
+ "\n <%= datetime_local_field 'q[0]', '#{name}_search_end', {value: @q[\'0\'][:#{name}_search_end], autocomplete: 'off', size: 40, class: 'form-control', placeholder: 'end' , 'data-date-range-picker-target': 'end' } %>" +
60
+ "\n </div>"
61
+ end
62
+
63
+
64
+ def where_query_statement
65
+ ".where(*#{name}_query)"
66
+ end
67
+
68
+ def load_all_query_statement
69
+ "#{name}_query = date_query_constructor(:#{name}, @q['0'][:#{name}_match], @q['0'][:#{name}_search_start], @q['0'][:#{name}_search_end])"
70
+ end
51
71
  end
@@ -38,7 +38,7 @@ class EnumField < Field
38
38
  enum_definer = "#{class_name}.defined_enums['#{name}']"
39
39
  end
40
40
 
41
- res = "<%= f.collection_select(:#{name}, enum_to_collection_select(#{enum_definer}), :key, :value, {selected: #{singular}.#{name} }, class: 'form-control') %>"
41
+ res = "<%= f.collection_select(:#{name}, enum_to_collection_select(#{enum_definer}), :key, :value, {include_blank: true, selected: #{singular}.#{name} }, class: 'form-control') %>"
42
42
 
43
43
 
44
44
  if modify_as && modify_as[:enum] == :partials
@@ -79,4 +79,25 @@ class EnumField < Field
79
79
  def form_show_only_output
80
80
  viewable_output
81
81
  end
82
+
83
+
84
+ def search_field_output
85
+ enum_type = eval("#{class_name}.columns.select{|x| x.name == '#{name}'}[0].sql_type")
86
+ if eval("defined? #{class_name}.#{enum_type}_labels") == "method"
87
+ enum_definer = "#{class_name}.#{enum_type}_labels"
88
+ else
89
+ enum_definer = "#{class_name}.defined_enums['#{name}']"
90
+ end
91
+
92
+ "<%= f.collection_select(\'q[0][#{name}_search]\', enum_to_collection_select(#{enum_definer}), :key, :value, {include_blank: true, selected: @q['0']['#{name}_search'] }, class: 'form-control') %>"
93
+ end
94
+
95
+
96
+ def where_query_statement
97
+ ".where(*#{name}_query)"
98
+ end
99
+
100
+ def load_all_query_statement
101
+ "#{name}_query = enum_constructor(:#{name}, @q['0'][:#{name}_search])"
102
+ end
82
103
  end
@@ -177,4 +177,8 @@ class Field
177
177
  def label_for
178
178
 
179
179
  end
180
+
181
+ def code_to_reset_match_if_search_is_blank
182
+ nil
183
+ end
180
184
  end
@@ -19,4 +19,16 @@ class FloatField < Field
19
19
  #
20
20
  # "<%= #{singular}.#{name} %>"
21
21
  # end
22
+
23
+ def search_field_output
24
+ ""
25
+ end
26
+
27
+
28
+ def where_query_statement
29
+ end
30
+
31
+ def load_all_query_statement
32
+
33
+ end
22
34
  end
@@ -47,4 +47,22 @@ class StringField < Field
47
47
  text_area_output( 65536)
48
48
  end
49
49
  end
50
+
51
+ def search_field_output
52
+ "<%= f.select 'q[0][#{name}_match]', options_for_select([['', ''], ['contains', 'contains'], ['is exactly', 'is_exactly'], ['starts with', 'starts_with'], ['ends with', 'ends_with']], @q[\'0\']['#{name}_match'] ), {} , { class: 'form-control match' } %>"+
53
+ "<%= f.text_field 'q[0][#{name}_search]', value: @q[\'0\'][:#{name}_search], autocomplete: 'off', size: 40, class: 'form-control', type: 'text' %>"
54
+ end
55
+
56
+
57
+ def where_query_statement
58
+ ".where('#{name} ILIKE ?', #{name}_query)"
59
+ end
60
+
61
+ def load_all_query_statement
62
+ "#{name}_query = string_query_constructor(@q['0'][:#{name}_match], @q['0'][:#{name}_search])"
63
+ end
64
+
65
+ def code_to_reset_match_if_search_is_blank
66
+ " @q['0'][:#{name}_match] = '' if @q['0'][:#{name}_search] == ''"
67
+ end
50
68
  end
@@ -28,4 +28,24 @@ class TextField < Field
28
28
  text_area_output( 65536)
29
29
  end
30
30
  end
31
+
32
+
33
+ def search_field_output
34
+ "<%= f.select 'q[0][#{name}_match]', options_for_select([['', ''], ['contains', 'contains'], ['is exactly', 'is_exactly'], ['starts with', 'starts_with'], ['ends with', 'ends_with']], @q[\'0\']['#{name}_match'] ), {} , { class: 'form-control match' } %>"+
35
+ "<%= f.text_field 'q[0][#{name}_search]', value: @q[\'0\'][:#{name}_search], autocomplete: 'off', size: 40, class: 'form-control', type: 'text' %>"
36
+ end
37
+
38
+
39
+ def where_query_statement
40
+ ".where('#{name} ILIKE ?', #{name}_query)"
41
+ end
42
+
43
+ def load_all_query_statement
44
+ "#{name}_query = string_query_constructor(@q['0'][:#{name}_match], @q['0'][:#{name}_search])"
45
+ end
46
+
47
+ def code_to_reset_match_if_search_is_blank
48
+ " @q['0'][:#{name}_match] = '' if @q['0'][:#{name}_search] == ''"
49
+ end
50
+
31
51
  end
@@ -5,7 +5,7 @@ class TimeField < Field
5
5
  end
6
6
 
7
7
  def form_field_output
8
- "<%= time_field_localized(f, :#{name}, #{singular}.#{name}, '#{ name.to_s.humanize }') %>"
8
+ "<%= time_field_localized(f, :#{name}, #{singular}.#{name}, label: '#{ name.to_s.humanize }') %>"
9
9
  end
10
10
 
11
11
  def line_field_output
@@ -30,5 +30,21 @@ class TimeField < Field
30
30
  # "expect(page).to have_content(#{singular}#{1}.#{name})"
31
31
  end
32
32
 
33
+ def search_field_output
34
+ " <div data-controller='time-range-picker' >"+
35
+ "\n <%= f.select 'q[0][#{name}_match]', options_for_select([['', ''], ['is at exactly', 'is_at_exactly']], @q[\'0\']['#{name}_match']), {} ," +
36
+ "\n { class: 'form-control match', 'data-action': 'change->time-range-picker#matchSelection' } %>"+
37
+ "\n <%= time_field_localized f, 'q[0][#{name}_search_start]', @q[\'0\'][:#{name}_search_start], autocomplete: 'off', size: 40, class: 'form-control', type: 'text', placeholder: 'start', 'data-time-range-picker-target': 'start' %>" +
38
+ "\n <%= time_field_localized f, 'q[0][#{name}_search_end]', @q[\'0\'][:#{name}_search_end], autocomplete: 'off', size: 40, class: 'form-control', type: 'text', placeholder: 'end' , 'data-time-range-picker-target': 'end' %>" +
39
+ "\n </div>"
40
+ end
41
+
33
42
 
43
+ def where_query_statement
44
+ ".where(*#{name}_query)"
45
+ end
46
+
47
+ def load_all_query_statement
48
+ "#{name}_query = time_query_constructor(:#{name}, @q['0'][:#{name}_match], @q['0'][:#{name}_search_start], @q['0'][:#{name}_search_end])"
49
+ end
34
50
  end