hot-glue 0.6.2 → 0.6.3
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.
- 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
|