Merge branch 'dedicated-radio' into 'master'

Dedicated radio button JS util

See merge request !159
This commit is contained in:
Felix Hamann 2019-03-03 21:30:27 +01:00
commit b225e6a5ba
15 changed files with 258 additions and 165 deletions

View File

@ -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

View File

@ -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

View File

@ -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 {

View 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);
}
}

View File

@ -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;

View 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;
}
}

View File

@ -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 {

View File

@ -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) {

View File

@ -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();

View File

@ -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() {},
};
}
})();

View File

@ -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);
});

View File

@ -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;

View File

@ -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}

View File

@ -0,0 +1,4 @@
.table-filter {
border-bottom: 1px solid #d3d3d3;
margin-bottom: 13px;
}

View File

@ -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>