card-mod-script 0.13.1 → 0.13.2
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/assets/script/decko/autosave.js.coffee +30 -0
- data/assets/script/decko/bridge.js.coffee +31 -0
- data/assets/script/decko/card_menu.js.coffee +26 -0
- data/assets/script/decko/components.js.coffee +46 -0
- data/assets/script/decko/decko.js.coffee +97 -0
- data/assets/script/decko/doubleclick.js.coffee +30 -0
- data/assets/script/decko/editor.js.coffee +55 -0
- data/assets/script/decko/filter.js.coffee +176 -0
- data/assets/script/decko/filter_items.js.coffee +128 -0
- data/assets/script/decko/filter_links.js.coffee +81 -0
- data/assets/script/decko/follow.js.coffee +22 -0
- data/assets/script/decko/layout.js.coffee +76 -0
- data/assets/script/decko/link_editor.js.coffee +61 -0
- data/assets/script/decko/mod.js.coffee +85 -0
- data/assets/script/decko/modal.js.coffee +113 -0
- data/assets/script/decko/name_editor.js.coffee +58 -0
- data/assets/script/decko/navbox.js.coffee +74 -0
- data/assets/script/decko/nest_editor.js.coffee +166 -0
- data/assets/script/decko/nest_editor_name.js.coffee +102 -0
- data/assets/script/decko/nest_editor_options.js.coffee +93 -0
- data/assets/script/decko/nest_editor_rules.js.coffee +3 -0
- data/assets/script/decko/overlay.js.coffee +57 -0
- data/assets/script/decko/recaptcha.js.coffee +19 -0
- data/assets/script/decko/selectable_filtered_content.js.coffee +12 -0
- data/assets/script/decko/slot.js.coffee +182 -0
- data/assets/script/decko/slot_ready.js.coffee +11 -0
- data/assets/script/decko/slotter.js.coffee +276 -0
- data/assets/script/decko/upload.js.coffee +57 -0
- data/assets/script/jquery-ui.js +10 -0
- data/assets/script/jquery.autosize.js +274 -0
- data/assets/script/manifest.yml +44 -0
- data/assets/script/script_pointer_config.js.coffee +80 -0
- data/assets/script/script_pointer_list_editor.js.coffee +67 -0
- metadata +42 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 740c8b43709f696ea82eb875a37d92dc4c29aaf193c35dd084472817574dcb24
|
4
|
+
data.tar.gz: cddc64356e56ede909a08cd2a6988e3f0b0f63c7e727de9bf123e2bedc5b1a25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b12a2aed352d954774cb731bf79ce89ae345962343762682246abd605a253d5e8556291c49790189a7975cd558e56626007ee7b2f6117191759e94d366fb436
|
7
|
+
data.tar.gz: 26181f4a51408bec334a90b4b782d68680903cb3ba68a81191d634411063747b82ab5788b4cb56980c24e5e080bbc1614223e7a7d305e8478c9ff6b24e9473bd
|
@@ -0,0 +1,30 @@
|
|
1
|
+
jQuery.fn.extend
|
2
|
+
autosave: ->
|
3
|
+
slot = @slot()
|
4
|
+
return if @attr 'no-autosave'
|
5
|
+
multi = @closest '.form-group'
|
6
|
+
if multi[0]
|
7
|
+
return unless id = multi.data 'cardId'
|
8
|
+
reportee = ': ' + multi.data 'cardName'
|
9
|
+
else
|
10
|
+
id = slot.data 'cardId'
|
11
|
+
reportee = ''
|
12
|
+
|
13
|
+
return unless id
|
14
|
+
|
15
|
+
# might be better to put this href base in the html
|
16
|
+
submit_url = decko.path 'update/~' + id
|
17
|
+
form_data = $('#edit_card_'+id).serializeArray().reduce( ((obj, item) ->
|
18
|
+
obj[item.name] = item.value
|
19
|
+
return obj
|
20
|
+
), { 'draft' : 'true', 'success[view]' : 'blank'});
|
21
|
+
$.ajax submit_url, {
|
22
|
+
data : form_data,
|
23
|
+
type : 'POST'
|
24
|
+
}
|
25
|
+
##{ 'card[content]' : @val() },
|
26
|
+
|
27
|
+
$(window).ready ->
|
28
|
+
$('body').on 'change', '.autosave .d0-card-content', ->
|
29
|
+
content_field = $(this)
|
30
|
+
setTimeout ( -> content_field.autosave() ), 500
|
@@ -0,0 +1,31 @@
|
|
1
|
+
decko.slotReady (slot, slotter) ->
|
2
|
+
slot.updateBridge(false, slotter)
|
3
|
+
|
4
|
+
links = slot.find('ul._auto-single-select > li.nav-item > a.nav-link')
|
5
|
+
if links.length == 1
|
6
|
+
$(links[0]).click()
|
7
|
+
|
8
|
+
jQuery.fn.extend
|
9
|
+
# overlayClosed=true means the bridge update was
|
10
|
+
# triggered by closing an overlay
|
11
|
+
updateBridge: (overlayClosed=false, slotter) ->
|
12
|
+
return unless @closest(".bridge").length > 0
|
13
|
+
if @data("breadcrumb")
|
14
|
+
@updateBreadcrumb()
|
15
|
+
else if slotter and $(slotter).data("breadcrumb")
|
16
|
+
$(slotter).updateBreadcrumb()
|
17
|
+
|
18
|
+
if overlayClosed
|
19
|
+
$(".bridge-pills > .nav-item > .nav-link.active").removeClass("active")
|
20
|
+
|
21
|
+
updateBreadcrumb: () ->
|
22
|
+
bc_item = $(".modal-header ._bridge-breadcrumb li:last-child")
|
23
|
+
bc_item.text(this.data("breadcrumb"))
|
24
|
+
bc_item.attr("class", "breadcrumb-item active #{this.data('breadcrumb-class')}")
|
25
|
+
|
26
|
+
$(window).ready ->
|
27
|
+
$('body').on "select2:select", "._close-rule-overlay-on-select", (event) ->
|
28
|
+
$(".overlay-container > ._overlay.card-slot.overlay_rule-view.RULE").removeOverlay()
|
29
|
+
|
30
|
+
$('body').on "click", "._update-history-pills", (event) ->
|
31
|
+
$(this).closest(".slotter").data("update-foreign-slot", ".card-slot.history_tab-view")
|
@@ -0,0 +1,26 @@
|
|
1
|
+
decko.isTouchDevice = ->
|
2
|
+
if 'ontouchstart' of window or window.DocumentTouch and
|
3
|
+
document instanceof DocumentTouch
|
4
|
+
return true
|
5
|
+
else
|
6
|
+
return detectMobileBrowser()
|
7
|
+
|
8
|
+
# source for this method: detectmobilebrowsers.com
|
9
|
+
detectMobileBrowser = (userAgent) ->
|
10
|
+
userAgent = navigator.userAgent or navigator.vendor or window.opera
|
11
|
+
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(userAgent) or /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4))
|
12
|
+
|
13
|
+
decko.slotReady (slot) ->
|
14
|
+
if decko.isTouchDevice()
|
15
|
+
slot.find('._show-on-hover').removeClass('_show-on-hover')
|
16
|
+
|
17
|
+
$(window).ready ->
|
18
|
+
$('body').on 'show.bs.popover', '._card-menu-popover', () ->
|
19
|
+
$(this).closest(".card-menu._show-on-hover")
|
20
|
+
.removeClass("_show-on-hover")
|
21
|
+
.addClass("_show-on-hover-disabled")
|
22
|
+
|
23
|
+
$('body').on 'hide.bs.popover', '._card-menu-popover', () ->
|
24
|
+
$(this).closest(".card-menu._show-on-hover-disabled")
|
25
|
+
.removeClass("_show-on-hover-disabled")
|
26
|
+
.addClass("_show-on-hover")
|
@@ -0,0 +1,46 @@
|
|
1
|
+
submitAfterTyping = null
|
2
|
+
|
3
|
+
$(window).ready ->
|
4
|
+
$('body').on 'show.bs.tab', 'a.load[data-toggle="tab"][data-url]', (e) ->
|
5
|
+
tab_id = $(e.target).attr('href')
|
6
|
+
url = $(e.target).data('url')
|
7
|
+
$(e.target).removeClass('load')
|
8
|
+
$.ajax
|
9
|
+
url: url
|
10
|
+
type: 'GET'
|
11
|
+
success: (html) ->
|
12
|
+
$(tab_id).append(html)
|
13
|
+
decko.contentLoaded($(tab_id), $(this))
|
14
|
+
|
15
|
+
$('body').on "input", "._submit-after-typing", (event) ->
|
16
|
+
form = $(event.target).closest('form')
|
17
|
+
form.slot().find(".autosubmit-success-notification").remove()
|
18
|
+
clearTimeout(submitAfterTyping) if submitAfterTyping
|
19
|
+
submitAfterTyping = setTimeout ->
|
20
|
+
$(event.target).closest('form').submit()
|
21
|
+
submitAfterTyping = null
|
22
|
+
, 1000
|
23
|
+
|
24
|
+
$('body').on "keydown", "._submit-after-typing", (event) ->
|
25
|
+
if event.which == 13
|
26
|
+
clearTimeout(submitAfterTyping) if submitAfterTyping
|
27
|
+
submitAfterTyping = null
|
28
|
+
$(event.target).closest('form').submit()
|
29
|
+
false
|
30
|
+
|
31
|
+
$('body').on "change", "._submit-on-change", (event) ->
|
32
|
+
$(event.target).closest('form').submit()
|
33
|
+
false
|
34
|
+
|
35
|
+
$('body').on "change", "._edit-item", (event) ->
|
36
|
+
cb = $(event.target)
|
37
|
+
if cb.is(":checked")
|
38
|
+
cb.attr("name", "add_item")
|
39
|
+
else
|
40
|
+
cb.attr("name", "drop_item")
|
41
|
+
|
42
|
+
$(event.target).closest('form').submit()
|
43
|
+
false
|
44
|
+
|
45
|
+
|
46
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
$.extend decko,
|
2
|
+
# returns absolute path (starting with a slash)
|
3
|
+
# if rawPath is complete url, this returns the complete url
|
4
|
+
# if rawPath is relative (no slash), this adds relative root
|
5
|
+
path: (rawPath) ->
|
6
|
+
if rawPath.match /^\/|:\/\//
|
7
|
+
rawPath
|
8
|
+
else
|
9
|
+
decko.rootUrl + rawPath
|
10
|
+
|
11
|
+
pingName: (name, success)->
|
12
|
+
$.getJSON decko.path(''), format: 'json', view: 'status', 'card[name]': name, success
|
13
|
+
|
14
|
+
jQuery.fn.extend {
|
15
|
+
notify: (message, status) ->
|
16
|
+
slot = @slot(status)
|
17
|
+
notice = slot.find '.card-notice'
|
18
|
+
unless notice[0]
|
19
|
+
notice = $('<div class="card-notice"></div>')
|
20
|
+
form = slot.find('.card-form')
|
21
|
+
if form[0]
|
22
|
+
$(form[0]).append notice
|
23
|
+
else
|
24
|
+
slot.append notice
|
25
|
+
notice.html message
|
26
|
+
notice.show 'blind'
|
27
|
+
|
28
|
+
report: (message) ->
|
29
|
+
report = @slot().find '.card-report'
|
30
|
+
return false unless report[0]
|
31
|
+
report.hide()
|
32
|
+
report.html message
|
33
|
+
report.show 'drop', 750
|
34
|
+
setTimeout (->report.hide 'drop', 750), 3000
|
35
|
+
}
|
36
|
+
|
37
|
+
#~~~~~ ( EVENTS )
|
38
|
+
|
39
|
+
$(window).ready ->
|
40
|
+
$.ajaxSetup cache: false
|
41
|
+
|
42
|
+
$('body').on 'click', '.submitter', ->
|
43
|
+
$(this).closest('form').submit()
|
44
|
+
|
45
|
+
$('body').on 'click', 'button.redirecter', ->
|
46
|
+
window.location = $(this).attr('href')
|
47
|
+
|
48
|
+
$('body').on "change", '.live-type-field', ->
|
49
|
+
$this = $(this)
|
50
|
+
|
51
|
+
setSlotMode($this)
|
52
|
+
$this.data 'params', $(this).closest('form').serialize()
|
53
|
+
$this.data 'url', $(this).attr 'href'
|
54
|
+
|
55
|
+
$('body').on 'change', '.edit-type-field', ->
|
56
|
+
$(this).closest('form').submit()
|
57
|
+
|
58
|
+
$('body').on 'mouseenter', '[hover_content]', ->
|
59
|
+
$(this).attr 'hover_restore', $(this).html()
|
60
|
+
$(this).html $(this).attr( 'hover_content' )
|
61
|
+
$('body').on 'mouseleave', '[hover_content]', ->
|
62
|
+
$(this).html $(this).attr( 'hover_restore' )
|
63
|
+
|
64
|
+
$('body').on 'click', '.render-error-link', (event) ->
|
65
|
+
msg = $(this).closest('.render-error').find '.render-error-message'
|
66
|
+
msg.show()
|
67
|
+
# msg.dialog()
|
68
|
+
event.preventDefault()
|
69
|
+
|
70
|
+
decko.slotReady (slot) ->
|
71
|
+
slot.find('card-view-placeholder').each ->
|
72
|
+
$place = $(this)
|
73
|
+
return if $place.data("loading")
|
74
|
+
|
75
|
+
$place.data "loading", true
|
76
|
+
$.get $place.data("url"), (data, _status) ->
|
77
|
+
$place.replaceWith data
|
78
|
+
|
79
|
+
# important: this prevents jquery-mobile from taking over everything
|
80
|
+
# $( document ).on "mobileinit", ->
|
81
|
+
# $.extend $.mobile , {
|
82
|
+
# #autoInitializePage: false
|
83
|
+
# #ajaxEnabled: false
|
84
|
+
# }
|
85
|
+
|
86
|
+
setSlotMode = ($el, mode=null) ->
|
87
|
+
$slotter = $el.closest(".slotter")
|
88
|
+
if $slotter.length && $slotter.attr('data-slotter-mode')
|
89
|
+
$slotter.attr 'data-original-slotter-mode', $slotter.attr('slotter-mode')
|
90
|
+
$slotter.attr 'data-slotter-mode', mode
|
91
|
+
|
92
|
+
|
93
|
+
warn = (stuff) -> console.log stuff if console?
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
doubleClickActiveMap = { off: false, on: true, signed_in: decko.currentUserId }
|
2
|
+
|
3
|
+
doubleClickActive = () ->
|
4
|
+
doubleClickActiveMap[decko.doubleClick]
|
5
|
+
# else alert "illegal configuration: " + decko.doubleClick
|
6
|
+
|
7
|
+
doubleClickApplies = (el) ->
|
8
|
+
return false if ['.nodblclick', '.d0-card-header', '.card-editor'].some (klass) ->
|
9
|
+
el.closest(klass)[0]
|
10
|
+
# double click inactive inside header, editor, or tag with "nodblclick" class
|
11
|
+
!el.slot().find('.card-editor')[0]?
|
12
|
+
|
13
|
+
|
14
|
+
triggerDoubleClickEditingOn = (el)->
|
15
|
+
slot = el.slot()
|
16
|
+
edit_link = decko.slotEditLink(slot)
|
17
|
+
|
18
|
+
if edit_link
|
19
|
+
edit_link.click()
|
20
|
+
else
|
21
|
+
edit_view = decko.slotEditView(slot)
|
22
|
+
url = decko.path("~#{slot.data('cardId')}?view=#{edit_view}")
|
23
|
+
slot.reloadSlot url
|
24
|
+
|
25
|
+
$(window).ready ->
|
26
|
+
if doubleClickActive()
|
27
|
+
$('body').on 'dblclick', 'div', (_event) ->
|
28
|
+
if doubleClickApplies $(this)
|
29
|
+
triggerDoubleClickEditingOn $(this)
|
30
|
+
false # don't propagate up to next slot
|
@@ -0,0 +1,55 @@
|
|
1
|
+
$.extend decko,
|
2
|
+
initializeEditors: (range, map) ->
|
3
|
+
map = decko.editorInitFunctionMap unless map?
|
4
|
+
$.each map, (selector, fn) ->
|
5
|
+
$.each range.find(selector), ->
|
6
|
+
fn.call $(this)
|
7
|
+
|
8
|
+
editorContentFunctionMap: {}
|
9
|
+
|
10
|
+
editorInitFunctionMap:
|
11
|
+
'textarea': -> $(this).autosize()
|
12
|
+
'.file-upload': -> decko.upload_file(this)
|
13
|
+
'.etherpad-textarea': ->
|
14
|
+
$(this).closest('form')
|
15
|
+
.find('.edit-submit-button')
|
16
|
+
.attr('class', 'etherpad-submit-button')
|
17
|
+
|
18
|
+
addEditor: (selector, init, get_content) ->
|
19
|
+
decko.editorContentFunctionMap[selector] = get_content
|
20
|
+
decko.editorInitFunctionMap[selector] = init
|
21
|
+
|
22
|
+
jQuery.fn.extend
|
23
|
+
setContentFieldsFromMap: (map) ->
|
24
|
+
map = decko.editorContentFunctionMap unless map?
|
25
|
+
this_form = $(this)
|
26
|
+
$.each map, (selector, fn) ->
|
27
|
+
this_form.setContentFields(selector, fn)
|
28
|
+
setContentFields: (selector, fn) ->
|
29
|
+
$.each @find(selector), ->
|
30
|
+
$(this).setContentField(fn)
|
31
|
+
setContentField: (fn) ->
|
32
|
+
field = @closest('.card-editor').find('.d0-card-content')
|
33
|
+
init_val = field.val() # tinymce-jquery overrides val();
|
34
|
+
# that's why we're not using it.
|
35
|
+
new_val = fn.call this
|
36
|
+
field.val new_val
|
37
|
+
field.change() if init_val != new_val
|
38
|
+
|
39
|
+
$(window).ready ->
|
40
|
+
# decko.initializeEditors $('body > :not(.modal)')
|
41
|
+
setTimeout (-> decko.initializeEditors $('body > :not(.modal)')), 10
|
42
|
+
# dislike the timeout, but without this forms with multiple TinyMCE editors
|
43
|
+
# were failing to load properly
|
44
|
+
# I couldn't reproduce that problem described above -pk
|
45
|
+
|
46
|
+
$('body').on 'submit', '.card-form', ->
|
47
|
+
$(this).setContentFieldsFromMap()
|
48
|
+
$(this).find('.d0-card-content').attr('no-autosave','true')
|
49
|
+
true
|
50
|
+
|
51
|
+
setInterval (-> $('.card-form').setContentFieldsFromMap()), 20000
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# filter object that manages dynamic sorting and filtering
|
2
|
+
|
3
|
+
# el can be any element inside widget
|
4
|
+
decko.filter = (el) ->
|
5
|
+
closest_widget = $(el).closest "._filter-widget"
|
6
|
+
@widget =
|
7
|
+
if closest_widget.length
|
8
|
+
closest_widget
|
9
|
+
else
|
10
|
+
$(el).closest("._filtered-content").find "._filter-widget"
|
11
|
+
|
12
|
+
@activeContainer = @widget.find "._filter-container"
|
13
|
+
@dropdown = @widget.find "._add-filter-dropdown"
|
14
|
+
@dropdownItems = @widget.find "._filter-category-select"
|
15
|
+
@form = @widget.find "._filter-form"
|
16
|
+
@quickFilter = @widget.find "._quick-filter"
|
17
|
+
|
18
|
+
@showWithStatus = (status) ->
|
19
|
+
f = this
|
20
|
+
$.each (@dropdownItems), ->
|
21
|
+
item = $(this)
|
22
|
+
if item.data status
|
23
|
+
f.activate item.data("category")
|
24
|
+
|
25
|
+
@reset = () ->
|
26
|
+
# @clear()
|
27
|
+
@dropdownItems.show()
|
28
|
+
@restrict @form.find("._reset-filter").data("reset")
|
29
|
+
|
30
|
+
@clear = () ->
|
31
|
+
@activeContainer.find(".input-group").remove()
|
32
|
+
|
33
|
+
@activate = (category, value) ->
|
34
|
+
@activateField category, value
|
35
|
+
@hideOption category
|
36
|
+
|
37
|
+
@showOption = (category) ->
|
38
|
+
@dropdown.show()
|
39
|
+
@option(category).show()
|
40
|
+
|
41
|
+
@hideOption = (category) ->
|
42
|
+
@option(category).hide()
|
43
|
+
@dropdown.hide() if @dropdownItems.length <= @activeFields().length
|
44
|
+
|
45
|
+
@activeFields = () ->
|
46
|
+
@activeContainer.find "._filter-input"
|
47
|
+
|
48
|
+
@option = (category) ->
|
49
|
+
@dropdownItems.filter("[data-category='#{category}']")
|
50
|
+
|
51
|
+
@findPrototype = (category) ->
|
52
|
+
@widget.find "._filter-input-field-prototypes ._filter-input-#{category}"
|
53
|
+
|
54
|
+
@activateField = (category, value) ->
|
55
|
+
field = @findPrototype(category).clone()
|
56
|
+
@fieldValue field, value
|
57
|
+
@dropdown.before field
|
58
|
+
@initField field
|
59
|
+
field.find("input, select").first().focus()
|
60
|
+
|
61
|
+
@fieldValue = (field, value) ->
|
62
|
+
if typeof(value) == "object"
|
63
|
+
@compoundFieldValue field, value
|
64
|
+
else
|
65
|
+
@simpleFieldValue field, value
|
66
|
+
|
67
|
+
@simpleFieldValue = (field, value) ->
|
68
|
+
input = field.find("input, select")
|
69
|
+
input.val value if (typeof value != 'undefined')
|
70
|
+
|
71
|
+
@compoundFieldValue = (field, vals) ->
|
72
|
+
for key of vals
|
73
|
+
input = field.find "#filter_value_" + key
|
74
|
+
input.val vals[key]
|
75
|
+
|
76
|
+
@removeField = (category)->
|
77
|
+
@activeField(category).remove()
|
78
|
+
@showOption category
|
79
|
+
|
80
|
+
@initField = (field) ->
|
81
|
+
@initSelectField field
|
82
|
+
decko.initAutoCardPlete field.find("input")
|
83
|
+
# only has effect if there is a data-options-card value
|
84
|
+
|
85
|
+
@initSelectField = (field) ->
|
86
|
+
field.find("select").select2(
|
87
|
+
containerCssClass: ":all:"
|
88
|
+
width: "auto"
|
89
|
+
dropdownAutoWidth: "true"
|
90
|
+
)
|
91
|
+
|
92
|
+
@activeField = (category) ->
|
93
|
+
@activeContainer.find("._filter-input-#{category}")
|
94
|
+
|
95
|
+
@isActive = (category) ->
|
96
|
+
@activeField(category).length
|
97
|
+
|
98
|
+
@restrict = (data) ->
|
99
|
+
@clear()
|
100
|
+
for key of data
|
101
|
+
@activateField key, data[key]
|
102
|
+
@update()
|
103
|
+
|
104
|
+
@addRestrictions = (hash) ->
|
105
|
+
for category of hash
|
106
|
+
@removeField category
|
107
|
+
@activate category, hash[category]
|
108
|
+
@update()
|
109
|
+
|
110
|
+
@removeRestrictions = (hash) ->
|
111
|
+
for category of hash
|
112
|
+
@removeField category
|
113
|
+
@update()
|
114
|
+
|
115
|
+
# triggers update
|
116
|
+
@setInputVal = (field, value) ->
|
117
|
+
select = field.find "select"
|
118
|
+
if select.length
|
119
|
+
@setSelect2Val select, value
|
120
|
+
else
|
121
|
+
@setTextInputVal field.find("input"), value
|
122
|
+
|
123
|
+
# this triggers change, which updates form
|
124
|
+
# if we just use simple "val", the display doesn't update correctly
|
125
|
+
@setSelect2Val = (select, value) ->
|
126
|
+
value = [value] if select.attr("multiple") && !Array.isArray(value)
|
127
|
+
select.select2 "val", value
|
128
|
+
|
129
|
+
@setTextInputVal = (input, value) ->
|
130
|
+
input.val value
|
131
|
+
@update()
|
132
|
+
|
133
|
+
@updateLastVals = ()->
|
134
|
+
@activeFields().find("input, select").each ()->
|
135
|
+
$(this).data "lastVal", $(this).val()
|
136
|
+
|
137
|
+
@updateUrlBar = () ->
|
138
|
+
return if @widget.closest('._noFilterUrlUpdates')[0]
|
139
|
+
window.history.pushState "filter", "filter", '?' + @form.serialize()
|
140
|
+
|
141
|
+
@update = ()->
|
142
|
+
@updateLastVals()
|
143
|
+
@updateQuickLinks()
|
144
|
+
@form.submit()
|
145
|
+
@updateUrlBar()
|
146
|
+
|
147
|
+
@updateQuickLinks = ()->
|
148
|
+
widget = this
|
149
|
+
links = @quickFilter.find "._filter-link"
|
150
|
+
links.addClass "active"
|
151
|
+
links.each ->
|
152
|
+
link = $(this)
|
153
|
+
opts = link.data "filter"
|
154
|
+
for key of opts
|
155
|
+
widget.deactivateQuickLink link, key, opts[key]
|
156
|
+
|
157
|
+
@deactivateQuickLink = (link, key, value) ->
|
158
|
+
sel = "._filter-input-#{key}"
|
159
|
+
$.map [@form.find("#{sel} input, #{sel} select").val()], (arr) ->
|
160
|
+
arr = [arr].flat()
|
161
|
+
link.removeClass "active" if $.inArray(value, arr) > -1
|
162
|
+
|
163
|
+
@updateIfChanged = ()->
|
164
|
+
@update() if @changedSinceLastVal()
|
165
|
+
|
166
|
+
@updateIfPresent = (category)->
|
167
|
+
val = @activeField(category).find("input, select").val()
|
168
|
+
@update() if val && val.length > 0
|
169
|
+
|
170
|
+
@changedSinceLastVal = () ->
|
171
|
+
changed = false
|
172
|
+
@activeFields().find("input, select").each ()->
|
173
|
+
changed = true if $(this).val() != $(this).data("lastVal")
|
174
|
+
changed
|
175
|
+
|
176
|
+
this
|