ab_admin 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +5 -2
- data/README.md +2 -4
- data/TODO +3 -0
- data/ab_admin.gemspec +1 -1
- data/app/assets/javascripts/ab_admin/application.js +4 -1
- data/app/assets/javascripts/ab_admin/components/in_place_edit.js.coffee +23 -0
- data/app/assets/javascripts/ab_admin/core/batch_actions.js.coffee +4 -1
- data/app/assets/javascripts/ab_admin/core/columns_hider.js.coffee +13 -5
- data/app/assets/javascripts/ab_admin/core/init.js.coffee +30 -15
- data/app/assets/javascripts/ab_admin/core/ui_utils.js.coffee +15 -7
- data/app/assets/javascripts/ab_admin/core/utils.js.coffee +3 -0
- data/app/assets/javascripts/ab_admin/inputs/datetime_input.js.coffee +1 -1
- data/app/assets/stylesheets/ab_admin/application.css.scss +2 -1
- data/app/assets/stylesheets/ab_admin/components/_table_view.css.scss +12 -0
- data/app/controllers/admin/base_controller.rb +20 -2
- data/app/controllers/admin/manager_controller.rb +0 -2
- data/app/views/admin/base/create.js.erb +6 -0
- data/app/views/admin/base/edit.js.erb +10 -0
- data/app/views/admin/base/index.html.slim +2 -3
- data/app/views/admin/base/new.js.erb +8 -0
- data/app/views/admin/base/update.js.erb +7 -0
- data/app/views/admin/manager/_search_form.html.slim +1 -1
- data/app/views/admin/manager/_show_table.html.slim +7 -0
- data/app/views/admin/manager/_table.html.slim +6 -2
- data/app/views/admin/shared/_save_buttons.html.slim +1 -1
- data/features/dsl/action_items.feature +4 -4
- data/features/dsl/in_place_edit.feature +26 -0
- data/features/dsl/list_edit.feature +46 -0
- data/features/dsl/show.feature +37 -0
- data/features/step_definitions/dsl/in_place_edit_steps.rb +7 -0
- data/features/step_definitions/dsl/show_steps.rb +8 -0
- data/features/step_definitions/dsl/table_steps.rb +2 -2
- data/features/step_definitions/web_steps/browsing_steps.rb +13 -0
- data/features/support/paths.rb +1 -1
- data/lib/ab_admin/abstract_resource.rb +5 -1
- data/lib/ab_admin/config/base.rb +14 -0
- data/lib/ab_admin/version.rb +1 -1
- data/lib/ab_admin/views/admin_helpers.rb +22 -0
- data/lib/ab_admin/views/admin_navigation_helpers.rb +6 -7
- data/lib/ab_admin/views/form_builder.rb +1 -1
- data/lib/ab_admin/views/manager_helpers.rb +4 -0
- data/lib/ab_admin/views/search_form_builder.rb +5 -1
- data/lib/generators/template.rb +4 -3
- data/spec/dummy/app/helpers/application_helper.rb +1 -0
- data/spec/dummy/app/models/ab_admin/ab_admin_product.rb +33 -70
- data/spec/dummy/app/models/product.rb +2 -0
- data/vendor/assets/javascripts/jquery.hotkeys.js +106 -0
- metadata +26 -15
- data/NOTES +0 -16
- data/app/assets/images/admin/chosen-sprite.png +0 -0
- data/app/assets/stylesheets/ab_admin/chosen.css.scss +0 -368
- data/app/assets/stylesheets/ab_admin/components/_table_tools.css.scss +0 -94
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/vendor/assets/javascripts/chosen.js.coffee +0 -780
@@ -1,780 +0,0 @@
|
|
1
|
-
root = this
|
2
|
-
|
3
|
-
class AbstractChosen
|
4
|
-
|
5
|
-
constructor: (@form_field, @options={}) ->
|
6
|
-
this.set_default_values()
|
7
|
-
|
8
|
-
@is_multiple = @form_field.multiple
|
9
|
-
this.set_default_text()
|
10
|
-
|
11
|
-
this.setup()
|
12
|
-
|
13
|
-
this.set_up_html()
|
14
|
-
this.register_observers()
|
15
|
-
|
16
|
-
this.finish_setup()
|
17
|
-
|
18
|
-
set_default_values: ->
|
19
|
-
@click_test_action = (evt) => this.test_active_click(evt)
|
20
|
-
@activate_action = (evt) => this.activate_field(evt)
|
21
|
-
@active_field = false
|
22
|
-
@mouse_on_container = false
|
23
|
-
@results_showing = false
|
24
|
-
@result_highlighted = null
|
25
|
-
@result_single_selected = null
|
26
|
-
@allow_single_deselect = if @options.allow_single_deselect? and @form_field.options[0]? and @form_field.options[0].text is "" then @options.allow_single_deselect else false
|
27
|
-
@disable_search_threshold = @options.disable_search_threshold || 0
|
28
|
-
@search_contains = @options.search_contains || false
|
29
|
-
@choices = 0
|
30
|
-
@single_backstroke_delete = @options.single_backstroke_delete || false
|
31
|
-
@max_selected_options = @options.max_selected_options || Infinity
|
32
|
-
|
33
|
-
set_default_text: ->
|
34
|
-
if @form_field.getAttribute("data-placeholder")
|
35
|
-
@default_text = @form_field.getAttribute("data-placeholder")
|
36
|
-
else if @is_multiple
|
37
|
-
@default_text = @options.placeholder_text_multiple || @options.placeholder_text || ""
|
38
|
-
else
|
39
|
-
@default_text = @options.placeholder_text_single || @options.placeholder_text || ""
|
40
|
-
|
41
|
-
@results_none_found = @form_field.getAttribute("data-no_results_text") || @options.no_results_text || "Ничего не найдено"
|
42
|
-
|
43
|
-
mouse_enter: -> @mouse_on_container = true
|
44
|
-
mouse_leave: -> @mouse_on_container = false
|
45
|
-
|
46
|
-
input_focus: (evt) ->
|
47
|
-
setTimeout (=> this.container_mousedown()), 50 unless @active_field
|
48
|
-
|
49
|
-
input_blur: (evt) ->
|
50
|
-
if not @mouse_on_container
|
51
|
-
@active_field = false
|
52
|
-
setTimeout (=> this.blur_test()), 100
|
53
|
-
|
54
|
-
result_add_option: (option) ->
|
55
|
-
if not option.disabled
|
56
|
-
option.dom_id = @container_id + "_o_" + option.array_index
|
57
|
-
|
58
|
-
classes = if option.selected and @is_multiple then [] else ["active-result"]
|
59
|
-
classes.push "result-selected" if option.selected
|
60
|
-
classes.push "group-option" if option.group_array_index?
|
61
|
-
classes.push option.classes if option.classes != ""
|
62
|
-
|
63
|
-
style = if option.style.cssText != "" then " style=\"#{option.style}\"" else ""
|
64
|
-
|
65
|
-
'<li id="' + option.dom_id + '" class="' + classes.join(' ') + '"'+style+'>' + option.html + '</li>'
|
66
|
-
else
|
67
|
-
""
|
68
|
-
|
69
|
-
results_update_field: ->
|
70
|
-
this.results_reset_cleanup() if not @is_multiple
|
71
|
-
this.result_clear_highlight()
|
72
|
-
@result_single_selected = null
|
73
|
-
this.results_build()
|
74
|
-
|
75
|
-
results_toggle: ->
|
76
|
-
if @results_showing
|
77
|
-
this.results_hide()
|
78
|
-
else
|
79
|
-
this.results_show()
|
80
|
-
|
81
|
-
remote_search: ->
|
82
|
-
@data_cache ||= {}
|
83
|
-
val = $.trim @search_field.attr('value')
|
84
|
-
# log 'remote_search', val
|
85
|
-
return false if val.length < 1 or val is @search_field.data('prevVal')
|
86
|
-
@search_field.data('prevVal', val)
|
87
|
-
|
88
|
-
@options.ajax.data ||= {}
|
89
|
-
@options.ajax.data.q = val
|
90
|
-
if @options.map
|
91
|
-
pos = @options.map.getCenter()
|
92
|
-
@options.ajax.data['with[lat]'] = pos.lat()
|
93
|
-
@options.ajax.data['with[lon]'] = pos.lng()
|
94
|
-
|
95
|
-
@options.ajax.success = (data) =>
|
96
|
-
@form_field_jq.find('option').each -> $(this).remove() if not $(this).is(":selected")
|
97
|
-
_.each data, (el) =>
|
98
|
-
$("<option />").attr('value', el.id).html(el.name).appendTo(@form_field_jq).data('info', el.data)
|
99
|
-
|
100
|
-
@keep_search_field = true
|
101
|
-
@form_field_jq.trigger("liszt:updated")
|
102
|
-
@keep_search_field = false
|
103
|
-
@winnow_results()
|
104
|
-
@data_cache[val] = data
|
105
|
-
|
106
|
-
if @data_cache[val]
|
107
|
-
@options.ajax.success(@data_cache[val])
|
108
|
-
else
|
109
|
-
$.ajax(@options.ajax)
|
110
|
-
|
111
|
-
results_search: (evt) ->
|
112
|
-
# log 'results_search'
|
113
|
-
if @options.ajax
|
114
|
-
@remote_search()
|
115
|
-
else
|
116
|
-
if @results_showing
|
117
|
-
this.winnow_results()
|
118
|
-
else
|
119
|
-
this.results_show()
|
120
|
-
|
121
|
-
keyup_checker: (evt) ->
|
122
|
-
stroke = evt.which ? evt.keyCode
|
123
|
-
this.search_field_scale()
|
124
|
-
|
125
|
-
switch stroke
|
126
|
-
when 8
|
127
|
-
if @is_multiple and @backstroke_length < 1 and @choices > 0
|
128
|
-
this.keydown_backstroke()
|
129
|
-
else if not @pending_backstroke
|
130
|
-
this.result_clear_highlight()
|
131
|
-
this.results_search()
|
132
|
-
when 13
|
133
|
-
evt.preventDefault()
|
134
|
-
this.result_select(evt) if this.results_showing
|
135
|
-
when 27
|
136
|
-
this.results_hide() if @results_showing
|
137
|
-
return true
|
138
|
-
when 9, 38, 40, 16, 91, 17
|
139
|
-
# don't do anything on these keys
|
140
|
-
else this.results_search()
|
141
|
-
|
142
|
-
generate_field_id: ->
|
143
|
-
new_id = this.generate_random_id()
|
144
|
-
@form_field.id = new_id
|
145
|
-
new_id
|
146
|
-
|
147
|
-
generate_random_char: ->
|
148
|
-
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
149
|
-
rand = Math.floor(Math.random() * chars.length)
|
150
|
-
newchar = chars.substring rand, rand+1
|
151
|
-
|
152
|
-
root.AbstractChosen = AbstractChosen
|
153
|
-
|
154
|
-
class SelectParser
|
155
|
-
|
156
|
-
constructor: ->
|
157
|
-
@options_index = 0
|
158
|
-
@parsed = []
|
159
|
-
|
160
|
-
add_node: (child) ->
|
161
|
-
if child.nodeName is "OPTGROUP"
|
162
|
-
this.add_group child
|
163
|
-
else
|
164
|
-
this.add_option child
|
165
|
-
|
166
|
-
add_group: (group) ->
|
167
|
-
group_position = @parsed.length
|
168
|
-
@parsed.push
|
169
|
-
array_index: group_position
|
170
|
-
group: true
|
171
|
-
label: group.label
|
172
|
-
children: 0
|
173
|
-
disabled: group.disabled
|
174
|
-
this.add_option( option, group_position, group.disabled ) for option in group.childNodes
|
175
|
-
|
176
|
-
add_option: (option, group_position, group_disabled) ->
|
177
|
-
if option.nodeName is "OPTION"
|
178
|
-
if option.text != ""
|
179
|
-
if group_position?
|
180
|
-
@parsed[group_position].children += 1
|
181
|
-
@parsed.push
|
182
|
-
array_index: @parsed.length
|
183
|
-
options_index: @options_index
|
184
|
-
value: option.value
|
185
|
-
text: option.text
|
186
|
-
html: option.innerHTML
|
187
|
-
selected: option.selected
|
188
|
-
disabled: if group_disabled is true then group_disabled else option.disabled
|
189
|
-
group_array_index: group_position
|
190
|
-
classes: option.className
|
191
|
-
style: option.style.cssText
|
192
|
-
else
|
193
|
-
@parsed.push
|
194
|
-
array_index: @parsed.length
|
195
|
-
options_index: @options_index
|
196
|
-
empty: true
|
197
|
-
@options_index += 1
|
198
|
-
|
199
|
-
SelectParser.select_to_array = (select) ->
|
200
|
-
parser = new SelectParser()
|
201
|
-
parser.add_node( child ) for child in select.childNodes
|
202
|
-
parser.parsed
|
203
|
-
|
204
|
-
this.SelectParser = SelectParser
|
205
|
-
|
206
|
-
root = this
|
207
|
-
$ = jQuery
|
208
|
-
|
209
|
-
$.fn.extend({
|
210
|
-
chosen: (options) ->
|
211
|
-
# Do no harm and return as soon as possible for unsupported browsers, namely IE6 and IE7
|
212
|
-
return this if $.browser.msie and ($.browser.version is "6.0" or $.browser.version is "7.0")
|
213
|
-
this.each((input_field) ->
|
214
|
-
$this = $ this
|
215
|
-
$this.data('chosen', new Chosen(this, options)) unless $this.hasClass "chzn-done"
|
216
|
-
)
|
217
|
-
})
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
# jQuery CHOSEN ========================
|
222
|
-
class Chosen extends AbstractChosen
|
223
|
-
|
224
|
-
setup: ->
|
225
|
-
@form_field_jq = $ @form_field
|
226
|
-
@current_value = @form_field_jq.val()
|
227
|
-
@is_rtl = @form_field_jq.hasClass "chzn-rtl"
|
228
|
-
|
229
|
-
finish_setup: ->
|
230
|
-
@form_field_jq.addClass "chzn-done"
|
231
|
-
|
232
|
-
set_up_html: ->
|
233
|
-
@container_id = if @form_field.id.length then @form_field.id.replace(/[^\w]/g, '_') else this.generate_field_id()
|
234
|
-
@container_id += "_chzn"
|
235
|
-
|
236
|
-
@f_width = @form_field_jq.outerWidth()
|
237
|
-
|
238
|
-
container_div = ($ "<div />", {
|
239
|
-
id: @container_id
|
240
|
-
class: "chzn-container#{ if @is_rtl then ' chzn-rtl' else '' }"
|
241
|
-
style: 'width: ' + (@f_width) + 'px;' #use parens around @f_width so coffeescript doesn't think + ' px' is a function parameter
|
242
|
-
})
|
243
|
-
|
244
|
-
if @is_multiple
|
245
|
-
container_div.html '<ul class="chzn-choices"><li class="search-field"><input type="text" value="' + @default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'
|
246
|
-
else
|
247
|
-
container_div.html '<a href="javascript:void(0)" class="chzn-single chzn-default"><span>' + @default_text + '</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'
|
248
|
-
|
249
|
-
@form_field_jq.hide().after container_div
|
250
|
-
@container = ($ '#' + @container_id)
|
251
|
-
@container.addClass( "chzn-container-" + (if @is_multiple then "multi" else "single") )
|
252
|
-
@dropdown = @container.find('div.chzn-drop').first()
|
253
|
-
|
254
|
-
dd_top = @container.height()
|
255
|
-
dd_width = (@f_width - get_side_border_padding(@dropdown))
|
256
|
-
|
257
|
-
@dropdown.css({"width": dd_width + "px", "top": dd_top + "px"})
|
258
|
-
|
259
|
-
@search_field = @container.find('input').first()
|
260
|
-
@search_results = @container.find('ul.chzn-results').first()
|
261
|
-
this.search_field_scale()
|
262
|
-
|
263
|
-
@search_no_results = @container.find('li.no-results').first()
|
264
|
-
|
265
|
-
if @is_multiple
|
266
|
-
@search_choices = @container.find('ul.chzn-choices').first()
|
267
|
-
@search_container = @container.find('li.search-field').first()
|
268
|
-
else
|
269
|
-
@search_container = @container.find('div.chzn-search').first()
|
270
|
-
@selected_item = @container.find('.chzn-single').first()
|
271
|
-
sf_width = dd_width - get_side_border_padding(@search_container) - get_side_border_padding(@search_field)
|
272
|
-
@search_field.css( {"width" : sf_width + "px"} )
|
273
|
-
|
274
|
-
this.results_build()
|
275
|
-
this.set_tab_index()
|
276
|
-
@form_field_jq.trigger("liszt:ready", {chosen: this})
|
277
|
-
|
278
|
-
register_observers: ->
|
279
|
-
@container.mousedown (evt) => this.container_mousedown(evt)
|
280
|
-
@container.mouseup (evt) => this.container_mouseup(evt)
|
281
|
-
@container.mouseenter (evt) => this.mouse_enter(evt)
|
282
|
-
@container.mouseleave (evt) => this.mouse_leave(evt)
|
283
|
-
|
284
|
-
@search_results.mouseup (evt) => this.search_results_mouseup(evt)
|
285
|
-
@search_results.mouseover (evt) => this.search_results_mouseover(evt)
|
286
|
-
@search_results.mouseout (evt) => this.search_results_mouseout(evt)
|
287
|
-
|
288
|
-
@form_field_jq.bind "liszt:updated", (evt) => this.results_update_field(evt)
|
289
|
-
|
290
|
-
@search_field.blur (evt) => this.input_blur(evt)
|
291
|
-
@search_field.keyup (evt) => this.keyup_checker(evt)
|
292
|
-
@search_field.keydown (evt) => this.keydown_checker(evt)
|
293
|
-
|
294
|
-
if @is_multiple
|
295
|
-
@search_choices.click (evt) => this.choices_click(evt)
|
296
|
-
@search_field.focus (evt) => this.input_focus(evt)
|
297
|
-
else
|
298
|
-
@container.click (evt) => evt.preventDefault() # gobble click of anchor
|
299
|
-
|
300
|
-
search_field_disabled: ->
|
301
|
-
@is_disabled = @form_field_jq[0].disabled
|
302
|
-
if(@is_disabled)
|
303
|
-
@container.addClass 'chzn-disabled'
|
304
|
-
@search_field[0].disabled = true
|
305
|
-
@selected_item.unbind "focus", @activate_action if !@is_multiple
|
306
|
-
this.close_field()
|
307
|
-
else
|
308
|
-
@container.removeClass 'chzn-disabled'
|
309
|
-
@search_field[0].disabled = false
|
310
|
-
@selected_item.bind "focus", @activate_action if !@is_multiple
|
311
|
-
|
312
|
-
container_mousedown: (evt) ->
|
313
|
-
if !@is_disabled
|
314
|
-
target_closelink = if evt? then ($ evt.target).hasClass "search-choice-close" else false
|
315
|
-
if evt and evt.type is "mousedown" and not @results_showing
|
316
|
-
evt.stopPropagation()
|
317
|
-
if not @pending_destroy_click and not target_closelink
|
318
|
-
if not @active_field
|
319
|
-
@search_field.val "" if @is_multiple
|
320
|
-
$(document).click @click_test_action
|
321
|
-
this.results_show()
|
322
|
-
else if not @is_multiple and evt and (($(evt.target)[0] == @selected_item[0]) || $(evt.target).parents("a.chzn-single").length)
|
323
|
-
evt.preventDefault()
|
324
|
-
this.results_toggle()
|
325
|
-
|
326
|
-
this.activate_field()
|
327
|
-
else
|
328
|
-
@pending_destroy_click = false
|
329
|
-
|
330
|
-
container_mouseup: (evt) ->
|
331
|
-
this.results_reset(evt) if evt.target.nodeName is "ABBR" and not @is_disabled
|
332
|
-
|
333
|
-
blur_test: (evt) ->
|
334
|
-
this.close_field() if not @active_field and @container.hasClass "chzn-container-active"
|
335
|
-
|
336
|
-
close_field: ->
|
337
|
-
$(document).unbind "click", @click_test_action
|
338
|
-
|
339
|
-
if not @is_multiple
|
340
|
-
@selected_item.attr "tabindex", @search_field.attr("tabindex")
|
341
|
-
@search_field.attr "tabindex", -1
|
342
|
-
|
343
|
-
@active_field = false
|
344
|
-
this.results_hide()
|
345
|
-
|
346
|
-
@container.removeClass "chzn-container-active"
|
347
|
-
this.winnow_results_clear()
|
348
|
-
this.clear_backstroke()
|
349
|
-
|
350
|
-
this.show_search_field_default()
|
351
|
-
this.search_field_scale()
|
352
|
-
|
353
|
-
activate_field: ->
|
354
|
-
if not @is_multiple and not @active_field
|
355
|
-
@search_field.attr "tabindex", (@selected_item.attr "tabindex")
|
356
|
-
@selected_item.attr "tabindex", -1
|
357
|
-
|
358
|
-
@container.addClass "chzn-container-active"
|
359
|
-
@active_field = true
|
360
|
-
|
361
|
-
@search_field.val(@search_field.val())
|
362
|
-
@search_field.focus()
|
363
|
-
|
364
|
-
|
365
|
-
test_active_click: (evt) ->
|
366
|
-
if $(evt.target).parents('#' + @container_id).length
|
367
|
-
@active_field = true
|
368
|
-
else
|
369
|
-
this.close_field()
|
370
|
-
|
371
|
-
results_build: ->
|
372
|
-
# log 'results_build'
|
373
|
-
@parsing = true
|
374
|
-
@results_data = root.SelectParser.select_to_array @form_field
|
375
|
-
|
376
|
-
if @is_multiple and @choices > 0
|
377
|
-
@search_choices.find("li.search-choice").remove()
|
378
|
-
@choices = 0
|
379
|
-
else if not @is_multiple
|
380
|
-
@selected_item.addClass("chzn-default").find("span").text(@default_text)
|
381
|
-
if @form_field.options.length <= @disable_search_threshold
|
382
|
-
@container.addClass "chzn-container-single-nosearch"
|
383
|
-
else
|
384
|
-
@container.removeClass "chzn-container-single-nosearch"
|
385
|
-
|
386
|
-
content = ''
|
387
|
-
for data in @results_data
|
388
|
-
if data.group
|
389
|
-
content += this.result_add_group data
|
390
|
-
else if !data.empty
|
391
|
-
content += this.result_add_option data
|
392
|
-
if data.selected and @is_multiple
|
393
|
-
this.choice_build data
|
394
|
-
else if data.selected and not @is_multiple
|
395
|
-
@selected_item.removeClass("chzn-default").find("span").text data.text
|
396
|
-
this.single_deselect_control_build() if @allow_single_deselect
|
397
|
-
|
398
|
-
this.search_field_disabled()
|
399
|
-
this.show_search_field_default()
|
400
|
-
this.search_field_scale()
|
401
|
-
|
402
|
-
@search_results.html content
|
403
|
-
@parsing = false
|
404
|
-
|
405
|
-
|
406
|
-
result_add_group: (group) ->
|
407
|
-
if not group.disabled
|
408
|
-
group.dom_id = @container_id + "_g_" + group.array_index
|
409
|
-
'<li id="' + group.dom_id + '" class="group-result">' + $("<div />").text(group.label).html() + '</li>'
|
410
|
-
else
|
411
|
-
""
|
412
|
-
|
413
|
-
result_do_highlight: (el) ->
|
414
|
-
if el.length
|
415
|
-
this.result_clear_highlight()
|
416
|
-
|
417
|
-
@result_highlight = el
|
418
|
-
@result_highlight.addClass "highlighted"
|
419
|
-
|
420
|
-
maxHeight = parseInt @search_results.css("maxHeight"), 10
|
421
|
-
visible_top = @search_results.scrollTop()
|
422
|
-
visible_bottom = maxHeight + visible_top
|
423
|
-
|
424
|
-
high_top = @result_highlight.position().top + @search_results.scrollTop()
|
425
|
-
high_bottom = high_top + @result_highlight.outerHeight()
|
426
|
-
|
427
|
-
if high_bottom >= visible_bottom
|
428
|
-
@search_results.scrollTop if (high_bottom - maxHeight) > 0 then (high_bottom - maxHeight) else 0
|
429
|
-
else if high_top < visible_top
|
430
|
-
@search_results.scrollTop high_top
|
431
|
-
|
432
|
-
result_clear_highlight: ->
|
433
|
-
@result_highlight.removeClass "highlighted" if @result_highlight
|
434
|
-
@result_highlight = null
|
435
|
-
|
436
|
-
results_show: ->
|
437
|
-
if not @is_multiple
|
438
|
-
@selected_item.addClass "chzn-single-with-drop"
|
439
|
-
if @result_single_selected
|
440
|
-
this.result_do_highlight( @result_single_selected )
|
441
|
-
else if @max_selected_options <= @choices
|
442
|
-
@form_field_jq.trigger("liszt:maxselected", {chosen: this})
|
443
|
-
return false
|
444
|
-
|
445
|
-
dd_top = if @is_multiple then @container.height() else (@container.height() - 1)
|
446
|
-
@form_field_jq.trigger("liszt:showing_dropdown", {chosen: this})
|
447
|
-
@dropdown.css {"top": dd_top + "px", "left":0}
|
448
|
-
@results_showing = true
|
449
|
-
|
450
|
-
@search_field.focus()
|
451
|
-
@search_field.val @search_field.val()
|
452
|
-
|
453
|
-
this.winnow_results()
|
454
|
-
|
455
|
-
results_hide: ->
|
456
|
-
@selected_item.removeClass "chzn-single-with-drop" unless @is_multiple
|
457
|
-
this.result_clear_highlight()
|
458
|
-
@form_field_jq.trigger("liszt:hiding_dropdown", {chosen: this})
|
459
|
-
@dropdown.css {"left":"-9000px"}
|
460
|
-
@results_showing = false
|
461
|
-
|
462
|
-
|
463
|
-
set_tab_index: (el) ->
|
464
|
-
if @form_field_jq.attr "tabindex"
|
465
|
-
ti = @form_field_jq.attr "tabindex"
|
466
|
-
@form_field_jq.attr "tabindex", -1
|
467
|
-
|
468
|
-
if @is_multiple
|
469
|
-
@search_field.attr "tabindex", ti
|
470
|
-
else
|
471
|
-
@selected_item.attr "tabindex", ti
|
472
|
-
@search_field.attr "tabindex", -1
|
473
|
-
|
474
|
-
show_search_field_default: ->
|
475
|
-
return if @keep_search_field
|
476
|
-
if @is_multiple and @choices < 1 and not @active_field
|
477
|
-
@search_field.val(@default_text)
|
478
|
-
@search_field.addClass "default"
|
479
|
-
else
|
480
|
-
@search_field.val("")
|
481
|
-
@search_field.removeClass "default"
|
482
|
-
|
483
|
-
search_results_mouseup: (evt) ->
|
484
|
-
target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first()
|
485
|
-
if target.length
|
486
|
-
@result_highlight = target
|
487
|
-
this.result_select(evt)
|
488
|
-
|
489
|
-
search_results_mouseover: (evt) ->
|
490
|
-
target = if $(evt.target).hasClass "active-result" then $(evt.target) else $(evt.target).parents(".active-result").first()
|
491
|
-
this.result_do_highlight( target ) if target
|
492
|
-
|
493
|
-
search_results_mouseout: (evt) ->
|
494
|
-
this.result_clear_highlight() if $(evt.target).hasClass "active-result" or $(evt.target).parents('.active-result').first()
|
495
|
-
|
496
|
-
|
497
|
-
choices_click: (evt) ->
|
498
|
-
evt.preventDefault()
|
499
|
-
if( @active_field and not($(evt.target).hasClass "search-choice" or $(evt.target).parents('.search-choice').first) and not @results_showing )
|
500
|
-
this.results_show()
|
501
|
-
|
502
|
-
choice_build: (item) ->
|
503
|
-
if @is_multiple and @max_selected_options <= @choices
|
504
|
-
@form_field_jq.trigger("liszt:maxselected", {chosen: this})
|
505
|
-
return false # fire event
|
506
|
-
choice_id = @container_id + "_c_" + item.array_index
|
507
|
-
@choices += 1
|
508
|
-
@search_container.before '<li class="search-choice" id="' + choice_id + '"><span>' + item.html + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>'
|
509
|
-
link = $('#' + choice_id).find("a").first()
|
510
|
-
link.click (evt) => this.choice_destroy_link_click(evt)
|
511
|
-
|
512
|
-
choice_destroy_link_click: (evt) ->
|
513
|
-
evt.preventDefault()
|
514
|
-
if not @is_disabled
|
515
|
-
@pending_destroy_click = true
|
516
|
-
this.choice_destroy $(evt.target)
|
517
|
-
else
|
518
|
-
evt.stopPropagation
|
519
|
-
|
520
|
-
choice_destroy: (link) ->
|
521
|
-
@choices -= 1
|
522
|
-
this.show_search_field_default()
|
523
|
-
|
524
|
-
this.results_hide() if @is_multiple and @choices > 0 and @search_field.val().length < 1
|
525
|
-
|
526
|
-
this.result_deselect (link.attr "rel")
|
527
|
-
link.parents('li').first().remove()
|
528
|
-
|
529
|
-
results_reset: ->
|
530
|
-
@form_field.options[0].selected = true
|
531
|
-
@selected_item.find("span").text @default_text
|
532
|
-
@selected_item.addClass("chzn-default") if not @is_multiple
|
533
|
-
this.show_search_field_default()
|
534
|
-
this.results_reset_cleanup()
|
535
|
-
@form_field_jq.trigger "change"
|
536
|
-
this.results_hide() if @active_field
|
537
|
-
|
538
|
-
results_reset_cleanup: ->
|
539
|
-
@selected_item.find("abbr").remove()
|
540
|
-
|
541
|
-
result_select: (evt) ->
|
542
|
-
if @result_highlight
|
543
|
-
high = @result_highlight
|
544
|
-
high_id = high.attr "id"
|
545
|
-
|
546
|
-
this.result_clear_highlight()
|
547
|
-
|
548
|
-
if @is_multiple
|
549
|
-
this.result_deactivate high
|
550
|
-
else
|
551
|
-
@search_results.find(".result-selected").removeClass "result-selected"
|
552
|
-
@result_single_selected = high
|
553
|
-
@selected_item.removeClass("chzn-default")
|
554
|
-
|
555
|
-
high.addClass "result-selected"
|
556
|
-
|
557
|
-
position = high_id.substr(high_id.lastIndexOf("_") + 1 )
|
558
|
-
item = @results_data[position]
|
559
|
-
item.selected = true
|
560
|
-
|
561
|
-
@form_field.options[item.options_index].selected = true
|
562
|
-
|
563
|
-
if @is_multiple
|
564
|
-
this.choice_build item
|
565
|
-
else
|
566
|
-
@selected_item.find("span").first().text item.text
|
567
|
-
this.single_deselect_control_build() if @allow_single_deselect
|
568
|
-
|
569
|
-
this.results_hide() unless evt.metaKey and @is_multiple
|
570
|
-
|
571
|
-
@search_field.val ""
|
572
|
-
|
573
|
-
@form_field_jq.trigger "change", {'selected': @form_field.options[item.options_index].value} if @is_multiple || @form_field_jq.val() != @current_value
|
574
|
-
@current_value = @form_field_jq.val()
|
575
|
-
this.search_field_scale()
|
576
|
-
|
577
|
-
result_activate: (el) ->
|
578
|
-
el.addClass("active-result")
|
579
|
-
|
580
|
-
result_deactivate: (el) ->
|
581
|
-
el.removeClass("active-result")
|
582
|
-
|
583
|
-
result_deselect: (pos) ->
|
584
|
-
result_data = @results_data[pos]
|
585
|
-
result_data.selected = false
|
586
|
-
|
587
|
-
@form_field.options[result_data.options_index].selected = false
|
588
|
-
result = $("#" + @container_id + "_o_" + pos)
|
589
|
-
result.removeClass("result-selected").addClass("active-result").show()
|
590
|
-
|
591
|
-
this.result_clear_highlight()
|
592
|
-
this.winnow_results()
|
593
|
-
|
594
|
-
@form_field_jq.trigger "change", {deselected: @form_field.options[result_data.options_index].value}
|
595
|
-
this.search_field_scale()
|
596
|
-
|
597
|
-
single_deselect_control_build: ->
|
598
|
-
@selected_item.find("span").first().after "<abbr class=\"search-choice-close\"></abbr>" if @allow_single_deselect and @selected_item.find("abbr").length < 1
|
599
|
-
|
600
|
-
winnow_results: ->
|
601
|
-
# log 'winnow_results'
|
602
|
-
# return if window.skip_winnow_results
|
603
|
-
this.no_results_clear()
|
604
|
-
|
605
|
-
results = 0
|
606
|
-
|
607
|
-
searchText = if @search_field.val() is @default_text then "" else $('<div/>').text($.trim(@search_field.val())).html()
|
608
|
-
regexAnchor = if @search_contains then "" else "^"
|
609
|
-
regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
|
610
|
-
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i')
|
611
|
-
|
612
|
-
# log 'searchText', searchText
|
613
|
-
# log 'results_data', @results_data[1]?.html
|
614
|
-
for option in @results_data
|
615
|
-
if not option.disabled and not option.empty
|
616
|
-
if option.group
|
617
|
-
$('#' + option.dom_id).css('display', 'none')
|
618
|
-
else if not (@is_multiple and option.selected)
|
619
|
-
found = false
|
620
|
-
result_id = option.dom_id
|
621
|
-
result = $("#" + result_id)
|
622
|
-
|
623
|
-
if regex.test option.html
|
624
|
-
found = true
|
625
|
-
results += 1
|
626
|
-
else if !@options.no_word_start_search and (option.html.indexOf(" ") >= 0 or option.html.indexOf("[") == 0)
|
627
|
-
#TODO: replace this substitution of /\[\]/ with a list of characters to skip.
|
628
|
-
parts = option.html.replace(/\[|\]/g, "").split(" ")
|
629
|
-
if parts.length
|
630
|
-
for part in parts
|
631
|
-
if regex.test part
|
632
|
-
found = true
|
633
|
-
results += 1
|
634
|
-
|
635
|
-
if found
|
636
|
-
if searchText.length
|
637
|
-
startpos = option.html.search zregex
|
638
|
-
text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length)
|
639
|
-
text = text.substr(0, startpos) + '<em>' + text.substr(startpos)
|
640
|
-
else
|
641
|
-
text = option.html
|
642
|
-
|
643
|
-
result.html(text)
|
644
|
-
this.result_activate result
|
645
|
-
|
646
|
-
$("#" + @results_data[option.group_array_index].dom_id).css('display', 'list-item') if option.group_array_index?
|
647
|
-
else
|
648
|
-
this.result_clear_highlight() if @result_highlight and result_id is @result_highlight.attr 'id'
|
649
|
-
this.result_deactivate result
|
650
|
-
|
651
|
-
if results < 1 and searchText.length
|
652
|
-
this.no_results searchText
|
653
|
-
else
|
654
|
-
this.winnow_results_set_highlight()
|
655
|
-
|
656
|
-
winnow_results_clear: ->
|
657
|
-
@search_field.val ""
|
658
|
-
lis = @search_results.find("li")
|
659
|
-
|
660
|
-
for li in lis
|
661
|
-
li = $(li)
|
662
|
-
if li.hasClass "group-result"
|
663
|
-
li.css('display', 'auto')
|
664
|
-
else if not @is_multiple or not li.hasClass "result-selected"
|
665
|
-
this.result_activate li
|
666
|
-
|
667
|
-
winnow_results_set_highlight: ->
|
668
|
-
if not @result_highlight
|
669
|
-
|
670
|
-
selected_results = if not @is_multiple then @search_results.find(".result-selected.active-result") else []
|
671
|
-
do_high = if selected_results.length then selected_results.first() else @search_results.find(".active-result").first()
|
672
|
-
|
673
|
-
this.result_do_highlight do_high if do_high?
|
674
|
-
|
675
|
-
no_results: (terms) ->
|
676
|
-
no_results_html = $('<li class="no-results">' + @results_none_found + ' "<span></span>"</li>')
|
677
|
-
no_results_html.find("span").first().html(terms)
|
678
|
-
|
679
|
-
@search_results.append no_results_html
|
680
|
-
|
681
|
-
no_results_clear: ->
|
682
|
-
@search_results.find(".no-results").remove()
|
683
|
-
|
684
|
-
keydown_arrow: ->
|
685
|
-
if not @result_highlight
|
686
|
-
first_active = @search_results.find("li.active-result").first()
|
687
|
-
this.result_do_highlight $(first_active) if first_active
|
688
|
-
else if @results_showing
|
689
|
-
next_sib = @result_highlight.nextAll("li.active-result").first()
|
690
|
-
this.result_do_highlight next_sib if next_sib
|
691
|
-
this.results_show() if not @results_showing
|
692
|
-
|
693
|
-
keyup_arrow: ->
|
694
|
-
if not @results_showing and not @is_multiple
|
695
|
-
this.results_show()
|
696
|
-
else if @result_highlight
|
697
|
-
prev_sibs = @result_highlight.prevAll("li.active-result")
|
698
|
-
|
699
|
-
if prev_sibs.length
|
700
|
-
this.result_do_highlight prev_sibs.first()
|
701
|
-
else
|
702
|
-
this.results_hide() if @choices > 0
|
703
|
-
this.result_clear_highlight()
|
704
|
-
|
705
|
-
keydown_backstroke: ->
|
706
|
-
if @pending_backstroke
|
707
|
-
this.choice_destroy @pending_backstroke.find("a").first()
|
708
|
-
this.clear_backstroke()
|
709
|
-
else
|
710
|
-
@pending_backstroke = @search_container.siblings("li.search-choice").last()
|
711
|
-
if @single_backstroke_delete
|
712
|
-
@keydown_backstroke()
|
713
|
-
else
|
714
|
-
@pending_backstroke.addClass "search-choice-focus"
|
715
|
-
|
716
|
-
clear_backstroke: ->
|
717
|
-
@pending_backstroke.removeClass "search-choice-focus" if @pending_backstroke
|
718
|
-
@pending_backstroke = null
|
719
|
-
|
720
|
-
keydown_checker: (evt) ->
|
721
|
-
stroke = evt.which ? evt.keyCode
|
722
|
-
this.search_field_scale()
|
723
|
-
|
724
|
-
this.clear_backstroke() if stroke != 8 and this.pending_backstroke
|
725
|
-
|
726
|
-
switch stroke
|
727
|
-
when 8
|
728
|
-
@backstroke_length = this.search_field.val().length
|
729
|
-
break
|
730
|
-
when 9
|
731
|
-
this.result_select(evt) if this.results_showing and not @is_multiple
|
732
|
-
@mouse_on_container = false
|
733
|
-
break
|
734
|
-
when 13
|
735
|
-
evt.preventDefault()
|
736
|
-
break
|
737
|
-
when 38
|
738
|
-
evt.preventDefault()
|
739
|
-
this.keyup_arrow()
|
740
|
-
break
|
741
|
-
when 40
|
742
|
-
this.keydown_arrow()
|
743
|
-
break
|
744
|
-
|
745
|
-
search_field_scale: ->
|
746
|
-
if @is_multiple
|
747
|
-
h = 0
|
748
|
-
w = 0
|
749
|
-
|
750
|
-
style_block = "position:absolute; left: -1000px; top: -1000px; display:none;"
|
751
|
-
styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing']
|
752
|
-
|
753
|
-
for style in styles
|
754
|
-
style_block += style + ":" + @search_field.css(style) + ";"
|
755
|
-
|
756
|
-
div = $('<div />', { 'style' : style_block })
|
757
|
-
div.text @search_field.val()
|
758
|
-
$('body').append div
|
759
|
-
|
760
|
-
w = div.width() + 25
|
761
|
-
div.remove()
|
762
|
-
|
763
|
-
if( w > @f_width-10 )
|
764
|
-
w = @f_width - 10
|
765
|
-
|
766
|
-
@search_field.css({'width': w + 'px'})
|
767
|
-
|
768
|
-
dd_top = @container.height()
|
769
|
-
@dropdown.css({"top": dd_top + "px"})
|
770
|
-
|
771
|
-
generate_random_id: ->
|
772
|
-
string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char()
|
773
|
-
while $("#" + string).length > 0
|
774
|
-
string += this.generate_random_char()
|
775
|
-
string
|
776
|
-
|
777
|
-
get_side_border_padding = (elmt) ->
|
778
|
-
side_border_padding = elmt.outerWidth() - elmt.width()
|
779
|
-
|
780
|
-
root.get_side_border_padding = get_side_border_padding
|