Update to new Django admin styles for v3.x

This commit is contained in:
Philip Sargent 2022-03-03 14:18:51 +00:00
parent 7f41017ce3
commit dc4374cb9e
151 changed files with 19072 additions and 3638 deletions

View File

@ -0,0 +1,275 @@
select.admin-autocomplete {
width: 20em;
}
.select2-container--admin-autocomplete.select2-container {
min-height: 30px;
}
.select2-container--admin-autocomplete .select2-selection--single,
.select2-container--admin-autocomplete .select2-selection--multiple {
min-height: 30px;
padding: 0;
}
.select2-container--admin-autocomplete.select2-container--focus .select2-selection,
.select2-container--admin-autocomplete.select2-container--open .select2-selection {
border-color: var(--body-quiet-color);
min-height: 30px;
}
.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--single,
.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--single {
padding: 0;
}
.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--multiple,
.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--multiple {
padding: 0;
}
.select2-container--admin-autocomplete .select2-selection--single {
background-color: var(--body-bg);
border: 1px solid var(--border-color);
border-radius: 4px;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
color: var(--body-fg);
line-height: 30px;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder {
color: var(--body-quiet-color);
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px;
}
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0;
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left;
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto;
}
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single {
background-color: var(--darkened-bg);
cursor: default;
}
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none;
}
.select2-container--admin-autocomplete.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px;
}
.select2-container--admin-autocomplete .select2-selection--multiple {
background-color: var(--body-bg);
border: 1px solid var(--border-color);
border-radius: 4px;
cursor: text;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered {
box-sizing: border-box;
list-style: none;
margin: 0;
padding: 0 10px 5px 5px;
width: 100%;
display: flex;
flex-wrap: wrap;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li {
list-style: none;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder {
color: var(--body-quiet-color);
margin-top: 5px;
float: left;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin: 5px;
position: absolute;
right: 0;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice {
background-color: var(--darkened-bg);
border: 1px solid var(--border-color);
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove {
color: var(--body-quiet-color);
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px;
}
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover {
color: var(--body-fg);
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right;
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto;
}
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto;
}
.select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple {
border: solid var(--body-quiet-color) 1px;
outline: 0;
}
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple {
background-color: var(--darkened-bg);
cursor: default;
}
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection__choice__remove {
display: none;
}
.select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.select2-container--admin-autocomplete .select2-search--dropdown {
background: var(--darkened-bg);
}
.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {
background: var(--body-bg);
color: var(--body-fg);
border: 1px solid var(--border-color);
border-radius: 4px;
}
.select2-container--admin-autocomplete .select2-search--inline .select2-search__field {
background: transparent;
color: var(--body-fg);
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield;
}
.select2-container--admin-autocomplete .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto;
color: var(--body-fg);
background: var(--body-bg);
}
.select2-container--admin-autocomplete .select2-results__option[role=group] {
padding: 0;
}
.select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] {
color: var(--body-quiet-color);
}
.select2-container--admin-autocomplete .select2-results__option[aria-selected=true] {
background-color: var(--selected-bg);
color: var(--body-fg);
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option {
padding-left: 1em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em;
}
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em;
}
.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
background-color: var(--primary);
color: var(--primary-fg);
}
.select2-container--admin-autocomplete .select2-results__group {
cursor: default;
display: block;
padding: 6px;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,14 @@
/* CHANGELISTS */ /* CHANGELISTS */
#changelist { #changelist {
position: relative; display: flex;
width: 100%; align-items: flex-start;
justify-content: space-between;
}
#changelist .changelist-form-container {
flex: 1 1 auto;
min-width: 0;
} }
#changelist table { #changelist table {
@ -12,20 +18,16 @@
.change-list .hiddenfields { display:none; } .change-list .hiddenfields { display:none; }
.change-list .filtered table { .change-list .filtered table {
border-right: 1px solid #ddd; border-right: none;
} }
.change-list .filtered { .change-list .filtered {
min-height: 400px; min-height: 400px;
} }
.change-list .filtered { .change-list .filtered .results, .change-list .filtered .paginator,
background: white url(../img/changelist-bg.gif) top right repeat-y !important; .filtered #toolbar, .filtered div.xfull {
} width: auto;
.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
margin-right: 160px !important;
width: auto !important;
} }
.change-list .filtered table tbody th { .change-list .filtered table tbody th {
@ -34,24 +36,20 @@
#changelist-form .results { #changelist-form .results {
overflow-x: auto; overflow-x: auto;
width: 100%;
} }
#changelist .toplinks { #changelist .toplinks {
border-bottom: 1px solid #ccc !important; border-bottom: 1px solid var(--hairline-color);
} }
#changelist .paginator { #changelist .paginator {
color: #666; color: var(--body-quiet-color);
border-top: 1px solid #eee; border-bottom: 1px solid var(--hairline-color);
border-bottom: 1px solid #eee; background: var(--body-bg);
background: white url(../img/nav-bg.gif) 0 180% repeat-x;
overflow: hidden; overflow: hidden;
} }
.change-list .filtered .paginator {
border-right: 1px solid #ddd;
}
/* CHANGELIST TABLES */ /* CHANGELIST TABLES */
#changelist table thead th { #changelist table thead th {
@ -65,72 +63,101 @@
text-align: center; text-align: center;
} }
#changelist table tbody td, #changelist table tbody th {
border-left: 1px solid #ddd;
}
#changelist table tbody td:first-child, #changelist table tbody th:first-child {
border-left: 0;
border-right: 1px solid #ddd;
}
#changelist table tbody td.action-checkbox { #changelist table tbody td.action-checkbox {
text-align:center; text-align: center;
} }
#changelist table tfoot { #changelist table tfoot {
color: #666; color: var(--body-quiet-color);
} }
/* TOOLBAR */ /* TOOLBAR */
#changelist #toolbar { #toolbar {
padding: 3px; padding: 8px 10px;
border-bottom: 1px solid #ddd; margin-bottom: 15px;
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; border-top: 1px solid var(--hairline-color);
color: #666; border-bottom: 1px solid var(--hairline-color);
background: var(--darkened-bg);
color: var(--body-quiet-color);
} }
#changelist #toolbar form input { #toolbar form input {
font-size: 11px; border-radius: 4px;
padding: 1px 2px; font-size: 14px;
padding: 5px;
color: var(--body-fg);
} }
#changelist #toolbar form #searchbar { #toolbar #searchbar {
padding: 2px; height: 19px;
border: 1px solid var(--border-color);
padding: 2px 5px;
margin: 0;
vertical-align: top;
font-size: 13px;
max-width: 100%;
} }
#changelist #changelist-search img { #toolbar #searchbar:focus {
border-color: var(--body-quiet-color);
}
#toolbar form input[type="submit"] {
border: 1px solid var(--border-color);
font-size: 13px;
padding: 4px 8px;
margin: 0;
vertical-align: middle; vertical-align: middle;
background: var(--body-bg);
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
cursor: pointer;
color: var(--body-fg);
}
#toolbar form input[type="submit"]:focus,
#toolbar form input[type="submit"]:hover {
border-color: var(--body-quiet-color);
}
#changelist-search img {
vertical-align: middle;
margin-right: 4px;
} }
/* FILTER COLUMN */ /* FILTER COLUMN */
#changelist-filter { #changelist-filter {
position: absolute; flex: 0 0 240px;
top: 0; order: 1;
right: 0; background: var(--darkened-bg);
z-index: 1000; border-left: none;
width: 160px; margin: 0 0 0 30px;
border-left: 1px solid #ddd;
background: #efefef;
margin: 0;
} }
#changelist-filter h2 { #changelist-filter h2 {
font-size: 11px; font-size: 14px;
padding: 2px 5px; text-transform: uppercase;
border-bottom: 1px solid #ddd; letter-spacing: 0.5px;
padding: 5px 15px;
margin-bottom: 12px;
border-bottom: none;
} }
#changelist-filter h3 { #changelist-filter h3 {
font-size: 12px; font-weight: 400;
margin-bottom: 0; padding: 0 15px;
margin-bottom: 10px;
} }
#changelist-filter ul { #changelist-filter ul {
padding-left: 0; margin: 5px 0;
margin-left: 10px; padding: 0 15px 15px;
border-bottom: 1px solid var(--hairline-color);
}
#changelist-filter ul:last-child {
border-bottom: none;
} }
#changelist-filter li { #changelist-filter li {
@ -140,32 +167,41 @@
} }
#changelist-filter a { #changelist-filter a {
color: #999; display: block;
} color: var(--body-quiet-color);
text-overflow: ellipsis;
#changelist-filter a:hover { overflow-x: hidden;
color: #036;
} }
#changelist-filter li.selected { #changelist-filter li.selected {
border-left: 5px solid #ccc; border-left: 5px solid var(--hairline-color);
padding-left: 5px; padding-left: 10px;
margin-left: -10px; margin-left: -15px;
} }
#changelist-filter li.selected a { #changelist-filter li.selected a {
color: #5b80b2 !important; color: var(--link-selected-fg);
}
#changelist-filter a:focus, #changelist-filter a:hover,
#changelist-filter li.selected a:focus,
#changelist-filter li.selected a:hover {
color: var(--link-hover-color);
}
#changelist-filter #changelist-filter-clear a {
font-size: 13px;
padding-bottom: 10px;
border-bottom: 1px solid var(--hairline-color);
} }
/* DATE DRILLDOWN */ /* DATE DRILLDOWN */
.change-list ul.toplinks { .change-list ul.toplinks {
display: block; display: block;
background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x;
border-top: 1px solid white;
float: left; float: left;
padding: 0 !important; padding: 0;
margin: 0 !important; margin: 0;
width: 100%; width: 100%;
} }
@ -177,43 +213,45 @@
} }
.change-list ul.toplinks .date-back a { .change-list ul.toplinks .date-back a {
color: #999; color: var(--body-quiet-color);
} }
.change-list ul.toplinks .date-back a:focus,
.change-list ul.toplinks .date-back a:hover { .change-list ul.toplinks .date-back a:hover {
color: #036; color: var(--link-hover-color);
} }
/* PAGINATOR */ /* PAGINATOR */
.paginator { .paginator {
font-size: 11px; font-size: 13px;
padding-top: 10px; padding-top: 10px;
padding-bottom: 10px; padding-bottom: 10px;
line-height: 22px; line-height: 22px;
margin: 0; margin: 0;
border-top: 1px solid #ddd; border-top: 1px solid var(--hairline-color);
width: 100%;
} }
.paginator a:link, .paginator a:visited { .paginator a:link, .paginator a:visited {
padding: 2px 6px; padding: 2px 6px;
border: solid 1px #ccc; background: var(--button-bg);
background: white;
text-decoration: none; text-decoration: none;
color: var(--button-fg);
} }
.paginator a.showall { .paginator a.showall {
padding: 0 !important; border: none;
border: none !important; background: none;
color: var(--link-fg);
} }
.paginator a.showall:hover { .paginator a.showall:focus, .paginator a.showall:hover {
color: #036 !important; background: none;
background: transparent !important; color: var(--link-hover-color);
} }
.paginator .end { .paginator .end {
border-width: 2px !important;
margin-right: 6px; margin-right: 6px;
} }
@ -224,38 +262,39 @@
vertical-align: top; vertical-align: top;
} }
.paginator a:hover { .paginator a:focus, .paginator a:hover {
color: white; color: white;
background: #5b80b2; background: var(--link-hover-color);
border-color: #036;
} }
/* ACTIONS */ /* ACTIONS */
.filtered .actions { .filtered .actions {
margin-right: 160px !important; border-right: none;
border-right: 1px solid #ddd;
} }
#changelist table input { #changelist table input {
margin: 0; margin: 0;
vertical-align: baseline;
} }
#changelist table tbody tr.selected { #changelist table tbody tr.selected {
background-color: #FFFFCC; background-color: var(--selected-row);
} }
#changelist .actions { #changelist .actions {
color: #999; padding: 10px;
padding: 3px; background: var(--body-bg);
border-top: 1px solid #fff; border-top: none;
border-bottom: 1px solid #ddd; border-bottom: none;
background: white url(../img/nav-bg-reverse.gif) 0 -10px repeat-x; line-height: 24px;
color: var(--body-quiet-color);
width: 100%;
} }
#changelist .actions.selected { #changelist .actions.selected { /* XXX Probably unused? */
background: #fffccf; background: var(--body-bg);
border-top: 1px solid #fffee8; border-top: 1px solid var(--body-bg);
border-bottom: 1px solid #edecd6; border-bottom: 1px solid #edecd6;
} }
@ -263,9 +302,8 @@
#changelist .actions span.action-counter, #changelist .actions span.action-counter,
#changelist .actions span.clear, #changelist .actions span.clear,
#changelist .actions span.question { #changelist .actions span.question {
font-size: 11px; font-size: 13px;
margin: 0 0.5em; margin: 0 0.5em;
display: none;
} }
#changelist .actions:last-child { #changelist .actions:last-child {
@ -273,21 +311,41 @@
} }
#changelist .actions select { #changelist .actions select {
border: 1px solid #aaa; vertical-align: top;
margin-left: 0.5em; height: 24px;
padding: 1px 2px; color: var(--body-fg);
border: 1px solid var(--border-color);
border-radius: 4px;
font-size: 14px;
padding: 0 0 0 4px;
margin: 0;
margin-left: 10px;
}
#changelist .actions select:focus {
border-color: var(--body-quiet-color);
} }
#changelist .actions label { #changelist .actions label {
font-size: 11px; display: inline-block;
margin-left: 0.5em; vertical-align: middle;
} font-size: 13px;
#changelist #action-toggle {
display: none;
} }
#changelist .actions .button { #changelist .actions .button {
font-size: 11px; font-size: 13px;
padding: 1px 2px; border: 1px solid var(--border-color);
border-radius: 4px;
background: var(--body-bg);
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;
cursor: pointer;
height: 24px;
line-height: 1;
padding: 4px 8px;
margin: 0;
color: var(--body-fg);
}
#changelist .actions .button:focus, #changelist .actions .button:hover {
border-color: var(--body-quiet-color);
} }

View File

@ -21,10 +21,6 @@
ul.actionlist li { ul.actionlist li {
list-style-type: none; list-style-type: none;
}
ul.actionlist li {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
-o-text-overflow: ellipsis;
} }

20
media/admin/css/fonts.css Normal file
View File

@ -0,0 +1,20 @@
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Bold-webfont.woff');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Regular-webfont.woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/Roboto-Light-webfont.woff');
font-weight: 300;
font-style: normal;
}

View File

@ -4,41 +4,35 @@
.form-row { .form-row {
overflow: hidden; overflow: hidden;
padding: 8px 12px; padding: 10px;
font-size: 11px; font-size: 13px;
border-bottom: 1px solid #eee; border-bottom: 1px solid var(--hairline-color);
} }
.form-row img, .form-row input { .form-row img, .form-row input {
vertical-align: middle; vertical-align: middle;
} }
form .form-row p { .form-row label input[type="checkbox"] {
padding-left: 0; margin-top: 0;
font-size: 11px; vertical-align: 0;
} }
.hidden { form .form-row p {
display: none; padding-left: 0;
} }
/* FORM LABELS */ /* FORM LABELS */
form h4 {
margin: 0 !important;
padding: 0 !important;
border: none !important;
}
label { label {
font-weight: normal !important; font-weight: normal;
color: #666; color: var(--body-quiet-color);
font-size: 12px; font-size: 13px;
} }
.required label, label.required { .required label, label.required {
font-weight: bold !important; font-weight: bold;
color: #333 !important; color: var(--body-fg);
} }
/* RADIO BUTTONS */ /* RADIO BUTTONS */
@ -52,6 +46,11 @@ form ul.radiolist label {
display: inline; display: inline;
} }
form ul.radiolist input[type="radio"] {
margin: -2px 4px 0 0;
padding: 0;
}
form ul.inline { form ul.inline {
margin-left: 0; margin-left: 0;
padding: 0; padding: 0;
@ -66,10 +65,25 @@ form ul.inline li {
.aligned label { .aligned label {
display: block; display: block;
padding: 3px 10px 0 0; padding: 4px 10px 0 0;
float: left; float: left;
width: 8em; width: 160px;
word-wrap: break-word; word-wrap: break-word;
line-height: 1;
}
.aligned label:not(.vCheckboxLabel):after {
content: '';
display: inline-block;
vertical-align: middle;
height: 26px;
}
.aligned label + p, .aligned label + div.help, .aligned label + div.readonly {
padding: 6px 0;
margin-top: 0;
margin-bottom: 0;
margin-left: 170px;
} }
.aligned ul label { .aligned ul label {
@ -78,13 +92,57 @@ form ul.inline li {
width: auto; width: auto;
} }
.aligned .form-row input {
margin-bottom: 0;
}
.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { .colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField {
width: 350px; width: 350px;
} }
form .aligned p, form .aligned ul { form .aligned ul {
margin-left: 7em; margin-left: 160px;
padding-left: 30px; padding-left: 10px;
}
form .aligned ul.radiolist {
display: inline-block;
margin: 0;
padding: 0;
}
form .aligned p.help,
form .aligned div.help {
clear: left;
margin-top: 0;
margin-left: 160px;
padding-left: 10px;
}
form .aligned label + p.help,
form .aligned label + div.help {
margin-left: 0;
padding-left: 0;
}
form .aligned p.help:last-child,
form .aligned div.help:last-child {
margin-bottom: 0;
padding-bottom: 0;
}
form .aligned input + p.help,
form .aligned textarea + p.help,
form .aligned select + p.help,
form .aligned input + div.help,
form .aligned textarea + div.help,
form .aligned select + div.help {
margin-left: 160px;
padding-left: 10px;
}
form .aligned ul li {
list-style: none;
} }
form .aligned table p { form .aligned table p {
@ -92,26 +150,30 @@ form .aligned table p {
padding-left: 0; padding-left: 0;
} }
form .aligned p.help { .aligned .vCheckboxLabel {
padding-left: 38px; float: none;
width: auto;
display: inline-block;
vertical-align: -3px;
padding: 0 0 5px 5px;
} }
.aligned .vCheckboxLabel { .aligned .vCheckboxLabel + p.help,
float: none !important; .aligned .vCheckboxLabel + div.help {
display: inline; margin-top: -4px;
padding-left: 4px;
} }
.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { .colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField {
width: 610px; width: 610px;
} }
.checkbox-row p.help { .checkbox-row p.help,
.checkbox-row div.help {
margin-left: 0; margin-left: 0;
padding-left: 0 !important; padding-left: 0;
} }
fieldset .field-box { fieldset .fieldBox {
float: left; float: left;
margin-right: 20px; margin-right: 20px;
} }
@ -119,17 +181,25 @@ fieldset .field-box {
/* WIDE FIELDSETS */ /* WIDE FIELDSETS */
.wide label { .wide label {
width: 15em !important; width: 200px;
} }
form .wide p { form .wide p,
margin-left: 15em; form .wide input + p.help,
form .wide input + div.help {
margin-left: 200px;
} }
form .wide p.help { form .wide p.help,
form .wide div.help {
padding-left: 38px; padding-left: 38px;
} }
form div.help ul {
padding-left: 0;
margin-left: 0;
}
.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { .colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField {
width: 450px; width: 450px;
} }
@ -141,34 +211,45 @@ fieldset.collapsed * {
} }
fieldset.collapsed h2, fieldset.collapsed { fieldset.collapsed h2, fieldset.collapsed {
display: block !important; display: block;
}
fieldset.collapsed {
border: 1px solid var(--hairline-color);
border-radius: 4px;
overflow: hidden;
} }
fieldset.collapsed h2 { fieldset.collapsed h2 {
background-image: url(../img/nav-bg.gif); background: var(--darkened-bg);
background-position: bottom left; color: var(--body-quiet-color);
color: #999; }
fieldset .collapse-toggle {
color: var(--header-link-color);
} }
fieldset.collapsed .collapse-toggle { fieldset.collapsed .collapse-toggle {
background: transparent; background: transparent;
display: inline !important; display: inline;
color: var(--link-fg);
} }
/* MONOSPACE TEXTAREAS */ /* MONOSPACE TEXTAREAS */
fieldset.monospace textarea { fieldset.monospace textarea {
font-family: "Bitstream Vera Sans Mono",Monaco,"Courier New",Courier,monospace; font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace;
} }
/* SUBMIT ROW */ /* SUBMIT ROW */
.submit-row { .submit-row {
padding: 5px 7px; padding: 12px 14px;
margin: 0 0 20px;
background: var(--darkened-bg);
border: 1px solid var(--hairline-color);
border-radius: 4px;
text-align: right; text-align: right;
background: white url(../img/nav-bg.gif) 0 100% repeat-x;
border: 1px solid #ccc;
margin: 5px 0;
overflow: hidden; overflow: hidden;
} }
@ -177,26 +258,62 @@ body.popup .submit-row {
} }
.submit-row input { .submit-row input {
height: 35px;
line-height: 15px;
margin: 0 0 0 5px; margin: 0 0 0 5px;
} }
.submit-row input.default {
margin: 0 0 0 8px;
text-transform: uppercase;
}
.submit-row p { .submit-row p {
margin: 0.3em; margin: 0.3em;
} }
.submit-row p.deletelink-box { .submit-row p.deletelink-box {
float: left; float: left;
margin: 0;
} }
.submit-row .deletelink { .submit-row a.deletelink {
background: url(../img/icon_deletelink.gif) 0 50% no-repeat; display: block;
padding-left: 14px; background: var(--delete-button-bg);
border-radius: 4px;
padding: 10px 15px;
height: 15px;
line-height: 15px;
color: var(--button-fg);
}
.submit-row a.closelink {
display: inline-block;
background: var(--close-button-bg);
border-radius: 4px;
padding: 10px 15px;
height: 15px;
line-height: 15px;
margin: 0 0 0 5px;
color: var(--button-fg);
}
.submit-row a.deletelink:focus,
.submit-row a.deletelink:hover,
.submit-row a.deletelink:active {
background: var(--delete-button-hover-bg);
}
.submit-row a.closelink:focus,
.submit-row a.closelink:hover,
.submit-row a.closelink:active {
background: var(--close-button-hover-bg);
} }
/* CUSTOM FORM FIELDS */ /* CUSTOM FORM FIELDS */
.vSelectMultipleField { .vSelectMultipleField {
vertical-align: top !important; vertical-align: top;
} }
.vCheckboxField { .vCheckboxField {
@ -205,6 +322,7 @@ body.popup .submit-row {
.vDateField, .vTimeField { .vDateField, .vTimeField {
margin-right: 2px; margin-right: 2px;
margin-bottom: 4px;
} }
.vDateField { .vDateField {
@ -231,7 +349,7 @@ body.popup .submit-row {
width: 2.2em; width: 2.2em;
} }
.vTextField { .vTextField, .vUUIDField {
width: 20em; width: 20em;
} }
@ -251,12 +369,15 @@ body.popup .submit-row {
.inline-group { .inline-group {
padding: 0; padding: 0;
border: 1px solid #ccc; margin: 0 0 30px;
margin: 10px 0; }
.inline-group thead th {
padding: 8px 10px;
} }
.inline-group .aligned label { .inline-group .aligned label {
width: 8em; width: 160px;
} }
.inline-related { .inline-related {
@ -265,11 +386,12 @@ body.popup .submit-row {
.inline-related h3 { .inline-related h3 {
margin: 0; margin: 0;
color: #666; color: var(--body-quiet-color);
padding: 3px 5px; padding: 5px;
font-size: 11px; font-size: 13px;
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; background: var(--darkened-bg);
border-bottom: 1px solid #ddd; border-top: 1px solid var(--hairline-color);
border-bottom: 1px solid var(--hairline-color);
} }
.inline-related h3 span.delete { .inline-related h3 span.delete {
@ -283,7 +405,7 @@ body.popup .submit-row {
.inline-related fieldset { .inline-related fieldset {
margin: 0; margin: 0;
background: #fff; background: var(--body-bg);
border: none; border: none;
width: 100%; width: 100%;
} }
@ -295,16 +417,16 @@ body.popup .submit-row {
text-align: left; text-align: left;
font-weight: bold; font-weight: bold;
background: #bcd; background: #bcd;
color: #fff; color: var(--body-bg);
} }
.inline-group .tabular fieldset.module { .inline-group .tabular fieldset.module {
border: none; border: none;
border-bottom: 1px solid #ddd;
} }
.inline-related.tabular fieldset.module table { .inline-related.tabular fieldset.module table {
width: 100%; width: 100%;
overflow-x: scroll;
} }
.last-related fieldset { .last-related fieldset {
@ -330,11 +452,11 @@ body.popup .submit-row {
position: absolute; position: absolute;
left: 0; left: 0;
height: 1.1em; height: 1.1em;
padding: 2px 7px; padding: 2px 9px;
overflow: hidden; overflow: hidden;
font-size: 9px; font-size: 9px;
font-weight: bold; font-weight: bold;
color: #666; color: var(--body-quiet-color);
_width: 700px; _width: 700px;
} }
@ -351,26 +473,51 @@ body.popup .submit-row {
.inline-group div.add-row, .inline-group div.add-row,
.inline-group .tabular tr.add-row td { .inline-group .tabular tr.add-row td {
color: #666; color: var(--body-quiet-color);
padding: 3px 5px; background: var(--darkened-bg);
border-bottom: 1px solid #ddd; padding: 8px 10px;
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x; border-bottom: 1px solid var(--hairline-color);
} }
.inline-group .tabular tr.add-row td { .inline-group .tabular tr.add-row td {
padding: 4px 5px 3px; padding: 8px 10px;
border-bottom: none; border-bottom: 1px solid var(--hairline-color);
} }
.inline-group ul.tools a.add, .inline-group ul.tools a.add,
.inline-group div.add-row a, .inline-group div.add-row a,
.inline-group .tabular tr.add-row td a { .inline-group .tabular tr.add-row td a {
background: url(../img/icon_addlink.gif) 0 50% no-repeat; background: url(../img/icon-addlink.svg) 0 1px no-repeat;
padding-left: 14px; padding-left: 16px;
font-size: 11px; font-size: 12px;
outline: 0; /* Remove dotted border around link */
} }
.empty-form { .empty-form {
display: none; display: none;
} }
/* RELATED FIELD ADD ONE / LOOKUP */
.related-lookup {
margin-left: 5px;
display: inline-block;
vertical-align: middle;
background-repeat: no-repeat;
background-size: 14px;
}
.related-lookup {
width: 16px;
height: 16px;
background-image: url(../img/search.svg);
}
form .related-widget-wrapper ul {
display: inline-block;
margin-left: 0;
padding-left: 0;
}
.clearable-file-input input {
margin-top: 0;
}

View File

@ -1,63 +0,0 @@
/* IE 6 & 7 */
/* Proper fixed width for dashboard in IE6 */
.dashboard #content {
*width: 768px;
}
.dashboard #content-main {
*width: 535px;
}
/* IE 6 ONLY */
/* Keep header from flowing off the page */
#container {
_position: static;
}
/* Put the right sidebars back on the page */
.colMS #content-related {
_margin-right: 0;
_margin-left: 10px;
_position: static;
}
/* Put the left sidebars back on the page */
.colSM #content-related {
_margin-right: 10px;
_margin-left: -115px;
_position: static;
}
.form-row {
_height: 1%;
}
/* Fix right margin for changelist filters in IE6 */
#changelist-filter ul {
_margin-right: -10px;
}
/* IE ignores min-height, but treats height as if it were min-height */
.change-list .filtered {
_height: 400px;
}
/* IE doesn't know alpha transparency in PNGs */
.inline-deletelink {
background: transparent url(../img/inline-delete-8bit.png) no-repeat;
}
/* IE7 doesn't support inline-block */
.change-list ul.toplinks li {
zoom: 1;
*display: inline;
}

View File

@ -1,58 +1,58 @@
/* LOGIN FORM */ /* LOGIN FORM */
body.login { .login {
background: #eee; background: var(--darkened-bg);
height: auto;
}
.login #header {
height: auto;
padding: 15px 16px;
justify-content: center;
}
.login #header h1 {
font-size: 18px;
}
.login #header h1 a {
color: var(--header-link-color);
}
.login #content {
padding: 20px 20px 0;
} }
.login #container { .login #container {
background: white; background: var(--body-bg);
border: 1px solid #ccc; border: 1px solid var(--hairline-color);
border-radius: 4px;
overflow: hidden;
width: 28em; width: 28em;
min-width: 300px; min-width: 300px;
margin-left: auto; margin: 100px auto;
margin-right: auto; height: auto;
margin-top: 100px;
}
.login #content-main {
width: 100%;
}
.login form {
margin-top: 1em;
} }
.login .form-row { .login .form-row {
padding: 4px 0; padding: 4px 0;
float: left;
width: 100%;
} }
.login .form-row label { .login .form-row label {
padding-right: 0.5em; display: block;
line-height: 2em; line-height: 2em;
font-size: 1em;
clear: both;
color: #333;
} }
.login .form-row #id_username, .login .form-row #id_password { .login .form-row #id_username, .login .form-row #id_password {
clear: both; padding: 8px;
padding: 6px;
width: 100%; width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
} }
.login span.help {
font-size: 10px;
display: block;
}
.login .submit-row { .login .submit-row {
clear: both; padding: 1em 0 0 0;
padding: 1em 0 0 9.4em; margin: 0;
text-align: center;
} }
.login .password-reset-link { .login .password-reset-link {

View File

@ -0,0 +1,120 @@
.sticky {
position: sticky;
top: 0;
max-height: 100vh;
}
.toggle-nav-sidebar {
z-index: 20;
left: 0;
display: flex;
align-items: center;
justify-content: center;
flex: 0 0 23px;
width: 23px;
border: 0;
border-right: 1px solid var(--hairline-color);
background-color: var(--body-bg);
cursor: pointer;
font-size: 20px;
color: var(--link-fg);
padding: 0;
}
[dir="rtl"] .toggle-nav-sidebar {
border-left: 1px solid var(--hairline-color);
border-right: 0;
}
.toggle-nav-sidebar:hover,
.toggle-nav-sidebar:focus {
background-color: var(--darkened-bg);
}
#nav-sidebar {
z-index: 15;
flex: 0 0 275px;
left: -276px;
margin-left: -276px;
border-top: 1px solid transparent;
border-right: 1px solid var(--hairline-color);
background-color: var(--body-bg);
overflow: auto;
}
[dir="rtl"] #nav-sidebar {
border-left: 1px solid var(--hairline-color);
border-right: 0;
left: 0;
margin-left: 0;
right: -276px;
margin-right: -276px;
}
.toggle-nav-sidebar::before {
content: '\00BB';
}
.main.shifted .toggle-nav-sidebar::before {
content: '\00AB';
}
.main.shifted > #nav-sidebar {
left: 24px;
margin-left: 0;
}
[dir="rtl"] .main.shifted > #nav-sidebar {
left: 0;
right: 24px;
margin-right: 0;
}
#nav-sidebar .module th {
width: 100%;
overflow-wrap: anywhere;
}
#nav-sidebar .module th,
#nav-sidebar .module caption {
padding-left: 16px;
}
#nav-sidebar .module td {
white-space: nowrap;
}
[dir="rtl"] #nav-sidebar .module th,
[dir="rtl"] #nav-sidebar .module caption {
padding-left: 8px;
padding-right: 16px;
}
#nav-sidebar .current-app .section:link,
#nav-sidebar .current-app .section:visited {
color: var(--header-color);
font-weight: bold;
}
#nav-sidebar .current-model {
background: var(--selected-row);
}
.main > #nav-sidebar + .content {
max-width: calc(100% - 23px);
}
.main.shifted > #nav-sidebar + .content {
max-width: calc(100% - 299px);
}
@media (max-width: 767px) {
#nav-sidebar, #toggle-nav-sidebar {
display: none;
}
.main > #nav-sidebar + .content,
.main.shifted > #nav-sidebar + .content {
max-width: 100%;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
/* TABLETS */
@media (max-width: 1024px) {
[dir="rtl"] .colMS {
margin-right: 0;
}
[dir="rtl"] #user-tools {
text-align: right;
}
[dir="rtl"] #changelist .actions label {
padding-left: 10px;
padding-right: 0;
}
[dir="rtl"] #changelist .actions select {
margin-left: 0;
margin-right: 15px;
}
[dir="rtl"] .change-list .filtered .results,
[dir="rtl"] .change-list .filtered .paginator,
[dir="rtl"] .filtered #toolbar,
[dir="rtl"] .filtered div.xfull,
[dir="rtl"] .filtered .actions,
[dir="rtl"] #changelist-filter {
margin-left: 0;
}
[dir="rtl"] .inline-group ul.tools a.add,
[dir="rtl"] .inline-group div.add-row a,
[dir="rtl"] .inline-group .tabular tr.add-row td a {
padding: 8px 26px 8px 10px;
background-position: calc(100% - 8px) 9px;
}
[dir="rtl"] .related-widget-wrapper-link + .selector {
margin-right: 0;
margin-left: 15px;
}
[dir="rtl"] .selector .selector-filter label {
margin-right: 0;
margin-left: 8px;
}
[dir="rtl"] .object-tools li {
float: right;
}
[dir="rtl"] .object-tools li + li {
margin-left: 0;
margin-right: 15px;
}
[dir="rtl"] .dashboard .module table td a {
padding-left: 0;
padding-right: 16px;
}
}
/* MOBILE */
@media (max-width: 767px) {
[dir="rtl"] .aligned .related-lookup,
[dir="rtl"] .aligned .datetimeshortcuts {
margin-left: 0;
margin-right: 15px;
}
[dir="rtl"] .aligned ul {
margin-right: 0;
}
[dir="rtl"] #changelist-filter {
margin-left: 0;
margin-right: 0;
}
}

View File

@ -1,25 +1,3 @@
body {
direction: rtl;
}
/* LOGIN */
.login .form-row {
float: right;
}
.login .form-row label {
float: right;
padding-left: 0.5em;
padding-right: 0;
text-align: left;
}
.login .submit-row {
clear: both;
padding: 1em 9.4em 0 0;
}
/* GLOBAL */ /* GLOBAL */
th { th {
@ -30,16 +8,21 @@ th {
text-align: right; text-align: right;
} }
.addlink, .changelink { .module ul, .module ol {
padding-left: 0px; margin-left: 0;
padding-right: 12px; margin-right: 1.5em;
background-position: 100% 0.2em; }
.viewlink, .addlink, .changelink {
padding-left: 0;
padding-right: 16px;
background-position: 100% 1px;
} }
.deletelink { .deletelink {
padding-left: 0px; padding-left: 0;
padding-right: 12px; padding-right: 16px;
background-position: 100% 0.25em; background-position: 100% 1px;
} }
.object-tools { .object-tools {
@ -48,7 +31,7 @@ th {
thead th:first-child, thead th:first-child,
tfoot td:first-child { tfoot td:first-child {
border-left: 1px solid #ddd !important; border-left: none;
} }
/* LAYOUT */ /* LAYOUT */
@ -69,13 +52,13 @@ div.breadcrumbs {
#content-related { #content-related {
float: left; float: left;
margin-left: -19em; margin-left: -300px;
margin-right: auto; margin-right: auto;
} }
.colMS { .colMS {
margin-left: 20em !important; margin-left: 300px;
margin-right: 10px !important; margin-right: 0;
} }
/* SORTABLE TABLES */ /* SORTABLE TABLES */
@ -93,51 +76,35 @@ thead th.sorted .text {
.dashboard .module table td a { .dashboard .module table td a {
padding-left: .6em; padding-left: .6em;
padding-right: 12px; padding-right: 16px;
} }
/* changelists styles */ /* changelists styles */
.change-list .filtered {
background: white url(../img/changelist-bg_rtl.gif) top left repeat-y !important;
}
.change-list .filtered table { .change-list .filtered table {
border-left: 1px solid #ddd; border-left: none;
border-right: 0px none; border-right: 0px none;
} }
#changelist-filter { #changelist-filter {
right: auto; border-left: none;
left: 0; border-right: none;
border-left: 0px none; margin-left: 0;
border-right: 1px solid #ddd; margin-right: 30px;
}
.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
margin-right: 0px !important;
margin-left: 160px !important;
} }
#changelist-filter li.selected { #changelist-filter li.selected {
border-left: 0px none; border-left: none;
padding-left: 0px; padding-left: 10px;
margin-left: 0; margin-left: 0;
border-right: 5px solid #ccc; border-right: 5px solid var(--hairline-color);
padding-right: 5px; padding-right: 10px;
margin-right: -10px; margin-right: -15px;
}
.filtered .actions {
border-left:1px solid #DDDDDD;
margin-left:160px !important;
border-right: 0 none;
margin-right:0 !important;
} }
#changelist table tbody td:first-child, #changelist table tbody th:first-child { #changelist table tbody td:first-child, #changelist table tbody th:first-child {
border-right: 0; border-right: none;
border-left: 1px solid #ddd; border-left: none;
} }
/* FORMS */ /* FORMS */
@ -155,15 +122,27 @@ thead th.sorted .text {
float: right; float: right;
} }
.submit-row .deletelink { .submit-row input.default {
background: url(../img/icon_deletelink.gif) 0 50% no-repeat; margin-left: 0;
padding-right: 14px;
} }
.vDateField, .vTimeField { .vDateField, .vTimeField {
margin-left: 2px; margin-left: 2px;
} }
.aligned .form-row input {
margin-left: 5px;
}
form .aligned p.help, form .aligned div.help {
clear: right;
}
form .aligned ul {
margin-right: 163px;
margin-left: 0;
}
form ul.inline li { form ul.inline li {
float: right; float: right;
padding-right: 0; padding-right: 0;
@ -174,20 +153,20 @@ input[type=submit].default, .submit-row input.default {
float: left; float: left;
} }
fieldset .field-box { fieldset .fieldBox {
float: right; float: right;
margin-left: 20px; margin-left: 20px;
margin-right: 0; margin-right: 0;
} }
.errorlist li { .errorlist li {
background-position: 100% .3em; background-position: 100% 12px;
padding: 4px 25px 4px 5px; padding: 0;
} }
.errornote { .errornote {
background-position: 100% .3em; background-position: 100% 12px;
padding: 4px 25px 4px 5px; padding: 10px 12px;
} }
/* WIDGETS */ /* WIDGETS */
@ -195,13 +174,13 @@ fieldset .field-box {
.calendarnav-previous { .calendarnav-previous {
top: 0; top: 0;
left: auto; left: auto;
right: 0; right: 10px;
} }
.calendarnav-next { .calendarnav-next {
top: 0; top: 0;
right: auto; right: auto;
left: 0; left: 10px;
} }
.calendar caption, .calendarbox h2 { .calendar caption, .calendarbox h2 {
@ -220,6 +199,14 @@ fieldset .field-box {
float: left; float: left;
} }
form .form-row p.datetime {
overflow: hidden;
}
.related-widget-wrapper {
float: right;
}
/* MISC */ /* MISC */
.inline-related h2, .inline-group h2 { .inline-related h2, .inline-group h2 {
@ -238,13 +225,3 @@ fieldset .field-box {
margin-left: inherit; margin-left: inherit;
margin-right: 2px; margin-right: 2px;
} }
/* IE7 specific bug fixes */
div.colM {
position: relative;
}
.submit-row input {
float: left;
}

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,481 @@
.select2-container {
box-sizing: border-box;
display: inline-block;
margin: 0;
position: relative;
vertical-align: middle; }
.select2-container .select2-selection--single {
box-sizing: border-box;
cursor: pointer;
display: block;
height: 28px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 8px;
padding-right: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-selection--single .select2-selection__clear {
position: relative; }
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
padding-right: 8px;
padding-left: 20px; }
.select2-container .select2-selection--multiple {
box-sizing: border-box;
cursor: pointer;
display: block;
min-height: 32px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--multiple .select2-selection__rendered {
display: inline-block;
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-search--inline {
float: left; }
.select2-container .select2-search--inline .select2-search__field {
box-sizing: border-box;
border: none;
font-size: 100%;
margin-top: 5px;
padding: 0; }
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-dropdown {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
box-sizing: border-box;
display: block;
position: absolute;
left: -100000px;
width: 100%;
z-index: 1051; }
.select2-results {
display: block; }
.select2-results__options {
list-style: none;
margin: 0;
padding: 0; }
.select2-results__option {
padding: 6px;
user-select: none;
-webkit-user-select: none; }
.select2-results__option[aria-selected] {
cursor: pointer; }
.select2-container--open .select2-dropdown {
left: 0; }
.select2-container--open .select2-dropdown--above {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--open .select2-dropdown--below {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-search--dropdown {
display: block;
padding: 4px; }
.select2-search--dropdown .select2-search__field {
padding: 4px;
width: 100%;
box-sizing: border-box; }
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-search--dropdown.select2-search--hide {
display: none; }
.select2-close-mask {
border: 0;
margin: 0;
padding: 0;
display: block;
position: fixed;
left: 0;
top: 0;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
opacity: 0;
z-index: 99;
background-color: #fff;
filter: alpha(opacity=0); }
.select2-hidden-accessible {
border: 0 !important;
clip: rect(0 0 0 0) !important;
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important;
height: 1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important; }
.select2-container--default .select2-selection--single {
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px; }
.select2-container--default .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--default .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold; }
.select2-container--default .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px; }
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto; }
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none; }
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
.select2-container--default .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
box-sizing: border-box;
list-style: none;
margin: 0;
padding: 0 5px;
width: 100%; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
list-style: none; }
.select2-container--default .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-top: 5px;
margin-right: 10px;
padding: 1px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
.select2-container--default.select2-container--focus .select2-selection--multiple {
border: solid black 1px;
outline: 0; }
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
display: none; }
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa; }
.select2-container--default .select2-search--inline .select2-search__field {
background: transparent;
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield; }
.select2-container--default .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--default .select2-results__option[role=group] {
padding: 0; }
.select2-container--default .select2-results__option[aria-disabled=true] {
color: #999; }
.select2-container--default .select2-results__option[aria-selected=true] {
background-color: #ddd; }
.select2-container--default .select2-results__option .select2-results__option {
padding-left: 1em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em; }
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: #5897fb;
color: white; }
.select2-container--default .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
.select2-container--classic .select2-selection--single {
background-color: #f7f7f7;
border: 1px solid #aaa;
border-radius: 4px;
outline: 0;
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic .select2-selection--single:focus {
border: 1px solid #5897fb; }
.select2-container--classic .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--classic .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-right: 10px; }
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--classic .select2-selection--single .select2-selection__arrow {
background-color: #ddd;
border: none;
border-left: 1px solid #aaa;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
border: none;
border-right: 1px solid #aaa;
border-radius: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
left: 1px;
right: auto; }
.select2-container--classic.select2-container--open .select2-selection--single {
border: 1px solid #5897fb; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
background: transparent;
border: none; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
.select2-container--classic .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
outline: 0; }
.select2-container--classic .select2-selection--multiple:focus {
border: 1px solid #5897fb; }
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
list-style: none;
margin: 0;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
display: none; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
color: #888;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #555; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
float: right;
margin-left: 5px;
margin-right: auto; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
.select2-container--classic.select2-container--open .select2-selection--multiple {
border: 1px solid #5897fb; }
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--classic .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
outline: 0; }
.select2-container--classic .select2-search--inline .select2-search__field {
outline: 0;
box-shadow: none; }
.select2-container--classic .select2-dropdown {
background-color: white;
border: 1px solid transparent; }
.select2-container--classic .select2-dropdown--above {
border-bottom: none; }
.select2-container--classic .select2-dropdown--below {
border-top: none; }
.select2-container--classic .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--classic .select2-results__option[role=group] {
padding: 0; }
.select2-container--classic .select2-results__option[aria-disabled=true] {
color: grey; }
.select2-container--classic .select2-results__option--highlighted[aria-selected] {
background-color: #3875d7;
color: white; }
.select2-container--classic .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
.select2-container--classic.select2-container--open .select2-dropdown {
border-color: #5897fb; }

File diff suppressed because one or more lines are too long

View File

@ -1,18 +1,18 @@
/* SELECTOR (FILTER INTERFACE) */ /* SELECTOR (FILTER INTERFACE) */
.selector { .selector {
width: 840px; width: 800px;
float: left; float: left;
} }
.selector select { .selector select {
width: 400px; width: 380px;
height: 17.2em; height: 17.2em;
} }
.selector-available, .selector-chosen { .selector-available, .selector-chosen {
float: left; float: left;
width: 400px; width: 380px;
text-align: center; text-align: center;
margin-bottom: 5px; margin-bottom: 5px;
} }
@ -22,20 +22,25 @@
} }
.selector-available h2, .selector-chosen h2 { .selector-available h2, .selector-chosen h2 {
border: 1px solid #ccc; border: 1px solid var(--border-color);
border-radius: 4px 4px 0 0;
}
.selector-chosen h2 {
background: var(--primary);
color: var(--header-link-color);
} }
.selector .selector-available h2 { .selector .selector-available h2 {
background: white url(../img/nav-bg.gif) bottom left repeat-x; background: var(--darkened-bg);
color: #666; color: var(--body-quiet-color);
} }
.selector .selector-filter { .selector .selector-filter {
background: white; border: 1px solid var(--border-color);
border: 1px solid #ccc;
border-width: 0 1px; border-width: 0 1px;
padding: 3px; padding: 8px;
color: #999; color: var(--body-quiet-color);
font-size: 10px; font-size: 10px;
margin: 0; margin: 0;
text-align: left; text-align: left;
@ -43,18 +48,24 @@
.selector .selector-filter label, .selector .selector-filter label,
.inline-group .aligned .selector .selector-filter label { .inline-group .aligned .selector .selector-filter label {
width: 16px; float: left;
padding: 2px; margin: 7px 0 0;
width: 18px;
height: 18px;
padding: 0;
overflow: hidden;
line-height: 1;
} }
.selector .selector-available input { .selector .selector-available input {
width: 360px; width: 320px;
margin-left: 8px;
} }
.selector ul.selector-chooser { .selector ul.selector-chooser {
float: left; float: left;
width: 22px; width: 22px;
background-color: #eee; background-color: var(--selected-bg);
border-radius: 10px; border-radius: 10px;
margin: 10em 5px 0 5px; margin: 10em 5px 0 5px;
padding: 0; padding: 0;
@ -67,8 +78,9 @@
} }
.selector select { .selector select {
margin-bottom: 10px; padding: 0 10px;
margin-top: 0; margin: 0 0 10px;
border-radius: 0 0 4px 4px;
} }
.selector-add, .selector-remove { .selector-add, .selector-remove {
@ -77,75 +89,85 @@
display: block; display: block;
text-indent: -3000px; text-indent: -3000px;
overflow: hidden; overflow: hidden;
cursor: default;
opacity: 0.55;
}
.active.selector-add, .active.selector-remove {
opacity: 1;
}
.active.selector-add:hover, .active.selector-remove:hover {
cursor: pointer;
} }
.selector-add { .selector-add {
background: url(../img/selector-icons.gif) 0 -161px no-repeat; background: url(../img/selector-icons.svg) 0 -96px no-repeat;
cursor: default;
margin-bottom: 2px;
} }
.active.selector-add { .active.selector-add:focus, .active.selector-add:hover {
background: url(../img/selector-icons.gif) 0 -187px no-repeat; background-position: 0 -112px;
cursor: pointer;
} }
.selector-remove { .selector-remove {
background: url(../img/selector-icons.gif) 0 -109px no-repeat; background: url(../img/selector-icons.svg) 0 -64px no-repeat;
cursor: default;
} }
.active.selector-remove { .active.selector-remove:focus, .active.selector-remove:hover {
background: url(../img/selector-icons.gif) 0 -135px no-repeat; background-position: 0 -80px;
cursor: pointer;
} }
a.selector-chooseall, a.selector-clearall { a.selector-chooseall, a.selector-clearall {
display: inline-block; display: inline-block;
height: 16px;
text-align: left; text-align: left;
margin-left: auto; margin: 1px auto 3px;
margin-right: auto; overflow: hidden;
font-weight: bold; font-weight: bold;
color: #666; line-height: 16px;
color: var(--body-quiet-color);
text-decoration: none;
opacity: 0.55;
} }
a.selector-chooseall { a.active.selector-chooseall:focus, a.active.selector-clearall:focus,
padding: 3px 18px 3px 0; a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
color: var(--link-fg);
} }
a.selector-clearall { a.active.selector-chooseall, a.active.selector-clearall {
padding: 3px 0 3px 18px; opacity: 1;
} }
a.active.selector-chooseall:hover, a.active.selector-clearall:hover { a.active.selector-chooseall:hover, a.active.selector-clearall:hover {
color: #036; cursor: pointer;
} }
a.selector-chooseall { a.selector-chooseall {
background: url(../img/selector-icons.gif) right -263px no-repeat; padding: 0 18px 0 0;
background: url(../img/selector-icons.svg) right -160px no-repeat;
cursor: default; cursor: default;
} }
a.active.selector-chooseall { a.active.selector-chooseall:focus, a.active.selector-chooseall:hover {
background: url(../img/selector-icons.gif) right -289px no-repeat; background-position: 100% -176px;
cursor: pointer;
} }
a.selector-clearall { a.selector-clearall {
background: url(../img/selector-icons.gif) left -211px no-repeat; padding: 0 0 0 18px;
background: url(../img/selector-icons.svg) 0 -128px no-repeat;
cursor: default; cursor: default;
} }
a.active.selector-clearall { a.active.selector-clearall:focus, a.active.selector-clearall:hover {
background: url(../img/selector-icons.gif) left -237px no-repeat; background-position: 0 -144px;
cursor: pointer;
} }
/* STACKED SELECTORS */ /* STACKED SELECTORS */
.stacked { .stacked {
float: left; float: left;
width: 500px; width: 490px;
} }
.stacked select { .stacked select {
@ -162,13 +184,13 @@ a.active.selector-clearall {
} }
.stacked .selector-available input { .stacked .selector-available input {
width: 442px; width: 422px;
} }
.stacked ul.selector-chooser { .stacked ul.selector-chooser {
height: 22px; height: 22px;
width: 50px; width: 50px;
margin: 0 0 3px 40%; margin: 0 0 10px 40%;
background-color: #eee; background-color: #eee;
border-radius: 10px; border-radius: 10px;
} }
@ -183,56 +205,123 @@ a.active.selector-clearall {
} }
.stacked .selector-add { .stacked .selector-add {
background: url(../img/selector-icons.gif) 0 -57px no-repeat; background: url(../img/selector-icons.svg) 0 -32px no-repeat;
cursor: default; cursor: default;
} }
.stacked .active.selector-add { .stacked .active.selector-add {
background: url(../img/selector-icons.gif) 0 -83px no-repeat; background-position: 0 -32px;
cursor: pointer;
}
.stacked .active.selector-add:focus, .stacked .active.selector-add:hover {
background-position: 0 -48px;
cursor: pointer; cursor: pointer;
} }
.stacked .selector-remove { .stacked .selector-remove {
background: url(../img/selector-icons.gif) 0 -5px no-repeat; background: url(../img/selector-icons.svg) 0 0 no-repeat;
cursor: default; cursor: default;
} }
.stacked .active.selector-remove { .stacked .active.selector-remove {
background: url(../img/selector-icons.gif) 0 -31px no-repeat; background-position: 0 0px;
cursor: pointer; cursor: pointer;
} }
.stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover {
background-position: 0 -16px;
cursor: pointer;
}
.selector .help-icon {
background: url(../img/icon-unknown.svg) 0 0 no-repeat;
display: inline-block;
vertical-align: middle;
margin: -2px 0 0 2px;
width: 13px;
height: 13px;
}
.selector .selector-chosen .help-icon {
background: url(../img/icon-unknown-alt.svg) 0 0 no-repeat;
}
.selector .search-label-icon {
background: url(../img/search.svg) 0 0 no-repeat;
display: inline-block;
height: 18px;
width: 18px;
}
/* DATE AND TIME */ /* DATE AND TIME */
p.datetime { p.datetime {
line-height: 20px; line-height: 20px;
margin: 0; margin: 0;
padding: 0; padding: 0;
color: #666; color: var(--body-quiet-color);
font-size: 11px;
font-weight: bold; font-weight: bold;
} }
.datetime span { .datetime span {
font-size: 11px;
color: #ccc;
font-weight: normal;
white-space: nowrap; white-space: nowrap;
font-weight: normal;
font-size: 11px;
color: var(--body-quiet-color);
}
.datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {
margin-left: 5px;
margin-bottom: 4px;
} }
table p.datetime { table p.datetime {
font-size: 10px; font-size: 11px;
margin-left: 0; margin-left: 0;
padding-left: 0; padding-left: 0;
} }
.datetimeshortcuts .clock-icon, .datetimeshortcuts .date-icon {
position: relative;
display: inline-block;
vertical-align: middle;
height: 16px;
width: 16px;
overflow: hidden;
}
.datetimeshortcuts .clock-icon {
background: url(../img/icon-clock.svg) 0 0 no-repeat;
}
.datetimeshortcuts a:focus .clock-icon,
.datetimeshortcuts a:hover .clock-icon {
background-position: 0 -16px;
}
.datetimeshortcuts .date-icon {
background: url(../img/icon-calendar.svg) 0 0 no-repeat;
top: -1px;
}
.datetimeshortcuts a:focus .date-icon,
.datetimeshortcuts a:hover .date-icon {
background-position: 0 -16px;
}
.timezonewarning {
font-size: 11px;
color: var(--body-quiet-color);
}
/* URL */ /* URL */
p.url { p.url {
line-height: 20px; line-height: 20px;
margin: 0; margin: 0;
padding: 0; padding: 0;
color: #666; color: var(--body-quiet-color);
font-size: 11px; font-size: 11px;
font-weight: bold; font-weight: bold;
} }
@ -247,11 +336,15 @@ p.file-upload {
line-height: 20px; line-height: 20px;
margin: 0; margin: 0;
padding: 0; padding: 0;
color: #666; color: var(--body-quiet-color);
font-size: 11px; font-size: 11px;
font-weight: bold; font-weight: bold;
} }
.aligned p.file-upload {
margin-left: 170px;
}
.file-upload a { .file-upload a {
font-weight: normal; font-weight: normal;
} }
@ -261,7 +354,7 @@ p.file-upload {
} }
span.clearable-file-input label { span.clearable-file-input label {
color: #333; color: var(--body-fg);
font-size: 11px; font-size: 11px;
display: inline; display: inline;
float: none; float: none;
@ -271,10 +364,15 @@ span.clearable-file-input label {
.calendarbox, .clockbox { .calendarbox, .clockbox {
margin: 5px auto; margin: 5px auto;
font-size: 11px; font-size: 12px;
width: 16em; width: 19em;
text-align: center; text-align: center;
background: white; background: var(--body-bg);
color: var(--body-fg);
border: 1px solid var(--hairline-color);
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
overflow: hidden;
position: relative; position: relative;
} }
@ -297,55 +395,62 @@ span.clearable-file-input label {
.calendar caption, .calendarbox h2 { .calendar caption, .calendarbox h2 {
margin: 0; margin: 0;
font-size: 11px;
text-align: center; text-align: center;
border-top: none; border-top: none;
font-weight: 700;
font-size: 12px;
color: #333;
background: var(--accent);
} }
.calendar th { .calendar th {
font-size: 10px; padding: 8px 5px;
color: #666; background: var(--darkened-bg);
padding: 2px 3px; border-bottom: 1px solid var(--border-color);
font-weight: 400;
font-size: 12px;
text-align: center; text-align: center;
background: #e1e1e1 url(../img/nav-bg.gif) 0 50% repeat-x; color: var(--body-quiet-color);
border-bottom: 1px solid #ddd;
} }
.calendar td { .calendar td {
font-size: 11px; font-weight: 400;
font-size: 12px;
text-align: center; text-align: center;
padding: 0; padding: 0;
border-top: 1px solid #eee; border-top: 1px solid var(--hairline-color);
border-bottom: none; border-bottom: none;
} }
.calendar td.selected a { .calendar td.selected a {
background: #C9DBED; background: var(--primary);
color: var(--button-fg);
} }
.calendar td.nonday { .calendar td.nonday {
background: #efefef; background: var(--darkened-bg);
} }
.calendar td.today a { .calendar td.today a {
background: #ffc; font-weight: 700;
} }
.calendar td a, .timelist a { .calendar td a, .timelist a {
display: block; display: block;
font-weight: bold; font-weight: 400;
padding: 4px; padding: 6px;
text-decoration: none; text-decoration: none;
color: #444; color: var(--body-quiet-color);
} }
.calendar td a:focus, .timelist a:focus,
.calendar td a:hover, .timelist a:hover { .calendar td a:hover, .timelist a:hover {
background: #5b80b2; background: var(--primary);
color: white; color: white;
} }
.calendar td a:active, .timelist a:active { .calendar td a:active, .timelist a:active {
background: #036; background: var(--header-bg);
color: white; color: white;
} }
@ -357,53 +462,61 @@ span.clearable-file-input label {
padding: 1px 3px; padding: 1px 3px;
} }
.calendarnav a:link, #calendarnav a:visited, #calendarnav a:hover { .calendarnav a:link, #calendarnav a:visited,
color: #999; #calendarnav a:focus, #calendarnav a:hover {
color: var(--body-quiet-color);
} }
.calendar-shortcuts { .calendar-shortcuts {
background: white; background: var(--body-bg);
font-size: 10px; color: var(--body-quiet-color);
font-size: 11px;
line-height: 11px; line-height: 11px;
border-top: 1px solid #eee; border-top: 1px solid var(--hairline-color);
padding: 3px 0 4px; padding: 8px 0;
color: #ccc;
} }
.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {
display: block; display: block;
position: absolute; position: absolute;
font-weight: bold; top: 8px;
font-size: 12px; width: 15px;
background: #C9DBED url(../img/default-bg.gif) bottom left repeat-x; height: 15px;
padding: 1px 4px 2px 4px; text-indent: -9999px;
color: white; padding: 0;
}
.calendarnav-previous:hover, .calendarnav-next:hover {
background: #036;
} }
.calendarnav-previous { .calendarnav-previous {
top: 0; left: 10px;
left: 0; background: url(../img/calendar-icons.svg) 0 0 no-repeat;
}
.calendarbox .calendarnav-previous:focus,
.calendarbox .calendarnav-previous:hover {
background-position: 0 -15px;
} }
.calendarnav-next { .calendarnav-next {
top: 0; right: 10px;
right: 0; background: url(../img/calendar-icons.svg) 0 -30px no-repeat;
}
.calendarbox .calendarnav-next:focus,
.calendarbox .calendarnav-next:hover {
background-position: 0 -45px;
} }
.calendar-cancel { .calendar-cancel {
margin: 0 !important; margin: 0;
padding: 0 !important; padding: 4px 0;
font-size: 10px; font-size: 12px;
background: #e1e1e1 url(../img/nav-bg.gif) 0 50% repeat-x; background: #eee;
border-top: 1px solid #ddd; border-top: 1px solid var(--border-color);
color: var(--body-fg);
} }
.calendar-cancel:hover { .calendar-cancel:focus, .calendar-cancel:hover {
background: #e1e1e1 url(../img/nav-bg-reverse.gif) 0 50% repeat-x; background: #ddd;
} }
.calendar-cancel a { .calendar-cancel a {
@ -421,158 +534,41 @@ ul.timelist, .timelist li {
padding: 2px; padding: 2px;
} }
/* INLINE ORDERER */
ul.orderer {
position: relative;
padding: 0 !important;
margin: 0 !important;
list-style-type: none;
}
ul.orderer li {
list-style-type: none;
display: block;
padding: 0;
margin: 0;
border: 1px solid #bbb;
border-width: 0 1px 1px 0;
white-space: nowrap;
overflow: hidden;
background: #e2e2e2 url(../img/nav-bg-grabber.gif) repeat-y;
}
ul.orderer li:hover {
cursor: move;
background-color: #ddd;
}
ul.orderer li a.selector {
margin-left: 12px;
overflow: hidden;
width: 83%;
font-size: 10px !important;
padding: 0.6em 0;
}
ul.orderer li a:link, ul.orderer li a:visited {
color: #333;
}
ul.orderer li .inline-deletelink {
position: absolute;
right: 4px;
margin-top: 0.6em;
}
ul.orderer li.selected {
background-color: #f8f8f8;
border-right-color: #f8f8f8;
}
ul.orderer li.deleted {
background: #bbb url(../img/deleted-overlay.gif);
}
ul.orderer li.deleted a:link, ul.orderer li.deleted a:visited {
color: #888;
}
ul.orderer li.deleted .inline-deletelink {
background-image: url(../img/inline-restore.png);
}
ul.orderer li.deleted:hover, ul.orderer li.deleted a.selector:hover {
cursor: default;
}
/* EDIT INLINE */ /* EDIT INLINE */
.inline-deletelink { .inline-deletelink {
float: right; float: right;
text-indent: -9999px; text-indent: -9999px;
background: transparent url(../img/inline-delete.png) no-repeat; background: url(../img/inline-delete.svg) 0 0 no-repeat;
width: 15px; width: 16px;
height: 15px; height: 16px;
border: 0px none; border: 0px none;
outline: 0; /* Remove dotted border around link */
} }
.inline-deletelink:hover { .inline-deletelink:focus, .inline-deletelink:hover {
background-position: -15px 0;
cursor: pointer; cursor: pointer;
} }
.editinline button.addlink { /* RELATED WIDGET WRAPPER */
border: 0px none; .related-widget-wrapper {
color: #5b80b2; float: left; /* display properly in form rows with multiple fields */
font-size: 100%; overflow: hidden; /* clear floated contents */
cursor: pointer;
} }
.editinline button.addlink:hover { .related-widget-wrapper-link {
color: #036; opacity: 0.3;
cursor: pointer;
} }
.editinline table .help { .related-widget-wrapper-link:link {
text-align: right; opacity: .8;
float: right;
padding-left: 2em;
} }
.editinline tfoot .addlink { .related-widget-wrapper-link:link:focus,
white-space: nowrap; .related-widget-wrapper-link:link:hover {
opacity: 1;
} }
.editinline table thead th:last-child { select + .related-widget-wrapper-link,
border-left: none; .related-widget-wrapper-link + .related-widget-wrapper-link {
} margin-left: 7px;
.editinline tr.deleted {
background: #ddd url(../img/deleted-overlay.gif);
}
.editinline tr.deleted .inline-deletelink {
background-image: url(../img/inline-restore.png);
}
.editinline tr.deleted td:hover {
cursor: default;
}
.editinline tr.deleted td:first-child {
background-image: none !important;
}
/* EDIT INLINE - STACKED */
.editinline-stacked {
min-width: 758px;
}
.editinline-stacked .inline-object {
margin-left: 210px;
background: white;
}
.editinline-stacked .inline-source {
float: left;
width: 200px;
background: #f8f8f8;
}
.editinline-stacked .inline-splitter {
float: left;
width: 9px;
background: #f8f8f8 url(../img/inline-splitter-bg.gif) 50% 50% no-repeat;
border-right: 1px solid #ccc;
}
.editinline-stacked .controls {
clear: both;
background: #e1e1e1 url(../img/nav-bg.gif) top left repeat-x;
padding: 3px 4px;
font-size: 11px;
border-top: 1px solid #ddd;
} }

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,3 @@
Roboto webfont source: https://www.google.com/fonts/specimen/Roboto
WOFF files extracted using https://github.com/majodev/google-webfonts-helper
Weights used in this project: Light (300), Regular (400), Bold (700)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
All icons are taken from Font Awesome (http://fontawesome.io/) project. All icons are taken from Font Awesome (http://fontawesome.io/) project.
The Font Awesome font is licensed under the SIL OFL 1.1: The Font Awesome font is licensed under the SIL OFL 1.1:
- http://scripts.sil.org/OFL - https://scripts.sil.org/OFL
SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG
Font-Awesome-SVG-PNG is licensed under the MIT license (see file license Font-Awesome-SVG-PNG is licensed under the MIT license (see file license

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 B

View File

@ -1,5 +0,0 @@
#!/usr/bin/env python3
from django.core import management
if __name__ == "__main__":
management.execute_from_command_line()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 711 B

View File

@ -0,0 +1 @@
<svg width="24" height="22" viewBox="0 0 847 779" xmlns="http://www.w3.org/2000/svg"><g><path fill="#EBECE6" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120z"/><path fill="#9E9E93" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120zm607 25h-607c-26 0-50 11-67 28-17 18-28 41-28 67v536c0 27 11 50 28 68 17 17 41 27 67 27h607c26 0 49-10 67-27 17-18 28-41 28-68v-536c0-26-11-49-28-67-18-17-41-28-67-28z"/><path stroke="#A9A8A4" stroke-width="20" d="M706 295l-68 281"/><path stroke="#E47474" stroke-width="20" d="M316 648l390-353M141 435l175 213"/><path stroke="#C9C9C9" stroke-width="20" d="M319 151l-178 284M706 295l-387-144"/><g fill="#040405"><path d="M319 111c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40zM141 395c22 0 40 18 40 40s-18 40-40 40c-23 0-41-18-41-40s18-40 41-40zM316 608c22 0 40 18 40 40 0 23-18 41-40 41s-40-18-40-41c0-22 18-40 40-40zM706 254c22 0 40 18 40 41 0 22-18 40-40 40s-40-18-40-40c0-23 18-41 40-41zM638 536c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 B

View File

@ -0,0 +1 @@
<svg width="24" height="22" viewBox="0 0 847 779" xmlns="http://www.w3.org/2000/svg"><g><path fill="#F1C02A" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120z"/><path fill="#9E9E93" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120zm607 25h-607c-26 0-50 11-67 28-17 18-28 41-28 67v536c0 27 11 50 28 68 17 17 41 27 67 27h607c26 0 49-10 67-27 17-18 28-41 28-68v-536c0-26-11-49-28-67-18-17-41-28-67-28z"/><path stroke="#A9A8A4" stroke-width="20" d="M706 295l-68 281"/><path stroke="#E47474" stroke-width="20" d="M316 648l390-353M141 435l175 213"/><path stroke="#C9A741" stroke-width="20" d="M319 151l-178 284M706 295l-387-144"/><g fill="#040405"><path d="M319 111c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40zM141 395c22 0 40 18 40 40s-18 40-40 40c-23 0-41-18-41-40s18-40 41-40zM316 608c22 0 40 18 40 40 0 23-18 41-40 41s-40-18-40-41c0-22 18-40 40-40zM706 254c22 0 40 18 40 41 0 22-18 40-40 40s-40-18-40-40c0-23 18-41 40-41zM638 536c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 B

View File

@ -0,0 +1,3 @@
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path fill="#2b70bf" d="M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5t-316.5 131.5-316.5-131.5-131.5-316.5q0-121 61-225-229 117-381 353 133 205 333.5 326.5t434.5 121.5 434.5-121.5 333.5-326.5zm-720-384q0-20-14-34t-34-14q-125 0-214.5 89.5t-89.5 214.5q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34zm848 384q0 34-20 69-140 230-376.5 368.5t-499.5 138.5-499.5-139-376.5-368q-20-35-20-69t20-69q140-229 376.5-368t499.5-139 499.5 139 376.5 368q20 35 20 69z"/>
</svg>

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 B

View File

@ -1,114 +1,112 @@
var SelectBox = { 'use strict';
cache: new Object(), {
const SelectBox = {
cache: {},
init: function(id) { init: function(id) {
var box = document.getElementById(id); const box = document.getElementById(id);
var node; SelectBox.cache[id] = [];
SelectBox.cache[id] = new Array(); const cache = SelectBox.cache[id];
var cache = SelectBox.cache[id]; for (const node of box.options) {
for (var i = 0; (node = box.options[i]); i++) {
cache.push({value: node.value, text: node.text, displayed: 1}); cache.push({value: node.value, text: node.text, displayed: 1});
} }
}, },
redisplay: function(id) { redisplay: function(id) {
// Repopulate HTML select box from cache // Repopulate HTML select box from cache
var box = document.getElementById(id); const box = document.getElementById(id);
box.options.length = 0; // clear all options const scroll_value_from_top = box.scrollTop;
for (var i = 0, j = SelectBox.cache[id].length; i < j; i++) { box.innerHTML = '';
var node = SelectBox.cache[id][i]; for (const node of SelectBox.cache[id]) {
if (node.displayed) { if (node.displayed) {
var new_option = new Option(node.text, node.value, false, false); const new_option = new Option(node.text, node.value, false, false);
// Shows a tooltip when hovering over the option // Shows a tooltip when hovering over the option
new_option.setAttribute("title", node.text); new_option.title = node.text;
box.options[box.options.length] = new_option; box.appendChild(new_option);
} }
} }
box.scrollTop = scroll_value_from_top;
}, },
filter: function(id, text) { filter: function(id, text) {
// Redisplay the HTML select box, displaying only the choices containing ALL // Redisplay the HTML select box, displaying only the choices containing ALL
// the words in text. (It's an AND search.) // the words in text. (It's an AND search.)
var tokens = text.toLowerCase().split(/\s+/); const tokens = text.toLowerCase().split(/\s+/);
var node, token; for (const node of SelectBox.cache[id]) {
for (var i = 0; (node = SelectBox.cache[id][i]); i++) {
node.displayed = 1; node.displayed = 1;
for (var j = 0; (token = tokens[j]); j++) { const node_text = node.text.toLowerCase();
if (node.text.toLowerCase().indexOf(token) == -1) { for (const token of tokens) {
if (!node_text.includes(token)) {
node.displayed = 0; node.displayed = 0;
break; // Once the first token isn't found we're done
} }
} }
} }
SelectBox.redisplay(id); SelectBox.redisplay(id);
}, },
delete_from_cache: function(id, value) { delete_from_cache: function(id, value) {
var node, delete_index = null; let delete_index = null;
for (var i = 0; (node = SelectBox.cache[id][i]); i++) { const cache = SelectBox.cache[id];
if (node.value == value) { for (const [i, node] of cache.entries()) {
if (node.value === value) {
delete_index = i; delete_index = i;
break; break;
} }
} }
var j = SelectBox.cache[id].length - 1; cache.splice(delete_index, 1);
for (var i = delete_index; i < j; i++) {
SelectBox.cache[id][i] = SelectBox.cache[id][i+1];
}
SelectBox.cache[id].length--;
}, },
add_to_cache: function(id, option) { add_to_cache: function(id, option) {
SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1}); SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1});
}, },
cache_contains: function(id, value) { cache_contains: function(id, value) {
// Check if an item is contained in the cache // Check if an item is contained in the cache
var node; for (const node of SelectBox.cache[id]) {
for (var i = 0; (node = SelectBox.cache[id][i]); i++) { if (node.value === value) {
if (node.value == value) {
return true; return true;
} }
} }
return false; return false;
}, },
move: function(from, to) { move: function(from, to) {
var from_box = document.getElementById(from); const from_box = document.getElementById(from);
var to_box = document.getElementById(to); for (const option of from_box.options) {
var option; const option_value = option.value;
for (var i = 0; (option = from_box.options[i]); i++) { if (option.selected && SelectBox.cache_contains(from, option_value)) {
if (option.selected && SelectBox.cache_contains(from, option.value)) { SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); SelectBox.delete_from_cache(from, option_value);
SelectBox.delete_from_cache(from, option.value);
} }
} }
SelectBox.redisplay(from); SelectBox.redisplay(from);
SelectBox.redisplay(to); SelectBox.redisplay(to);
}, },
move_all: function(from, to) { move_all: function(from, to) {
var from_box = document.getElementById(from); const from_box = document.getElementById(from);
var to_box = document.getElementById(to); for (const option of from_box.options) {
var option; const option_value = option.value;
for (var i = 0; (option = from_box.options[i]); i++) { if (SelectBox.cache_contains(from, option_value)) {
if (SelectBox.cache_contains(from, option.value)) { SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});
SelectBox.add_to_cache(to, {value: option.value, text: option.text, displayed: 1}); SelectBox.delete_from_cache(from, option_value);
SelectBox.delete_from_cache(from, option.value);
} }
} }
SelectBox.redisplay(from); SelectBox.redisplay(from);
SelectBox.redisplay(to); SelectBox.redisplay(to);
}, },
sort: function(id) { sort: function(id) {
SelectBox.cache[id].sort( function(a, b) { SelectBox.cache[id].sort(function(a, b) {
a = a.text.toLowerCase(); a = a.text.toLowerCase();
b = b.text.toLowerCase(); b = b.text.toLowerCase();
try { if (a > b) {
if (a > b) return 1; return 1;
if (a < b) return -1;
} }
catch (e) { if (a < b) {
// silently fail on IE 'unknown' exception return -1;
} }
return 0; return 0;
} ); } );
}, },
select_all: function(id) { select_all: function(id) {
var box = document.getElementById(id); const box = document.getElementById(id);
for (var i = 0; i < box.options.length; i++) { for (const option of box.options) {
box.options[i].selected = 'selected'; option.selected = true;
} }
} }
};
window.SelectBox = SelectBox;
} }

View File

@ -1,95 +1,153 @@
/*global SelectBox, gettext, interpolate, quickElement, SelectFilter*/
/* /*
SelectFilter2 - Turns a multiple-select box into a filter interface. SelectFilter2 - Turns a multiple-select box into a filter interface.
Requires core.js, SelectBox.js and addevent.js. Requires core.js and SelectBox.js.
*/ */
(function($) { 'use strict';
function findForm(node) { {
// returns the node of the form containing the given node window.SelectFilter = {
if (node.tagName.toLowerCase() != 'form') { init: function(field_id, field_name, is_stacked) {
return findForm(node.parentNode); if (field_id.match(/__prefix__/)) {
}
return node;
}
window.SelectFilter = {
init: function(field_id, field_name, is_stacked, admin_static_prefix) {
if (field_id.match(/__prefix__/)){
// Don't initialize on empty forms. // Don't initialize on empty forms.
return; return;
} }
var from_box = document.getElementById(field_id); const from_box = document.getElementById(field_id);
from_box.id += '_from'; // change its ID from_box.id += '_from'; // change its ID
from_box.className = 'filtered'; from_box.className = 'filtered';
var ps = from_box.parentNode.getElementsByTagName('p'); for (const p of from_box.parentNode.getElementsByTagName('p')) {
for (var i=0; i<ps.length; i++) { if (p.classList.contains("info")) {
if (ps[i].className.indexOf("info") != -1) {
// Remove <p class="info">, because it just gets in the way. // Remove <p class="info">, because it just gets in the way.
from_box.parentNode.removeChild(ps[i]); from_box.parentNode.removeChild(p);
} else if (ps[i].className.indexOf("help") != -1) { } else if (p.classList.contains("help")) {
// Move help text up to the top so it isn't below the select // Move help text up to the top so it isn't below the select
// boxes or wrapped off on the side to the right of the add // boxes or wrapped off on the side to the right of the add
// button: // button:
from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild); from_box.parentNode.insertBefore(p, from_box.parentNode.firstChild);
} }
} }
// <div class="selector"> or <div class="selector stacked"> // <div class="selector"> or <div class="selector stacked">
var selector_div = quickElement('div', from_box.parentNode); const selector_div = quickElement('div', from_box.parentNode);
selector_div.className = is_stacked ? 'selector stacked' : 'selector'; selector_div.className = is_stacked ? 'selector stacked' : 'selector';
// <div class="selector-available"> // <div class="selector-available">
var selector_available = quickElement('div', selector_div); const selector_available = quickElement('div', selector_div);
selector_available.className = 'selector-available'; selector_available.className = 'selector-available';
var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name])); const title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));
quickElement('img', title_available, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of available %s. You may choose some by selecting them in the box below and then clicking the "Choose" arrow between the two boxes.'), [field_name])); quickElement(
'span', title_available, '',
'class', 'help help-tooltip help-icon',
'title', interpolate(
gettext(
'This is the list of available %s. You may choose some by ' +
'selecting them in the box below and then clicking the ' +
'"Choose" arrow between the two boxes.'
),
[field_name]
)
);
var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter'); const filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');
filter_p.className = 'selector-filter'; filter_p.className = 'selector-filter';
var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + "_input"); const search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input');
var search_selector_img = quickElement('img', search_filter_label, '', 'src', admin_static_prefix + 'img/selector-search.gif', 'class', 'help-tooltip', 'alt', '', 'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])); quickElement(
'span', search_filter_label, '',
'class', 'help-tooltip search-label-icon',
'title', interpolate(gettext("Type into this box to filter down the list of available %s."), [field_name])
);
filter_p.appendChild(document.createTextNode(' ')); filter_p.appendChild(document.createTextNode(' '));
var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter")); const filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext("Filter"));
filter_input.id = field_id + '_input'; filter_input.id = field_id + '_input';
selector_available.appendChild(from_box); selector_available.appendChild(from_box);
var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', 'javascript: (function(){ SelectBox.move_all("' + field_id + '_from", "' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_all_link'); const choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_add_all_link');
choose_all.className = 'selector-chooseall'; choose_all.className = 'selector-chooseall';
// <ul class="selector-chooser"> // <ul class="selector-chooser">
var selector_chooser = quickElement('ul', selector_div); const selector_chooser = quickElement('ul', selector_div);
selector_chooser.className = 'selector-chooser'; selector_chooser.className = 'selector-chooser';
var add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_from","' + field_id + '_to"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_add_link'); const add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', '#', 'id', field_id + '_add_link');
add_link.className = 'selector-add'; add_link.className = 'selector-add';
var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', 'javascript: (function(){ SelectBox.move("' + field_id + '_to","' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_link'); const remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', '#', 'id', field_id + '_remove_link');
remove_link.className = 'selector-remove'; remove_link.className = 'selector-remove';
// <div class="selector-chosen"> // <div class="selector-chosen">
var selector_chosen = quickElement('div', selector_div); const selector_chosen = quickElement('div', selector_div);
selector_chosen.className = 'selector-chosen'; selector_chosen.className = 'selector-chosen';
var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name])); const title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));
quickElement('img', title_chosen, '', 'src', admin_static_prefix + 'img/icon-unknown.gif', 'width', '10', 'height', '10', 'class', 'help help-tooltip', 'title', interpolate(gettext('This is the list of chosen %s. You may remove some by selecting them in the box below and then clicking the "Remove" arrow between the two boxes.'), [field_name])); quickElement(
'span', title_chosen, '',
'class', 'help help-tooltip help-icon',
'title', interpolate(
gettext(
'This is the list of chosen %s. You may remove some by ' +
'selecting them in the box below and then clicking the ' +
'"Remove" arrow between the two boxes.'
),
[field_name]
)
);
var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name')); const to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', '', 'size', from_box.size, 'name', from_box.name);
to_box.className = 'filtered'; to_box.className = 'filtered';
var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from"); SelectFilter.refresh_icons("' + field_id + '");})()', 'id', field_id + '_remove_all_link'); const clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_remove_all_link');
clear_all.className = 'selector-clearall'; clear_all.className = 'selector-clearall';
from_box.setAttribute('name', from_box.getAttribute('name') + '_old'); from_box.name = from_box.name + '_old';
// Set up the JavaScript event handlers for the select box filter interface // Set up the JavaScript event handlers for the select box filter interface
addEvent(filter_input, 'keyup', function(e) { SelectFilter.filter_key_up(e, field_id); }); const move_selection = function(e, elem, move_func, from, to) {
addEvent(filter_input, 'keydown', function(e) { SelectFilter.filter_key_down(e, field_id); }); if (elem.classList.contains('active')) {
addEvent(from_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); move_func(from, to);
addEvent(to_box, 'change', function(e) { SelectFilter.refresh_icons(field_id) }); SelectFilter.refresh_icons(field_id);
addEvent(from_box, 'dblclick', function() { SelectBox.move(field_id + '_from', field_id + '_to'); SelectFilter.refresh_icons(field_id); }); }
addEvent(to_box, 'dblclick', function() { SelectBox.move(field_id + '_to', field_id + '_from'); SelectFilter.refresh_icons(field_id); }); e.preventDefault();
addEvent(findForm(from_box), 'submit', function() { SelectBox.select_all(field_id + '_to'); }); };
choose_all.addEventListener('click', function(e) {
move_selection(e, this, SelectBox.move_all, field_id + '_from', field_id + '_to');
});
add_link.addEventListener('click', function(e) {
move_selection(e, this, SelectBox.move, field_id + '_from', field_id + '_to');
});
remove_link.addEventListener('click', function(e) {
move_selection(e, this, SelectBox.move, field_id + '_to', field_id + '_from');
});
clear_all.addEventListener('click', function(e) {
move_selection(e, this, SelectBox.move_all, field_id + '_to', field_id + '_from');
});
filter_input.addEventListener('keypress', function(e) {
SelectFilter.filter_key_press(e, field_id);
});
filter_input.addEventListener('keyup', function(e) {
SelectFilter.filter_key_up(e, field_id);
});
filter_input.addEventListener('keydown', function(e) {
SelectFilter.filter_key_down(e, field_id);
});
selector_div.addEventListener('change', function(e) {
if (e.target.tagName === 'SELECT') {
SelectFilter.refresh_icons(field_id);
}
});
selector_div.addEventListener('dblclick', function(e) {
if (e.target.tagName === 'OPTION') {
if (e.target.closest('select').id === field_id + '_to') {
SelectBox.move(field_id + '_to', field_id + '_from');
} else {
SelectBox.move(field_id + '_from', field_id + '_to');
}
SelectFilter.refresh_icons(field_id);
}
});
from_box.closest('form').addEventListener('submit', function() {
SelectBox.select_all(field_id + '_to');
});
SelectBox.init(field_id + '_from'); SelectBox.init(field_id + '_from');
SelectBox.init(field_id + '_to'); SelectBox.init(field_id + '_to');
// Move selected from_box options to to_box // Move selected from_box options to to_box
@ -97,65 +155,82 @@ window.SelectFilter = {
if (!is_stacked) { if (!is_stacked) {
// In horizontal mode, give the same height to the two boxes. // In horizontal mode, give the same height to the two boxes.
var j_from_box = $(from_box); const j_from_box = document.getElementById(field_id + '_from');
var j_to_box = $(to_box); const j_to_box = document.getElementById(field_id + '_to');
var resize_filters = function() { j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight()); } let height = filter_p.offsetHeight + j_from_box.offsetHeight;
if (j_from_box.outerHeight() > 0) {
resize_filters(); // This fieldset is already open. Resize now. const j_to_box_style = window.getComputedStyle(j_to_box);
} else { if (j_to_box_style.getPropertyValue('box-sizing') === 'border-box') {
// This fieldset is probably collapsed. Wait for its 'show' event. // Add the padding and border to the final height.
j_to_box.closest('fieldset').one('show.fieldset', resize_filters); height += parseInt(j_to_box_style.getPropertyValue('padding-top'), 10)
+ parseInt(j_to_box_style.getPropertyValue('padding-bottom'), 10)
+ parseInt(j_to_box_style.getPropertyValue('border-top-width'), 10)
+ parseInt(j_to_box_style.getPropertyValue('border-bottom-width'), 10);
} }
j_to_box.style.height = height + 'px';
} }
// Initial icon refresh // Initial icon refresh
SelectFilter.refresh_icons(field_id); SelectFilter.refresh_icons(field_id);
}, },
any_selected: function(field) {
// Temporarily add the required attribute and check validity.
field.required = true;
const any_selected = field.checkValidity();
field.required = false;
return any_selected;
},
refresh_icons: function(field_id) { refresh_icons: function(field_id) {
var from = $('#' + field_id + '_from'); const from = document.getElementById(field_id + '_from');
var to = $('#' + field_id + '_to'); const to = document.getElementById(field_id + '_to');
var is_from_selected = from.find('option:selected').length > 0;
var is_to_selected = to.find('option:selected').length > 0;
// Active if at least one item is selected // Active if at least one item is selected
$('#' + field_id + '_add_link').toggleClass('active', is_from_selected); document.getElementById(field_id + '_add_link').classList.toggle('active', SelectFilter.any_selected(from));
$('#' + field_id + '_remove_link').toggleClass('active', is_to_selected); document.getElementById(field_id + '_remove_link').classList.toggle('active', SelectFilter.any_selected(to));
// Active if the corresponding box isn't empty // Active if the corresponding box isn't empty
$('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0); document.getElementById(field_id + '_add_all_link').classList.toggle('active', from.querySelector('option'));
$('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0); document.getElementById(field_id + '_remove_all_link').classList.toggle('active', to.querySelector('option'));
},
filter_key_press: function(event, field_id) {
const from = document.getElementById(field_id + '_from');
// don't submit form if user pressed Enter
if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) {
from.selectedIndex = 0;
SelectBox.move(field_id + '_from', field_id + '_to');
from.selectedIndex = 0;
event.preventDefault();
}
}, },
filter_key_up: function(event, field_id) { filter_key_up: function(event, field_id) {
var from = document.getElementById(field_id + '_from'); const from = document.getElementById(field_id + '_from');
// don't submit form if user pressed Enter const temp = from.selectedIndex;
if ((event.which && event.which == 13) || (event.keyCode && event.keyCode == 13)) {
from.selectedIndex = 0;
SelectBox.move(field_id + '_from', field_id + '_to');
from.selectedIndex = 0;
return false;
}
var temp = from.selectedIndex;
SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value); SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);
from.selectedIndex = temp; from.selectedIndex = temp;
return true;
}, },
filter_key_down: function(event, field_id) { filter_key_down: function(event, field_id) {
var from = document.getElementById(field_id + '_from'); const from = document.getElementById(field_id + '_from');
// right arrow -- move across // right arrow -- move across
if ((event.which && event.which == 39) || (event.keyCode && event.keyCode == 39)) { if ((event.which && event.which === 39) || (event.keyCode && event.keyCode === 39)) {
var old_index = from.selectedIndex; const old_index = from.selectedIndex;
SelectBox.move(field_id + '_from', field_id + '_to'); SelectBox.move(field_id + '_from', field_id + '_to');
from.selectedIndex = (old_index == from.length) ? from.length - 1 : old_index; from.selectedIndex = (old_index === from.length) ? from.length - 1 : old_index;
return false; return;
} }
// down arrow -- wrap around // down arrow -- wrap around
if ((event.which && event.which == 40) || (event.keyCode && event.keyCode == 40)) { if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) {
from.selectedIndex = (from.length == from.selectedIndex + 1) ? 0 : from.selectedIndex + 1; from.selectedIndex = (from.length === from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;
} }
// up arrow -- wrap around // up arrow -- wrap around
if ((event.which && event.which == 38) || (event.keyCode && event.keyCode == 38)) { if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) {
from.selectedIndex = (from.selectedIndex == 0) ? from.length - 1 : from.selectedIndex - 1; from.selectedIndex = (from.selectedIndex === 0) ? from.length - 1 : from.selectedIndex - 1;
} }
return true;
} }
} };
})(django.jQuery); window.addEventListener('load', function(e) {
document.querySelectorAll('select.selectfilter, select.selectfilterstacked').forEach(function(el) {
const data = el.dataset;
SelectFilter.init(el.id, data.fieldName, parseInt(data.isStacked, 10));
});
});
}

View File

@ -1,144 +1,201 @@
(function($) { /*global gettext, interpolate, ngettext*/
var lastChecked; 'use strict';
{
$.fn.actions = function(opts) { function show(selector) {
var options = $.extend({}, $.fn.actions.defaults, opts); document.querySelectorAll(selector).forEach(function(el) {
var actionCheckboxes = $(this); el.classList.remove('hidden');
var list_editable_changed = false; });
var checker = function(checked) {
if (checked) {
showQuestion();
} else {
reset();
} }
$(actionCheckboxes).prop("checked", checked)
.parent().parent().toggleClass(options.selectedClass, checked); function hide(selector) {
}, document.querySelectorAll(selector).forEach(function(el) {
updateCounter = function() { el.classList.add('hidden');
var sel = $(actionCheckboxes).filter(":checked").length; });
// _actions_icnt is defined in the generated HTML }
function showQuestion(options) {
hide(options.acrossClears);
show(options.acrossQuestions);
hide(options.allContainer);
}
function showClear(options) {
show(options.acrossClears);
hide(options.acrossQuestions);
document.querySelector(options.actionContainer).classList.remove(options.selectedClass);
show(options.allContainer);
hide(options.counterContainer);
}
function reset(options) {
hide(options.acrossClears);
hide(options.acrossQuestions);
hide(options.allContainer);
show(options.counterContainer);
}
function clearAcross(options) {
reset(options);
const acrossInputs = document.querySelectorAll(options.acrossInput);
acrossInputs.forEach(function(acrossInput) {
acrossInput.value = 0;
});
document.querySelector(options.actionContainer).classList.remove(options.selectedClass);
}
function checker(actionCheckboxes, options, checked) {
if (checked) {
showQuestion(options);
} else {
reset(options);
}
actionCheckboxes.forEach(function(el) {
el.checked = checked;
el.closest('tr').classList.toggle(options.selectedClass, checked);
});
}
function updateCounter(actionCheckboxes, options) {
const sel = Array.from(actionCheckboxes).filter(function(el) {
return el.checked;
}).length;
const counter = document.querySelector(options.counterContainer);
// data-actions-icnt is defined in the generated HTML
// and contains the total amount of objects in the queryset // and contains the total amount of objects in the queryset
$(options.counterContainer).html(interpolate( const actions_icnt = Number(counter.dataset.actionsIcnt);
counter.textContent = interpolate(
ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), { ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
sel: sel, sel: sel,
cnt: _actions_icnt cnt: actions_icnt
}, true)); }, true);
$(options.allToggle).prop("checked", function() { const allToggle = document.getElementById(options.allToggleId);
var value; allToggle.checked = sel === actionCheckboxes.length;
if (sel == actionCheckboxes.length) { if (allToggle.checked) {
value = true; showQuestion(options);
showQuestion();
} else { } else {
value = false; clearAcross(options);
clearAcross();
}
return value;
});
},
showQuestion = function() {
$(options.acrossClears).hide();
$(options.acrossQuestions).show();
$(options.allContainer).hide();
},
showClear = function() {
$(options.acrossClears).show();
$(options.acrossQuestions).hide();
$(options.actionContainer).toggleClass(options.selectedClass);
$(options.allContainer).show();
$(options.counterContainer).hide();
},
reset = function() {
$(options.acrossClears).hide();
$(options.acrossQuestions).hide();
$(options.allContainer).hide();
$(options.counterContainer).show();
},
clearAcross = function() {
reset();
$(options.acrossInput).val(0);
$(options.actionContainer).removeClass(options.selectedClass);
};
// Show counter by default
$(options.counterContainer).show();
// Check state of checkboxes and reinit state if needed
$(this).filter(":checked").each(function(i) {
$(this).parent().parent().toggleClass(options.selectedClass);
updateCounter();
if ($(options.acrossInput).val() == 1) {
showClear();
}
});
$(options.allToggle).show().click(function() {
checker($(this).prop("checked"));
updateCounter();
});
$("a", options.acrossQuestions).click(function(event) {
event.preventDefault();
$(options.acrossInput).val(1);
showClear();
});
$("a", options.acrossClears).click(function(event) {
event.preventDefault();
$(options.allToggle).prop("checked", false);
clearAcross();
checker(0);
updateCounter();
});
lastChecked = null;
$(actionCheckboxes).click(function(event) {
if (!event) { event = window.event; }
var target = event.target ? event.target : event.srcElement;
if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey === true) {
var inrange = false;
$(lastChecked).prop("checked", target.checked)
.parent().parent().toggleClass(options.selectedClass, target.checked);
$(actionCheckboxes).each(function() {
if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) {
inrange = (inrange) ? false : true;
}
if (inrange) {
$(this).prop("checked", target.checked)
.parent().parent().toggleClass(options.selectedClass, target.checked);
}
});
}
$(target).parent().parent().toggleClass(options.selectedClass, target.checked);
lastChecked = target;
updateCounter();
});
$('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
list_editable_changed = true;
});
$('form#changelist-form button[name="index"]').click(function(event) {
if (list_editable_changed) {
return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
}
});
$('form#changelist-form input[name="_save"]').click(function(event) {
var action_changed = false;
$('select option:selected', options.actionContainer).each(function() {
if ($(this).val()) {
action_changed = true;
}
});
if (action_changed) {
if (list_editable_changed) {
return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
} else {
return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."));
} }
} }
});
}; const defaults = {
/* Setup plugin defaults */
$.fn.actions.defaults = {
actionContainer: "div.actions", actionContainer: "div.actions",
counterContainer: "span.action-counter", counterContainer: "span.action-counter",
allContainer: "div.actions span.all", allContainer: "div.actions span.all",
acrossInput: "div.actions input.select-across", acrossInput: "div.actions input.select-across",
acrossQuestions: "div.actions span.question", acrossQuestions: "div.actions span.question",
acrossClears: "div.actions span.clear", acrossClears: "div.actions span.clear",
allToggle: "#action-toggle", allToggleId: "action-toggle",
selectedClass: "selected" selectedClass: "selected"
}; };
})(django.jQuery);
window.Actions = function(actionCheckboxes, options) {
options = Object.assign({}, defaults, options);
let list_editable_changed = false;
let lastChecked = null;
let shiftPressed = false;
document.addEventListener('keydown', (event) => {
shiftPressed = event.shiftKey;
});
document.addEventListener('keyup', (event) => {
shiftPressed = event.shiftKey;
});
document.getElementById(options.allToggleId).addEventListener('click', function(event) {
checker(actionCheckboxes, options, this.checked);
updateCounter(actionCheckboxes, options);
});
document.querySelectorAll(options.acrossQuestions + " a").forEach(function(el) {
el.addEventListener('click', function(event) {
event.preventDefault();
const acrossInputs = document.querySelectorAll(options.acrossInput);
acrossInputs.forEach(function(acrossInput) {
acrossInput.value = 1;
});
showClear(options);
});
});
document.querySelectorAll(options.acrossClears + " a").forEach(function(el) {
el.addEventListener('click', function(event) {
event.preventDefault();
document.getElementById(options.allToggleId).checked = false;
clearAcross(options);
checker(actionCheckboxes, options, false);
updateCounter(actionCheckboxes, options);
});
});
function affectedCheckboxes(target, withModifier) {
const multiSelect = (lastChecked && withModifier && lastChecked !== target);
if (!multiSelect) {
return [target];
}
const checkboxes = Array.from(actionCheckboxes);
const targetIndex = checkboxes.findIndex(el => el === target);
const lastCheckedIndex = checkboxes.findIndex(el => el === lastChecked);
const startIndex = Math.min(targetIndex, lastCheckedIndex);
const endIndex = Math.max(targetIndex, lastCheckedIndex);
const filtered = checkboxes.filter((el, index) => (startIndex <= index) && (index <= endIndex));
return filtered;
};
Array.from(document.getElementById('result_list').tBodies).forEach(function(el) {
el.addEventListener('change', function(event) {
const target = event.target;
if (target.classList.contains('action-select')) {
const checkboxes = affectedCheckboxes(target, shiftPressed);
checker(checkboxes, options, target.checked);
updateCounter(actionCheckboxes, options);
lastChecked = target;
} else {
list_editable_changed = true;
}
});
});
document.querySelector('#changelist-form button[name=index]').addEventListener('click', function() {
if (list_editable_changed) {
const confirmed = confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
if (!confirmed) {
event.preventDefault();
}
}
});
const el = document.querySelector('#changelist-form input[name=_save]');
// The button does not exist if no fields are editable.
if (el) {
el.addEventListener('click', function(event) {
if (document.querySelector('[name=action]').value) {
const text = list_editable_changed
? gettext("You have selected an action, but you havent saved your changes to individual fields yet. Please click OK to save. Youll need to re-run the action.")
: gettext("You have selected an action, and you havent made any changes on individual fields. Youre probably looking for the Go button rather than the Save button.");
if (!confirm(text)) {
event.preventDefault();
}
}
});
}
};
// Call function fn when the DOM is loaded and ready. If it is already
// loaded, call the function now.
// http://youmightnotneedjquery.com/#ready
function ready(fn) {
if (document.readyState !== 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
ready(function() {
const actionsEls = document.querySelectorAll('tr input.action-select');
if (actionsEls.length > 0) {
Actions(actionsEls);
}
});
}

View File

@ -1,6 +0,0 @@
(function(a){var f;a.fn.actions=function(q){var b=a.extend({},a.fn.actions.defaults,q),g=a(this),e=!1,m=function(c){c?k():l();a(g).prop("checked",c).parent().parent().toggleClass(b.selectedClass,c)},h=function(){var c=a(g).filter(":checked").length;a(b.counterContainer).html(interpolate(ngettext("%(sel)s of %(cnt)s selected","%(sel)s of %(cnt)s selected",c),{sel:c,cnt:_actions_icnt},!0));a(b.allToggle).prop("checked",function(){var a;c==g.length?(a=!0,k()):(a=!1,n());return a})},k=function(){a(b.acrossClears).hide();
a(b.acrossQuestions).show();a(b.allContainer).hide()},p=function(){a(b.acrossClears).show();a(b.acrossQuestions).hide();a(b.actionContainer).toggleClass(b.selectedClass);a(b.allContainer).show();a(b.counterContainer).hide()},l=function(){a(b.acrossClears).hide();a(b.acrossQuestions).hide();a(b.allContainer).hide();a(b.counterContainer).show()},n=function(){l();a(b.acrossInput).val(0);a(b.actionContainer).removeClass(b.selectedClass)};a(b.counterContainer).show();a(this).filter(":checked").each(function(c){a(this).parent().parent().toggleClass(b.selectedClass);
h();1==a(b.acrossInput).val()&&p()});a(b.allToggle).show().click(function(){m(a(this).prop("checked"));h()});a("a",b.acrossQuestions).click(function(c){c.preventDefault();a(b.acrossInput).val(1);p()});a("a",b.acrossClears).click(function(c){c.preventDefault();a(b.allToggle).prop("checked",!1);n();m(0);h()});f=null;a(g).click(function(c){c||(c=window.event);var d=c.target?c.target:c.srcElement;if(f&&a.data(f)!=a.data(d)&&!0===c.shiftKey){var e=!1;a(f).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,
d.checked);a(g).each(function(){if(a.data(this)==a.data(f)||a.data(this)==a.data(d))e=e?!1:!0;e&&a(this).prop("checked",d.checked).parent().parent().toggleClass(b.selectedClass,d.checked)})}a(d).parent().parent().toggleClass(b.selectedClass,d.checked);f=d;h()});a("form#changelist-form table#result_list tr").find("td:gt(0) :input").change(function(){e=!0});a('form#changelist-form button[name="index"]').click(function(a){if(e)return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."))});
a('form#changelist-form input[name="_save"]').click(function(c){var d=!1;a("select option:selected",b.actionContainer).each(function(){a(this).val()&&(d=!0)});if(d)return e?confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.")):confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."))})};
a.fn.actions.defaults={actionContainer:"div.actions",counterContainer:"span.action-counter",allContainer:"div.actions span.all",acrossInput:"div.actions input.select-across",acrossQuestions:"div.actions span.question",acrossClears:"div.actions span.clear",allToggle:"#action-toggle",selectedClass:"selected"}})(django.jQuery);

View File

@ -1,47 +1,45 @@
/*global Calendar, findPosX, findPosY, get_format, gettext, gettext_noop, interpolate, ngettext, quickElement*/
// Inserts shortcut buttons after all of the following: // Inserts shortcut buttons after all of the following:
// <input type="text" class="vDateField"> // <input type="text" class="vDateField">
// <input type="text" class="vTimeField"> // <input type="text" class="vTimeField">
'use strict';
var DateTimeShortcuts = { {
const DateTimeShortcuts = {
calendars: [], calendars: [],
calendarInputs: [], calendarInputs: [],
clockInputs: [], clockInputs: [],
clockHours: {
default_: [
[gettext_noop('Now'), -1],
[gettext_noop('Midnight'), 0],
[gettext_noop('6 a.m.'), 6],
[gettext_noop('Noon'), 12],
[gettext_noop('6 p.m.'), 18]
]
},
dismissClockFunc: [], dismissClockFunc: [],
dismissCalendarFunc: [], dismissCalendarFunc: [],
calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
calendarDivName2: 'calendarin', // name of <div> that contains calendar calendarDivName2: 'calendarin', // name of <div> that contains calendar
calendarLinkName: 'calendarlink',// name of the link that is used to toggle calendarLinkName: 'calendarlink', // name of the link that is used to toggle
clockDivName: 'clockbox', // name of clock <div> that gets toggled clockDivName: 'clockbox', // name of clock <div> that gets toggled
clockLinkName: 'clocklink', // name of the link that is used to toggle clockLinkName: 'clocklink', // name of the link that is used to toggle
shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts
timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
timezoneOffset: 0, timezoneOffset: 0,
admin_media_prefix: '',
init: function() { init: function() {
// Get admin_media_prefix by grabbing it off the window object. It's const serverOffset = document.body.dataset.adminUtcOffset;
// set in the admin/base.html template, so if it's not there, someone's if (serverOffset) {
// overridden the template. In that case, we'll set a clearly-invalid const localOffset = new Date().getTimezoneOffset() * -60;
// value in the hopes that someone will examine HTTP requests and see it.
if (window.__admin_media_prefix__ != undefined) {
DateTimeShortcuts.admin_media_prefix = window.__admin_media_prefix__;
} else {
DateTimeShortcuts.admin_media_prefix = '/missing-admin-media-prefix/';
}
if (window.__admin_utc_offset__ != undefined) {
var serverOffset = window.__admin_utc_offset__;
var localOffset = new Date().getTimezoneOffset() * -60;
DateTimeShortcuts.timezoneOffset = localOffset - serverOffset; DateTimeShortcuts.timezoneOffset = localOffset - serverOffset;
} }
var inputs = document.getElementsByTagName('input'); for (const inp of document.getElementsByTagName('input')) {
for (i=0; i<inputs.length; i++) { if (inp.type === 'text' && inp.classList.contains('vTimeField')) {
var inp = inputs[i];
if (inp.getAttribute('type') == 'text' && inp.className.match(/vTimeField/)) {
DateTimeShortcuts.addClock(inp); DateTimeShortcuts.addClock(inp);
DateTimeShortcuts.addTimezoneWarning(inp); DateTimeShortcuts.addTimezoneWarning(inp);
} }
else if (inp.getAttribute('type') == 'text' && inp.className.match(/vDateField/)) { else if (inp.type === 'text' && inp.classList.contains('vDateField')) {
DateTimeShortcuts.addCalendar(inp); DateTimeShortcuts.addCalendar(inp);
DateTimeShortcuts.addTimezoneWarning(inp); DateTimeShortcuts.addTimezoneWarning(inp);
} }
@ -49,10 +47,10 @@ var DateTimeShortcuts = {
}, },
// Return the current time while accounting for the server timezone. // Return the current time while accounting for the server timezone.
now: function() { now: function() {
if (window.__admin_utc_offset__ != undefined) { const serverOffset = document.body.dataset.adminUtcOffset;
var serverOffset = window.__admin_utc_offset__; if (serverOffset) {
var localNow = new Date(); const localNow = new Date();
var localOffset = localNow.getTimezoneOffset() * -60; const localOffset = localNow.getTimezoneOffset() * -60;
localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset)); localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset));
return localNow; return localNow;
} else { } else {
@ -61,19 +59,20 @@ var DateTimeShortcuts = {
}, },
// Add a warning when the time zone in the browser and backend do not match. // Add a warning when the time zone in the browser and backend do not match.
addTimezoneWarning: function(inp) { addTimezoneWarning: function(inp) {
var $ = django.jQuery; const warningClass = DateTimeShortcuts.timezoneWarningClass;
var warningClass = DateTimeShortcuts.timezoneWarningClass; let timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600;
var timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600;
// Only warn if there is a time zone mismatch. // Only warn if there is a time zone mismatch.
if (!timezoneOffset) if (!timezoneOffset) {
return; return;
}
// Check if warning is already there. // Check if warning is already there.
if ($(inp).siblings('.' + warningClass).length) if (inp.parentNode.querySelectorAll('.' + warningClass).length) {
return; return;
}
var message; let message;
if (timezoneOffset > 0) { if (timezoneOffset > 0) {
message = ngettext( message = ngettext(
'Note: You are %s hour ahead of server time.', 'Note: You are %s hour ahead of server time.',
@ -82,7 +81,7 @@ var DateTimeShortcuts = {
); );
} }
else { else {
timezoneOffset *= -1 timezoneOffset *= -1;
message = ngettext( message = ngettext(
'Note: You are %s hour behind server time.', 'Note: You are %s hour behind server time.',
'Note: You are %s hours behind server time.', 'Note: You are %s hours behind server time.',
@ -91,34 +90,47 @@ var DateTimeShortcuts = {
} }
message = interpolate(message, [timezoneOffset]); message = interpolate(message, [timezoneOffset]);
var $warning = $('<span>'); const warning = document.createElement('span');
$warning.attr('class', warningClass); warning.className = warningClass;
$warning.text(message); warning.textContent = message;
inp.parentNode.appendChild(document.createElement('br'));
$(inp).parent() inp.parentNode.appendChild(warning);
.append($('<br>'))
.append($warning)
}, },
// Add clock widget to a given field // Add clock widget to a given field
addClock: function(inp) { addClock: function(inp) {
var num = DateTimeShortcuts.clockInputs.length; const num = DateTimeShortcuts.clockInputs.length;
DateTimeShortcuts.clockInputs[num] = inp; DateTimeShortcuts.clockInputs[num] = inp;
DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; }; DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; };
// Shortcut links (clock icon and "Now" link) // Shortcut links (clock icon and "Now" link)
var shortcuts_span = document.createElement('span'); const shortcuts_span = document.createElement('span');
shortcuts_span.className = DateTimeShortcuts.shortCutsClass; shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
var now_link = document.createElement('a'); const now_link = document.createElement('a');
now_link.setAttribute('href', "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); now_link.href = "#";
now_link.appendChild(document.createTextNode(gettext('Now'))); now_link.textContent = gettext('Now');
var clock_link = document.createElement('a'); now_link.addEventListener('click', function(e) {
clock_link.setAttribute('href', 'javascript:DateTimeShortcuts.openClock(' + num + ');'); e.preventDefault();
DateTimeShortcuts.handleClockQuicklink(num, -1);
});
const clock_link = document.createElement('a');
clock_link.href = '#';
clock_link.id = DateTimeShortcuts.clockLinkName + num; clock_link.id = DateTimeShortcuts.clockLinkName + num;
quickElement('img', clock_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/icon_clock.gif', 'alt', gettext('Clock')); clock_link.addEventListener('click', function(e) {
shortcuts_span.appendChild(document.createTextNode('\240')); e.preventDefault();
// avoid triggering the document click handler to dismiss the clock
e.stopPropagation();
DateTimeShortcuts.openClock(num);
});
quickElement(
'span', clock_link, '',
'class', 'clock-icon',
'title', gettext('Choose a Time')
);
shortcuts_span.appendChild(document.createTextNode('\u00A0'));
shortcuts_span.appendChild(now_link); shortcuts_span.appendChild(now_link);
shortcuts_span.appendChild(document.createTextNode('\240|\240')); shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0'));
shortcuts_span.appendChild(clock_link); shortcuts_span.appendChild(clock_link);
// Create clock link div // Create clock link div
@ -131,31 +143,44 @@ var DateTimeShortcuts = {
// <li><a href="#">Midnight</a></li> // <li><a href="#">Midnight</a></li>
// <li><a href="#">6 a.m.</a></li> // <li><a href="#">6 a.m.</a></li>
// <li><a href="#">Noon</a></li> // <li><a href="#">Noon</a></li>
// <li><a href="#">6 p.m.</a></li>
// </ul> // </ul>
// <p class="calendar-cancel"><a href="#">Cancel</a></p> // <p class="calendar-cancel"><a href="#">Cancel</a></p>
// </div> // </div>
var clock_box = document.createElement('div'); const clock_box = document.createElement('div');
clock_box.style.display = 'none'; clock_box.style.display = 'none';
clock_box.style.position = 'absolute'; clock_box.style.position = 'absolute';
clock_box.className = 'clockbox module'; clock_box.className = 'clockbox module';
clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num); clock_box.id = DateTimeShortcuts.clockDivName + num;
document.body.appendChild(clock_box); document.body.appendChild(clock_box);
addEvent(clock_box, 'click', cancelEventPropagation); clock_box.addEventListener('click', function(e) { e.stopPropagation(); });
quickElement('h2', clock_box, gettext('Choose a time')); quickElement('h2', clock_box, gettext('Choose a time'));
var time_list = quickElement('ul', clock_box); const time_list = quickElement('ul', clock_box);
time_list.className = 'timelist'; time_list.className = 'timelist';
quickElement("a", quickElement("li", time_list), gettext("Now"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", -1);"); // The list of choices can be overridden in JavaScript like this:
quickElement("a", quickElement("li", time_list), gettext("Midnight"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 0);"); // DateTimeShortcuts.clockHours.name = [['3 a.m.', 3]];
quickElement("a", quickElement("li", time_list), gettext("6 a.m."), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 6);"); // where name is the name attribute of the <input>.
quickElement("a", quickElement("li", time_list), gettext("Noon"), "href", "javascript:DateTimeShortcuts.handleClockQuicklink(" + num + ", 12);"); const name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name;
DateTimeShortcuts.clockHours[name].forEach(function(element) {
const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#');
time_link.addEventListener('click', function(e) {
e.preventDefault();
DateTimeShortcuts.handleClockQuicklink(num, element[1]);
});
});
var cancel_p = quickElement('p', clock_box); const cancel_p = quickElement('p', clock_box);
cancel_p.className = 'calendar-cancel'; cancel_p.className = 'calendar-cancel';
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissClock(' + num + ');'); const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
django.jQuery(document).bind('keyup', function(event) { cancel_link.addEventListener('click', function(e) {
if (event.which == 27) { e.preventDefault();
DateTimeShortcuts.dismissClock(num);
});
document.addEventListener('keyup', function(event) {
if (event.which === 27) {
// ESC key closes popup // ESC key closes popup
DateTimeShortcuts.dismissClock(num); DateTimeShortcuts.dismissClock(num);
event.preventDefault(); event.preventDefault();
@ -163,38 +188,36 @@ var DateTimeShortcuts = {
}); });
}, },
openClock: function(num) { openClock: function(num) {
var clock_box = document.getElementById(DateTimeShortcuts.clockDivName+num) const clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num);
var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName+num) const clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num);
// Recalculate the clockbox position // Recalculate the clockbox position
// is it left-to-right or right-to-left layout ? // is it left-to-right or right-to-left layout ?
if (getStyle(document.body,'direction')!='rtl') { if (window.getComputedStyle(document.body).direction !== 'rtl') {
clock_box.style.left = findPosX(clock_link) + 17 + 'px'; clock_box.style.left = findPosX(clock_link) + 17 + 'px';
} }
else { else {
// since style's width is in em, it'd be tough to calculate // since style's width is in em, it'd be tough to calculate
// px value of it. let's use an estimated px for now // px value of it. let's use an estimated px for now
// TODO: IE returns wrong value for findPosX when in rtl mode
// (it returns as it was left aligned), needs to be fixed.
clock_box.style.left = findPosX(clock_link) - 110 + 'px'; clock_box.style.left = findPosX(clock_link) - 110 + 'px';
} }
clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px'; clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px';
// Show the clock box // Show the clock box
clock_box.style.display = 'block'; clock_box.style.display = 'block';
addEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); document.addEventListener('click', DateTimeShortcuts.dismissClockFunc[num]);
}, },
dismissClock: function(num) { dismissClock: function(num) {
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none'; document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';
removeEvent(document, 'click', DateTimeShortcuts.dismissClockFunc[num]); document.removeEventListener('click', DateTimeShortcuts.dismissClockFunc[num]);
}, },
handleClockQuicklink: function(num, val) { handleClockQuicklink: function(num, val) {
var d; let d;
if (val == -1) { if (val === -1) {
d = DateTimeShortcuts.now(); d = DateTimeShortcuts.now();
} }
else { else {
d = new Date(1970, 1, 1, val, 0, 0, 0) d = new Date(1970, 1, 1, val, 0, 0, 0);
} }
DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]); DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]);
DateTimeShortcuts.clockInputs[num].focus(); DateTimeShortcuts.clockInputs[num].focus();
@ -202,25 +225,39 @@ var DateTimeShortcuts = {
}, },
// Add calendar widget to a given field. // Add calendar widget to a given field.
addCalendar: function(inp) { addCalendar: function(inp) {
var num = DateTimeShortcuts.calendars.length; const num = DateTimeShortcuts.calendars.length;
DateTimeShortcuts.calendarInputs[num] = inp; DateTimeShortcuts.calendarInputs[num] = inp;
DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; }; DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; };
// Shortcut links (calendar icon and "Today" link) // Shortcut links (calendar icon and "Today" link)
var shortcuts_span = document.createElement('span'); const shortcuts_span = document.createElement('span');
shortcuts_span.className = DateTimeShortcuts.shortCutsClass; shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling); inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
var today_link = document.createElement('a'); const today_link = document.createElement('a');
today_link.setAttribute('href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); today_link.href = '#';
today_link.appendChild(document.createTextNode(gettext('Today'))); today_link.appendChild(document.createTextNode(gettext('Today')));
var cal_link = document.createElement('a'); today_link.addEventListener('click', function(e) {
cal_link.setAttribute('href', 'javascript:DateTimeShortcuts.openCalendar(' + num + ');'); e.preventDefault();
DateTimeShortcuts.handleCalendarQuickLink(num, 0);
});
const cal_link = document.createElement('a');
cal_link.href = '#';
cal_link.id = DateTimeShortcuts.calendarLinkName + num; cal_link.id = DateTimeShortcuts.calendarLinkName + num;
quickElement('img', cal_link, '', 'src', DateTimeShortcuts.admin_media_prefix + 'img/icon_calendar.gif', 'alt', gettext('Calendar')); cal_link.addEventListener('click', function(e) {
shortcuts_span.appendChild(document.createTextNode('\240')); e.preventDefault();
// avoid triggering the document click handler to dismiss the calendar
e.stopPropagation();
DateTimeShortcuts.openCalendar(num);
});
quickElement(
'span', cal_link, '',
'class', 'date-icon',
'title', gettext('Choose a Date')
);
shortcuts_span.appendChild(document.createTextNode('\u00A0'));
shortcuts_span.appendChild(today_link); shortcuts_span.appendChild(today_link);
shortcuts_span.appendChild(document.createTextNode('\240|\240')); shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0'));
shortcuts_span.appendChild(cal_link); shortcuts_span.appendChild(cal_link);
// Create calendarbox div. // Create calendarbox div.
@ -240,42 +277,67 @@ var DateTimeShortcuts = {
// </div> // </div>
// <p class="calendar-cancel"><a href="#">Cancel</a></p> // <p class="calendar-cancel"><a href="#">Cancel</a></p>
// </div> // </div>
var cal_box = document.createElement('div'); const cal_box = document.createElement('div');
cal_box.style.display = 'none'; cal_box.style.display = 'none';
cal_box.style.position = 'absolute'; cal_box.style.position = 'absolute';
cal_box.className = 'calendarbox module'; cal_box.className = 'calendarbox module';
cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num); cal_box.id = DateTimeShortcuts.calendarDivName1 + num;
document.body.appendChild(cal_box); document.body.appendChild(cal_box);
addEvent(cal_box, 'click', cancelEventPropagation); cal_box.addEventListener('click', function(e) { e.stopPropagation(); });
// next-prev links // next-prev links
var cal_nav = quickElement('div', cal_box); const cal_nav = quickElement('div', cal_box);
var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', 'javascript:DateTimeShortcuts.drawPrev('+num+');'); const cal_nav_prev = quickElement('a', cal_nav, '<', 'href', '#');
cal_nav_prev.className = 'calendarnav-previous'; cal_nav_prev.className = 'calendarnav-previous';
var cal_nav_next = quickElement('a', cal_nav, '>', 'href', 'javascript:DateTimeShortcuts.drawNext('+num+');'); cal_nav_prev.addEventListener('click', function(e) {
e.preventDefault();
DateTimeShortcuts.drawPrev(num);
});
const cal_nav_next = quickElement('a', cal_nav, '>', 'href', '#');
cal_nav_next.className = 'calendarnav-next'; cal_nav_next.className = 'calendarnav-next';
cal_nav_next.addEventListener('click', function(e) {
e.preventDefault();
DateTimeShortcuts.drawNext(num);
});
// main box // main box
var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num); const cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
cal_main.className = 'calendar'; cal_main.className = 'calendar';
DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num)); DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));
DateTimeShortcuts.calendars[num].drawCurrent(); DateTimeShortcuts.calendars[num].drawCurrent();
// calendar shortcuts // calendar shortcuts
var shortcuts = quickElement('div', cal_box); const shortcuts = quickElement('div', cal_box);
shortcuts.className = 'calendar-shortcuts'; shortcuts.className = 'calendar-shortcuts';
quickElement('a', shortcuts, gettext('Yesterday'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', -1);'); let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#');
shortcuts.appendChild(document.createTextNode('\240|\240')); day_link.addEventListener('click', function(e) {
quickElement('a', shortcuts, gettext('Today'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', 0);'); e.preventDefault();
shortcuts.appendChild(document.createTextNode('\240|\240')); DateTimeShortcuts.handleCalendarQuickLink(num, -1);
quickElement('a', shortcuts, gettext('Tomorrow'), 'href', 'javascript:DateTimeShortcuts.handleCalendarQuickLink(' + num + ', +1);'); });
shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0'));
day_link = quickElement('a', shortcuts, gettext('Today'), 'href', '#');
day_link.addEventListener('click', function(e) {
e.preventDefault();
DateTimeShortcuts.handleCalendarQuickLink(num, 0);
});
shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0'));
day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'href', '#');
day_link.addEventListener('click', function(e) {
e.preventDefault();
DateTimeShortcuts.handleCalendarQuickLink(num, +1);
});
// cancel bar // cancel bar
var cancel_p = quickElement('p', cal_box); const cancel_p = quickElement('p', cal_box);
cancel_p.className = 'calendar-cancel'; cancel_p.className = 'calendar-cancel';
quickElement('a', cancel_p, gettext('Cancel'), 'href', 'javascript:DateTimeShortcuts.dismissCalendar(' + num + ');'); const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
django.jQuery(document).bind('keyup', function(event) { cancel_link.addEventListener('click', function(e) {
if (event.which == 27) { e.preventDefault();
DateTimeShortcuts.dismissCalendar(num);
});
document.addEventListener('keyup', function(event) {
if (event.which === 27) {
// ESC key closes popup // ESC key closes popup
DateTimeShortcuts.dismissCalendar(num); DateTimeShortcuts.dismissCalendar(num);
event.preventDefault(); event.preventDefault();
@ -283,42 +345,41 @@ var DateTimeShortcuts = {
}); });
}, },
openCalendar: function(num) { openCalendar: function(num) {
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num) const cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num);
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num) const cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num);
var inp = DateTimeShortcuts.calendarInputs[num]; const inp = DateTimeShortcuts.calendarInputs[num];
// Determine if the current value in the input has a valid date. // Determine if the current value in the input has a valid date.
// If so, draw the calendar with that date's year and month. // If so, draw the calendar with that date's year and month.
if (inp.value) { if (inp.value) {
var date_parts = inp.value.split('-'); const format = get_format('DATE_INPUT_FORMATS')[0];
var year = date_parts[0]; const selected = inp.value.strptime(format);
var month = parseFloat(date_parts[1]); const year = selected.getUTCFullYear();
var selected = new Date(inp.value); const month = selected.getUTCMonth() + 1;
if (year.match(/\d\d\d\d/) && month >= 1 && month <= 12) { const re = /\d{4}/;
if (re.test(year.toString()) && month >= 1 && month <= 12) {
DateTimeShortcuts.calendars[num].drawDate(month, year, selected); DateTimeShortcuts.calendars[num].drawDate(month, year, selected);
} }
} }
// Recalculate the clockbox position // Recalculate the clockbox position
// is it left-to-right or right-to-left layout ? // is it left-to-right or right-to-left layout ?
if (getStyle(document.body,'direction')!='rtl') { if (window.getComputedStyle(document.body).direction !== 'rtl') {
cal_box.style.left = findPosX(cal_link) + 17 + 'px'; cal_box.style.left = findPosX(cal_link) + 17 + 'px';
} }
else { else {
// since style's width is in em, it'd be tough to calculate // since style's width is in em, it'd be tough to calculate
// px value of it. let's use an estimated px for now // px value of it. let's use an estimated px for now
// TODO: IE returns wrong value for findPosX when in rtl mode
// (it returns as it was left aligned), needs to be fixed.
cal_box.style.left = findPosX(cal_link) - 180 + 'px'; cal_box.style.left = findPosX(cal_link) - 180 + 'px';
} }
cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px'; cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px';
cal_box.style.display = 'block'; cal_box.style.display = 'block';
addEvent(document, 'click', DateTimeShortcuts.dismissCalendarFunc[num]); document.addEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]);
}, },
dismissCalendar: function(num) { dismissCalendar: function(num) {
document.getElementById(DateTimeShortcuts.calendarDivName1+num).style.display = 'none'; document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none';
removeEvent(document, 'click', DateTimeShortcuts.dismissCalendarFunc[num]); document.removeEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]);
}, },
drawPrev: function(num) { drawPrev: function(num) {
DateTimeShortcuts.calendars[num].drawPreviousMonth(); DateTimeShortcuts.calendars[num].drawPreviousMonth();
@ -327,30 +388,28 @@ var DateTimeShortcuts = {
DateTimeShortcuts.calendars[num].drawNextMonth(); DateTimeShortcuts.calendars[num].drawNextMonth();
}, },
handleCalendarCallback: function(num) { handleCalendarCallback: function(num) {
var format = get_format('DATE_INPUT_FORMATS')[0]; let format = get_format('DATE_INPUT_FORMATS')[0];
// the format needs to be escaped a little // the format needs to be escaped a little
format = format.replace('\\', '\\\\'); format = format.replace('\\', '\\\\')
format = format.replace('\r', '\\r'); .replace('\r', '\\r')
format = format.replace('\n', '\\n'); .replace('\n', '\\n')
format = format.replace('\t', '\\t'); .replace('\t', '\\t')
format = format.replace("'", "\\'"); .replace("'", "\\'");
return ["function(y, m, d) { DateTimeShortcuts.calendarInputs[", return function(y, m, d) {
num, DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format);
"].value = new Date(y, m-1, d).strftime('", DateTimeShortcuts.calendarInputs[num].focus();
format, document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none';
"');DateTimeShortcuts.calendarInputs[", };
num,
"].focus();document.getElementById(DateTimeShortcuts.calendarDivName1+",
num,
").style.display='none';}"].join('');
}, },
handleCalendarQuickLink: function(num, offset) { handleCalendarQuickLink: function(num, offset) {
var d = DateTimeShortcuts.now(); const d = DateTimeShortcuts.now();
d.setDate(d.getDate() + offset) d.setDate(d.getDate() + offset);
DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]); DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);
DateTimeShortcuts.calendarInputs[num].focus(); DateTimeShortcuts.calendarInputs[num].focus();
DateTimeShortcuts.dismissCalendar(num); DateTimeShortcuts.dismissCalendar(num);
} }
} };
addEvent(window, 'load', DateTimeShortcuts.init); window.addEventListener('load', DateTimeShortcuts.init);
window.DateTimeShortcuts = DateTimeShortcuts;
}

View File

@ -1,97 +1,155 @@
/*global SelectBox, interpolate*/
// Handles related-objects functionality: lookup link for raw_id_fields // Handles related-objects functionality: lookup link for raw_id_fields
// and Add Another links. // and Add Another links.
'use strict';
{
const $ = django.jQuery;
function html_unescape(text) { function showAdminPopup(triggeringLink, name_regexp, add_popup) {
// Unescape a string that was escaped using django.utils.html.escape. const name = triggeringLink.id.replace(name_regexp, '');
text = text.replace(/&lt;/g, '<'); const href = new URL(triggeringLink.href);
text = text.replace(/&gt;/g, '>'); if (add_popup) {
text = text.replace(/&quot;/g, '"'); href.searchParams.set('_popup', 1);
text = text.replace(/&#39;/g, "'");
text = text.replace(/&amp;/g, '&');
return text;
}
// IE doesn't accept periods or dashes in the window name, but the element IDs
// we use to generate popup window names may contain them, therefore we map them
// to allowed characters in a reversible way so that we can locate the correct
// element when the popup window is dismissed.
function id_to_windowname(text) {
text = text.replace(/\./g, '__dot__');
text = text.replace(/\-/g, '__dash__');
return text;
}
function windowname_to_id(text) {
text = text.replace(/__dot__/g, '.');
text = text.replace(/__dash__/g, '-');
return text;
}
function showRelatedObjectLookupPopup(triggeringLink) {
var name = triggeringLink.id.replace(/^lookup_/, '');
name = id_to_windowname(name);
var href;
if (triggeringLink.href.search(/\?/) >= 0) {
href = triggeringLink.href + '&_popup=1';
} else {
href = triggeringLink.href + '?_popup=1';
} }
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes'); const win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus(); win.focus();
return false; return false;
} }
function dismissRelatedLookupPopup(win, chosenId) { function showRelatedObjectLookupPopup(triggeringLink) {
var name = windowname_to_id(win.name); return showAdminPopup(triggeringLink, /^lookup_/, true);
var elem = document.getElementById(name); }
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
function dismissRelatedLookupPopup(win, chosenId) {
const name = win.name;
const elem = document.getElementById(name);
if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
elem.value += ',' + chosenId; elem.value += ',' + chosenId;
} else { } else {
document.getElementById(name).value = chosenId; document.getElementById(name).value = chosenId;
} }
win.close(); win.close();
}
function showAddAnotherPopup(triggeringLink) {
var name = triggeringLink.id.replace(/^add_/, '');
name = id_to_windowname(name);
var href = triggeringLink.href;
if (href.indexOf('?') == -1) {
href += '?_popup=1';
} else {
href += '&_popup=1';
} }
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
return false;
}
function dismissAddAnotherPopup(win, newId, newRepr) { function showRelatedObjectPopup(triggeringLink) {
// newId and newRepr are expected to have previously been escaped by return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false);
// django.utils.html.escape. }
newId = html_unescape(newId);
newRepr = html_unescape(newRepr); function updateRelatedObjectLinks(triggeringLink) {
var name = windowname_to_id(win.name); const $this = $(triggeringLink);
var elem = document.getElementById(name); const siblings = $this.nextAll('.view-related, .change-related, .delete-related');
var o; if (!siblings.length) {
return;
}
const value = $this.val();
if (value) {
siblings.each(function() {
const elm = $(this);
elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));
});
} else {
siblings.removeAttr('href');
}
}
function dismissAddRelatedObjectPopup(win, newId, newRepr) {
const name = win.name;
const elem = document.getElementById(name);
if (elem) { if (elem) {
var elemName = elem.nodeName.toUpperCase(); const elemName = elem.nodeName.toUpperCase();
if (elemName == 'SELECT') { if (elemName === 'SELECT') {
o = new Option(newRepr, newId); elem.options[elem.options.length] = new Option(newRepr, newId, true, true);
elem.options[elem.options.length] = o; } else if (elemName === 'INPUT') {
o.selected = true; if (elem.classList.contains('vManyToManyRawIdAdminField') && elem.value) {
} else if (elemName == 'INPUT') {
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
elem.value += ',' + newId; elem.value += ',' + newId;
} else { } else {
elem.value = newId; elem.value = newId;
} }
} }
// Trigger a change event to update related links if required.
$(elem).trigger('change');
} else { } else {
var toId = name + "_to"; const toId = name + "_to";
o = new Option(newRepr, newId); const o = new Option(newRepr, newId);
SelectBox.add_to_cache(toId, o); SelectBox.add_to_cache(toId, o);
SelectBox.redisplay(toId); SelectBox.redisplay(toId);
} }
win.close(); win.close();
}
function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
const id = win.name.replace(/^edit_/, '');
const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
const selects = $(selectsSelector);
selects.find('option').each(function() {
if (this.value === objId) {
this.textContent = newRepr;
this.value = newId;
}
});
selects.next().find('.select2-selection__rendered').each(function() {
// The element can have a clear button as a child.
// Use the lastChild to modify only the displayed value.
this.lastChild.textContent = newRepr;
this.title = newRepr;
});
win.close();
}
function dismissDeleteRelatedObjectPopup(win, objId) {
const id = win.name.replace(/^delete_/, '');
const selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
const selects = $(selectsSelector);
selects.find('option').each(function() {
if (this.value === objId) {
$(this).remove();
}
}).trigger('change');
win.close();
}
window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup;
window.dismissRelatedLookupPopup = dismissRelatedLookupPopup;
window.showRelatedObjectPopup = showRelatedObjectPopup;
window.updateRelatedObjectLinks = updateRelatedObjectLinks;
window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup;
window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup;
window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup;
// Kept for backward compatibility
window.showAddAnotherPopup = showRelatedObjectPopup;
window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup;
$(document).ready(function() {
$("a[data-popup-opener]").on('click', function(event) {
event.preventDefault();
opener.dismissRelatedLookupPopup(window, $(this).data("popup-opener"));
});
$('body').on('click', '.related-widget-wrapper-link', function(e) {
e.preventDefault();
if (this.href) {
const event = $.Event('django:show-related', {href: this.href});
$(this).trigger(event);
if (!event.isDefaultPrevented()) {
showRelatedObjectPopup(this);
}
}
});
$('body').on('change', '.related-widget-wrapper select', function(e) {
const event = $.Event('django:update-related');
$(this).trigger(event);
if (!event.isDefaultPrevented()) {
updateRelatedObjectLinks(this);
}
});
$('.related-widget-wrapper select').trigger('change');
$('body').on('click', '.related-lookup', function(e) {
e.preventDefault();
const event = $.Event('django:lookup-related');
$(this).trigger(event);
if (!event.isDefaultPrevented()) {
showRelatedObjectLookupPopup(this);
}
});
});
} }

View File

@ -0,0 +1,41 @@
'use strict';
{
const $ = django.jQuery;
const init = function($element, options) {
const settings = $.extend({
ajax: {
data: function(params) {
return {
term: params.term,
page: params.page,
app_label: $element.data('app-label'),
model_name: $element.data('model-name'),
field_name: $element.data('field-name')
};
}
}
}, options);
$element.select2(settings);
};
$.fn.djangoAdminSelect2 = function(options) {
const settings = $.extend({}, options);
$.each(this, function(i, element) {
const $element = $(element);
init($element, settings);
});
return this;
};
$(function() {
// Initialize all autocomplete widgets except the one in the template
// form used when a new formset is added.
$('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();
});
$(document).on('formset:added', (function() {
return function(event, $newFormset) {
return $newFormset.find('.admin-autocomplete').djangoAdminSelect2();
};
})(this));
}

View File

@ -1,25 +1,62 @@
/*global gettext, pgettext, get_format, quickElement, removeChildren*/
/* /*
calendar.js - Calendar functions by Adrian Holovaty calendar.js - Calendar functions by Adrian Holovaty
depends on core.js for utility functions like removeChildren or quickElement depends on core.js for utility functions like removeChildren or quickElement
*/ */
'use strict';
// CalendarNamespace -- Provides a collection of HTML calendar-related helper functions {
var CalendarNamespace = { // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions
monthsOfYear: gettext('January February March April May June July August September October November December').split(' '), const CalendarNamespace = {
daysOfWeek: gettext('S M T W T F S').split(' '), monthsOfYear: [
gettext('January'),
gettext('February'),
gettext('March'),
gettext('April'),
gettext('May'),
gettext('June'),
gettext('July'),
gettext('August'),
gettext('September'),
gettext('October'),
gettext('November'),
gettext('December')
],
monthsOfYearAbbrev: [
pgettext('abbrev. month January', 'Jan'),
pgettext('abbrev. month February', 'Feb'),
pgettext('abbrev. month March', 'Mar'),
pgettext('abbrev. month April', 'Apr'),
pgettext('abbrev. month May', 'May'),
pgettext('abbrev. month June', 'Jun'),
pgettext('abbrev. month July', 'Jul'),
pgettext('abbrev. month August', 'Aug'),
pgettext('abbrev. month September', 'Sep'),
pgettext('abbrev. month October', 'Oct'),
pgettext('abbrev. month November', 'Nov'),
pgettext('abbrev. month December', 'Dec')
],
daysOfWeek: [
pgettext('one letter Sunday', 'S'),
pgettext('one letter Monday', 'M'),
pgettext('one letter Tuesday', 'T'),
pgettext('one letter Wednesday', 'W'),
pgettext('one letter Thursday', 'T'),
pgettext('one letter Friday', 'F'),
pgettext('one letter Saturday', 'S')
],
firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')), firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),
isLeapYear: function(year) { isLeapYear: function(year) {
return (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0)); return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0));
}, },
getDaysInMonth: function(month,year) { getDaysInMonth: function(month, year) {
var days; let days;
if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) { if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
days = 31; days = 31;
} }
else if (month==4 || month==6 || month==9 || month==11) { else if (month === 4 || month === 6 || month === 9 || month === 11) {
days = 30; days = 30;
} }
else if (month==2 && CalendarNamespace.isLeapYear(year)) { else if (month === 2 && CalendarNamespace.isLeapYear(year)) {
days = 29; days = 29;
} }
else { else {
@ -28,11 +65,11 @@ var CalendarNamespace = {
return days; return days;
}, },
draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999 draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999
var today = new Date(); const today = new Date();
var todayDay = today.getDate(); const todayDay = today.getDate();
var todayMonth = today.getMonth()+1; const todayMonth = today.getMonth() + 1;
var todayYear = today.getFullYear(); const todayYear = today.getFullYear();
var todayClass = ''; let todayClass = '';
// Use UTC functions here because the date field does not contain time // Use UTC functions here because the date field does not contain time
// and using the UTC function variants prevent the local time offset // and using the UTC function variants prevent the local time offset
@ -45,71 +82,83 @@ var CalendarNamespace = {
// //
// The day variable above will be 1 instead of 2 in, say, US Pacific time // The day variable above will be 1 instead of 2 in, say, US Pacific time
// zone. // zone.
var isSelectedMonth = false; let isSelectedMonth = false;
if (typeof selected != 'undefined') { if (typeof selected !== 'undefined') {
isSelectedMonth = (selected.getUTCFullYear() == year && (selected.getUTCMonth()+1) == month); isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month);
} }
month = parseInt(month); month = parseInt(month);
year = parseInt(year); year = parseInt(year);
var calDiv = document.getElementById(div_id); const calDiv = document.getElementById(div_id);
removeChildren(calDiv); removeChildren(calDiv);
var calTable = document.createElement('table'); const calTable = document.createElement('table');
quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month-1] + ' ' + year); quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year);
var tableBody = quickElement('tbody', calTable); const tableBody = quickElement('tbody', calTable);
// Draw days-of-week header // Draw days-of-week header
var tableRow = quickElement('tr', tableBody); let tableRow = quickElement('tr', tableBody);
for (var i = 0; i < 7; i++) { for (let i = 0; i < 7; i++) {
quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]); quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);
} }
var startingPos = new Date(year, month-1, 1 - CalendarNamespace.firstDayOfWeek).getDay(); const startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();
var days = CalendarNamespace.getDaysInMonth(month, year); const days = CalendarNamespace.getDaysInMonth(month, year);
let nonDayCell;
// Draw blanks before first of month // Draw blanks before first of month
tableRow = quickElement('tr', tableBody); tableRow = quickElement('tr', tableBody);
for (var i = 0; i < startingPos; i++) { for (let i = 0; i < startingPos; i++) {
var _cell = quickElement('td', tableRow, ' '); nonDayCell = quickElement('td', tableRow, ' ');
_cell.className = "nonday"; nonDayCell.className = "nonday";
}
function calendarMonth(y, m) {
function onClick(e) {
e.preventDefault();
callback(y, m, this.textContent);
}
return onClick;
} }
// Draw days of month // Draw days of month
var currentDay = 1; let currentDay = 1;
for (var i = startingPos; currentDay <= days; i++) { for (let i = startingPos; currentDay <= days; i++) {
if (i%7 == 0 && currentDay != 1) { if (i % 7 === 0 && currentDay !== 1) {
tableRow = quickElement('tr', tableBody); tableRow = quickElement('tr', tableBody);
} }
if ((currentDay==todayDay) && (month==todayMonth) && (year==todayYear)) { if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) {
todayClass='today'; todayClass = 'today';
} else { } else {
todayClass=''; todayClass = '';
} }
// use UTC function; see above for explanation. // use UTC function; see above for explanation.
if (isSelectedMonth && currentDay == selected.getUTCDate()) { if (isSelectedMonth && currentDay === selected.getUTCDate()) {
if (todayClass != '') todayClass += " "; if (todayClass !== '') {
todayClass += " ";
}
todayClass += "selected"; todayClass += "selected";
} }
var cell = quickElement('td', tableRow, '', 'class', todayClass); const cell = quickElement('td', tableRow, '', 'class', todayClass);
const link = quickElement('a', cell, currentDay, 'href', '#');
quickElement('a', cell, currentDay, 'href', 'javascript:void(' + callback + '('+year+','+month+','+currentDay+'));'); link.addEventListener('click', calendarMonth(year, month));
currentDay++; currentDay++;
} }
// Draw blanks after end of month (optional, but makes for valid code) // Draw blanks after end of month (optional, but makes for valid code)
while (tableRow.childNodes.length < 7) { while (tableRow.childNodes.length < 7) {
var _cell = quickElement('td', tableRow, ' '); nonDayCell = quickElement('td', tableRow, ' ');
_cell.className = "nonday"; nonDayCell.className = "nonday";
} }
calDiv.appendChild(calTable); calDiv.appendChild(calTable);
} }
} };
// Calendar -- A calendar instance // Calendar -- A calendar instance
function Calendar(div_id, callback, selected) { function Calendar(div_id, callback, selected) {
// div_id (string) is the ID of the element in which the calendar will // div_id (string) is the ID of the element in which the calendar will
// be displayed // be displayed
// callback (string) is the name of a JavaScript function that will be // callback (string) is the name of a JavaScript function that will be
@ -120,11 +169,11 @@ function Calendar(div_id, callback, selected) {
this.today = new Date(); this.today = new Date();
this.currentMonth = this.today.getMonth() + 1; this.currentMonth = this.today.getMonth() + 1;
this.currentYear = this.today.getFullYear(); this.currentYear = this.today.getFullYear();
if (typeof selected != 'undefined') { if (typeof selected !== 'undefined') {
this.selected = selected; this.selected = selected;
} }
} }
Calendar.prototype = { Calendar.prototype = {
drawCurrent: function() { drawCurrent: function() {
CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected); CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected);
}, },
@ -139,7 +188,7 @@ Calendar.prototype = {
this.drawCurrent(); this.drawCurrent();
}, },
drawPreviousMonth: function() { drawPreviousMonth: function() {
if (this.currentMonth == 1) { if (this.currentMonth === 1) {
this.currentMonth = 12; this.currentMonth = 12;
this.currentYear--; this.currentYear--;
} }
@ -149,7 +198,7 @@ Calendar.prototype = {
this.drawCurrent(); this.drawCurrent();
}, },
drawNextMonth: function() { drawNextMonth: function() {
if (this.currentMonth == 12) { if (this.currentMonth === 12) {
this.currentMonth = 1; this.currentMonth = 1;
this.currentYear++; this.currentYear++;
} }
@ -166,4 +215,7 @@ Calendar.prototype = {
this.currentYear++; this.currentYear++;
this.drawCurrent(); this.drawCurrent();
} }
};
window.Calendar = Calendar;
window.CalendarNamespace = CalendarNamespace;
} }

29
media/admin/js/cancel.js Normal file
View File

@ -0,0 +1,29 @@
'use strict';
{
// Call function fn when the DOM is loaded and ready. If it is already
// loaded, call the function now.
// http://youmightnotneedjquery.com/#ready
function ready(fn) {
if (document.readyState !== 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
ready(function() {
function handleClick(event) {
event.preventDefault();
const params = new URLSearchParams(window.location.search);
if (params.has('_popup')) {
window.close(); // Close the popup.
} else {
window.history.back(); // Otherwise, go back.
}
}
document.querySelectorAll('.cancel-link').forEach(function(el) {
el.addEventListener('click', handleClick);
});
});
}

View File

@ -0,0 +1,16 @@
'use strict';
{
const inputTags = ['BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'];
const modelName = document.getElementById('django-admin-form-add-constants').dataset.modelName;
if (modelName) {
const form = document.getElementById(modelName + '_form');
for (const element of form.elements) {
// HTMLElement.offsetParent returns null when the element is not
// rendered.
if (inputTags.includes(element.tagName) && !element.disabled && element.offsetParent) {
element.focus();
break;
}
}
}
}

View File

@ -1,24 +1,43 @@
(function($) { /*global gettext*/
$(document).ready(function() { 'use strict';
{
window.addEventListener('load', function() {
// Add anchor tag for Show/Hide link // Add anchor tag for Show/Hide link
$("fieldset.collapse").each(function(i, elem) { const fieldsets = document.querySelectorAll('fieldset.collapse');
for (const [i, elem] of fieldsets.entries()) {
// Don't hide if fields in this fieldset have errors // Don't hide if fields in this fieldset have errors
if ($(elem).find("div.errors").length == 0) { if (elem.querySelectorAll('div.errors, ul.errorlist').length === 0) {
$(elem).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser' + elem.classList.add('collapsed');
i +'" class="collapse-toggle" href="#">' + gettext("Show") + const h2 = elem.querySelector('h2');
'</a>)'); const link = document.createElement('a');
link.id = 'fieldsetcollapser' + i;
link.className = 'collapse-toggle';
link.href = '#';
link.textContent = gettext('Show');
h2.appendChild(document.createTextNode(' ('));
h2.appendChild(link);
h2.appendChild(document.createTextNode(')'));
} }
}); }
// Add toggle to anchor tag // Add toggle to hide/show anchor tag
$("fieldset.collapse a.collapse-toggle").click(function(ev) { const toggleFunc = function(ev) {
if ($(this).closest("fieldset").hasClass("collapsed")) { if (ev.target.matches('.collapse-toggle')) {
ev.preventDefault();
ev.stopPropagation();
const fieldset = ev.target.closest('fieldset');
if (fieldset.classList.contains('collapsed')) {
// Show // Show
$(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]); ev.target.textContent = gettext('Hide');
fieldset.classList.remove('collapsed');
} else { } else {
// Hide // Hide
$(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]); ev.target.textContent = gettext('Show');
fieldset.classList.add('collapsed');
} }
return false; }
};
document.querySelectorAll('fieldset.module').forEach(function(el) {
el.addEventListener('click', toggleFunc);
}); });
}); });
})(django.jQuery); }

View File

@ -1,2 +0,0 @@
(function(a){a(document).ready(function(){a("fieldset.collapse").each(function(c,b){a(b).find("div.errors").length==0&&a(b).addClass("collapsed").find("h2").first().append(' (<a id="fieldsetcollapser'+c+'" class="collapse-toggle" href="#">'+gettext("Show")+"</a>)")});a("fieldset.collapse a.collapse-toggle").click(function(){a(this).closest("fieldset").hasClass("collapsed")?a(this).text(gettext("Hide")).closest("fieldset").removeClass("collapsed").trigger("show.fieldset",[a(this).attr("id")]):a(this).text(gettext("Show")).closest("fieldset").addClass("collapsed").trigger("hide.fieldset",
[a(this).attr("id")]);return false})})})(django.jQuery);

View File

@ -1,50 +1,16 @@
// Core javascript helper functions // Core javascript helper functions
'use strict';
// basic browser identification & version
var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion);
var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]);
// Cross-browser event handlers.
function addEvent(obj, evType, fn) {
if (obj.addEventListener) {
obj.addEventListener(evType, fn, false);
return true;
} else if (obj.attachEvent) {
var r = obj.attachEvent("on" + evType, fn);
return r;
} else {
return false;
}
}
function removeEvent(obj, evType, fn) {
if (obj.removeEventListener) {
obj.removeEventListener(evType, fn, false);
return true;
} else if (obj.detachEvent) {
obj.detachEvent("on" + evType, fn);
return true;
} else {
return false;
}
}
function cancelEventPropagation(e) {
if (!e) e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
}
// quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]); // quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]);
function quickElement() { function quickElement() {
var obj = document.createElement(arguments[0]); const obj = document.createElement(arguments[0]);
if (arguments[2]) { if (arguments[2]) {
var textNode = document.createTextNode(arguments[2]); const textNode = document.createTextNode(arguments[2]);
obj.appendChild(textNode); obj.appendChild(textNode);
} }
var len = arguments.length; const len = arguments.length;
for (var i = 3; i < len; i += 2) { for (let i = 3; i < len; i += 2) {
obj.setAttribute(arguments[i], arguments[i+1]); obj.setAttribute(arguments[i], arguments[i + 1]);
} }
arguments[1].appendChild(obj); arguments[1].appendChild(obj);
return obj; return obj;
@ -52,46 +18,21 @@ function quickElement() {
// "a" is reference to an object // "a" is reference to an object
function removeChildren(a) { function removeChildren(a) {
while (a.hasChildNodes()) a.removeChild(a.lastChild); while (a.hasChildNodes()) {
} a.removeChild(a.lastChild);
// ----------------------------------------------------------------------------
// Cross-browser xmlhttp object
// from http://jibbering.com/2002/4/httprequest.html
// ----------------------------------------------------------------------------
var xmlhttp;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
} }
}
@else
xmlhttp = false;
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
xmlhttp = new XMLHttpRequest();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Find-position functions by PPK // Find-position functions by PPK
// See http://www.quirksmode.org/js/findpos.html // See https://www.quirksmode.org/js/findpos.html
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
function findPosX(obj) { function findPosX(obj) {
var curleft = 0; let curleft = 0;
if (obj.offsetParent) { if (obj.offsetParent) {
while (obj.offsetParent) { while (obj.offsetParent) {
curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft);
obj = obj.offsetParent;
}
// IE offsetParent does not include the top-level
if (isIE && obj.parentElement){
curleft += obj.offsetLeft - obj.scrollLeft; curleft += obj.offsetLeft - obj.scrollLeft;
obj = obj.offsetParent;
} }
} else if (obj.x) { } else if (obj.x) {
curleft += obj.x; curleft += obj.x;
@ -100,15 +41,11 @@ function findPosX(obj) {
} }
function findPosY(obj) { function findPosY(obj) {
var curtop = 0; let curtop = 0;
if (obj.offsetParent) { if (obj.offsetParent) {
while (obj.offsetParent) { while (obj.offsetParent) {
curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop);
obj = obj.offsetParent;
}
// IE offsetParent does not include the top-level
if (isIE && obj.parentElement){
curtop += obj.offsetTop - obj.scrollTop; curtop += obj.offsetTop - obj.scrollTop;
obj = obj.offsetParent;
} }
} else if (obj.y) { } else if (obj.y) {
curtop += obj.y; curtop += obj.y;
@ -119,51 +56,51 @@ function findPosY(obj) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Date object extensions // Date object extensions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
{
Date.prototype.getTwelveHours = function() {
return this.getHours() % 12 || 12;
};
Date.prototype.getTwelveHours = function() { Date.prototype.getTwoDigitMonth = function() {
hours = this.getHours(); return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1);
if (hours == 0) { };
return 12;
}
else {
return hours <= 12 ? hours : hours-12
}
}
Date.prototype.getTwoDigitMonth = function() { Date.prototype.getTwoDigitDate = function() {
return (this.getMonth() < 9) ? '0' + (this.getMonth()+1) : (this.getMonth()+1);
}
Date.prototype.getTwoDigitDate = function() {
return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate(); return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();
} };
Date.prototype.getTwoDigitTwelveHour = function() { Date.prototype.getTwoDigitTwelveHour = function() {
return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours(); return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours();
} };
Date.prototype.getTwoDigitHour = function() { Date.prototype.getTwoDigitHour = function() {
return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours(); return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();
} };
Date.prototype.getTwoDigitMinute = function() { Date.prototype.getTwoDigitMinute = function() {
return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes(); return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();
} };
Date.prototype.getTwoDigitSecond = function() { Date.prototype.getTwoDigitSecond = function() {
return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds(); return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();
} };
Date.prototype.getHourMinute = function() { Date.prototype.getAbbrevMonthName = function() {
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute(); return typeof window.CalendarNamespace === "undefined"
} ? this.getTwoDigitMonth()
: window.CalendarNamespace.monthsOfYearAbbrev[this.getMonth()];
};
Date.prototype.getHourMinuteSecond = function() { Date.prototype.getFullMonthName = function() {
return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond(); return typeof window.CalendarNamespace === "undefined"
} ? this.getTwoDigitMonth()
: window.CalendarNamespace.monthsOfYear[this.getMonth()];
};
Date.prototype.strftime = function(format) { Date.prototype.strftime = function(format) {
var fields = { const fields = {
b: this.getAbbrevMonthName(),
B: this.getFullMonthName(),
c: this.toString(), c: this.toString(),
d: this.getTwoDigitDate(), d: this.getTwoDigitDate(),
H: this.getTwoDigitHour(), H: this.getTwoDigitHour(),
@ -177,9 +114,9 @@ Date.prototype.strftime = function(format) {
X: this.toLocaleTimeString(), X: this.toLocaleTimeString(),
y: ('' + this.getFullYear()).substr(2, 4), y: ('' + this.getFullYear()).substr(2, 4),
Y: '' + this.getFullYear(), Y: '' + this.getFullYear(),
'%' : '%' '%': '%'
}; };
var result = '', i = 0; let result = '', i = 0;
while (i < format.length) { while (i < format.length) {
if (format.charAt(i) === '%') { if (format.charAt(i) === '%') {
result = result + fields[format.charAt(i + 1)]; result = result + fields[format.charAt(i + 1)];
@ -191,32 +128,43 @@ Date.prototype.strftime = function(format) {
++i; ++i;
} }
return result; return result;
} };
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// String object extensions // String object extensions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
String.prototype.pad_left = function(pad_length, pad_string) { String.prototype.strptime = function(format) {
var new_string = this; const split_format = format.split(/[.\-/]/);
for (var i = 0; new_string.length < pad_length; i++) { const date = this.split(/[.\-/]/);
new_string = pad_string + new_string; let i = 0;
let day, month, year;
while (i < split_format.length) {
switch (split_format[i]) {
case "%d":
day = date[i];
break;
case "%m":
month = date[i] - 1;
break;
case "%Y":
year = date[i];
break;
case "%y":
// A %y value in the range of [00, 68] is in the current
// century, while [69, 99] is in the previous century,
// according to the Open Group Specification.
if (parseInt(date[i], 10) >= 69) {
year = date[i];
} else {
year = (new Date(Date.UTC(date[i], 0))).getUTCFullYear() + 100;
} }
return new_string; break;
} }
++i;
// ---------------------------------------------------------------------------- }
// Get the computed style for and element // Create Date object from UTC since the parsed value is supposed to be
// ---------------------------------------------------------------------------- // in UTC, not local time. Also, the calendar uses UTC functions for
function getStyle(oElm, strCssRule){ // date extraction.
var strValue = ""; return new Date(Date.UTC(year, month, day));
if(document.defaultView && document.defaultView.getComputedStyle){ };
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
}
else if(oElm.currentStyle){
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
return strValue;
} }

View File

@ -1,3 +1,4 @@
/*global DateTimeShortcuts, SelectFilter*/
/** /**
* Django admin inlines * Django admin inlines
* *
@ -12,16 +13,18 @@
* and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip. * and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip.
* *
* Licensed under the New BSD License * Licensed under the New BSD License
* See: http://www.opensource.org/licenses/bsd-license.php * See: https://opensource.org/licenses/bsd-license.php
*/ */
(function($) { 'use strict';
{
const $ = django.jQuery;
$.fn.formset = function(opts) { $.fn.formset = function(opts) {
var options = $.extend({}, $.fn.formset.defaults, opts); const options = $.extend({}, $.fn.formset.defaults, opts);
var $this = $(this); const $this = $(this);
var $parent = $this.parent(); const $parent = $this.parent();
var updateElementIndex = function(el, prefix, ndx) { const updateElementIndex = function(el, prefix, ndx) {
var id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))"); const id_regex = new RegExp("(" + prefix + "-(\\d+|__prefix__))");
var replacement = prefix + "-" + ndx; const replacement = prefix + "-" + ndx;
if ($(el).prop("for")) { if ($(el).prop("for")) {
$(el).prop("for", $(el).prop("for").replace(id_regex, replacement)); $(el).prop("for", $(el).prop("for").replace(id_regex, replacement));
} }
@ -32,95 +35,154 @@
el.name = el.name.replace(id_regex, replacement); el.name = el.name.replace(id_regex, replacement);
} }
}; };
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off"); const totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS").prop("autocomplete", "off");
var nextIndex = parseInt(totalForms.val(), 10); let nextIndex = parseInt(totalForms.val(), 10);
var maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off"); const maxForms = $("#id_" + options.prefix + "-MAX_NUM_FORMS").prop("autocomplete", "off");
// only show the add button if we are allowed to add more items, const minForms = $("#id_" + options.prefix + "-MIN_NUM_FORMS").prop("autocomplete", "off");
// note that max_num = None translates to a blank string. let addButton;
var showAddButton = maxForms.val() === '' || (maxForms.val()-totalForms.val()) > 0;
$this.each(function(i) { /**
$(this).not("." + options.emptyCssClass).addClass(options.formCssClass); * The "Add another MyModel" button below the inline forms.
}); */
if ($this.length && showAddButton) { const addInlineAddButton = function() {
var addButton; if (addButton === null) {
if ($this.prop("tagName") == "TR") { if ($this.prop("tagName") === "TR") {
// If forms are laid out as table rows, insert the // If forms are laid out as table rows, insert the
// "add" button in a new table row: // "add" button in a new table row:
var numCols = this.eq(-1).children().length; const numCols = $this.eq(-1).children().length;
$parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="javascript:void(0)">' + options.addText + "</a></tr>"); $parent.append('<tr class="' + options.addCssClass + '"><td colspan="' + numCols + '"><a href="#">' + options.addText + "</a></tr>");
addButton = $parent.find("tr:last a"); addButton = $parent.find("tr:last a");
} else { } else {
// Otherwise, insert it immediately after the last form: // Otherwise, insert it immediately after the last form:
$this.filter(":last").after('<div class="' + options.addCssClass + '"><a href="javascript:void(0)">' + options.addText + "</a></div>"); $this.filter(":last").after('<div class="' + options.addCssClass + '"><a href="#">' + options.addText + "</a></div>");
addButton = $this.filter(":last").next().find("a"); addButton = $this.filter(":last").next().find("a");
} }
addButton.click(function(e) { }
addButton.on('click', addInlineClickHandler);
};
const addInlineClickHandler = function(e) {
e.preventDefault(); e.preventDefault();
var totalForms = $("#id_" + options.prefix + "-TOTAL_FORMS"); const template = $("#" + options.prefix + "-empty");
var template = $("#" + options.prefix + "-empty"); const row = template.clone(true);
var row = template.clone(true);
row.removeClass(options.emptyCssClass) row.removeClass(options.emptyCssClass)
.addClass(options.formCssClass) .addClass(options.formCssClass)
.attr("id", options.prefix + "-" + nextIndex); .attr("id", options.prefix + "-" + nextIndex);
if (row.is("tr")) { addInlineDeleteButton(row);
// If the forms are laid out in table rows, insert
// the remove button into the last table cell:
row.children(":last").append('<div><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></div>");
} else if (row.is("ul") || row.is("ol")) {
// If they're laid out as an ordered/unordered list,
// insert an <li> after the last list item:
row.append('<li><a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + "</a></li>");
} else {
// Otherwise, just insert the remove button as the
// last child element of the form's container:
row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText + "</a></span>");
}
row.find("*").each(function() { row.find("*").each(function() {
updateElementIndex(this, options.prefix, totalForms.val()); updateElementIndex(this, options.prefix, totalForms.val());
}); });
// Insert the new form when it has been fully edited // Insert the new form when it has been fully edited.
row.insertBefore($(template)); row.insertBefore($(template));
// Update number of total forms // Update number of total forms.
$(totalForms).val(parseInt(totalForms.val(), 10) + 1); $(totalForms).val(parseInt(totalForms.val(), 10) + 1);
nextIndex += 1; nextIndex += 1;
// Hide add button in case we've hit the max, except we want to add infinitely // Hide the add button if there's a limit and it's been reached.
if ((maxForms.val() !== '') && (maxForms.val()-totalForms.val()) <= 0) { if ((maxForms.val() !== '') && (maxForms.val() - totalForms.val()) <= 0) {
addButton.parent().hide(); addButton.parent().hide();
} }
// The delete button of each row triggers a bunch of other things // Show the remove buttons if there are more than min_num.
row.find("a." + options.deleteCssClass).click(function(e) { toggleDeleteButtonVisibility(row.closest('.inline-group'));
e.preventDefault();
// Remove the parent form containing this button: // Pass the new form to the post-add callback, if provided.
var row = $(this).parents("." + options.formCssClass);
row.remove();
nextIndex -= 1;
// If a post-delete callback was provided, call it with the deleted form:
if (options.removed) {
options.removed(row);
}
// Update the TOTAL_FORMS form count.
var forms = $("." + options.formCssClass);
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
// Show add button again once we drop below max
if ((maxForms.val() === '') || (maxForms.val()-forms.length) > 0) {
addButton.parent().show();
}
// Also, update names and ids for all remaining form controls
// so they remain in sequence:
for (var i=0, formCount=forms.length; i<formCount; i++)
{
updateElementIndex($(forms).get(i), options.prefix, i);
$(forms.get(i)).find("*").each(function() {
updateElementIndex(this, options.prefix, i);
});
}
});
// If a post-add callback was supplied, call it with the added form:
if (options.added) { if (options.added) {
options.added(row); options.added(row);
} }
}); $(document).trigger('formset:added', [row, options.prefix]);
};
/**
* The "X" button that is part of every unsaved inline.
* (When saved, it is replaced with a "Delete" checkbox.)
*/
const addInlineDeleteButton = function(row) {
if (row.is("tr")) {
// If the forms are laid out in table rows, insert
// the remove button into the last table cell:
row.children(":last").append('<div><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></div>");
} else if (row.is("ul") || row.is("ol")) {
// If they're laid out as an ordered/unordered list,
// insert an <li> after the last list item:
row.append('<li><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></li>");
} else {
// Otherwise, just insert the remove button as the
// last child element of the form's container:
row.children(":first").append('<span><a class="' + options.deleteCssClass + '" href="#">' + options.deleteText + "</a></span>");
} }
// Add delete handler for each row.
row.find("a." + options.deleteCssClass).on('click', inlineDeleteHandler.bind(this));
};
const inlineDeleteHandler = function(e1) {
e1.preventDefault();
const deleteButton = $(e1.target);
const row = deleteButton.closest('.' + options.formCssClass);
const inlineGroup = row.closest('.inline-group');
// Remove the parent form containing this button,
// and also remove the relevant row with non-field errors:
const prevRow = row.prev();
if (prevRow.length && prevRow.hasClass('row-form-errors')) {
prevRow.remove();
}
row.remove();
nextIndex -= 1;
// Pass the deleted form to the post-delete callback, if provided.
if (options.removed) {
options.removed(row);
}
$(document).trigger('formset:removed', [row, options.prefix]);
// Update the TOTAL_FORMS form count.
const forms = $("." + options.formCssClass);
$("#id_" + options.prefix + "-TOTAL_FORMS").val(forms.length);
// Show add button again once below maximum number.
if ((maxForms.val() === '') || (maxForms.val() - forms.length) > 0) {
addButton.parent().show();
}
// Hide the remove buttons if at min_num.
toggleDeleteButtonVisibility(inlineGroup);
// Also, update names and ids for all remaining form controls so
// they remain in sequence:
let i, formCount;
const updateElementCallback = function() {
updateElementIndex(this, options.prefix, i);
};
for (i = 0, formCount = forms.length; i < formCount; i++) {
updateElementIndex($(forms).get(i), options.prefix, i);
$(forms.get(i)).find("*").each(updateElementCallback);
}
};
const toggleDeleteButtonVisibility = function(inlineGroup) {
if ((minForms.val() !== '') && (minForms.val() - totalForms.val()) >= 0) {
inlineGroup.find('.inline-deletelink').hide();
} else {
inlineGroup.find('.inline-deletelink').show();
}
};
$this.each(function(i) {
$(this).not("." + options.emptyCssClass).addClass(options.formCssClass);
});
// Create the delete buttons for all unsaved inlines:
$this.filter('.' + options.formCssClass + ':not(.has_original):not(.' + options.emptyCssClass + ')').each(function() {
addInlineDeleteButton($(this));
});
toggleDeleteButtonVisibility($this);
// Create the add button, initially hidden.
addButton = options.addButton;
addInlineAddButton();
// Show the add button if allowed to add more items.
// Note that max_num = None translates to a blank string.
const showAddButton = maxForms.val() === '' || (maxForms.val() - totalForms.val()) > 0;
if ($this.length && showAddButton) {
addButton.parent().show();
} else {
addButton.parent().hide();
}
return this; return this;
}; };
@ -134,45 +196,41 @@
emptyCssClass: "empty-row", // CSS class applied to the empty row emptyCssClass: "empty-row", // CSS class applied to the empty row
formCssClass: "dynamic-form", // CSS class applied to each form in a formset formCssClass: "dynamic-form", // CSS class applied to each form in a formset
added: null, // Function called each time a new form is added added: null, // Function called each time a new form is added
removed: null // Function called each time a form is deleted removed: null, // Function called each time a form is deleted
addButton: null // Existing add button to use
}; };
// Tabular inlines --------------------------------------------------------- // Tabular inlines ---------------------------------------------------------
$.fn.tabularFormset = function(options) { $.fn.tabularFormset = function(selector, options) {
var $rows = $(this); const $rows = $(this);
var alternatingRows = function(row) {
$($rows.selector).not(".add-row").removeClass("row1 row2")
.filter(":even").addClass("row1").end()
.filter(":odd").addClass("row2");
};
var reinitDateTimeShortCuts = function() { const reinitDateTimeShortCuts = function() {
// Reinitialize the calendar and clock widgets by force // Reinitialize the calendar and clock widgets by force
if (typeof DateTimeShortcuts != "undefined") { if (typeof DateTimeShortcuts !== "undefined") {
$(".datetimeshortcuts").remove(); $(".datetimeshortcuts").remove();
DateTimeShortcuts.init(); DateTimeShortcuts.init();
} }
}; };
var updateSelectFilter = function() { const updateSelectFilter = function() {
// If any SelectFilter widgets are a part of the new form, // If any SelectFilter widgets are a part of the new form,
// instantiate a new SelectFilter instance for it. // instantiate a new SelectFilter instance for it.
if (typeof SelectFilter != 'undefined'){ if (typeof SelectFilter !== 'undefined') {
$('.selectfilter').each(function(index, value){ $('.selectfilter').each(function(index, value) {
var namearr = value.name.split('-'); const namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], false, options.adminStaticPrefix ); SelectFilter.init(value.id, namearr[namearr.length - 1], false);
}); });
$('.selectfilterstacked').each(function(index, value){ $('.selectfilterstacked').each(function(index, value) {
var namearr = value.name.split('-'); const namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], true, options.adminStaticPrefix ); SelectFilter.init(value.id, namearr[namearr.length - 1], true);
}); });
} }
}; };
var initPrepopulatedFields = function(row) { const initPrepopulatedFields = function(row) {
row.find('.prepopulated_field').each(function() { row.find('.prepopulated_field').each(function() {
var field = $(this), const field = $(this),
input = field.find('input, select, textarea'), input = field.find('input, select, textarea'),
dependency_list = input.data('dependency_list') || [], dependency_list = input.data('dependency_list') || [],
dependencies = []; dependencies = [];
@ -192,53 +250,52 @@
deleteCssClass: "inline-deletelink", deleteCssClass: "inline-deletelink",
deleteText: options.deleteText, deleteText: options.deleteText,
emptyCssClass: "empty-form", emptyCssClass: "empty-form",
removed: alternatingRows,
added: function(row) { added: function(row) {
initPrepopulatedFields(row); initPrepopulatedFields(row);
reinitDateTimeShortCuts(); reinitDateTimeShortCuts();
updateSelectFilter(); updateSelectFilter();
alternatingRows(row); },
} addButton: options.addButton
}); });
return $rows; return $rows;
}; };
// Stacked inlines --------------------------------------------------------- // Stacked inlines ---------------------------------------------------------
$.fn.stackedFormset = function(options) { $.fn.stackedFormset = function(selector, options) {
var $rows = $(this); const $rows = $(this);
var updateInlineLabel = function(row) { const updateInlineLabel = function(row) {
$($rows.selector).find(".inline_label").each(function(i) { $(selector).find(".inline_label").each(function(i) {
var count = i + 1; const count = i + 1;
$(this).html($(this).html().replace(/(#\d+)/g, "#" + count)); $(this).html($(this).html().replace(/(#\d+)/g, "#" + count));
}); });
}; };
var reinitDateTimeShortCuts = function() { const reinitDateTimeShortCuts = function() {
// Reinitialize the calendar and clock widgets by force, yuck. // Reinitialize the calendar and clock widgets by force, yuck.
if (typeof DateTimeShortcuts != "undefined") { if (typeof DateTimeShortcuts !== "undefined") {
$(".datetimeshortcuts").remove(); $(".datetimeshortcuts").remove();
DateTimeShortcuts.init(); DateTimeShortcuts.init();
} }
}; };
var updateSelectFilter = function() { const updateSelectFilter = function() {
// If any SelectFilter widgets were added, instantiate a new instance. // If any SelectFilter widgets were added, instantiate a new instance.
if (typeof SelectFilter != "undefined"){ if (typeof SelectFilter !== "undefined") {
$(".selectfilter").each(function(index, value){ $(".selectfilter").each(function(index, value) {
var namearr = value.name.split('-'); const namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], false, options.adminStaticPrefix); SelectFilter.init(value.id, namearr[namearr.length - 1], false);
}); });
$(".selectfilterstacked").each(function(index, value){ $(".selectfilterstacked").each(function(index, value) {
var namearr = value.name.split('-'); const namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], true, options.adminStaticPrefix); SelectFilter.init(value.id, namearr[namearr.length - 1], true);
}); });
} }
}; };
var initPrepopulatedFields = function(row) { const initPrepopulatedFields = function(row) {
row.find('.prepopulated_field').each(function() { row.find('.prepopulated_field').each(function() {
var field = $(this), const field = $(this),
input = field.find('input, select, textarea'), input = field.find('input, select, textarea'),
dependency_list = input.data('dependency_list') || [], dependency_list = input.data('dependency_list') || [],
dependencies = []; dependencies = [];
@ -259,14 +316,33 @@
deleteText: options.deleteText, deleteText: options.deleteText,
emptyCssClass: "empty-form", emptyCssClass: "empty-form",
removed: updateInlineLabel, removed: updateInlineLabel,
added: (function(row) { added: function(row) {
initPrepopulatedFields(row); initPrepopulatedFields(row);
reinitDateTimeShortCuts(); reinitDateTimeShortCuts();
updateSelectFilter(); updateSelectFilter();
updateInlineLabel(row); updateInlineLabel(row);
}) },
addButton: options.addButton
}); });
return $rows; return $rows;
}; };
})(django.jQuery);
$(document).ready(function() {
$(".js-inline-admin-formset").each(function() {
const data = $(this).data(),
inlineOptions = data.inlineFormset;
let selector;
switch(data.inlineType) {
case "stacked":
selector = inlineOptions.name + "-group .inline-related";
$(selector).stackedFormset(selector, inlineOptions.options);
break;
case "tabular":
selector = inlineOptions.name + "-group .tabular.inline-related tbody:first > tr.form-row";
$(selector).tabularFormset(selector, inlineOptions.options);
break;
}
});
});
}

View File

@ -1,9 +0,0 @@
(function(a){a.fn.formset=function(g){var b=a.extend({},a.fn.formset.defaults,g),i=a(this);g=i.parent();var m=function(e,k,h){var j=RegExp("("+k+"-(\\d+|__prefix__))");k=k+"-"+h;a(e).prop("for")&&a(e).prop("for",a(e).prop("for").replace(j,k));if(e.id)e.id=e.id.replace(j,k);if(e.name)e.name=e.name.replace(j,k)},l=a("#id_"+b.prefix+"-TOTAL_FORMS").prop("autocomplete","off"),d=parseInt(l.val(),10),c=a("#id_"+b.prefix+"-MAX_NUM_FORMS").prop("autocomplete","off");l=c.val()===""||c.val()-l.val()>0;i.each(function(){a(this).not("."+
b.emptyCssClass).addClass(b.formCssClass)});if(i.length&&l){var f;if(i.prop("tagName")=="TR"){i=this.eq(-1).children().length;g.append('<tr class="'+b.addCssClass+'"><td colspan="'+i+'"><a href="javascript:void(0)">'+b.addText+"</a></tr>");f=g.find("tr:last a")}else{i.filter(":last").after('<div class="'+b.addCssClass+'"><a href="javascript:void(0)">'+b.addText+"</a></div>");f=i.filter(":last").next().find("a")}f.click(function(e){e.preventDefault();var k=a("#id_"+b.prefix+"-TOTAL_FORMS");e=a("#"+
b.prefix+"-empty");var h=e.clone(true);h.removeClass(b.emptyCssClass).addClass(b.formCssClass).attr("id",b.prefix+"-"+d);if(h.is("tr"))h.children(":last").append('<div><a class="'+b.deleteCssClass+'" href="javascript:void(0)">'+b.deleteText+"</a></div>");else h.is("ul")||h.is("ol")?h.append('<li><a class="'+b.deleteCssClass+'" href="javascript:void(0)">'+b.deleteText+"</a></li>"):h.children(":first").append('<span><a class="'+b.deleteCssClass+'" href="javascript:void(0)">'+b.deleteText+"</a></span>");
h.find("*").each(function(){m(this,b.prefix,k.val())});h.insertBefore(a(e));a(k).val(parseInt(k.val(),10)+1);d+=1;c.val()!==""&&c.val()-k.val()<=0&&f.parent().hide();h.find("a."+b.deleteCssClass).click(function(j){j.preventDefault();j=a(this).parents("."+b.formCssClass);j.remove();d-=1;b.removed&&b.removed(j);j=a("."+b.formCssClass);a("#id_"+b.prefix+"-TOTAL_FORMS").val(j.length);if(c.val()===""||c.val()-j.length>0)f.parent().show();for(var n=0,o=j.length;n<o;n++){m(a(j).get(n),b.prefix,n);a(j.get(n)).find("*").each(function(){m(this,
b.prefix,n)})}});b.added&&b.added(h)})}return this};a.fn.formset.defaults={prefix:"form",addText:"add another",deleteText:"remove",addCssClass:"add-row",deleteCssClass:"delete-row",emptyCssClass:"empty-row",formCssClass:"dynamic-form",added:null,removed:null};a.fn.tabularFormset=function(g){var b=a(this),i=function(){a(b.selector).not(".add-row").removeClass("row1 row2").filter(":even").addClass("row1").end().filter(":odd").addClass("row2")},m=function(){if(typeof SelectFilter!="undefined"){a(".selectfilter").each(function(d,
c){var f=c.name.split("-");SelectFilter.init(c.id,f[f.length-1],false,g.adminStaticPrefix)});a(".selectfilterstacked").each(function(d,c){var f=c.name.split("-");SelectFilter.init(c.id,f[f.length-1],true,g.adminStaticPrefix)})}},l=function(d){d.find(".prepopulated_field").each(function(){var c=a(this).find("input, select, textarea"),f=c.data("dependency_list")||[],e=[];a.each(f,function(k,h){e.push("#"+d.find(".field-"+h).find("input, select, textarea").attr("id"))});e.length&&c.prepopulate(e,c.attr("maxlength"))})};
b.formset({prefix:g.prefix,addText:g.addText,formCssClass:"dynamic-"+g.prefix,deleteCssClass:"inline-deletelink",deleteText:g.deleteText,emptyCssClass:"empty-form",removed:i,added:function(d){l(d);if(typeof DateTimeShortcuts!="undefined"){a(".datetimeshortcuts").remove();DateTimeShortcuts.init()}m();i(d)}});return b};a.fn.stackedFormset=function(g){var b=a(this),i=function(){a(b.selector).find(".inline_label").each(function(d){d=d+1;a(this).html(a(this).html().replace(/(#\d+)/g,"#"+d))})},m=function(){if(typeof SelectFilter!=
"undefined"){a(".selectfilter").each(function(d,c){var f=c.name.split("-");SelectFilter.init(c.id,f[f.length-1],false,g.adminStaticPrefix)});a(".selectfilterstacked").each(function(d,c){var f=c.name.split("-");SelectFilter.init(c.id,f[f.length-1],true,g.adminStaticPrefix)})}},l=function(d){d.find(".prepopulated_field").each(function(){var c=a(this).find("input, select, textarea"),f=c.data("dependency_list")||[],e=[];a.each(f,function(k,h){e.push("#"+d.find(".form-row .field-"+h).find("input, select, textarea").attr("id"))});
e.length&&c.prepopulate(e,c.attr("maxlength"))})};b.formset({prefix:g.prefix,addText:g.addText,formCssClass:"dynamic-"+g.prefix,deleteCssClass:"inline-deletelink",deleteText:g.deleteText,emptyCssClass:"empty-form",removed:i,added:function(d){l(d);if(typeof DateTimeShortcuts!="undefined"){a(".datetimeshortcuts").remove();DateTimeShortcuts.init()}m();i(d)}});return b}})(django.jQuery);

View File

@ -1,7 +1,8 @@
/*global jQuery:false*/
'use strict';
/* Puts the included jQuery into our own namespace using noConflict and passing /* Puts the included jQuery into our own namespace using noConflict and passing
* it 'true'. This ensures that the included jQuery doesn't pollute the global * it 'true'. This ensures that the included jQuery doesn't pollute the global
* namespace (i.e. this preserves pre-existing values for both window.$ and * namespace (i.e. this preserves pre-existing values for both window.$ and
* window.jQuery). * window.jQuery).
*/ */
var django = django || {}; window.django = {jQuery: jQuery.noConflict(true)};
django.jQuery = jQuery.noConflict(true);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,39 @@
'use strict';
{
const toggleNavSidebar = document.getElementById('toggle-nav-sidebar');
if (toggleNavSidebar !== null) {
const navLinks = document.querySelectorAll('#nav-sidebar a');
function disableNavLinkTabbing() {
for (const navLink of navLinks) {
navLink.tabIndex = -1;
}
}
function enableNavLinkTabbing() {
for (const navLink of navLinks) {
navLink.tabIndex = 0;
}
}
const main = document.getElementById('main');
let navSidebarIsOpen = localStorage.getItem('django.admin.navSidebarIsOpen');
if (navSidebarIsOpen === null) {
navSidebarIsOpen = 'true';
}
if (navSidebarIsOpen === 'false') {
disableNavLinkTabbing();
}
main.classList.toggle('shifted', navSidebarIsOpen === 'true');
toggleNavSidebar.addEventListener('click', function() {
if (navSidebarIsOpen === 'true') {
navSidebarIsOpen = 'false';
disableNavLinkTabbing();
} else {
navSidebarIsOpen = 'true';
enableNavLinkTabbing();
}
localStorage.setItem('django.admin.navSidebarIsOpen', navSidebarIsOpen);
main.classList.toggle('shifted');
});
}
}

View File

@ -0,0 +1,16 @@
/*global opener */
'use strict';
{
const initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);
switch(initData.action) {
case 'change':
opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value);
break;
case 'delete':
opener.dismissDeleteRelatedObjectPopup(window, initData.value);
break;
default:
opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj);
break;
}
}

View File

@ -1,39 +1,43 @@
(function($) { /*global URLify*/
$.fn.prepopulate = function(dependencies, maxLength) { 'use strict';
{
const $ = django.jQuery;
$.fn.prepopulate = function(dependencies, maxLength, allowUnicode) {
/* /*
Depends on urlify.js Depends on urlify.js
Populates a selected field with the values of the dependent fields, Populates a selected field with the values of the dependent fields,
URLifies and shortens the string. URLifies and shortens the string.
dependencies - array of dependent fields ids dependencies - array of dependent fields ids
maxLength - maximum length of the URLify'd string maxLength - maximum length of the URLify'd string
allowUnicode - Unicode support of the URLify'd string
*/ */
return this.each(function() { return this.each(function() {
var prepopulatedField = $(this); const prepopulatedField = $(this);
var populate = function () { const populate = function() {
// Bail if the field's value has been changed by the user // Bail if the field's value has been changed by the user
if (prepopulatedField.data('_changed')) { if (prepopulatedField.data('_changed')) {
return; return;
} }
var values = []; const values = [];
$.each(dependencies, function(i, field) { $.each(dependencies, function(i, field) {
field = $(field); field = $(field);
if (field.val().length > 0) { if (field.val().length > 0) {
values.push(field.val()); values.push(field.val());
} }
}); });
prepopulatedField.val(URLify(values.join(' '), maxLength)); prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode));
}; };
prepopulatedField.data('_changed', false); prepopulatedField.data('_changed', false);
prepopulatedField.change(function() { prepopulatedField.on('change', function() {
prepopulatedField.data('_changed', true); prepopulatedField.data('_changed', true);
}); });
if (!prepopulatedField.val()) { if (!prepopulatedField.val()) {
$(dependencies.join(',')).keyup(populate).change(populate).focus(populate); $(dependencies.join(',')).on('keyup change focus', populate);
} }
}); });
}; };
})(django.jQuery); }

View File

@ -1 +0,0 @@
(function(b){b.fn.prepopulate=function(e,g){return this.each(function(){var a=b(this),d=function(){if(!a.data("_changed")){var f=[];b.each(e,function(h,c){c=b(c);c.val().length>0&&f.push(c.val())});a.val(URLify(f.join(" "),g))}};a.data("_changed",false);a.change(function(){a.data("_changed",true)});a.val()||b(e.join(",")).keyup(d).change(d).focus(d)})}})(django.jQuery);

View File

@ -0,0 +1,11 @@
'use strict';
{
const $ = django.jQuery;
const fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields');
$.each(fields, function(index, field) {
$('.empty-form .form-row .field-' + field.name + ', .empty-form.form-row .field-' + field.name).addClass('prepopulated_field');
$(field.id).data('dependency_list', field.dependency_list).prepopulate(
field.dependency_ids, field.maxLength, field.allowUnicode
);
});
}

View File

@ -1,94 +0,0 @@
var timeParsePatterns = [
// 9
{ re: /^\d{1,2}$/i,
handler: function(bits) {
if (bits[0].length == 1) {
return '0' + bits[0] + ':00';
} else {
return bits[0] + ':00';
}
}
},
// 13:00
{ re: /^\d{2}[:.]\d{2}$/i,
handler: function(bits) {
return bits[0].replace('.', ':');
}
},
// 9:00
{ re: /^\d[:.]\d{2}$/i,
handler: function(bits) {
return '0' + bits[0].replace('.', ':');
}
},
// 3 am / 3 a.m. / 3am
{ re: /^(\d+)\s*([ap])(?:.?m.?)?$/i,
handler: function(bits) {
var hour = parseInt(bits[1]);
if (hour == 12) {
hour = 0;
}
if (bits[2].toLowerCase() == 'p') {
if (hour == 12) {
hour = 0;
}
return (hour + 12) + ':00';
} else {
if (hour < 10) {
return '0' + hour + ':00';
} else {
return hour + ':00';
}
}
}
},
// 3.30 am / 3:15 a.m. / 3.00am
{ re: /^(\d+)[.:](\d{2})\s*([ap]).?m.?$/i,
handler: function(bits) {
var hour = parseInt(bits[1]);
var mins = parseInt(bits[2]);
if (mins < 10) {
mins = '0' + mins;
}
if (hour == 12) {
hour = 0;
}
if (bits[3].toLowerCase() == 'p') {
if (hour == 12) {
hour = 0;
}
return (hour + 12) + ':' + mins;
} else {
if (hour < 10) {
return '0' + hour + ':' + mins;
} else {
return hour + ':' + mins;
}
}
}
},
// noon
{ re: /^no/i,
handler: function(bits) {
return '12:00';
}
},
// midnight
{ re: /^mid/i,
handler: function(bits) {
return '00:00';
}
}
];
function parseTimeString(s) {
for (var i = 0; i < timeParsePatterns.length; i++) {
var re = timeParsePatterns[i].re;
var handler = timeParsePatterns[i].handler;
var bits = re.exec(s);
if (bits) {
return handler(bits);
}
}
return s;
}

View File

@ -1,147 +1,170 @@
var LATIN_MAP = { /*global XRegExp*/
'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE', 'Ç': 'use strict';
'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I', 'Î': 'I', {
'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O', 'Õ': 'O', 'Ö': const LATIN_MAP = {
'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U', 'Ü': 'U', 'Ű': 'U', 'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE',
'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à':'a', 'á':'a', 'â': 'a', 'ã': 'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I',
'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c', 'è': 'e', 'é': 'e', 'ê': 'e', 'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O',
'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U',
'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à': 'a',
'ú': 'u', 'û': 'u', 'ü': 'u', 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y' 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c',
}; 'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i',
var LATIN_SYMBOLS_MAP = { 'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o',
'©':'(c)' 'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',
}; 'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'
var GREEK_MAP = { };
'α':'a', 'β':'b', 'γ':'g', 'δ':'d', 'ε':'e', 'ζ':'z', 'η':'h', 'θ':'8', const LATIN_SYMBOLS_MAP = {
'ι':'i', 'κ':'k', 'λ':'l', 'μ':'m', 'ν':'n', 'ξ':'3', 'ο':'o', 'π':'p', '©': '(c)'
'ρ':'r', 'σ':'s', 'τ':'t', 'υ':'y', 'φ':'f', 'χ':'x', 'ψ':'ps', 'ω':'w', };
'ά':'a', 'έ':'e', 'ί':'i', 'ό':'o', 'ύ':'y', 'ή':'h', 'ώ':'w', 'ς':'s', const GREEK_MAP = {
'ϊ':'i', 'ΰ':'y', 'ϋ':'y', 'ΐ':'i', 'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h',
'Α':'A', 'Β':'B', 'Γ':'G', 'Δ':'D', 'Ε':'E', 'Ζ':'Z', 'Η':'H', 'Θ':'8', 'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3',
'Ι':'I', 'Κ':'K', 'Λ':'L', 'Μ':'M', 'Ν':'N', 'Ξ':'3', 'Ο':'O', 'Π':'P', 'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f',
'Ρ':'R', 'Σ':'S', 'Τ':'T', 'Υ':'Y', 'Φ':'F', 'Χ':'X', 'Ψ':'PS', 'Ω':'W', 'χ': 'x', 'ψ': 'ps', 'ω': 'w', 'ά': 'a', 'έ': 'e', 'ί': 'i', 'ό': 'o',
'Ά':'A', 'Έ':'E', 'Ί':'I', 'Ό':'O', 'Ύ':'Y', 'Ή':'H', 'Ώ':'W', 'Ϊ':'I', 'ύ': 'y', 'ή': 'h', 'ώ': 'w', 'ς': 's', 'ϊ': 'i', 'ΰ': 'y', 'ϋ': 'y',
'Ϋ':'Y' 'ΐ': 'i', 'Α': 'A', 'Β': 'B', 'Γ': 'G', 'Δ': 'D', 'Ε': 'E', 'Ζ': 'Z',
}; 'Η': 'H', 'Θ': '8', 'Ι': 'I', 'Κ': 'K', 'Λ': 'L', 'Μ': 'M', 'Ν': 'N',
var TURKISH_MAP = { 'Ξ': '3', 'Ο': 'O', 'Π': 'P', 'Ρ': 'R', 'Σ': 'S', 'Τ': 'T', 'Υ': 'Y',
'ş':'s', 'Ş':'S', 'ı':'i', 'İ':'I', 'ç':'c', 'Ç':'C', 'ü':'u', 'Ü':'U', 'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I',
'ö':'o', 'Ö':'O', 'ğ':'g', 'Ğ':'G' 'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y'
}; };
var RUSSIAN_MAP = { const TURKISH_MAP = {
'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'yo', 'ж':'zh', 'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u',
'з':'z', 'и':'i', 'й':'j', 'к':'k', 'л':'l', 'м':'m', 'н':'n', 'о':'o', 'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G'
'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u', 'ф':'f', 'х':'h', 'ц':'c', };
'ч':'ch', 'ш':'sh', 'щ':'sh', 'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu', const ROMANIAN_MAP = {
'я':'ya', 'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a',
'А':'A', 'Б':'B', 'В':'V', 'Г':'G', 'Д':'D', 'Е':'E', 'Ё':'Yo', 'Ж':'Zh', 'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A'
'З':'Z', 'И':'I', 'Й':'J', 'К':'K', 'Л':'L', 'М':'M', 'Н':'N', 'О':'O', };
'П':'P', 'Р':'R', 'С':'S', 'Т':'T', 'У':'U', 'Ф':'F', 'Х':'H', 'Ц':'C', const RUSSIAN_MAP = {
'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu', 'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo',
'Я':'Ya' 'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm',
}; 'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',
var UKRAINIAN_MAP = { 'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'sh', 'ъ': '',
'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g' 'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya',
}; 'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'Yo',
var CZECH_MAP = { 'Ж': 'Zh', 'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M',
'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u', 'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U',
'ž':'z', 'Č':'C', 'Ď':'D', 'Ě':'E', 'Ň': 'N', 'Ř':'R', 'Š':'S', 'Ť':'T', 'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '',
'Ů':'U', 'Ž':'Z' 'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya'
}; };
var POLISH_MAP = { const UKRAINIAN_MAP = {
'ą':'a', 'ć':'c', 'ę':'e', 'ł':'l', 'ń':'n', 'ó':'o', 'ś':'s', 'ź':'z', 'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i',
'ż':'z', 'Ą':'A', 'Ć':'C', 'Ę':'E', 'Ł':'L', 'Ń':'N', 'Ó':'O', 'Ś':'S', 'ї': 'yi', 'ґ': 'g'
'Ź':'Z', 'Ż':'Z' };
}; const CZECH_MAP = {
var LATVIAN_MAP = { 'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't',
'ā':'a', 'č':'c', 'ē':'e', 'ģ':'g', 'ī':'i', 'ķ':'k', 'ļ':'l', 'ņ':'n', 'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R',
'š':'s', 'ū':'u', 'ž':'z', 'Ā':'A', 'Č':'C', 'Ē':'E', 'Ģ':'G', 'Ī':'I', 'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z'
'Ķ':'K', 'Ļ':'L', 'Ņ':'N', 'Š':'S', 'Ū':'U', 'Ž':'Z' };
}; const SLOVAK_MAP = {
var ARABIC_MAP = { 'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l',
'أ':'a', 'ب':'b', 'ت':'t', 'ث': 'th', 'ج':'g', 'ح':'h', 'خ':'kh', 'د':'d', 'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't',
'ذ':'th', 'ر':'r', 'ز':'z', 'س':'s', 'ش':'sh', 'ص':'s', 'ض':'d', 'ط':'t', 'ú': 'u', 'ý': 'y', 'ž': 'z',
'ظ':'th', 'ع':'aa', 'غ':'gh', 'ف':'f', 'ق':'k', 'ك':'k', 'ل':'l', 'م':'m', 'Á': 'a', 'Ä': 'A', 'Č': 'C', 'Ď': 'D', 'É': 'E', 'Í': 'I', 'Ľ': 'L',
'ن':'n', 'ه':'h', 'و':'o', 'ي':'y' 'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T',
}; 'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z'
var LITHUANIAN_MAP = { };
'ą':'a', 'č':'c', 'ę':'e', 'ė':'e', 'į':'i', 'š':'s', 'ų':'u', 'ū':'u', const POLISH_MAP = {
'ž':'z', 'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's',
'Ą':'A', 'Č':'C', 'Ę':'E', 'Ė':'E', 'Į':'I', 'Š':'S', 'Ų':'U', 'Ū':'U', 'ź': 'z', 'ż': 'z',
'Ž':'Z' 'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S',
}; 'Ź': 'Z', 'Ż': 'Z'
var SERBIAN_MAP = { };
'ђ':'dj', 'ј':'j', 'љ':'lj', 'њ':'nj', 'ћ':'c', 'џ':'dz', 'đ':'dj', const LATVIAN_MAP = {
'Ђ':'Dj', 'Ј':'j', 'Љ':'Lj', 'Њ':'Nj', 'Ћ':'C', 'Џ':'Dz', 'Đ':'Dj' 'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l',
}; 'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z',
var AZERBAIJANI_MAP = { 'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L',
'ç':'c', 'ə':'e', 'ğ':'g', 'ı':'i', 'ö':'o', 'ş':'s', 'ü':'u', 'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z'
'Ç':'C', 'Ə':'E', 'Ğ':'G', 'İ':'I', 'Ö':'O', 'Ş':'S', 'Ü':'U' };
}; const ARABIC_MAP = {
'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd',
'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't',
'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm',
'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y'
};
const LITHUANIAN_MAP = {
'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u',
'ū': 'u', 'ž': 'z',
'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U',
'Ū': 'U', 'Ž': 'Z'
};
const SERBIAN_MAP = {
'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz',
'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C',
'Џ': 'Dz', 'Đ': 'Dj'
};
const AZERBAIJANI_MAP = {
'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u',
'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U'
};
const GEORGIAN_MAP = {
'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z',
'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o',
'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f',
'ქ': 'q', 'ღ': 'g', '': 'y', 'შ': 'sh', 'ჩ': 'ch', 'ც': 'c', 'ძ': 'dz',
'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h'
};
var ALL_DOWNCODE_MAPS = [ const ALL_DOWNCODE_MAPS = [
LATIN_MAP, LATIN_MAP,
LATIN_SYMBOLS_MAP, LATIN_SYMBOLS_MAP,
GREEK_MAP, GREEK_MAP,
TURKISH_MAP, TURKISH_MAP,
ROMANIAN_MAP,
RUSSIAN_MAP, RUSSIAN_MAP,
UKRAINIAN_MAP, UKRAINIAN_MAP,
CZECH_MAP, CZECH_MAP,
SLOVAK_MAP,
POLISH_MAP, POLISH_MAP,
LATVIAN_MAP, LATVIAN_MAP,
ARABIC_MAP, ARABIC_MAP,
LITHUANIAN_MAP, LITHUANIAN_MAP,
SERBIAN_MAP, SERBIAN_MAP,
AZERBAIJANI_MAP AZERBAIJANI_MAP,
]; GEORGIAN_MAP
];
var Downcoder = { const Downcoder = {
'Initialize': function() { 'Initialize': function() {
if (Downcoder.map) { // already made if (Downcoder.map) { // already made
return; return;
} }
Downcoder.map = {}; Downcoder.map = {};
Downcoder.chars = []; for (const lookup of ALL_DOWNCODE_MAPS) {
for (var i=0; i<ALL_DOWNCODE_MAPS.length; i++) { Object.assign(Downcoder.map, lookup);
var lookup = ALL_DOWNCODE_MAPS[i];
for (var c in lookup) {
if (lookup.hasOwnProperty(c)) {
Downcoder.map[c] = lookup[c];
} }
Downcoder.regex = new RegExp(Object.keys(Downcoder.map).join('|'), 'g');
} }
} };
for (var k in Downcoder.map) {
if (Downcoder.map.hasOwnProperty(k)) {
Downcoder.chars.push(k);
}
}
Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g');
}
};
function downcode(slug) { function downcode(slug) {
Downcoder.Initialize(); Downcoder.Initialize();
return slug.replace(Downcoder.regex, function(m) { return slug.replace(Downcoder.regex, function(m) {
return Downcoder.map[m]; return Downcoder.map[m];
}); });
} }
function URLify(s, num_chars) { function URLify(s, num_chars, allowUnicode) {
// changes, e.g., "Petty theft" to "petty_theft" // changes, e.g., "Petty theft" to "petty-theft"
// remove all these words from the string before urlifying if (!allowUnicode) {
s = downcode(s); s = downcode(s);
var removelist = [ }
"a", "an", "as", "at", "before", "but", "by", "for", "from", "is", s = s.toLowerCase(); // convert to lowercase
"in", "into", "like", "of", "off", "on", "onto", "per", "since",
"than", "the", "this", "that", "to", "up", "via", "with"
];
var r = new RegExp('\\b(' + removelist.join('|') + ')\\b', 'gi');
s = s.replace(r, '');
// if downcode doesn't hit, the char will be stripped here // if downcode doesn't hit, the char will be stripped here
if (allowUnicode) {
// Keep Unicode letters including both lowercase and uppercase
// characters, whitespace, and dash; remove other characters.
s = XRegExp.replace(s, XRegExp('[^-_\\p{L}\\p{N}\\s]', 'g'), '');
} else {
s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars s = s.replace(/[^-\w\s]/g, ''); // remove unneeded chars
}
s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces s = s.replace(/^\s+|\s+$/g, ''); // trim leading/trailing spaces
s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens s = s.replace(/[-\s]+/g, '-'); // convert spaces to hyphens
s = s.toLowerCase(); // convert to lowercase s = s.substring(0, num_chars); // trim to first num_chars chars
return s.substring(0, num_chars);// trim to first num_chars chars s = s.replace(/-+$/g, ''); // trim any trailing hyphens
return s;
}
window.URLify = URLify;
} }

View File

@ -1,4 +1,4 @@
Copyright (c) 2010 John Resig, http://jquery.com/ Copyright JS Foundation and other contributors, https://js.foundation/
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(n){return"الرجاء حذف "+(n.input.length-n.maximum)+" عناصر"},inputTooShort:function(n){return"الرجاء إضافة "+(n.minimum-n.input.length)+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(n){return"تستطيع إختيار "+n.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"},removeAllItems:function(){return"قم بإزالة كل العناصر"}}}),n.define,n.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/az",[],function(){return{inputTooLong:function(n){return n.input.length-n.maximum+" simvol silin"},inputTooShort:function(n){return n.minimum-n.input.length+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(n){return"Sadəcə "+n.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"},removeAllItems:function(){return"Bütün elementləri sil"}}}),n.define,n.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/bs",[],function(){function e(e,n,r,t){return e%10==1&&e%100!=11?n:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(n){var r=n.input.length-n.maximum,t="Obrišite "+r+" simbol";return t+=e(r,"","a","a")},inputTooShort:function(n){var r=n.minimum-n.input.length,t="Ukucajte bar još "+r+" simbol";return t+=e(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(n){var r="Možete izabrati samo "+n.maximum+" stavk";return r+=e(n.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),e.define,e.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/cs",[],function(){function e(e,n){switch(e){case 2:return n?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadejte o jeden znak méně.":t<=4?"Prosím, zadejte o "+e(t,!0)+" znaky méně.":"Prosím, zadejte o "+t+" znaků méně."},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadejte ještě jeden znak.":t<=4?"Prosím, zadejte ještě další "+e(t,!0)+" znaky.":"Prosím, zadejte ještě dalších "+t+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(n){var t=n.maximum;return 1==t?"Můžete zvolit jen jednu položku.":t<=4?"Můžete zvolit maximálně "+e(t,!1)+" položky.":"Můžete zvolit maximálně "+t+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),e.define,e.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Element";return 1!=e.maximum&&(n+="e"),n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Elemente"}}}),e.define,e.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/dsb",[],function(){var n=["znamuško","znamušce","znamuška","znamuškow"],e=["zapisk","zapiska","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Pšosym lašuj "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Pšosym zapódaj nanejmjenjej "+a+" "+u(a,n)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(n){return"Móžoš jano "+n.maximum+" "+u(n.maximum,e)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(n){var e=n.input.length-n.maximum,u="Παρακαλώ διαγράψτε "+e+" χαρακτήρ";return 1==e&&(u+="α"),1!=e&&(u+="ες"),u},inputTooShort:function(n){return"Παρακαλώ συμπληρώστε "+(n.minimum-n.input.length)+" ή περισσότερους χαρακτήρες"},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(n){var e="Μπορείτε να επιλέξετε μόνο "+n.maximum+" επιλογ";return 1==n.maximum&&(e+="ή"),1!=n.maximum&&(e+="ές"),e},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),n.define,n.require}();

View File

@ -0,0 +1,3 @@
/*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */
!function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}();

Some files were not shown because too many files have changed in this diff Show More