fnschool 20251011.80531.840__py3-none-any.whl → 20251011.81705.829__py3-none-any.whl
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.
Potentially problematic release.
This version of fnschool might be problematic. Click here for more details.
- fnschoo1/__init__.py +2 -1
- fnschoo1/db.sqlite3 +0 -0
- fnschoo1/static/images/favicon.ico +0 -0
- {fnschool-20251011.80531.840.dist-info → fnschool-20251011.81705.829.dist-info}/METADATA +1 -1
- fnschool-20251011.81705.829.dist-info/RECORD +101 -0
- fnschoo1/static_collected/admin/css/autocomplete.css +0 -377
- fnschoo1/static_collected/admin/css/base.css +0 -1224
- fnschoo1/static_collected/admin/css/changelists.css +0 -334
- fnschoo1/static_collected/admin/css/dark_mode.css +0 -136
- fnschoo1/static_collected/admin/css/dashboard.css +0 -30
- fnschoo1/static_collected/admin/css/forms.css +0 -546
- fnschoo1/static_collected/admin/css/login.css +0 -62
- fnschoo1/static_collected/admin/css/nav_sidebar.css +0 -145
- fnschoo1/static_collected/admin/css/responsive.css +0 -1043
- fnschoo1/static_collected/admin/css/responsive_rtl.css +0 -84
- fnschoo1/static_collected/admin/css/rtl.css +0 -311
- fnschoo1/static_collected/admin/css/vendor/select2/select2.css +0 -708
- fnschoo1/static_collected/admin/css/vendor/select2/select2.min.css +0 -1
- fnschoo1/static_collected/admin/css/widgets.css +0 -639
- fnschoo1/static_collected/admin/js/SelectBox.js +0 -128
- fnschoo1/static_collected/admin/js/SelectFilter2.js +0 -503
- fnschoo1/static_collected/admin/js/actions.js +0 -232
- fnschoo1/static_collected/admin/js/admin/DateTimeShortcuts.js +0 -496
- fnschoo1/static_collected/admin/js/admin/RelatedObjectLookups.js +0 -276
- fnschoo1/static_collected/admin/js/autocomplete.js +0 -33
- fnschoo1/static_collected/admin/js/calendar.js +0 -251
- fnschoo1/static_collected/admin/js/cancel.js +0 -29
- fnschoo1/static_collected/admin/js/change_form.js +0 -21
- fnschoo1/static_collected/admin/js/collapse.js +0 -43
- fnschoo1/static_collected/admin/js/core.js +0 -174
- fnschoo1/static_collected/admin/js/filters.js +0 -37
- fnschoo1/static_collected/admin/js/inlines.js +0 -439
- fnschoo1/static_collected/admin/js/jquery.init.js +0 -8
- fnschoo1/static_collected/admin/js/nav_sidebar.js +0 -81
- fnschoo1/static_collected/admin/js/popup_response.js +0 -24
- fnschoo1/static_collected/admin/js/prepopulate.js +0 -43
- fnschoo1/static_collected/admin/js/prepopulate_init.js +0 -20
- fnschoo1/static_collected/admin/js/theme.js +0 -57
- fnschoo1/static_collected/admin/js/urlify.js +0 -529
- fnschoo1/static_collected/admin/js/vendor/jquery/jquery.js +0 -10913
- fnschoo1/static_collected/admin/js/vendor/jquery/jquery.min.js +0 -2
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/af.js +0 -43
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ar.js +0 -36
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/az.js +0 -33
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bg.js +0 -38
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bn.js +0 -39
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bs.js +0 -48
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ca.js +0 -41
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/cs.js +0 -62
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/da.js +0 -37
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/de.js +0 -41
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/dsb.js +0 -51
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/el.js +0 -43
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/en.js +0 -41
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/es.js +0 -41
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/et.js +0 -38
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/eu.js +0 -45
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fa.js +0 -42
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fi.js +0 -42
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fr.js +0 -43
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/gl.js +0 -40
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/he.js +0 -44
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hi.js +0 -40
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hr.js +0 -45
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hsb.js +0 -51
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hu.js +0 -44
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hy.js +0 -40
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/id.js +0 -36
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/is.js +0 -37
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/it.js +0 -43
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ja.js +0 -40
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ka.js +0 -42
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/km.js +0 -38
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ko.js +0 -42
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/lt.js +0 -45
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/lv.js +0 -41
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/mk.js +0 -42
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ms.js +0 -38
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/nb.js +0 -38
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ne.js +0 -44
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/nl.js +0 -46
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pl.js +0 -43
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ps.js +0 -41
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pt-BR.js +0 -39
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pt.js +0 -41
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ro.js +0 -43
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ru.js +0 -48
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sk.js +0 -61
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sl.js +0 -41
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sq.js +0 -43
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sr-Cyrl.js +0 -48
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sr.js +0 -48
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sv.js +0 -40
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/th.js +0 -36
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/tk.js +0 -36
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/tr.js +0 -40
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/uk.js +0 -59
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/vi.js +0 -37
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/zh-CN.js +0 -36
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/zh-TW.js +0 -33
- fnschoo1/static_collected/admin/js/vendor/select2/select2.full.js +0 -7115
- fnschoo1/static_collected/admin/js/vendor/select2/select2.full.min.js +0 -2
- fnschoo1/static_collected/admin/js/vendor/xregexp/xregexp.js +0 -4993
- fnschoo1/static_collected/admin/js/vendor/xregexp/xregexp.min.js +0 -160
- fnschoo1/static_collected/css/bootstrap.min.css +0 -11776
- fnschoo1/static_collected/css/fnschool.css +0 -26
- fnschoo1/static_collected/js/bootstrap.bundle.min.js +0 -4223
- fnschoo1/static_collected/js/bootstrap.min.js +0 -2919
- fnschoo1/static_collected/js/fnschool.js +0 -84
- fnschoo1/static_collected/js/jquery.min.js +0 -5413
- fnschoo1/static_collected/js/jquery.slim.min.js +0 -4331
- fnschoo1/static_collected/js/popper.min.js +0 -1306
- fnschool-20251011.80531.840.dist-info/RECORD +0 -207
- {fnschool-20251011.80531.840.dist-info → fnschool-20251011.81705.829.dist-info}/WHEEL +0 -0
- {fnschool-20251011.80531.840.dist-info → fnschool-20251011.81705.829.dist-info}/entry_points.txt +0 -0
- {fnschool-20251011.80531.840.dist-info → fnschool-20251011.81705.829.dist-info}/licenses/LICENSE +0 -0
- {fnschool-20251011.80531.840.dist-info → fnschool-20251011.81705.829.dist-info}/top_level.txt +0 -0
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
{
|
|
3
|
-
const SelectBox = {
|
|
4
|
-
cache: {},
|
|
5
|
-
init: function (id) {
|
|
6
|
-
const box = document.getElementById(id)
|
|
7
|
-
SelectBox.cache[id] = []
|
|
8
|
-
const cache = SelectBox.cache[id]
|
|
9
|
-
for (const node of box.options) {
|
|
10
|
-
cache.push({ value: node.value, text: node.text, displayed: 1 })
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
redisplay: function (id) {
|
|
14
|
-
// Repopulate HTML select box from cache
|
|
15
|
-
const box = document.getElementById(id)
|
|
16
|
-
const scroll_value_from_top = box.scrollTop
|
|
17
|
-
box.innerHTML = ''
|
|
18
|
-
for (const node of SelectBox.cache[id]) {
|
|
19
|
-
if (node.displayed) {
|
|
20
|
-
const new_option = new Option(node.text, node.value, false, false)
|
|
21
|
-
// Shows a tooltip when hovering over the option
|
|
22
|
-
new_option.title = node.text
|
|
23
|
-
box.appendChild(new_option)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
box.scrollTop = scroll_value_from_top
|
|
27
|
-
},
|
|
28
|
-
filter: function (id, text) {
|
|
29
|
-
// Redisplay the HTML select box, displaying only the choices containing ALL
|
|
30
|
-
// the words in text. (It's an AND search.)
|
|
31
|
-
const tokens = text.toLowerCase().split(/\s+/)
|
|
32
|
-
for (const node of SelectBox.cache[id]) {
|
|
33
|
-
node.displayed = 1
|
|
34
|
-
const node_text = node.text.toLowerCase()
|
|
35
|
-
for (const token of tokens) {
|
|
36
|
-
if (!node_text.includes(token)) {
|
|
37
|
-
node.displayed = 0
|
|
38
|
-
break // Once the first token isn't found we're done
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
SelectBox.redisplay(id)
|
|
43
|
-
},
|
|
44
|
-
get_hidden_node_count(id) {
|
|
45
|
-
const cache = SelectBox.cache[id] || []
|
|
46
|
-
return cache.filter((node) => node.displayed === 0).length
|
|
47
|
-
},
|
|
48
|
-
delete_from_cache: function (id, value) {
|
|
49
|
-
let delete_index = null
|
|
50
|
-
const cache = SelectBox.cache[id]
|
|
51
|
-
for (const [i, node] of cache.entries()) {
|
|
52
|
-
if (node.value === value) {
|
|
53
|
-
delete_index = i
|
|
54
|
-
break
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
cache.splice(delete_index, 1)
|
|
58
|
-
},
|
|
59
|
-
add_to_cache: function (id, option) {
|
|
60
|
-
SelectBox.cache[id].push({
|
|
61
|
-
value: option.value,
|
|
62
|
-
text: option.text,
|
|
63
|
-
displayed: 1,
|
|
64
|
-
})
|
|
65
|
-
},
|
|
66
|
-
cache_contains: function (id, value) {
|
|
67
|
-
// Check if an item is contained in the cache
|
|
68
|
-
for (const node of SelectBox.cache[id]) {
|
|
69
|
-
if (node.value === value) {
|
|
70
|
-
return true
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return false
|
|
74
|
-
},
|
|
75
|
-
move: function (from, to) {
|
|
76
|
-
const from_box = document.getElementById(from)
|
|
77
|
-
for (const option of from_box.options) {
|
|
78
|
-
const option_value = option.value
|
|
79
|
-
if (option.selected && SelectBox.cache_contains(from, option_value)) {
|
|
80
|
-
SelectBox.add_to_cache(to, {
|
|
81
|
-
value: option_value,
|
|
82
|
-
text: option.text,
|
|
83
|
-
displayed: 1,
|
|
84
|
-
})
|
|
85
|
-
SelectBox.delete_from_cache(from, option_value)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
SelectBox.redisplay(from)
|
|
89
|
-
SelectBox.redisplay(to)
|
|
90
|
-
},
|
|
91
|
-
move_all: function (from, to) {
|
|
92
|
-
const from_box = document.getElementById(from)
|
|
93
|
-
for (const option of from_box.options) {
|
|
94
|
-
const option_value = option.value
|
|
95
|
-
if (SelectBox.cache_contains(from, option_value)) {
|
|
96
|
-
SelectBox.add_to_cache(to, {
|
|
97
|
-
value: option_value,
|
|
98
|
-
text: option.text,
|
|
99
|
-
displayed: 1,
|
|
100
|
-
})
|
|
101
|
-
SelectBox.delete_from_cache(from, option_value)
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
SelectBox.redisplay(from)
|
|
105
|
-
SelectBox.redisplay(to)
|
|
106
|
-
},
|
|
107
|
-
sort: function (id) {
|
|
108
|
-
SelectBox.cache[id].sort(function (a, b) {
|
|
109
|
-
a = a.text.toLowerCase()
|
|
110
|
-
b = b.text.toLowerCase()
|
|
111
|
-
if (a > b) {
|
|
112
|
-
return 1
|
|
113
|
-
}
|
|
114
|
-
if (a < b) {
|
|
115
|
-
return -1
|
|
116
|
-
}
|
|
117
|
-
return 0
|
|
118
|
-
})
|
|
119
|
-
},
|
|
120
|
-
select_all: function (id) {
|
|
121
|
-
const box = document.getElementById(id)
|
|
122
|
-
for (const option of box.options) {
|
|
123
|
-
option.selected = true
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
}
|
|
127
|
-
window.SelectBox = SelectBox
|
|
128
|
-
}
|
|
@@ -1,503 +0,0 @@
|
|
|
1
|
-
/*global SelectBox, gettext, interpolate, quickElement, SelectFilter*/
|
|
2
|
-
/*
|
|
3
|
-
SelectFilter2 - Turns a multiple-select box into a filter interface.
|
|
4
|
-
|
|
5
|
-
Requires core.js and SelectBox.js.
|
|
6
|
-
*/
|
|
7
|
-
'use strict'
|
|
8
|
-
{
|
|
9
|
-
window.SelectFilter = {
|
|
10
|
-
init: function (field_id, field_name, is_stacked) {
|
|
11
|
-
if (field_id.match(/__prefix__/)) {
|
|
12
|
-
// Don't initialize on empty forms.
|
|
13
|
-
return
|
|
14
|
-
}
|
|
15
|
-
const from_box = document.getElementById(field_id)
|
|
16
|
-
from_box.id += '_from' // change its ID
|
|
17
|
-
from_box.className = 'filtered'
|
|
18
|
-
|
|
19
|
-
for (const p of from_box.parentNode.getElementsByTagName('p')) {
|
|
20
|
-
if (p.classList.contains('info')) {
|
|
21
|
-
// Remove <p class="info">, because it just gets in the way.
|
|
22
|
-
from_box.parentNode.removeChild(p)
|
|
23
|
-
} else if (p.classList.contains('help')) {
|
|
24
|
-
// Move help text up to the top so it isn't below the select
|
|
25
|
-
// boxes or wrapped off on the side to the right of the add
|
|
26
|
-
// button:
|
|
27
|
-
from_box.parentNode.insertBefore(p, from_box.parentNode.firstChild)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// <div class="selector"> or <div class="selector stacked">
|
|
32
|
-
const selector_div = quickElement('div', from_box.parentNode)
|
|
33
|
-
selector_div.className = is_stacked ? 'selector stacked' : 'selector'
|
|
34
|
-
|
|
35
|
-
// <div class="selector-available">
|
|
36
|
-
const selector_available = quickElement('div', selector_div)
|
|
37
|
-
selector_available.className = 'selector-available'
|
|
38
|
-
const title_available = quickElement(
|
|
39
|
-
'h2',
|
|
40
|
-
selector_available,
|
|
41
|
-
interpolate(gettext('Available %s') + ' ', [field_name])
|
|
42
|
-
)
|
|
43
|
-
quickElement(
|
|
44
|
-
'span',
|
|
45
|
-
title_available,
|
|
46
|
-
'',
|
|
47
|
-
'class',
|
|
48
|
-
'help help-tooltip help-icon',
|
|
49
|
-
'title',
|
|
50
|
-
interpolate(
|
|
51
|
-
gettext(
|
|
52
|
-
'This is the list of available %s. You may choose some by ' +
|
|
53
|
-
'selecting them in the box below and then clicking the ' +
|
|
54
|
-
'"Choose" arrow between the two boxes.'
|
|
55
|
-
),
|
|
56
|
-
[field_name]
|
|
57
|
-
)
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
const filter_p = quickElement(
|
|
61
|
-
'p',
|
|
62
|
-
selector_available,
|
|
63
|
-
'',
|
|
64
|
-
'id',
|
|
65
|
-
field_id + '_filter'
|
|
66
|
-
)
|
|
67
|
-
filter_p.className = 'selector-filter'
|
|
68
|
-
|
|
69
|
-
const search_filter_label = quickElement(
|
|
70
|
-
'label',
|
|
71
|
-
filter_p,
|
|
72
|
-
'',
|
|
73
|
-
'for',
|
|
74
|
-
field_id + '_input'
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
quickElement(
|
|
78
|
-
'span',
|
|
79
|
-
search_filter_label,
|
|
80
|
-
'',
|
|
81
|
-
'class',
|
|
82
|
-
'help-tooltip search-label-icon',
|
|
83
|
-
'title',
|
|
84
|
-
interpolate(
|
|
85
|
-
gettext(
|
|
86
|
-
'Type into this box to filter down the list of available %s.'
|
|
87
|
-
),
|
|
88
|
-
[field_name]
|
|
89
|
-
)
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
filter_p.appendChild(document.createTextNode(' '))
|
|
93
|
-
|
|
94
|
-
const filter_input = quickElement(
|
|
95
|
-
'input',
|
|
96
|
-
filter_p,
|
|
97
|
-
'',
|
|
98
|
-
'type',
|
|
99
|
-
'text',
|
|
100
|
-
'placeholder',
|
|
101
|
-
gettext('Filter')
|
|
102
|
-
)
|
|
103
|
-
filter_input.id = field_id + '_input'
|
|
104
|
-
|
|
105
|
-
selector_available.appendChild(from_box)
|
|
106
|
-
const choose_all = quickElement(
|
|
107
|
-
'a',
|
|
108
|
-
selector_available,
|
|
109
|
-
gettext('Choose all'),
|
|
110
|
-
'title',
|
|
111
|
-
interpolate(gettext('Click to choose all %s at once.'), [field_name]),
|
|
112
|
-
'href',
|
|
113
|
-
'#',
|
|
114
|
-
'id',
|
|
115
|
-
field_id + '_add_all_link'
|
|
116
|
-
)
|
|
117
|
-
choose_all.className = 'selector-chooseall'
|
|
118
|
-
|
|
119
|
-
// <ul class="selector-chooser">
|
|
120
|
-
const selector_chooser = quickElement('ul', selector_div)
|
|
121
|
-
selector_chooser.className = 'selector-chooser'
|
|
122
|
-
const add_link = quickElement(
|
|
123
|
-
'a',
|
|
124
|
-
quickElement('li', selector_chooser),
|
|
125
|
-
gettext('Choose'),
|
|
126
|
-
'title',
|
|
127
|
-
gettext('Choose'),
|
|
128
|
-
'href',
|
|
129
|
-
'#',
|
|
130
|
-
'id',
|
|
131
|
-
field_id + '_add_link'
|
|
132
|
-
)
|
|
133
|
-
add_link.className = 'selector-add'
|
|
134
|
-
const remove_link = quickElement(
|
|
135
|
-
'a',
|
|
136
|
-
quickElement('li', selector_chooser),
|
|
137
|
-
gettext('Remove'),
|
|
138
|
-
'title',
|
|
139
|
-
gettext('Remove'),
|
|
140
|
-
'href',
|
|
141
|
-
'#',
|
|
142
|
-
'id',
|
|
143
|
-
field_id + '_remove_link'
|
|
144
|
-
)
|
|
145
|
-
remove_link.className = 'selector-remove'
|
|
146
|
-
|
|
147
|
-
// <div class="selector-chosen">
|
|
148
|
-
const selector_chosen = quickElement(
|
|
149
|
-
'div',
|
|
150
|
-
selector_div,
|
|
151
|
-
'',
|
|
152
|
-
'id',
|
|
153
|
-
field_id + '_selector_chosen'
|
|
154
|
-
)
|
|
155
|
-
selector_chosen.className = 'selector-chosen'
|
|
156
|
-
const title_chosen = quickElement(
|
|
157
|
-
'h2',
|
|
158
|
-
selector_chosen,
|
|
159
|
-
interpolate(gettext('Chosen %s') + ' ', [field_name])
|
|
160
|
-
)
|
|
161
|
-
quickElement(
|
|
162
|
-
'span',
|
|
163
|
-
title_chosen,
|
|
164
|
-
'',
|
|
165
|
-
'class',
|
|
166
|
-
'help help-tooltip help-icon',
|
|
167
|
-
'title',
|
|
168
|
-
interpolate(
|
|
169
|
-
gettext(
|
|
170
|
-
'This is the list of chosen %s. You may remove some by ' +
|
|
171
|
-
'selecting them in the box below and then clicking the ' +
|
|
172
|
-
'"Remove" arrow between the two boxes.'
|
|
173
|
-
),
|
|
174
|
-
[field_name]
|
|
175
|
-
)
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
const filter_selected_p = quickElement(
|
|
179
|
-
'p',
|
|
180
|
-
selector_chosen,
|
|
181
|
-
'',
|
|
182
|
-
'id',
|
|
183
|
-
field_id + '_filter_selected'
|
|
184
|
-
)
|
|
185
|
-
filter_selected_p.className = 'selector-filter'
|
|
186
|
-
|
|
187
|
-
const search_filter_selected_label = quickElement(
|
|
188
|
-
'label',
|
|
189
|
-
filter_selected_p,
|
|
190
|
-
'',
|
|
191
|
-
'for',
|
|
192
|
-
field_id + '_selected_input'
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
quickElement(
|
|
196
|
-
'span',
|
|
197
|
-
search_filter_selected_label,
|
|
198
|
-
'',
|
|
199
|
-
'class',
|
|
200
|
-
'help-tooltip search-label-icon',
|
|
201
|
-
'title',
|
|
202
|
-
interpolate(
|
|
203
|
-
gettext('Type into this box to filter down the list of selected %s.'),
|
|
204
|
-
[field_name]
|
|
205
|
-
)
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
filter_selected_p.appendChild(document.createTextNode(' '))
|
|
209
|
-
|
|
210
|
-
const filter_selected_input = quickElement(
|
|
211
|
-
'input',
|
|
212
|
-
filter_selected_p,
|
|
213
|
-
'',
|
|
214
|
-
'type',
|
|
215
|
-
'text',
|
|
216
|
-
'placeholder',
|
|
217
|
-
gettext('Filter')
|
|
218
|
-
)
|
|
219
|
-
filter_selected_input.id = field_id + '_selected_input'
|
|
220
|
-
|
|
221
|
-
const to_box = quickElement(
|
|
222
|
-
'select',
|
|
223
|
-
selector_chosen,
|
|
224
|
-
'',
|
|
225
|
-
'id',
|
|
226
|
-
field_id + '_to',
|
|
227
|
-
'multiple',
|
|
228
|
-
'',
|
|
229
|
-
'size',
|
|
230
|
-
from_box.size,
|
|
231
|
-
'name',
|
|
232
|
-
from_box.name
|
|
233
|
-
)
|
|
234
|
-
to_box.className = 'filtered'
|
|
235
|
-
|
|
236
|
-
const warning_footer = quickElement(
|
|
237
|
-
'div',
|
|
238
|
-
selector_chosen,
|
|
239
|
-
'',
|
|
240
|
-
'class',
|
|
241
|
-
'list-footer-display'
|
|
242
|
-
)
|
|
243
|
-
quickElement(
|
|
244
|
-
'span',
|
|
245
|
-
warning_footer,
|
|
246
|
-
'',
|
|
247
|
-
'id',
|
|
248
|
-
field_id + '_list-footer-display-text'
|
|
249
|
-
)
|
|
250
|
-
quickElement(
|
|
251
|
-
'span',
|
|
252
|
-
warning_footer,
|
|
253
|
-
' (click to clear)',
|
|
254
|
-
'class',
|
|
255
|
-
'list-footer-display__clear'
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
const clear_all = quickElement(
|
|
259
|
-
'a',
|
|
260
|
-
selector_chosen,
|
|
261
|
-
gettext('Remove all'),
|
|
262
|
-
'title',
|
|
263
|
-
interpolate(gettext('Click to remove all chosen %s at once.'), [
|
|
264
|
-
field_name,
|
|
265
|
-
]),
|
|
266
|
-
'href',
|
|
267
|
-
'#',
|
|
268
|
-
'id',
|
|
269
|
-
field_id + '_remove_all_link'
|
|
270
|
-
)
|
|
271
|
-
clear_all.className = 'selector-clearall'
|
|
272
|
-
|
|
273
|
-
from_box.name = from_box.name + '_old'
|
|
274
|
-
|
|
275
|
-
// Set up the JavaScript event handlers for the select box filter interface
|
|
276
|
-
const move_selection = function (e, elem, move_func, from, to) {
|
|
277
|
-
if (elem.classList.contains('active')) {
|
|
278
|
-
move_func(from, to)
|
|
279
|
-
SelectFilter.refresh_icons(field_id)
|
|
280
|
-
SelectFilter.refresh_filtered_selects(field_id)
|
|
281
|
-
SelectFilter.refresh_filtered_warning(field_id)
|
|
282
|
-
}
|
|
283
|
-
e.preventDefault()
|
|
284
|
-
}
|
|
285
|
-
choose_all.addEventListener('click', function (e) {
|
|
286
|
-
move_selection(
|
|
287
|
-
e,
|
|
288
|
-
this,
|
|
289
|
-
SelectBox.move_all,
|
|
290
|
-
field_id + '_from',
|
|
291
|
-
field_id + '_to'
|
|
292
|
-
)
|
|
293
|
-
})
|
|
294
|
-
add_link.addEventListener('click', function (e) {
|
|
295
|
-
move_selection(
|
|
296
|
-
e,
|
|
297
|
-
this,
|
|
298
|
-
SelectBox.move,
|
|
299
|
-
field_id + '_from',
|
|
300
|
-
field_id + '_to'
|
|
301
|
-
)
|
|
302
|
-
})
|
|
303
|
-
remove_link.addEventListener('click', function (e) {
|
|
304
|
-
move_selection(
|
|
305
|
-
e,
|
|
306
|
-
this,
|
|
307
|
-
SelectBox.move,
|
|
308
|
-
field_id + '_to',
|
|
309
|
-
field_id + '_from'
|
|
310
|
-
)
|
|
311
|
-
})
|
|
312
|
-
clear_all.addEventListener('click', function (e) {
|
|
313
|
-
move_selection(
|
|
314
|
-
e,
|
|
315
|
-
this,
|
|
316
|
-
SelectBox.move_all,
|
|
317
|
-
field_id + '_to',
|
|
318
|
-
field_id + '_from'
|
|
319
|
-
)
|
|
320
|
-
})
|
|
321
|
-
warning_footer.addEventListener('click', function (e) {
|
|
322
|
-
filter_selected_input.value = ''
|
|
323
|
-
SelectBox.filter(field_id + '_to', '')
|
|
324
|
-
SelectFilter.refresh_filtered_warning(field_id)
|
|
325
|
-
SelectFilter.refresh_icons(field_id)
|
|
326
|
-
})
|
|
327
|
-
filter_input.addEventListener('keypress', function (e) {
|
|
328
|
-
SelectFilter.filter_key_press(e, field_id, '_from', '_to')
|
|
329
|
-
})
|
|
330
|
-
filter_input.addEventListener('keyup', function (e) {
|
|
331
|
-
SelectFilter.filter_key_up(e, field_id, '_from')
|
|
332
|
-
})
|
|
333
|
-
filter_input.addEventListener('keydown', function (e) {
|
|
334
|
-
SelectFilter.filter_key_down(e, field_id, '_from', '_to')
|
|
335
|
-
})
|
|
336
|
-
filter_selected_input.addEventListener('keypress', function (e) {
|
|
337
|
-
SelectFilter.filter_key_press(e, field_id, '_to', '_from')
|
|
338
|
-
})
|
|
339
|
-
filter_selected_input.addEventListener('keyup', function (e) {
|
|
340
|
-
SelectFilter.filter_key_up(e, field_id, '_to', '_selected_input')
|
|
341
|
-
})
|
|
342
|
-
filter_selected_input.addEventListener('keydown', function (e) {
|
|
343
|
-
SelectFilter.filter_key_down(e, field_id, '_to', '_from')
|
|
344
|
-
})
|
|
345
|
-
selector_div.addEventListener('change', function (e) {
|
|
346
|
-
if (e.target.tagName === 'SELECT') {
|
|
347
|
-
SelectFilter.refresh_icons(field_id)
|
|
348
|
-
}
|
|
349
|
-
})
|
|
350
|
-
selector_div.addEventListener('dblclick', function (e) {
|
|
351
|
-
if (e.target.tagName === 'OPTION') {
|
|
352
|
-
if (e.target.closest('select').id === field_id + '_to') {
|
|
353
|
-
SelectBox.move(field_id + '_to', field_id + '_from')
|
|
354
|
-
} else {
|
|
355
|
-
SelectBox.move(field_id + '_from', field_id + '_to')
|
|
356
|
-
}
|
|
357
|
-
SelectFilter.refresh_icons(field_id)
|
|
358
|
-
}
|
|
359
|
-
})
|
|
360
|
-
from_box.closest('form').addEventListener('submit', function () {
|
|
361
|
-
SelectBox.filter(field_id + '_to', '')
|
|
362
|
-
SelectBox.select_all(field_id + '_to')
|
|
363
|
-
})
|
|
364
|
-
SelectBox.init(field_id + '_from')
|
|
365
|
-
SelectBox.init(field_id + '_to')
|
|
366
|
-
// Move selected from_box options to to_box
|
|
367
|
-
SelectBox.move(field_id + '_from', field_id + '_to')
|
|
368
|
-
|
|
369
|
-
// Initial icon refresh
|
|
370
|
-
SelectFilter.refresh_icons(field_id)
|
|
371
|
-
},
|
|
372
|
-
any_selected: function (field) {
|
|
373
|
-
// Temporarily add the required attribute and check validity.
|
|
374
|
-
field.required = true
|
|
375
|
-
const any_selected = field.checkValidity()
|
|
376
|
-
field.required = false
|
|
377
|
-
return any_selected
|
|
378
|
-
},
|
|
379
|
-
refresh_filtered_warning: function (field_id) {
|
|
380
|
-
const count = SelectBox.get_hidden_node_count(field_id + '_to')
|
|
381
|
-
const selector = document.getElementById(field_id + '_selector_chosen')
|
|
382
|
-
const warning = document.getElementById(
|
|
383
|
-
field_id + '_list-footer-display-text'
|
|
384
|
-
)
|
|
385
|
-
selector.className = selector.className.replace(
|
|
386
|
-
'selector-chosen--with-filtered',
|
|
387
|
-
''
|
|
388
|
-
)
|
|
389
|
-
warning.textContent = interpolate(
|
|
390
|
-
ngettext(
|
|
391
|
-
'%s selected option not visible',
|
|
392
|
-
'%s selected options not visible',
|
|
393
|
-
count
|
|
394
|
-
),
|
|
395
|
-
[count]
|
|
396
|
-
)
|
|
397
|
-
if (count > 0) {
|
|
398
|
-
selector.className += ' selector-chosen--with-filtered'
|
|
399
|
-
}
|
|
400
|
-
},
|
|
401
|
-
refresh_filtered_selects: function (field_id) {
|
|
402
|
-
SelectBox.filter(
|
|
403
|
-
field_id + '_from',
|
|
404
|
-
document.getElementById(field_id + '_input').value
|
|
405
|
-
)
|
|
406
|
-
SelectBox.filter(
|
|
407
|
-
field_id + '_to',
|
|
408
|
-
document.getElementById(field_id + '_selected_input').value
|
|
409
|
-
)
|
|
410
|
-
},
|
|
411
|
-
refresh_icons: function (field_id) {
|
|
412
|
-
const from = document.getElementById(field_id + '_from')
|
|
413
|
-
const to = document.getElementById(field_id + '_to')
|
|
414
|
-
// Active if at least one item is selected
|
|
415
|
-
document
|
|
416
|
-
.getElementById(field_id + '_add_link')
|
|
417
|
-
.classList.toggle('active', SelectFilter.any_selected(from))
|
|
418
|
-
document
|
|
419
|
-
.getElementById(field_id + '_remove_link')
|
|
420
|
-
.classList.toggle('active', SelectFilter.any_selected(to))
|
|
421
|
-
// Active if the corresponding box isn't empty
|
|
422
|
-
document
|
|
423
|
-
.getElementById(field_id + '_add_all_link')
|
|
424
|
-
.classList.toggle('active', from.querySelector('option'))
|
|
425
|
-
document
|
|
426
|
-
.getElementById(field_id + '_remove_all_link')
|
|
427
|
-
.classList.toggle('active', to.querySelector('option'))
|
|
428
|
-
SelectFilter.refresh_filtered_warning(field_id)
|
|
429
|
-
},
|
|
430
|
-
filter_key_press: function (event, field_id, source, target) {
|
|
431
|
-
const source_box = document.getElementById(field_id + source)
|
|
432
|
-
// don't submit form if user pressed Enter
|
|
433
|
-
if (
|
|
434
|
-
(event.which && event.which === 13) ||
|
|
435
|
-
(event.keyCode && event.keyCode === 13)
|
|
436
|
-
) {
|
|
437
|
-
source_box.selectedIndex = 0
|
|
438
|
-
SelectBox.move(field_id + source, field_id + target)
|
|
439
|
-
source_box.selectedIndex = 0
|
|
440
|
-
event.preventDefault()
|
|
441
|
-
}
|
|
442
|
-
},
|
|
443
|
-
filter_key_up: function (event, field_id, source, filter_input) {
|
|
444
|
-
const input = filter_input || '_input'
|
|
445
|
-
const source_box = document.getElementById(field_id + source)
|
|
446
|
-
const temp = source_box.selectedIndex
|
|
447
|
-
SelectBox.filter(
|
|
448
|
-
field_id + source,
|
|
449
|
-
document.getElementById(field_id + input).value
|
|
450
|
-
)
|
|
451
|
-
source_box.selectedIndex = temp
|
|
452
|
-
SelectFilter.refresh_filtered_warning(field_id)
|
|
453
|
-
SelectFilter.refresh_icons(field_id)
|
|
454
|
-
},
|
|
455
|
-
filter_key_down: function (event, field_id, source, target) {
|
|
456
|
-
const source_box = document.getElementById(field_id + source)
|
|
457
|
-
// right key (39) or left key (37)
|
|
458
|
-
const direction = source === '_from' ? 39 : 37
|
|
459
|
-
// right arrow -- move across
|
|
460
|
-
if (
|
|
461
|
-
(event.which && event.which === direction) ||
|
|
462
|
-
(event.keyCode && event.keyCode === direction)
|
|
463
|
-
) {
|
|
464
|
-
const old_index = source_box.selectedIndex
|
|
465
|
-
SelectBox.move(field_id + source, field_id + target)
|
|
466
|
-
SelectFilter.refresh_filtered_selects(field_id)
|
|
467
|
-
SelectFilter.refresh_filtered_warning(field_id)
|
|
468
|
-
source_box.selectedIndex =
|
|
469
|
-
old_index === source_box.length ? source_box.length - 1 : old_index
|
|
470
|
-
return
|
|
471
|
-
}
|
|
472
|
-
// down arrow -- wrap around
|
|
473
|
-
if (
|
|
474
|
-
(event.which && event.which === 40) ||
|
|
475
|
-
(event.keyCode && event.keyCode === 40)
|
|
476
|
-
) {
|
|
477
|
-
source_box.selectedIndex =
|
|
478
|
-
source_box.length === source_box.selectedIndex + 1
|
|
479
|
-
? 0
|
|
480
|
-
: source_box.selectedIndex + 1
|
|
481
|
-
}
|
|
482
|
-
// up arrow -- wrap around
|
|
483
|
-
if (
|
|
484
|
-
(event.which && event.which === 38) ||
|
|
485
|
-
(event.keyCode && event.keyCode === 38)
|
|
486
|
-
) {
|
|
487
|
-
source_box.selectedIndex =
|
|
488
|
-
source_box.selectedIndex === 0
|
|
489
|
-
? source_box.length - 1
|
|
490
|
-
: source_box.selectedIndex - 1
|
|
491
|
-
}
|
|
492
|
-
},
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
window.addEventListener('load', function (e) {
|
|
496
|
-
document
|
|
497
|
-
.querySelectorAll('select.selectfilter, select.selectfilterstacked')
|
|
498
|
-
.forEach(function (el) {
|
|
499
|
-
const data = el.dataset
|
|
500
|
-
SelectFilter.init(el.id, data.fieldName, parseInt(data.isStacked, 10))
|
|
501
|
-
})
|
|
502
|
-
})
|
|
503
|
-
}
|