ransack_ui 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"