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 +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +112 -2
- data/app/helpers/hot_glue/controller_helper.rb +116 -12
- data/app/helpers/hot_glue_helper.rb +2 -0
- data/lib/generators/hot_glue/fields/association_field.rb +72 -0
- data/lib/generators/hot_glue/fields/boolean_field.rb +30 -0
- data/lib/generators/hot_glue/fields/date_field.rb +21 -1
- data/lib/generators/hot_glue/fields/date_time_field.rb +21 -1
- data/lib/generators/hot_glue/fields/enum_field.rb +22 -1
- data/lib/generators/hot_glue/fields/field.rb +4 -0
- data/lib/generators/hot_glue/fields/float_field.rb +12 -0
- data/lib/generators/hot_glue/fields/string_field.rb +18 -0
- data/lib/generators/hot_glue/fields/text_field.rb +20 -0
- data/lib/generators/hot_glue/fields/time_field.rb +17 -1
- data/lib/generators/hot_glue/markup_templates/erb.rb +61 -15
- data/lib/generators/hot_glue/scaffold_generator.rb +114 -14
- data/lib/generators/hot_glue/set_search_interface_install_generator.rb +26 -0
- data/lib/generators/hot_glue/templates/controller.rb.erb +31 -32
- data/lib/generators/hot_glue/templates/erb/_list.erb +5 -0
- data/lib/generators/hot_glue/templates/javascript/date_range_picker_controller.js +45 -0
- data/lib/generators/hot_glue/templates/javascript/search_form_controller.js +16 -0
- data/lib/generators/hot_glue/templates/javascript/time_range_picker_controller.js +38 -0
- data/lib/hotglue/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54b2a13a1fb9740be4ca14f108d98b72d8f1250b6131389c5e1d2130f07578cb
|
4
|
+
data.tar.gz: 15010c5e7fb34e35503b5a43aa563159d52f19c0b36f690ff03d67b7f1468060
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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
|
-
|
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,
|
8
|
+
def datetime_field_localized(form_object, field_name, value, **args )
|
9
9
|
current_timezone
|
10
|
-
|
11
|
-
|
12
|
-
|
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,
|
17
|
-
|
18
|
-
|
19
|
-
|
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,
|
30
|
+
def time_field_localized(form_object, field_name, value, **args )
|
23
31
|
current_timezone
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
@@ -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
|
@@ -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},
|
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
|