ransack_ui 0.1.4 → 0.1.5

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.
@@ -3,54 +3,38 @@
3
3
  options: {}
4
4
 
5
5
  _create: ->
6
- el = this.element
7
- el.on 'click', '.add_fields', $.proxy(this.add_fields, this)
8
- el.on 'click', '.remove_fields', $.proxy(this.remove_fields, this)
9
- el.on 'change', 'select.ransack_predicate', $.proxy(this.predicate_changed, this)
10
- el.on 'change', 'select.ransack_attribute', $.proxy(this.attribute_changed, this)
11
-
12
- # Set up Select2 on select lists in .filters
13
- this.init_select2(this.element.find('.filters'))
6
+ el = @element
7
+ el.on 'click', '.add_fields', $.proxy(@add_fields, this)
8
+ el.on 'click', '.remove_fields', $.proxy(@remove_fields, this)
9
+ el.on 'change', 'select.ransack_predicate', $.proxy(@predicate_changed, this)
10
+ el.on 'change', 'select.ransack_attribute', $.proxy(@attribute_changed, this)
11
+ el.on 'change', 'input.ransack_query_multi', $.proxy(@multi_query_changed, this)
12
+
13
+ # Store initial predicates and set up Select2 on select lists in .filters
14
+ containers = el.find('.filters')
15
+ @init_select2(containers)
16
+ @store_initial_predicates(containers)
14
17
 
15
18
  # show spinner and disable the form when the search is underway
16
- el.find("form input:submit").click $.proxy(this.form_submit, this)
19
+ el.find("form input:submit").click $.proxy(@form_submit, this)
17
20
 
18
21
  # Fire change event for any existing selects.
19
22
  el.find(".filters select").change()
20
23
 
21
- # For basic search, remove placeholder text on focus, restore on blur
22
- $('#query').focusin (e) ->
23
- $(this).data('placeholder', $(this).attr('placeholder')).attr('placeholder', '')
24
- $('#query').focusout (e) ->
25
- $(this).attr('placeholder', $(this).data('placeholder'))
26
-
27
- predicate_changed: (e) ->
28
- target = $(e.currentTarget)
29
- base_id = target.attr('id').slice(0, -1)
30
- query_input = $('input#' + base_id + "v_0_value")
31
- if target.val() in ["true", "false", "blank", "present", "null", "not_null"]
32
- query_input.val("true")
33
- query_input.hide()
34
- query_input.parent().find('.ui-datepicker-trigger').hide()
35
- else
36
- unless query_input.is(":visible")
37
- query_input.val("")
38
- query_input.show()
39
- query_input.parent().find('.ui-datepicker-trigger').show()
40
-
41
24
  attribute_changed: (e) ->
42
25
  target = $(e.currentTarget)
43
26
  selected = target.find('option:selected')
44
27
  column_type = selected.data('type')
45
28
 
46
29
  base_id = target.attr('id').slice(0, -8)
47
- predicate_select = this.element.find('select#' + base_id + 'p')
48
- predicate_select2 = this.element.find('#s2id_' + base_id + 'p')
30
+ predicate_select = @element.find('select#' + base_id + 'p')
31
+ predicate_select2 = @element.find('#s2id_' + base_id + 'p')
49
32
  query_input = $('input#' + base_id + "v_0_value")
50
33
 
51
34
  # Initialize datepicker if column is date/datetime/time
52
- $.proxy(this.init_datetimepicker, this)(base_id)
35
+ $.proxy(@init_datetimepicker, this)(base_id)
53
36
 
37
+ # Handle association columns with AJAX autocomplete
54
38
  if selected.data('ajax-url') and Select2?
55
39
  controller = selected.data('controller')
56
40
 
@@ -76,10 +60,12 @@
76
60
  obj
77
61
  results: (data, page) ->
78
62
  {results: $.map(data, (text, id) -> {id: id, text: text}) }
63
+
64
+ # Handle regular columns
79
65
  else
80
66
  predicate_select2.show()
81
67
  # If Select2 is on query input, remove and set defaults
82
- if query_select2 = this.element.find('#s2id_' + base_id + 'v_0_value')
68
+ if query_select2 = @element.find('#s2id_' + base_id + 'v_0_value')
83
69
  query_input.select2('destroy')
84
70
  query_input.val('')
85
71
  previous_val = ''
@@ -96,9 +82,15 @@
96
82
 
97
83
  $.each available, (i, p) =>
98
84
  [val, label] = [p[0], p[1]]
85
+
86
+ # Also allow compound predicates, unless column
87
+ # is a date type. (No support for any/all on dates yet.)
88
+ unless column_type?.match(/date|time/)
89
+ val = val.replace(/_(any|all)$/, '')
90
+
99
91
  if val in predicates
100
92
  # Get alternative predicate label depending on column type
101
- label = this.alt_predicate_label_or_default(val, column_type, label)
93
+ label = @alt_predicate_label_or_default(val, column_type, label)
102
94
  predicate_select.append $('<option value='+val+'>'+label+'</option>')
103
95
 
104
96
  # Select first predicate if current selection is invalid
@@ -109,6 +101,42 @@
109
101
 
110
102
  return true
111
103
 
104
+ predicate_changed: (e) ->
105
+ target = $(e.currentTarget)
106
+ p = target.val() || ""
107
+ base_id = target.attr('id').slice(0, -1)
108
+ query_input = $('input#' + base_id + "v_0_value")
109
+
110
+ # We need to use a dummy input to handle multiple terms
111
+ multi_id = query_input.attr('id') + '_multi'
112
+ multi_input = @element.find('#' + multi_id)
113
+
114
+ if Select2?
115
+ # Turn query input into Select2 tag list when query accepts multiple values
116
+ if p in ["in", "not_in"] || p.match(/_(all|any)$/)
117
+ # Add dummy 'multi' input for select2 if not already added
118
+ if multi_input.length == 0
119
+ @setup_multi_query_input(target, query_input, multi_id)
120
+ return
121
+ else
122
+ if multi_input.length > 0
123
+ # Otherwise, remove Select2 from multi-query input, and remove input
124
+ multi_input.select2('destroy').remove()
125
+ query_input.val('').show()
126
+
127
+ # Hide query input when not needed
128
+ if p in ["true", "false", "blank", "present", "null", "not_null"]
129
+ query_input.val("true")
130
+ query_input.hide()
131
+ query_input.parent().find('.ui-datepicker-trigger').hide()
132
+ # Otherwise, reset query input and show datepicker trigger if present
133
+ else
134
+ unless query_input.is(":visible")
135
+ query_input.val("")
136
+ query_input.show()
137
+ query_input.parent().find('.ui-datepicker-trigger').show()
138
+
139
+
112
140
  # Attempts to find a predicate translation for the specific column type,
113
141
  # or returns the default label.
114
142
  # For example, 'lt' on an integer column will be translated to 'is less than',
@@ -118,7 +146,6 @@
118
146
  # 'created_at is before 2 weeks ago' is much easier to understand.
119
147
  alt_predicate_label_or_default: (p, type, default_label) ->
120
148
  return default_label unless Ransack?.alt_predicates_i18n?
121
-
122
149
  alt_labels = {}
123
150
  switch type
124
151
  when "date", "datetime", "time"
@@ -128,10 +155,52 @@
128
155
 
129
156
  alt_labels[p] || default_label
130
157
 
158
+ multi_query_changed: (e) ->
159
+ target = $(e.currentTarget)
160
+
161
+ # Fetch all query inputs for condition
162
+ base_name = target.data('base-name')
163
+ inputs = @element.find('input[name^="'+base_name+'"]')
164
+
165
+ # Set the original query input to the first value before shifting inputs and values
166
+ $(inputs[0]).val(e.val[0])
167
+
168
+ inputs = inputs.slice(1)
169
+ values = e.val.slice(1)
170
+
171
+ # If value was added after the first value, then append extra input with added value
172
+ if values.length && e.added
173
+ @add_query_input(target, base_name, inputs.length + 1, e.added.text)
174
+
175
+ else if e.removed
176
+ # If value was removed, clear all extra inputs, then rebuild inputs for extra terms
177
+ inputs.remove()
178
+ $.each values, (i, v) =>
179
+ @add_query_input(target, base_name, i + 1, v)
180
+
181
+ setup_multi_query_input: (predicate_el, query_el, multi_id) ->
182
+ # Hide query input
183
+ query_el.hide()
184
+ base_name = predicate_el.attr('name').slice(0, -3) + '[v]'
185
+ query_el.after(
186
+ $('<input class="ransack_query_multi" id="' + multi_id + '" ' +
187
+ 'style="width:' + (query_el.width() * 2) + 'px;" ' +
188
+ 'data-base-name="' + base_name + '" />'))
189
+
190
+ # Find newly created input and setup Select2
191
+ @element.find('#' + multi_id).select2
192
+ tags: []
193
+ tokenSeparators: [',']
194
+ formatNoMatches: (t) ->
195
+ "Add a search term"
196
+
197
+ add_query_input: (base_input, base_name, id, value) ->
198
+ base_input.after $('<input name="'+base_name+'['+id+'][value]" '+
199
+ 'value="'+value+'" style="display:none;" />')
131
200
 
132
201
  form_submit: (e) ->
133
202
  $("#loading").show()
134
- this.element.css({ opacity: 0.4 })
203
+ @element.css({ opacity: 0.4 })
135
204
  $('div.list').html('')
136
205
  true
137
206
 
@@ -143,7 +212,9 @@
143
212
  regexp = new RegExp('new_' + type, 'g')
144
213
  container = target.closest('p')
145
214
  container.before content.replace(regexp, new_id)
146
- this.init_select2 container.prev()
215
+ prev_container = container.prev()
216
+ @init_select2(prev_container)
217
+ @store_initial_predicates(prev_container)
147
218
  # Fire change event on any new selects.
148
219
  container.prev().find("select").change()
149
220
  false
@@ -157,24 +228,25 @@
157
228
  container.parent().closest('.fields').remove()
158
229
  false
159
230
 
231
+ store_initial_predicates: (container) ->
232
+ # Store current predicates in data attribute
233
+ predicate_select = container.find('select.ransack_predicate')
234
+ unless predicate_select.data['predicates']
235
+ predicates = []
236
+ predicate_select.find('option').each (i, o) ->
237
+ o = $(o)
238
+ predicates.push [o.val(), o.text()]
239
+ predicate_select.data['predicates'] = predicates
240
+
160
241
  init_select2: (container) ->
161
242
  if Select2?
162
- # Store current predicates in data attribute
163
- predicate_select = container.find('select.ransack_predicate')
164
- unless predicate_select.data['predicates']
165
- predicates = []
166
- predicate_select.find('option').each (i, o) ->
167
- $o = $(o)
168
- predicates.push [$o.val(), $o.text()]
169
- predicate_select.data['predicates'] = predicates
170
-
171
243
  container.find('select.ransack_predicate').select2
172
- width: '130px'
244
+ width: '160px'
173
245
  formatNoMatches: (term) ->
174
246
  "Select a field first"
175
247
 
176
248
  container.find('select.ransack_attribute').select2
177
- width: '220px'
249
+ width: '230px'
178
250
  placeholder: "Select a Field"
179
251
  allowClear: true
180
252
  formatSelection: (object, container) ->
@@ -189,12 +261,10 @@
189
261
  else
190
262
  $(object.element).parent().attr('label') + ': ' + object.text
191
263
 
192
-
193
-
194
264
  init_datetimepicker: (base_id) ->
195
265
  if $.ui?.timepicker?
196
- query_input = this.element.find('input#' + base_id + "v_0_value")
197
- selected_attr = this.element.find('select#' + base_id + 'a_0_name option:selected')
266
+ query_input = @element.find('input#' + base_id + "v_0_value")
267
+ selected_attr = @element.find('select#' + base_id + 'a_0_name option:selected')
198
268
 
199
269
  # Clear any datepicker from query input first
200
270
  query_input.datepicker('destroy')
@@ -10,7 +10,7 @@ en:
10
10
  lteq_any: "is before or on any"
11
11
  lteq_all: "is before or on all"
12
12
  gt: "is after"
13
- gt_any: "ais fter any"
13
+ gt_any: "is after any"
14
14
  gt_all: "is after all"
15
15
  gteq: "is after or on"
16
16
  gteq_any: "is after or on any"
@@ -1,3 +1,3 @@
1
1
  module RansackUI
2
- VERSION = "0.1.4"
2
+ VERSION = "0.1.5"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ransack_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
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: 2012-11-14 00:00:00.000000000 Z
12
+ date: 2012-11-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ransack_chronic
@@ -47,7 +47,6 @@ files:
47
47
  - app/views/ransack_ui/_condition_fields.html.haml
48
48
  - app/views/ransack_ui/_grouping_fields.html.haml
49
49
  - app/views/ransack_ui/_search.html.haml
50
- - config/locales/en-US.yml
51
50
  - config/locales/en.yml
52
51
  - lib/core_ext/enumerable.rb
53
52
  - lib/ransack_ui.rb
@@ -77,7 +76,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
76
  version: '0'
78
77
  segments:
79
78
  - 0
80
- hash: 3737585242911340372
79
+ hash: -81964240255838638
81
80
  required_rubygems_version: !ruby/object:Gem::Requirement
82
81
  none: false
83
82
  requirements:
@@ -86,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
85
  version: '0'
87
86
  segments:
88
87
  - 0
89
- hash: 3737585242911340372
88
+ hash: -81964240255838638
90
89
  requirements: []
91
90
  rubyforge_project:
92
91
  rubygems_version: 1.8.24
@@ -1,17 +0,0 @@
1
- en-US:
2
- ransack:
3
- predicates:
4
- alt:
5
- date:
6
- lt: "is before"
7
- lt_any: "is before any"
8
- lt_all: "is before all"
9
- lteq: "is before or on"
10
- lteq_any: "is before or on any"
11
- lteq_all: "is before or on all"
12
- gt: "is after"
13
- gt_any: "ais fter any"
14
- gt_all: "is after all"
15
- gteq: "is after or on"
16
- gteq_any: "is after or on any"
17
- gteq_all: "is after or on all"