Merge branch 'dedicated-radio' into 'master'
Dedicated radio button JS util See merge request !159
This commit is contained in:
commit
b225e6a5ba
@ -87,6 +87,7 @@ CourseRegisterToTip: Anmeldung darf auch unbegrenzt offen bleiben
|
||||
CourseDeregisterUntilTip: Abmeldung darf auch unbegrenzt erlaubt bleiben
|
||||
CourseFilterSearch: Volltext-Suche
|
||||
CourseFilterRegistered: Registriert
|
||||
CourseFilterNone: Egal
|
||||
CourseDeleteQuestion: Wollen Sie den unten aufgeführten Kurs wirklich löschen?
|
||||
CourseDeleted: Kurs gelöscht
|
||||
CourseUserNote: Notiz
|
||||
|
||||
@ -1035,9 +1035,11 @@ siteLayout' headingOverride widget = do
|
||||
addStylesheet $ StaticR css_utils_asyncForm_scss
|
||||
addStylesheet $ StaticR css_utils_asyncTable_scss
|
||||
addStylesheet $ StaticR css_utils_asyncTableFilter_scss
|
||||
addStylesheet $ StaticR css_utils_checkbox_scss
|
||||
addStylesheet $ StaticR css_utils_form_scss
|
||||
addStylesheet $ StaticR css_utils_inputs_scss
|
||||
addStylesheet $ StaticR css_utils_modal_scss
|
||||
addStylesheet $ StaticR css_utils_radio_scss
|
||||
addStylesheet $ StaticR css_utils_showHide_scss
|
||||
addStylesheet $ StaticR css_utils_tabber_scss
|
||||
addStylesheet $ StaticR css_utils_tooltip_scss
|
||||
|
||||
@ -57,7 +57,7 @@
|
||||
padding-left: 10px;
|
||||
|
||||
&.js-show-hide__toggle::before {
|
||||
top: 25px;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,6 @@
|
||||
&::before {
|
||||
left: auto;
|
||||
right: 20px;
|
||||
top: 30px;
|
||||
color: var(--color-font);
|
||||
}
|
||||
}
|
||||
@ -314,6 +313,10 @@
|
||||
word-break: break-all;
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-lightwhite);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-dark);
|
||||
}
|
||||
}
|
||||
|
||||
.asidenav__link-shorthand {
|
||||
|
||||
74
static/css/utils/checkbox.scss
Normal file
74
static/css/utils/checkbox.scss
Normal file
@ -0,0 +1,74 @@
|
||||
|
||||
/* CUSTOM CHECKBOXES */
|
||||
/* Completely replaces legacy checkbox */
|
||||
.checkbox {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
[type="checkbox"] {
|
||||
position: fixed;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
background-color: #f3f3f3;
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05);
|
||||
border: 2px solid var(--color-primary);
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
label::before,
|
||||
label::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 12px;
|
||||
left: 8px;
|
||||
height: 2px;
|
||||
width: 8px;
|
||||
background-color: var(--color-font);
|
||||
}
|
||||
|
||||
:checked + label {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
[type="checkbox"]:focus + label {
|
||||
border-color: #3273dc;
|
||||
box-shadow: 0 0 0 0.125em rgba(50,115,220,.25);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
:checked + label::before,
|
||||
:checked + label::after {
|
||||
content: '';
|
||||
}
|
||||
|
||||
:checked + label::before {
|
||||
background-color: white;
|
||||
transform: rotate(45deg);
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
:checked + label::after {
|
||||
background-color: white;
|
||||
transform: rotate(-45deg);
|
||||
top: 11px;
|
||||
width: 13px;
|
||||
}
|
||||
|
||||
[disabled] + label {
|
||||
pointer-events: none;
|
||||
border: none;
|
||||
opacity: 0.6;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
}
|
||||
@ -183,130 +183,6 @@ option {
|
||||
}
|
||||
}
|
||||
|
||||
/* CUSTOM LEGACY CHECKBOX AND RADIO BOXES */
|
||||
input[type="checkbox"] {
|
||||
position: relative;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
input[type="checkbox"]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: var(--color-lighter);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 2px;
|
||||
}
|
||||
input[type="checkbox"]:checked::before {
|
||||
background-color: var(--color-light);
|
||||
}
|
||||
input[type="checkbox"]:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
/* CUSTOM CHECKBOXES AND RADIO BOXES */
|
||||
/* Completely replaces legacy checkbox and radiobox */
|
||||
.checkbox,
|
||||
.radio {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
position: fixed;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
background-color: #f3f3f3;
|
||||
box-shadow: inset 0 1px 2px 1px rgba(50, 50, 50, 0.05);
|
||||
border: 2px solid var(--color-primary);
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
label::before,
|
||||
label::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 12px;
|
||||
left: 8px;
|
||||
height: 2px;
|
||||
width: 8px;
|
||||
background-color: var(--color-font);
|
||||
}
|
||||
|
||||
:checked + label {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
[type="checkbox"]:focus + label,
|
||||
[type="radio"]:focus + label {
|
||||
border-color: #3273dc;
|
||||
box-shadow: 0 0 0 0.125em rgba(50,115,220,.25);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
:checked + label::before,
|
||||
:checked + label::after {
|
||||
content: '';
|
||||
}
|
||||
|
||||
:checked + label::before {
|
||||
background-color: white;
|
||||
transform: rotate(45deg);
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
:checked + label::after {
|
||||
background-color: white;
|
||||
transform: rotate(-45deg);
|
||||
top: 11px;
|
||||
width: 13px;
|
||||
}
|
||||
|
||||
[disabled] + label {
|
||||
pointer-events: none;
|
||||
border: none;
|
||||
opacity: 0.6;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.radio::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
right: 2px;
|
||||
bottom: 2px;
|
||||
border-radius: 4px;
|
||||
border: 2px solid white;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/* CUSTOM FILE INPUT */
|
||||
.file-input__label {
|
||||
cursor: pointer;
|
||||
|
||||
76
static/css/utils/radio.scss
Normal file
76
static/css/utils/radio.scss
Normal file
@ -0,0 +1,76 @@
|
||||
/* CUSTOM RADIO BOXES */
|
||||
/* Completely replaces native radiobox */
|
||||
|
||||
.radio-group {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.radio-group__option {
|
||||
min-width: 30px;
|
||||
}
|
||||
|
||||
.radio {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
[type="radio"] {
|
||||
position: fixed;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
height: 34px;
|
||||
min-width: 42px;
|
||||
line-height: 34px;
|
||||
text-align: center;
|
||||
padding: 0 7px;
|
||||
background-color: #f3f3f3;
|
||||
box-shadow: inset 2px 1px 2px 1px rgba(50, 50, 50, 0.05);
|
||||
color: var(--color-font);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:checked + label {
|
||||
background-color: #818181;
|
||||
color: var(--color-lightwhite);
|
||||
box-shadow: inset -2px -1px 2px 1px rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
:focus + label {
|
||||
border-color: #3273dc;
|
||||
box-shadow: 0 0 0.125em 0 rgba(50,115,220,0.8);
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
[disabled] + label {
|
||||
pointer-events: none;
|
||||
border: none;
|
||||
opacity: 0.6;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.radio:first-child {
|
||||
label {
|
||||
border-top-left-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.radio:last-child {
|
||||
label {
|
||||
border-top-right-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.radio + .radio {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
@ -1,22 +1,30 @@
|
||||
$show-hide-toggle-size: 6px;
|
||||
|
||||
.js-show-hide__toggle {
|
||||
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
padding: 3px 7px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-grey-lighter);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.js-show-hide__toggle::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
left: -28px;
|
||||
top: 6px;
|
||||
width: $show-hide-toggle-size;
|
||||
height: $show-hide-toggle-size;
|
||||
left: -15px;
|
||||
top: 12px - $show-hide-toggle-size / 2;
|
||||
color: var(--color-primary);
|
||||
border-right: 8px solid transparent;
|
||||
border-top: 8px solid transparent;
|
||||
border-left: 8px solid transparent;
|
||||
border-bottom: 8px solid currentColor;
|
||||
border-right: 2px solid currentColor;
|
||||
border-top: 2px solid currentColor;
|
||||
transition: transform .2s ease;
|
||||
transform-origin: 8px 12px;
|
||||
transform-origin: ($show-hide-toggle-size / 2);
|
||||
transform: translateY($show-hide-toggle-size) rotate(-45deg);
|
||||
}
|
||||
|
||||
.js-show-hide__target {
|
||||
@ -26,7 +34,7 @@
|
||||
.js-show-hide--collapsed {
|
||||
|
||||
.js-show-hide__toggle::before {
|
||||
transform: rotate(180deg);
|
||||
transform: translateY($show-hide-toggle-size / 3) rotate(135deg);
|
||||
}
|
||||
|
||||
.js-show-hide__target {
|
||||
|
||||
@ -51,6 +51,9 @@
|
||||
// check all
|
||||
utilInstances.push(window.utils.setup('checkAll', wrapper));
|
||||
|
||||
// showhide
|
||||
utilInstances.push(window.utils.setup('showHide', wrapper));
|
||||
|
||||
// filter
|
||||
var filterForm = wrapper.querySelector('.' + TABLE_FILTER_FORM_CLASS);
|
||||
if (filterForm) {
|
||||
|
||||
@ -82,7 +82,7 @@
|
||||
checkAllCheckbox.setAttribute('id', getCheckboxId());
|
||||
th.innerHTML = '';
|
||||
th.insertBefore(checkAllCheckbox, null);
|
||||
utilInstances.push(window.utils.setup('checkboxRadio', checkAllCheckbox));
|
||||
utilInstances.push(window.utils.setup('checkbox', checkAllCheckbox));
|
||||
|
||||
checkAllCheckbox.addEventListener('input', onCheckAllCheckboxInput);
|
||||
setupCheckboxListeners();
|
||||
|
||||
@ -13,10 +13,16 @@
|
||||
|
||||
var utilInstances = [];
|
||||
|
||||
// checkboxes / radios
|
||||
var checkboxes = Array.from(wrapper.querySelectorAll('input[type="checkbox"], input[type="radio"]'));
|
||||
// checkboxes
|
||||
var checkboxes = Array.from(wrapper.querySelectorAll('input[type="checkbox"]'));
|
||||
checkboxes.filter(isNotInitialized).forEach(function(checkbox) {
|
||||
utilInstances.push(window.utils.setup('checkboxRadio', checkbox));
|
||||
utilInstances.push(window.utils.setup('checkbox', checkbox));
|
||||
});
|
||||
|
||||
// radios
|
||||
var radios = Array.from(wrapper.querySelectorAll('input[type="radio"]'));
|
||||
radios.filter(isNotInitialized).forEach(function(radio) {
|
||||
utilInstances.push(window.utils.setup('radio', radio));
|
||||
});
|
||||
|
||||
// file-uploads
|
||||
@ -167,17 +173,15 @@
|
||||
};
|
||||
}
|
||||
|
||||
// turns native checkboxes and radio buttons into custom ones
|
||||
window.utils.checkboxRadio = function(input) {
|
||||
// turns native checkboxes into custom ones
|
||||
window.utils.checkbox = function(input) {
|
||||
|
||||
var type = input.getAttribute('type');
|
||||
|
||||
if (!input.parentElement.classList.contains(type)) {
|
||||
if (!input.parentElement.classList.contains('checkbox')) {
|
||||
var parentEl = input.parentElement;
|
||||
var siblingEl = input.nextElementSibling;
|
||||
var wrapperEl = document.createElement('div');
|
||||
var labelEl = document.createElement('label');
|
||||
wrapperEl.classList.add(type);
|
||||
wrapperEl.classList.add('checkbox');
|
||||
labelEl.setAttribute('for', input.id);
|
||||
wrapperEl.appendChild(input);
|
||||
wrapperEl.appendChild(labelEl);
|
||||
@ -195,4 +199,27 @@
|
||||
};
|
||||
}
|
||||
|
||||
// turns native radio buttons into custom ones
|
||||
window.utils.radio = function(input) {
|
||||
|
||||
if (!input.parentElement.classList.contains('radio')) {
|
||||
var parentEl = input.parentElement;
|
||||
var siblingEl = input.nextElementSibling;
|
||||
var wrapperEl = document.createElement('div');
|
||||
wrapperEl.classList.add('radio');
|
||||
wrapperEl.appendChild(input);
|
||||
|
||||
if (siblingEl && siblingEl.matches('label')) {
|
||||
wrapperEl.appendChild(siblingEl);
|
||||
}
|
||||
|
||||
input.classList.add(JS_INITIALIZED_CLASS);
|
||||
parentEl.appendChild(wrapperEl);
|
||||
}
|
||||
|
||||
return {
|
||||
destroy: function() {},
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
@ -3,7 +3,12 @@
|
||||
|
||||
window.utils = window.utils || {};
|
||||
|
||||
var JS_INITIALIZED_CLASS = 'js-show-hide-initialized';
|
||||
var LOCAL_STORAGE_SHOW_HIDE = 'SHOW_HIDE';
|
||||
var SHOW_HIDE_TOGGLE_CLASS = 'js-show-hide__toggle';
|
||||
var SHOW_HIDE_COLLAPSED_CLASS = 'js-show-hide--collapsed';
|
||||
var SHOW_HIDE_TARGET_CLASS = 'js-show-hide__target';
|
||||
|
||||
/**
|
||||
* div
|
||||
* div.js-show-hide__toggle
|
||||
@ -12,9 +17,12 @@
|
||||
* content here
|
||||
*/
|
||||
window.utils.showHide = function(wrapper, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
function addEventHandler(el) {
|
||||
el.addEventListener('click', function elClickListener() {
|
||||
var newState = el.parentElement.classList.toggle('js-show-hide--collapsed');
|
||||
var newState = el.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS);
|
||||
updateLSState(el.dataset.shIndex || null, newState);
|
||||
});
|
||||
}
|
||||
@ -23,32 +31,41 @@
|
||||
if (!index) {
|
||||
return false;
|
||||
}
|
||||
var lsData = fromLocalStorage();
|
||||
var lsData = getLocalStorageData();
|
||||
lsData[index] = state;
|
||||
window.localStorage.setItem(LOCAL_STORAGE_SHOW_HIDE, JSON.stringify(lsData));
|
||||
}
|
||||
|
||||
function collapsedStateInLocalStorage(index) {
|
||||
return fromLocalStorage()[index] || null;
|
||||
var lsState = getLocalStorageData();
|
||||
return lsState[index];
|
||||
}
|
||||
|
||||
function fromLocalStorage() {
|
||||
function getLocalStorageData() {
|
||||
return JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_SHOW_HIDE)) || {};
|
||||
}
|
||||
|
||||
Array
|
||||
.from(wrapper.querySelectorAll('.js-show-hide__toggle'))
|
||||
.from(wrapper.querySelectorAll('.' + SHOW_HIDE_TOGGLE_CLASS))
|
||||
.forEach(function(el) {
|
||||
if (el.classList.contains(JS_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var index = el.dataset.shIndex || null;
|
||||
el.parentElement.classList.toggle(
|
||||
'js-show-hide--collapsed',
|
||||
collapsedStateInLocalStorage(index) || el.dataset.collapsed === 'true'
|
||||
);
|
||||
var isCollapsed = el.dataset.collapsed === 'true';
|
||||
var lsCollapsedState = collapsedStateInLocalStorage(index);
|
||||
if (typeof lsCollapsedState !== 'undefined') {
|
||||
isCollapsed = lsCollapsedState;
|
||||
}
|
||||
el.parentElement.classList.toggle(SHOW_HIDE_COLLAPSED_CLASS, isCollapsed);
|
||||
|
||||
Array.from(el.parentElement.children).forEach(function(el) {
|
||||
if (!el.classList.contains('js-show-hide__toggle')) {
|
||||
el.classList.add('js-show-hide__target');
|
||||
if (!el.classList.contains('' + SHOW_HIDE_TOGGLE_CLASS)) {
|
||||
el.classList.add(SHOW_HIDE_TARGET_CLASS);
|
||||
}
|
||||
});
|
||||
el.classList.add(JS_INITIALIZED_CLASS);
|
||||
addEventHandler(el);
|
||||
});
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
--color-lightwhite: #fcfffa;
|
||||
--color-grey: #B1B5C0;
|
||||
--color-grey-light: #efefef;
|
||||
--color-grey-lighter: #f5f5f5;
|
||||
--color-grey-medium: #9A989E;
|
||||
--color-font: #34303a;
|
||||
--color-fontsec: #5b5861;
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
$newline never
|
||||
<section>
|
||||
<form .table-filter-form method=GET action=#{filterAction} enctype=#{filterEnctype}>
|
||||
^{filterWgdt}
|
||||
<button type=submit data-autosubmit>
|
||||
^{btnLabel BtnSubmit}
|
||||
<section>
|
||||
^{scrolltable}
|
||||
<div .table-filter>
|
||||
<h3 .js-show-hide__toggle data-sh-index=table-filter data-collapsed=true>Filter
|
||||
<div>
|
||||
<form .table-filter-form method=GET action=#{filterAction} enctype=#{filterEnctype}>
|
||||
^{filterWgdt}
|
||||
<button type=submit data-autosubmit>
|
||||
^{btnLabel BtnSubmit}
|
||||
^{scrolltable}
|
||||
|
||||
4
templates/table/layout-filter-default.lucius
Normal file
4
templates/table/layout-filter-default.lucius
Normal file
@ -0,0 +1,4 @@
|
||||
.table-filter {
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
@ -3,7 +3,7 @@ $newline never
|
||||
$if not isReq
|
||||
<div .radio>
|
||||
<input id=#{theId}-none *{attrs} type=radio name=#{name} value=none checked>
|
||||
<label for=#{theId}-none>_{MsgSelectNone}
|
||||
<label for=#{theId}-none>_{MsgCourseFilterNone}
|
||||
|
||||
<div .radio>
|
||||
<input id=#{theId}-yes *{attrs} type=radio name=#{name} value=yes :showVal id val:checked>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user