fnschool 20250109.80500.803__py3-none-any.whl → 20251011.80531.840__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 +52 -0
- fnschoo1/canteen/admin.py +3 -0
- fnschoo1/canteen/apps.py +6 -0
- fnschoo1/canteen/forms.py +84 -0
- fnschoo1/canteen/migrations/0001_initial.py +119 -0
- fnschoo1/canteen/migrations/0002_ingredient_is_disabled.py +20 -0
- fnschoo1/canteen/migrations/0003_consumption_is_disabled_alter_ingredient_is_disabled.py +23 -0
- fnschoo1/canteen/migrations/0004_alter_ingredient_name_category_and_more.py +66 -0
- fnschoo1/canteen/migrations/0005_alter_category_created_at_alter_category_name_and_more.py +41 -0
- fnschoo1/canteen/migrations/0006_category_is_disabled_alter_category_user_and_more.py +49 -0
- fnschoo1/canteen/migrations/0007_alter_consumption_amount_used_and_more.py +30 -0
- fnschoo1/canteen/migrations/0008_category_abbreviation_mealtype.py +67 -0
- fnschoo1/canteen/migrations/0009_alter_category_abbreviation_and_more.py +55 -0
- fnschoo1/canteen/migrations/0010_alter_consumption_options_alter_ingredient_options_and_more.py +215 -0
- fnschoo1/canteen/migrations/0011_category_pin_to_consumptions_top.py +23 -0
- fnschoo1/canteen/migrations/0012_alter_ingredient_storage_date.py +18 -0
- fnschoo1/canteen/models.py +179 -0
- fnschoo1/canteen/templates/canteen/category/create.html +17 -0
- fnschoo1/canteen/templates/canteen/category/delete.html +61 -0
- fnschoo1/canteen/templates/canteen/category/list.html +63 -0
- fnschoo1/canteen/templates/canteen/category/update.html +23 -0
- fnschoo1/canteen/templates/canteen/close.html +11 -0
- fnschoo1/canteen/templates/canteen/consumption/_create.html +19 -0
- fnschoo1/canteen/templates/canteen/consumption/create.html +456 -0
- fnschoo1/canteen/templates/canteen/ingredient/close.html +11 -0
- fnschoo1/canteen/templates/canteen/ingredient/create.html +19 -0
- fnschoo1/canteen/templates/canteen/ingredient/create_one.html +17 -0
- fnschoo1/canteen/templates/canteen/ingredient/delete.html +41 -0
- fnschoo1/canteen/templates/canteen/ingredient/list.html +128 -0
- fnschoo1/canteen/templates/canteen/ingredient/update.html +23 -0
- fnschoo1/canteen/templates/canteen/meal_type/create.html +17 -0
- fnschoo1/canteen/templates/canteen/meal_type/delete.html +56 -0
- fnschoo1/canteen/templates/canteen/meal_type/list.html +59 -0
- fnschoo1/canteen/templates/canteen/meal_type/update.html +23 -0
- fnschoo1/canteen/tests.py +3 -0
- fnschoo1/canteen/urls.py +116 -0
- fnschoo1/canteen/views.py +814 -0
- fnschoo1/canteen/workbook/generate.py +2098 -0
- fnschoo1/db.sqlite3 +0 -0
- fnschoo1/fnschool/__init__.py +13 -0
- fnschoo1/fnschool/asgi.py +16 -0
- fnschoo1/fnschool/settings.py +167 -0
- fnschoo1/fnschool/templatetags/fnschool_tags.py +27 -0
- fnschoo1/fnschool/urls.py +30 -0
- fnschoo1/fnschool/views.py +9 -0
- fnschoo1/fnschool/wsgi.py +16 -0
- fnschoo1/locale/en/LC_MESSAGES/django.mo +0 -0
- fnschoo1/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- fnschoo1/manage.py +25 -0
- fnschoo1/profiles/admin.py +27 -0
- fnschoo1/profiles/apps.py +12 -0
- fnschoo1/profiles/forms.py +67 -0
- fnschoo1/profiles/migrations/0001_initial.py +192 -0
- fnschoo1/profiles/migrations/0002_alter_profile_bio.py +20 -0
- fnschoo1/profiles/migrations/0003_alter_profile_options_alter_profile_address_and_more.py +67 -0
- fnschoo1/profiles/migrations/0004_profile_gender.py +26 -0
- fnschoo1/profiles/migrations/0005_alter_profile_gender.py +23 -0
- fnschoo1/profiles/models.py +60 -0
- fnschoo1/profiles/signals.py +20 -0
- fnschoo1/profiles/templates/profiles/create.html +16 -0
- fnschoo1/profiles/templates/profiles/detail.html +14 -0
- fnschoo1/profiles/templates/profiles/edit.html +12 -0
- fnschoo1/profiles/templates/profiles/log_in.html +20 -0
- fnschoo1/profiles/templates/profiles/log_out.html +12 -0
- fnschoo1/profiles/tests.py +3 -0
- fnschoo1/profiles/urls.py +15 -0
- fnschoo1/profiles/views.py +63 -0
- fnschoo1/static/css/bootstrap.min.css +11776 -0
- fnschoo1/static/css/fnschool.css +26 -0
- fnschoo1/static/js/bootstrap.bundle.min.js +4223 -0
- fnschoo1/static/js/bootstrap.min.js +2919 -0
- fnschoo1/static/js/fnschool.js +84 -0
- fnschoo1/static/js/jquery.min.js +5413 -0
- fnschoo1/static/js/jquery.slim.min.js +4331 -0
- fnschoo1/static/js/popper.min.js +1306 -0
- fnschoo1/static_collected/admin/css/autocomplete.css +377 -0
- fnschoo1/static_collected/admin/css/base.css +1224 -0
- fnschoo1/static_collected/admin/css/changelists.css +334 -0
- fnschoo1/static_collected/admin/css/dark_mode.css +136 -0
- fnschoo1/static_collected/admin/css/dashboard.css +30 -0
- fnschoo1/static_collected/admin/css/forms.css +546 -0
- fnschoo1/static_collected/admin/css/login.css +62 -0
- fnschoo1/static_collected/admin/css/nav_sidebar.css +145 -0
- fnschoo1/static_collected/admin/css/responsive.css +1043 -0
- fnschoo1/static_collected/admin/css/responsive_rtl.css +84 -0
- fnschoo1/static_collected/admin/css/rtl.css +311 -0
- fnschoo1/static_collected/admin/css/vendor/select2/select2.css +708 -0
- fnschoo1/static_collected/admin/css/vendor/select2/select2.min.css +1 -0
- fnschoo1/static_collected/admin/css/widgets.css +639 -0
- fnschoo1/static_collected/admin/js/SelectBox.js +128 -0
- fnschoo1/static_collected/admin/js/SelectFilter2.js +503 -0
- fnschoo1/static_collected/admin/js/actions.js +232 -0
- fnschoo1/static_collected/admin/js/admin/DateTimeShortcuts.js +496 -0
- fnschoo1/static_collected/admin/js/admin/RelatedObjectLookups.js +276 -0
- fnschoo1/static_collected/admin/js/autocomplete.js +33 -0
- fnschoo1/static_collected/admin/js/calendar.js +251 -0
- fnschoo1/static_collected/admin/js/cancel.js +29 -0
- fnschoo1/static_collected/admin/js/change_form.js +21 -0
- fnschoo1/static_collected/admin/js/collapse.js +43 -0
- fnschoo1/static_collected/admin/js/core.js +174 -0
- fnschoo1/static_collected/admin/js/filters.js +37 -0
- fnschoo1/static_collected/admin/js/inlines.js +439 -0
- fnschoo1/static_collected/admin/js/jquery.init.js +8 -0
- fnschoo1/static_collected/admin/js/nav_sidebar.js +81 -0
- fnschoo1/static_collected/admin/js/popup_response.js +24 -0
- fnschoo1/static_collected/admin/js/prepopulate.js +43 -0
- fnschoo1/static_collected/admin/js/prepopulate_init.js +20 -0
- fnschoo1/static_collected/admin/js/theme.js +57 -0
- fnschoo1/static_collected/admin/js/urlify.js +529 -0
- fnschoo1/static_collected/admin/js/vendor/jquery/jquery.js +10913 -0
- fnschoo1/static_collected/admin/js/vendor/jquery/jquery.min.js +2 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/af.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ar.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/az.js +33 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bg.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bn.js +39 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bs.js +48 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ca.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/cs.js +62 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/da.js +37 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/de.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/dsb.js +51 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/el.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/en.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/es.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/et.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/eu.js +45 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fa.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fi.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fr.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/gl.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/he.js +44 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hi.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hr.js +45 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hsb.js +51 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hu.js +44 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hy.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/id.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/is.js +37 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/it.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ja.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ka.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/km.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ko.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/lt.js +45 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/lv.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/mk.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ms.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/nb.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ne.js +44 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/nl.js +46 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pl.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ps.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pt-BR.js +39 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pt.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ro.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ru.js +48 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sk.js +61 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sl.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sq.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sr-Cyrl.js +48 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sr.js +48 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sv.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/th.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/tk.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/tr.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/uk.js +59 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/vi.js +37 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/zh-CN.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/zh-TW.js +33 -0
- fnschoo1/static_collected/admin/js/vendor/select2/select2.full.js +7115 -0
- fnschoo1/static_collected/admin/js/vendor/select2/select2.full.min.js +2 -0
- fnschoo1/static_collected/admin/js/vendor/xregexp/xregexp.js +4993 -0
- fnschoo1/static_collected/admin/js/vendor/xregexp/xregexp.min.js +160 -0
- fnschoo1/static_collected/css/bootstrap.min.css +11776 -0
- fnschoo1/static_collected/css/fnschool.css +26 -0
- fnschoo1/static_collected/js/bootstrap.bundle.min.js +4223 -0
- fnschoo1/static_collected/js/bootstrap.min.js +2919 -0
- fnschoo1/static_collected/js/fnschool.js +84 -0
- fnschoo1/static_collected/js/jquery.min.js +5413 -0
- fnschoo1/static_collected/js/jquery.slim.min.js +4331 -0
- fnschoo1/static_collected/js/popper.min.js +1306 -0
- fnschoo1/templates/base/_css.html +1 -0
- fnschoo1/templates/base/_js.html +15 -0
- fnschoo1/templates/base/content.html +30 -0
- fnschoo1/templates/base/header_content_footer.html +35 -0
- fnschoo1/templates/close.html +11 -0
- fnschoo1/templates/home.html +51 -0
- fnschoo1/templates/includes/_footer.html +39 -0
- fnschoo1/templates/includes/_header.html +77 -0
- fnschoo1/templates/includes/_navigation.html +0 -0
- fnschoo1/templates/includes/_paginator.html +27 -0
- fnschoo1/templates/registration/logged_out.html +0 -0
- fnschoo1/templates/registration/login.html +0 -0
- fnschool-20251011.80531.840.dist-info/METADATA +179 -0
- fnschool-20251011.80531.840.dist-info/RECORD +207 -0
- {fnschool-20250109.80500.803.dist-info → fnschool-20251011.80531.840.dist-info}/WHEEL +1 -1
- fnschool-20251011.80531.840.dist-info/entry_points.txt +2 -0
- fnschool-20251011.80531.840.dist-info/top_level.txt +1 -0
- fnschool/__init__.py +0 -35
- fnschool/__main__.py +0 -16
- fnschool/app.py +0 -103
- fnschool/canteen/__init__.py +0 -3
- fnschool/canteen/__main__.py +0 -3
- fnschool/canteen/bill.py +0 -253
- fnschool/canteen/canteen.py +0 -1
- fnschool/canteen/canteen.toml +0 -61
- fnschool/canteen/config.py +0 -10
- fnschool/canteen/consuming.py +0 -53
- fnschool/canteen/currency.py +0 -17
- fnschool/canteen/data/bill.i18n.xlsx +0 -0
- fnschool/canteen/data/bill.xlsx +0 -0
- fnschool/canteen/data/consuming.xlsx +0 -0
- fnschool/canteen/data/purchase_list.xlsx +0 -0
- fnschool/canteen/entry.py +0 -40
- fnschool/canteen/food.py +0 -206
- fnschool/canteen/food_classes.py +0 -33
- fnschool/canteen/food_classes.toml +0 -64
- fnschool/canteen/operator.py +0 -91
- fnschool/canteen/path.py +0 -28
- fnschool/canteen/spreadsheet/base.py +0 -212
- fnschool/canteen/spreadsheet/consuming.py +0 -310
- fnschool/canteen/spreadsheet/consumingsum.py +0 -76
- fnschool/canteen/spreadsheet/cover.py +0 -64
- fnschool/canteen/spreadsheet/ctspreadsheet.py +0 -351
- fnschool/canteen/spreadsheet/food.py +0 -680
- fnschool/canteen/spreadsheet/inventory.py +0 -375
- fnschool/canteen/spreadsheet/merging.py +0 -340
- fnschool/canteen/spreadsheet/preconsuming.py +0 -329
- fnschool/canteen/spreadsheet/purchasing.py +0 -885
- fnschool/canteen/spreadsheet/purchasingsum.py +0 -110
- fnschool/canteen/spreadsheet/spreadsheet.py +0 -363
- fnschool/canteen/spreadsheet/translating.py +0 -12
- fnschool/canteen/spreadsheet/unwarehousing.py +0 -178
- fnschool/canteen/spreadsheet/unwarehousingsum.py +0 -11
- fnschool/canteen/spreadsheet/warehousing.py +0 -360
- fnschool/canteen/spreadsheet/workbook.py +0 -17
- fnschool/canteen/test.py +0 -97
- fnschool/config.py +0 -48
- fnschool/entry.py +0 -67
- fnschool/exam/__init__.py +0 -8
- fnschool/exam/data/parental_emails.xlsx +0 -0
- fnschool/exam/data/score.xlsx +0 -0
- fnschool/exam/email.py +0 -349
- fnschool/exam/entry.py +0 -36
- fnschool/exam/language.py +0 -19
- fnschool/exam/path.py +0 -24
- fnschool/exam/score.py +0 -1191
- fnschool/exam/subject.py +0 -20
- fnschool/exam/teacher.py +0 -54
- fnschool/external.py +0 -89
- fnschool/games/__init__.py +0 -1
- fnschool/games/__main__.py +0 -1
- fnschool/games/games.py +0 -1
- fnschool/inoutput.py +0 -97
- fnschool/language.py +0 -40
- fnschool/locales/en_US/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/locales/zh_CN/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/locales/zh_HK/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/locales/zh_SG/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/locales/zh_TW/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/path.py +0 -45
- fnschool/test.py +0 -24
- fnschool/user.py +0 -262
- fnschool-20250109.80500.803.dist-info/METADATA +0 -342
- fnschool-20250109.80500.803.dist-info/RECORD +0 -78
- fnschool-20250109.80500.803.dist-info/entry_points.txt +0 -5
- fnschool-20250109.80500.803.dist-info/top_level.txt +0 -1
- /fnschool/canteen/consume.py → /fnschoo1/canteen/__init__.py +0 -0
- /fnschool/canteen/food_recount.toml → /fnschoo1/canteen/migrations/__init__.py +0 -0
- {fnschool/canteen/spreadsheet → fnschoo1/canteen/workbook}/__init__.py +0 -0
- /fnschool/exam/__main__.py → /fnschoo1/fnschool/templatetags/__init__.py +0 -0
- /fnschool/canteen/food_recounts.toml → /fnschoo1/profiles/__init__.py +0 -0
- /fnschool/canteen/warehouse.py → /fnschoo1/profiles/migrations/__init__.py +0 -0
- /fnschool/canteen/workbook.toml → /fnschoo1/templates/base/_content.html +0 -0
- {fnschool-20250109.80500.803.dist-info → fnschool-20251011.80531.840.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/*global SelectBox, interpolate*/
|
|
2
|
+
// Handles related-objects functionality: lookup link for raw_id_fields
|
|
3
|
+
// and Add Another links.
|
|
4
|
+
'use strict'
|
|
5
|
+
{
|
|
6
|
+
const $ = django.jQuery
|
|
7
|
+
let popupIndex = 0
|
|
8
|
+
const relatedWindows = []
|
|
9
|
+
|
|
10
|
+
function dismissChildPopups() {
|
|
11
|
+
relatedWindows.forEach(function (win) {
|
|
12
|
+
if (!win.closed) {
|
|
13
|
+
win.dismissChildPopups()
|
|
14
|
+
win.close()
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function setPopupIndex() {
|
|
20
|
+
if (document.getElementsByName('_popup').length > 0) {
|
|
21
|
+
const index = window.name.lastIndexOf('__') + 2
|
|
22
|
+
popupIndex = parseInt(window.name.substring(index))
|
|
23
|
+
} else {
|
|
24
|
+
popupIndex = 0
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function addPopupIndex(name) {
|
|
29
|
+
return name + '__' + (popupIndex + 1)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function removePopupIndex(name) {
|
|
33
|
+
return name.replace(new RegExp('__' + (popupIndex + 1) + '$'), '')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function showAdminPopup(triggeringLink, name_regexp, add_popup) {
|
|
37
|
+
const name = addPopupIndex(triggeringLink.id.replace(name_regexp, ''))
|
|
38
|
+
const href = new URL(triggeringLink.href)
|
|
39
|
+
if (add_popup) {
|
|
40
|
+
href.searchParams.set('_popup', 1)
|
|
41
|
+
}
|
|
42
|
+
const win = window.open(
|
|
43
|
+
href,
|
|
44
|
+
name,
|
|
45
|
+
'height=500,width=800,resizable=yes,scrollbars=yes'
|
|
46
|
+
)
|
|
47
|
+
relatedWindows.push(win)
|
|
48
|
+
win.focus()
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function showRelatedObjectLookupPopup(triggeringLink) {
|
|
53
|
+
return showAdminPopup(triggeringLink, /^lookup_/, true)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function dismissRelatedLookupPopup(win, chosenId) {
|
|
57
|
+
const name = removePopupIndex(win.name)
|
|
58
|
+
const elem = document.getElementById(name)
|
|
59
|
+
if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
|
|
60
|
+
elem.value += ',' + chosenId
|
|
61
|
+
} else {
|
|
62
|
+
document.getElementById(name).value = chosenId
|
|
63
|
+
}
|
|
64
|
+
const index = relatedWindows.indexOf(win)
|
|
65
|
+
if (index > -1) {
|
|
66
|
+
relatedWindows.splice(index, 1)
|
|
67
|
+
}
|
|
68
|
+
win.close()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function showRelatedObjectPopup(triggeringLink) {
|
|
72
|
+
return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function updateRelatedObjectLinks(triggeringLink) {
|
|
76
|
+
const $this = $(triggeringLink)
|
|
77
|
+
const siblings = $this.nextAll(
|
|
78
|
+
'.view-related, .change-related, .delete-related'
|
|
79
|
+
)
|
|
80
|
+
if (!siblings.length) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
const value = $this.val()
|
|
84
|
+
if (value) {
|
|
85
|
+
siblings.each(function () {
|
|
86
|
+
const elm = $(this)
|
|
87
|
+
elm.attr(
|
|
88
|
+
'href',
|
|
89
|
+
elm.attr('data-href-template').replace('__fk__', value)
|
|
90
|
+
)
|
|
91
|
+
})
|
|
92
|
+
} else {
|
|
93
|
+
siblings.removeAttr('href')
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function updateRelatedSelectsOptions(
|
|
98
|
+
currentSelect,
|
|
99
|
+
win,
|
|
100
|
+
objId,
|
|
101
|
+
newRepr,
|
|
102
|
+
newId
|
|
103
|
+
) {
|
|
104
|
+
// After create/edit a model from the options next to the current
|
|
105
|
+
// select (+ or :pencil:) update ForeignKey PK of the rest of selects
|
|
106
|
+
// in the page.
|
|
107
|
+
|
|
108
|
+
const path = win.location.pathname
|
|
109
|
+
// Extract the model from the popup url '.../<model>/add/' or
|
|
110
|
+
// '.../<model>/<id>/change/' depending the action (add or change).
|
|
111
|
+
const modelName = path.split('/')[path.split('/').length - (objId ? 4 : 3)]
|
|
112
|
+
// Exclude autocomplete selects.
|
|
113
|
+
const selectsRelated = document.querySelectorAll(
|
|
114
|
+
`[data-model-ref="${modelName}"] select:not(.admin-autocomplete)`
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
selectsRelated.forEach(function (select) {
|
|
118
|
+
if (currentSelect === select) {
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let option = select.querySelector(`option[value="${objId}"]`)
|
|
123
|
+
|
|
124
|
+
if (!option) {
|
|
125
|
+
option = new Option(newRepr, newId)
|
|
126
|
+
select.options.add(option)
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
option.textContent = newRepr
|
|
131
|
+
option.value = newId
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function dismissAddRelatedObjectPopup(win, newId, newRepr) {
|
|
136
|
+
const name = removePopupIndex(win.name)
|
|
137
|
+
const elem = document.getElementById(name)
|
|
138
|
+
if (elem) {
|
|
139
|
+
const elemName = elem.nodeName.toUpperCase()
|
|
140
|
+
if (elemName === 'SELECT') {
|
|
141
|
+
elem.options[elem.options.length] = new Option(
|
|
142
|
+
newRepr,
|
|
143
|
+
newId,
|
|
144
|
+
true,
|
|
145
|
+
true
|
|
146
|
+
)
|
|
147
|
+
updateRelatedSelectsOptions(elem, win, null, newRepr, newId)
|
|
148
|
+
} else if (elemName === 'INPUT') {
|
|
149
|
+
if (
|
|
150
|
+
elem.classList.contains('vManyToManyRawIdAdminField') &&
|
|
151
|
+
elem.value
|
|
152
|
+
) {
|
|
153
|
+
elem.value += ',' + newId
|
|
154
|
+
} else {
|
|
155
|
+
elem.value = newId
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Trigger a change event to update related links if required.
|
|
159
|
+
$(elem).trigger('change')
|
|
160
|
+
} else {
|
|
161
|
+
const toId = name + '_to'
|
|
162
|
+
const o = new Option(newRepr, newId)
|
|
163
|
+
SelectBox.add_to_cache(toId, o)
|
|
164
|
+
SelectBox.redisplay(toId)
|
|
165
|
+
}
|
|
166
|
+
const index = relatedWindows.indexOf(win)
|
|
167
|
+
if (index > -1) {
|
|
168
|
+
relatedWindows.splice(index, 1)
|
|
169
|
+
}
|
|
170
|
+
win.close()
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
|
|
174
|
+
const id = removePopupIndex(win.name.replace(/^edit_/, ''))
|
|
175
|
+
const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id])
|
|
176
|
+
const selects = $(selectsSelector)
|
|
177
|
+
selects
|
|
178
|
+
.find('option')
|
|
179
|
+
.each(function () {
|
|
180
|
+
if (this.value === objId) {
|
|
181
|
+
this.textContent = newRepr
|
|
182
|
+
this.value = newId
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
.trigger('change')
|
|
186
|
+
updateRelatedSelectsOptions(selects[0], win, objId, newRepr, newId)
|
|
187
|
+
selects
|
|
188
|
+
.next()
|
|
189
|
+
.find('.select2-selection__rendered')
|
|
190
|
+
.each(function () {
|
|
191
|
+
// The element can have a clear button as a child.
|
|
192
|
+
// Use the lastChild to modify only the displayed value.
|
|
193
|
+
this.lastChild.textContent = newRepr
|
|
194
|
+
this.title = newRepr
|
|
195
|
+
})
|
|
196
|
+
const index = relatedWindows.indexOf(win)
|
|
197
|
+
if (index > -1) {
|
|
198
|
+
relatedWindows.splice(index, 1)
|
|
199
|
+
}
|
|
200
|
+
win.close()
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function dismissDeleteRelatedObjectPopup(win, objId) {
|
|
204
|
+
const id = removePopupIndex(win.name.replace(/^delete_/, ''))
|
|
205
|
+
const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id])
|
|
206
|
+
const selects = $(selectsSelector)
|
|
207
|
+
selects
|
|
208
|
+
.find('option')
|
|
209
|
+
.each(function () {
|
|
210
|
+
if (this.value === objId) {
|
|
211
|
+
$(this).remove()
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
.trigger('change')
|
|
215
|
+
const index = relatedWindows.indexOf(win)
|
|
216
|
+
if (index > -1) {
|
|
217
|
+
relatedWindows.splice(index, 1)
|
|
218
|
+
}
|
|
219
|
+
win.close()
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup
|
|
223
|
+
window.dismissRelatedLookupPopup = dismissRelatedLookupPopup
|
|
224
|
+
window.showRelatedObjectPopup = showRelatedObjectPopup
|
|
225
|
+
window.updateRelatedObjectLinks = updateRelatedObjectLinks
|
|
226
|
+
window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup
|
|
227
|
+
window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup
|
|
228
|
+
window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup
|
|
229
|
+
window.dismissChildPopups = dismissChildPopups
|
|
230
|
+
|
|
231
|
+
// Kept for backward compatibility
|
|
232
|
+
window.showAddAnotherPopup = showRelatedObjectPopup
|
|
233
|
+
window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup
|
|
234
|
+
|
|
235
|
+
window.addEventListener('unload', function (evt) {
|
|
236
|
+
window.dismissChildPopups()
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
$(document).ready(function () {
|
|
240
|
+
setPopupIndex()
|
|
241
|
+
$('a[data-popup-opener]').on('click', function (event) {
|
|
242
|
+
event.preventDefault()
|
|
243
|
+
opener.dismissRelatedLookupPopup(window, $(this).data('popup-opener'))
|
|
244
|
+
})
|
|
245
|
+
$('body').on(
|
|
246
|
+
'click',
|
|
247
|
+
'.related-widget-wrapper-link[data-popup="yes"]',
|
|
248
|
+
function (e) {
|
|
249
|
+
e.preventDefault()
|
|
250
|
+
if (this.href) {
|
|
251
|
+
const event = $.Event('django:show-related', { href: this.href })
|
|
252
|
+
$(this).trigger(event)
|
|
253
|
+
if (!event.isDefaultPrevented()) {
|
|
254
|
+
showRelatedObjectPopup(this)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
$('body').on('change', '.related-widget-wrapper select', function (e) {
|
|
260
|
+
const event = $.Event('django:update-related')
|
|
261
|
+
$(this).trigger(event)
|
|
262
|
+
if (!event.isDefaultPrevented()) {
|
|
263
|
+
updateRelatedObjectLinks(this)
|
|
264
|
+
}
|
|
265
|
+
})
|
|
266
|
+
$('.related-widget-wrapper select').trigger('change')
|
|
267
|
+
$('body').on('click', '.related-lookup', function (e) {
|
|
268
|
+
e.preventDefault()
|
|
269
|
+
const event = $.Event('django:lookup-related')
|
|
270
|
+
$(this).trigger(event)
|
|
271
|
+
if (!event.isDefaultPrevented()) {
|
|
272
|
+
showRelatedObjectLookupPopup(this)
|
|
273
|
+
}
|
|
274
|
+
})
|
|
275
|
+
})
|
|
276
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
{
|
|
3
|
+
const $ = django.jQuery
|
|
4
|
+
|
|
5
|
+
$.fn.djangoAdminSelect2 = function () {
|
|
6
|
+
$.each(this, function (i, element) {
|
|
7
|
+
$(element).select2({
|
|
8
|
+
ajax: {
|
|
9
|
+
data: (params) => {
|
|
10
|
+
return {
|
|
11
|
+
term: params.term,
|
|
12
|
+
page: params.page,
|
|
13
|
+
app_label: element.dataset.appLabel,
|
|
14
|
+
model_name: element.dataset.modelName,
|
|
15
|
+
field_name: element.dataset.fieldName,
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
return this
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
$(function () {
|
|
25
|
+
// Initialize all autocomplete widgets except the one in the template
|
|
26
|
+
// form used when a new formset is added.
|
|
27
|
+
$('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
document.addEventListener('formset:added', (event) => {
|
|
31
|
+
$(event.target).find('.admin-autocomplete').djangoAdminSelect2()
|
|
32
|
+
})
|
|
33
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/*global gettext, pgettext, get_format, quickElement, removeChildren*/
|
|
2
|
+
/*
|
|
3
|
+
calendar.js - Calendar functions by Adrian Holovaty
|
|
4
|
+
depends on core.js for utility functions like removeChildren or quickElement
|
|
5
|
+
*/
|
|
6
|
+
'use strict'
|
|
7
|
+
{
|
|
8
|
+
// CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
|
|
9
|
+
const CalendarNamespace = {
|
|
10
|
+
monthsOfYear: [
|
|
11
|
+
gettext('January'),
|
|
12
|
+
gettext('February'),
|
|
13
|
+
gettext('March'),
|
|
14
|
+
gettext('April'),
|
|
15
|
+
gettext('May'),
|
|
16
|
+
gettext('June'),
|
|
17
|
+
gettext('July'),
|
|
18
|
+
gettext('August'),
|
|
19
|
+
gettext('September'),
|
|
20
|
+
gettext('October'),
|
|
21
|
+
gettext('November'),
|
|
22
|
+
gettext('December'),
|
|
23
|
+
],
|
|
24
|
+
monthsOfYearAbbrev: [
|
|
25
|
+
pgettext('abbrev. month January', 'Jan'),
|
|
26
|
+
pgettext('abbrev. month February', 'Feb'),
|
|
27
|
+
pgettext('abbrev. month March', 'Mar'),
|
|
28
|
+
pgettext('abbrev. month April', 'Apr'),
|
|
29
|
+
pgettext('abbrev. month May', 'May'),
|
|
30
|
+
pgettext('abbrev. month June', 'Jun'),
|
|
31
|
+
pgettext('abbrev. month July', 'Jul'),
|
|
32
|
+
pgettext('abbrev. month August', 'Aug'),
|
|
33
|
+
pgettext('abbrev. month September', 'Sep'),
|
|
34
|
+
pgettext('abbrev. month October', 'Oct'),
|
|
35
|
+
pgettext('abbrev. month November', 'Nov'),
|
|
36
|
+
pgettext('abbrev. month December', 'Dec'),
|
|
37
|
+
],
|
|
38
|
+
daysOfWeek: [
|
|
39
|
+
pgettext('one letter Sunday', 'S'),
|
|
40
|
+
pgettext('one letter Monday', 'M'),
|
|
41
|
+
pgettext('one letter Tuesday', 'T'),
|
|
42
|
+
pgettext('one letter Wednesday', 'W'),
|
|
43
|
+
pgettext('one letter Thursday', 'T'),
|
|
44
|
+
pgettext('one letter Friday', 'F'),
|
|
45
|
+
pgettext('one letter Saturday', 'S'),
|
|
46
|
+
],
|
|
47
|
+
firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
|
|
48
|
+
isLeapYear: function (year) {
|
|
49
|
+
return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
|
|
50
|
+
},
|
|
51
|
+
getDaysInMonth: function (month, year) {
|
|
52
|
+
let days
|
|
53
|
+
if (
|
|
54
|
+
month === 1 ||
|
|
55
|
+
month === 3 ||
|
|
56
|
+
month === 5 ||
|
|
57
|
+
month === 7 ||
|
|
58
|
+
month === 8 ||
|
|
59
|
+
month === 10 ||
|
|
60
|
+
month === 12
|
|
61
|
+
) {
|
|
62
|
+
days = 31
|
|
63
|
+
} else if (month === 4 || month === 6 || month === 9 || month === 11) {
|
|
64
|
+
days = 30
|
|
65
|
+
} else if (month === 2 && CalendarNamespace.isLeapYear(year)) {
|
|
66
|
+
days = 29
|
|
67
|
+
} else {
|
|
68
|
+
days = 28
|
|
69
|
+
}
|
|
70
|
+
return days
|
|
71
|
+
},
|
|
72
|
+
draw: function (month, year, div_id, callback, selected) {
|
|
73
|
+
// month = 1-12, year = 1-9999
|
|
74
|
+
const today = new Date()
|
|
75
|
+
const todayDay = today.getDate()
|
|
76
|
+
const todayMonth = today.getMonth() + 1
|
|
77
|
+
const todayYear = today.getFullYear()
|
|
78
|
+
let todayClass = ''
|
|
79
|
+
|
|
80
|
+
// Use UTC functions here because the date field does not contain time
|
|
81
|
+
// and using the UTC function variants prevent the local time offset
|
|
82
|
+
// from altering the date, specifically the day field. For example:
|
|
83
|
+
//
|
|
84
|
+
// ```
|
|
85
|
+
// var x = new Date('2013-10-02');
|
|
86
|
+
// var day = x.getDate();
|
|
87
|
+
// ```
|
|
88
|
+
//
|
|
89
|
+
// The day variable above will be 1 instead of 2 in, say, US Pacific time
|
|
90
|
+
// zone.
|
|
91
|
+
let isSelectedMonth = false
|
|
92
|
+
if (typeof selected !== 'undefined') {
|
|
93
|
+
isSelectedMonth =
|
|
94
|
+
selected.getUTCFullYear() === year &&
|
|
95
|
+
selected.getUTCMonth() + 1 === month
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
month = parseInt(month)
|
|
99
|
+
year = parseInt(year)
|
|
100
|
+
const calDiv = document.getElementById(div_id)
|
|
101
|
+
removeChildren(calDiv)
|
|
102
|
+
const calTable = document.createElement('table')
|
|
103
|
+
quickElement(
|
|
104
|
+
'caption',
|
|
105
|
+
calTable,
|
|
106
|
+
CalendarNamespace.monthsOfYear[month - 1] + ' ' + year
|
|
107
|
+
)
|
|
108
|
+
const tableBody = quickElement('tbody', calTable)
|
|
109
|
+
|
|
110
|
+
// Draw days-of-week header
|
|
111
|
+
let tableRow = quickElement('tr', tableBody)
|
|
112
|
+
for (let i = 0; i < 7; i++) {
|
|
113
|
+
quickElement(
|
|
114
|
+
'th',
|
|
115
|
+
tableRow,
|
|
116
|
+
CalendarNamespace.daysOfWeek[
|
|
117
|
+
(i + CalendarNamespace.firstDayOfWeek) % 7
|
|
118
|
+
]
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const startingPos = new Date(
|
|
123
|
+
year,
|
|
124
|
+
month - 1,
|
|
125
|
+
1 - CalendarNamespace.firstDayOfWeek
|
|
126
|
+
).getDay()
|
|
127
|
+
const days = CalendarNamespace.getDaysInMonth(month, year)
|
|
128
|
+
|
|
129
|
+
let nonDayCell
|
|
130
|
+
|
|
131
|
+
// Draw blanks before first of month
|
|
132
|
+
tableRow = quickElement('tr', tableBody)
|
|
133
|
+
for (let i = 0; i < startingPos; i++) {
|
|
134
|
+
nonDayCell = quickElement('td', tableRow, ' ')
|
|
135
|
+
nonDayCell.className = 'nonday'
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function calendarMonth(y, m) {
|
|
139
|
+
function onClick(e) {
|
|
140
|
+
e.preventDefault()
|
|
141
|
+
callback(y, m, this.textContent)
|
|
142
|
+
}
|
|
143
|
+
return onClick
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Draw days of month
|
|
147
|
+
let currentDay = 1
|
|
148
|
+
for (let i = startingPos; currentDay <= days; i++) {
|
|
149
|
+
if (i % 7 === 0 && currentDay !== 1) {
|
|
150
|
+
tableRow = quickElement('tr', tableBody)
|
|
151
|
+
}
|
|
152
|
+
if (
|
|
153
|
+
currentDay === todayDay &&
|
|
154
|
+
month === todayMonth &&
|
|
155
|
+
year === todayYear
|
|
156
|
+
) {
|
|
157
|
+
todayClass = 'today'
|
|
158
|
+
} else {
|
|
159
|
+
todayClass = ''
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// use UTC function; see above for explanation.
|
|
163
|
+
if (isSelectedMonth && currentDay === selected.getUTCDate()) {
|
|
164
|
+
if (todayClass !== '') {
|
|
165
|
+
todayClass += ' '
|
|
166
|
+
}
|
|
167
|
+
todayClass += 'selected'
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const cell = quickElement('td', tableRow, '', 'class', todayClass)
|
|
171
|
+
const link = quickElement('a', cell, currentDay, 'href', '#')
|
|
172
|
+
link.addEventListener('click', calendarMonth(year, month))
|
|
173
|
+
currentDay++
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Draw blanks after end of month (optional, but makes for valid code)
|
|
177
|
+
while (tableRow.childNodes.length < 7) {
|
|
178
|
+
nonDayCell = quickElement('td', tableRow, ' ')
|
|
179
|
+
nonDayCell.className = 'nonday'
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
calDiv.appendChild(calTable)
|
|
183
|
+
},
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Calendar -- A calendar instance
|
|
187
|
+
function Calendar(div_id, callback, selected) {
|
|
188
|
+
// div_id (string) is the ID of the element in which the calendar will
|
|
189
|
+
// be displayed
|
|
190
|
+
// callback (string) is the name of a JavaScript function that will be
|
|
191
|
+
// called with the parameters (year, month, day) when a day in the
|
|
192
|
+
// calendar is clicked
|
|
193
|
+
this.div_id = div_id
|
|
194
|
+
this.callback = callback
|
|
195
|
+
this.today = new Date()
|
|
196
|
+
this.currentMonth = this.today.getMonth() + 1
|
|
197
|
+
this.currentYear = this.today.getFullYear()
|
|
198
|
+
if (typeof selected !== 'undefined') {
|
|
199
|
+
this.selected = selected
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
Calendar.prototype = {
|
|
203
|
+
drawCurrent: function () {
|
|
204
|
+
CalendarNamespace.draw(
|
|
205
|
+
this.currentMonth,
|
|
206
|
+
this.currentYear,
|
|
207
|
+
this.div_id,
|
|
208
|
+
this.callback,
|
|
209
|
+
this.selected
|
|
210
|
+
)
|
|
211
|
+
},
|
|
212
|
+
drawDate: function (month, year, selected) {
|
|
213
|
+
this.currentMonth = month
|
|
214
|
+
this.currentYear = year
|
|
215
|
+
|
|
216
|
+
if (selected) {
|
|
217
|
+
this.selected = selected
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
this.drawCurrent()
|
|
221
|
+
},
|
|
222
|
+
drawPreviousMonth: function () {
|
|
223
|
+
if (this.currentMonth === 1) {
|
|
224
|
+
this.currentMonth = 12
|
|
225
|
+
this.currentYear--
|
|
226
|
+
} else {
|
|
227
|
+
this.currentMonth--
|
|
228
|
+
}
|
|
229
|
+
this.drawCurrent()
|
|
230
|
+
},
|
|
231
|
+
drawNextMonth: function () {
|
|
232
|
+
if (this.currentMonth === 12) {
|
|
233
|
+
this.currentMonth = 1
|
|
234
|
+
this.currentYear++
|
|
235
|
+
} else {
|
|
236
|
+
this.currentMonth++
|
|
237
|
+
}
|
|
238
|
+
this.drawCurrent()
|
|
239
|
+
},
|
|
240
|
+
drawPreviousYear: function () {
|
|
241
|
+
this.currentYear--
|
|
242
|
+
this.drawCurrent()
|
|
243
|
+
},
|
|
244
|
+
drawNextYear: function () {
|
|
245
|
+
this.currentYear++
|
|
246
|
+
this.drawCurrent()
|
|
247
|
+
},
|
|
248
|
+
}
|
|
249
|
+
window.Calendar = Calendar
|
|
250
|
+
window.CalendarNamespace = CalendarNamespace
|
|
251
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
{
|
|
3
|
+
// Call function fn when the DOM is loaded and ready. If it is already
|
|
4
|
+
// loaded, call the function now.
|
|
5
|
+
// http://youmightnotneedjquery.com/#ready
|
|
6
|
+
function ready(fn) {
|
|
7
|
+
if (document.readyState !== 'loading') {
|
|
8
|
+
fn()
|
|
9
|
+
} else {
|
|
10
|
+
document.addEventListener('DOMContentLoaded', fn)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
ready(function () {
|
|
15
|
+
function handleClick(event) {
|
|
16
|
+
event.preventDefault()
|
|
17
|
+
const params = new URLSearchParams(window.location.search)
|
|
18
|
+
if (params.has('_popup')) {
|
|
19
|
+
window.close() // Close the popup.
|
|
20
|
+
} else {
|
|
21
|
+
window.history.back() // Otherwise, go back.
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
document.querySelectorAll('.cancel-link').forEach(function (el) {
|
|
26
|
+
el.addEventListener('click', handleClick)
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
{
|
|
3
|
+
const inputTags = ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA']
|
|
4
|
+
const modelName = document.getElementById('django-admin-form-add-constants')
|
|
5
|
+
.dataset.modelName
|
|
6
|
+
if (modelName) {
|
|
7
|
+
const form = document.getElementById(modelName + '_form')
|
|
8
|
+
for (const element of form.elements) {
|
|
9
|
+
// HTMLElement.offsetParent returns null when the element is not
|
|
10
|
+
// rendered.
|
|
11
|
+
if (
|
|
12
|
+
inputTags.includes(element.tagName) &&
|
|
13
|
+
!element.disabled &&
|
|
14
|
+
element.offsetParent
|
|
15
|
+
) {
|
|
16
|
+
element.focus()
|
|
17
|
+
break
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*global gettext*/
|
|
2
|
+
'use strict'
|
|
3
|
+
{
|
|
4
|
+
window.addEventListener('load', function () {
|
|
5
|
+
// Add anchor tag for Show/Hide link
|
|
6
|
+
const fieldsets = document.querySelectorAll('fieldset.collapse')
|
|
7
|
+
for (const [i, elem] of fieldsets.entries()) {
|
|
8
|
+
// Don't hide if fields in this fieldset have errors
|
|
9
|
+
if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) {
|
|
10
|
+
elem.classList.add('collapsed')
|
|
11
|
+
const h2 = elem.querySelector('h2')
|
|
12
|
+
const link = document.createElement('a')
|
|
13
|
+
link.id = 'fieldsetcollapser' + i
|
|
14
|
+
link.className = 'collapse-toggle'
|
|
15
|
+
link.href = '#'
|
|
16
|
+
link.textContent = gettext('Show')
|
|
17
|
+
h2.appendChild(document.createTextNode(' ('))
|
|
18
|
+
h2.appendChild(link)
|
|
19
|
+
h2.appendChild(document.createTextNode(')'))
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Add toggle to hide/show anchor tag
|
|
23
|
+
const toggleFunc = function (ev) {
|
|
24
|
+
if (ev.target.matches('.collapse-toggle')) {
|
|
25
|
+
ev.preventDefault()
|
|
26
|
+
ev.stopPropagation()
|
|
27
|
+
const fieldset = ev.target.closest('fieldset')
|
|
28
|
+
if (fieldset.classList.contains('collapsed')) {
|
|
29
|
+
// Show
|
|
30
|
+
ev.target.textContent = gettext('Hide')
|
|
31
|
+
fieldset.classList.remove('collapsed')
|
|
32
|
+
} else {
|
|
33
|
+
// Hide
|
|
34
|
+
ev.target.textContent = gettext('Show')
|
|
35
|
+
fieldset.classList.add('collapsed')
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
document.querySelectorAll('fieldset.module').forEach(function (el) {
|
|
40
|
+
el.addEventListener('click', toggleFunc)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
}
|