Merge branch 'form-errors' into 'master'
small ui/ux refinements See merge request !170
This commit is contained in:
commit
6fbb1888c5
@ -66,6 +66,14 @@
|
||||
input, textarea {
|
||||
border-color: var(--color-error) !important;
|
||||
}
|
||||
|
||||
.form-error {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.form-error {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
@ -8,6 +8,9 @@
|
||||
var AUTOSUBMIT_BUTTON_SELECTOR = '[type="submit"][data-autosubmit]';
|
||||
var AJAX_SUBMIT_FLAG = 'ajaxSubmit';
|
||||
|
||||
var FORM_GROUP_CLASS = 'form-group';
|
||||
var FORM_GROUP_WITH_ERRORS_CLASS = 'form-group--has-error';
|
||||
|
||||
function formValidator(inputs) {
|
||||
var done = true;
|
||||
inputs.forEach(function(inp) {
|
||||
@ -52,6 +55,12 @@
|
||||
// inputs
|
||||
utilInstances.push(window.utils.setup('inputs', form, options));
|
||||
|
||||
// form group errors
|
||||
var formGroups = Array.from(form.querySelectorAll('.' + FORM_GROUP_CLASS));
|
||||
formGroups.forEach(function(formGroup) {
|
||||
utilInstances.push(window.utils.setup('errorRemover', formGroup, options));
|
||||
});
|
||||
|
||||
form.classList.add(JS_INITIALIZED);
|
||||
|
||||
function destroyUtils() {
|
||||
@ -165,4 +174,29 @@
|
||||
destroy: function() {},
|
||||
};
|
||||
};
|
||||
|
||||
// listens for focus events and removes any errors on an input
|
||||
window.utils.errorRemover = function(formGroup, options) {
|
||||
|
||||
var inputElement = formGroup.querySelector('input:not([type="hidden"]), textarea, select');
|
||||
if (!inputElement) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inputElement.addEventListener('focus', focusListener);
|
||||
|
||||
function focusListener() {
|
||||
var hasError = formGroup.classList.contains(FORM_GROUP_WITH_ERRORS_CLASS);
|
||||
if (hasError) {
|
||||
formGroup.classList.remove(FORM_GROUP_WITH_ERRORS_CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
scope: formGroup,
|
||||
destroy: function() {
|
||||
inputElement.removeEventListener('focus', focusListener);
|
||||
},
|
||||
};
|
||||
};
|
||||
})();
|
||||
|
||||
@ -3,37 +3,37 @@
|
||||
|
||||
window.utils = window.utils || {};
|
||||
|
||||
var JS_INITIALIZED_CLASS = 'js-initialized';
|
||||
|
||||
function isNotInitialized(element) {
|
||||
return !element.classList.contains(JS_INITIALIZED_CLASS);
|
||||
}
|
||||
var JS_INITIALIZED_CLASS = 'js-inputs-initialized';
|
||||
|
||||
window.utils.inputs = function(wrapper, options) {
|
||||
|
||||
options = options || {};
|
||||
var utilInstances = [];
|
||||
|
||||
if (wrapper.classList.contains(JS_INITIALIZED_CLASS) && !options.force) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// checkboxes
|
||||
var checkboxes = Array.from(wrapper.querySelectorAll('input[type="checkbox"]'));
|
||||
checkboxes.filter(isNotInitialized).forEach(function(checkbox) {
|
||||
checkboxes.forEach(function(checkbox) {
|
||||
utilInstances.push(window.utils.setup('checkbox', checkbox));
|
||||
});
|
||||
|
||||
// radios
|
||||
var radios = Array.from(wrapper.querySelectorAll('input[type="radio"]'));
|
||||
radios.filter(isNotInitialized).forEach(function(radio) {
|
||||
radios.forEach(function(radio) {
|
||||
utilInstances.push(window.utils.setup('radio', radio));
|
||||
});
|
||||
|
||||
// file-uploads
|
||||
var fileUploads = Array.from(wrapper.querySelectorAll('input[type="file"]'));
|
||||
fileUploads.filter(isNotInitialized).forEach(function(input) {
|
||||
fileUploads.forEach(function(input) {
|
||||
utilInstances.push(window.utils.setup('fileUpload', input, options));
|
||||
});
|
||||
|
||||
// file-checkboxes
|
||||
var fileCheckboxes = Array.from(wrapper.querySelectorAll('.file-checkbox'));
|
||||
fileCheckboxes.filter(isNotInitialized).forEach(function(input) {
|
||||
fileCheckboxes.forEach(function(input) {
|
||||
utilInstances.push(window.utils.setup('fileCheckbox', input, options));
|
||||
});
|
||||
|
||||
@ -45,6 +45,8 @@
|
||||
});
|
||||
}
|
||||
|
||||
wrapper.classList.add(JS_INITIALIZED_CLASS);
|
||||
|
||||
return {
|
||||
scope: wrapper,
|
||||
destroy: destroyUtils,
|
||||
@ -74,7 +76,6 @@
|
||||
if (!i18n) {
|
||||
throw new Error('window.utils.fileUpload(input, options) needs to be passed i18n object via options');
|
||||
}
|
||||
input.classList.add(JS_INITIALIZED_CLASS);
|
||||
|
||||
function renderFileList(files) {
|
||||
fileList.innerHTML = '';
|
||||
@ -166,8 +167,6 @@
|
||||
cont = cont.parentNode;
|
||||
}
|
||||
addListener(cont);
|
||||
input.classList.add(JS_INITIALIZED_CLASS);
|
||||
cont.classList.add(JS_INITIALIZED_CLASS);
|
||||
}
|
||||
|
||||
setup();
|
||||
@ -190,7 +189,6 @@
|
||||
labelEl.setAttribute('for', input.id);
|
||||
wrapperEl.appendChild(input);
|
||||
wrapperEl.appendChild(labelEl);
|
||||
input.classList.add(JS_INITIALIZED_CLASS);
|
||||
|
||||
if (siblingEl) {
|
||||
parentEl.insertBefore(wrapperEl, siblingEl);
|
||||
@ -219,7 +217,6 @@
|
||||
wrapperEl.appendChild(siblingEl);
|
||||
}
|
||||
|
||||
input.classList.add(JS_INITIALIZED_CLASS);
|
||||
parentEl.appendChild(wrapperEl);
|
||||
}
|
||||
|
||||
@ -233,8 +230,6 @@
|
||||
window.utils.implicitSubmit = function(input, options) {
|
||||
var submit = options.submit;
|
||||
|
||||
console.log('implicitSubmit', input, submit);
|
||||
|
||||
if (!submit) {
|
||||
throw new Error('window.utils.implicitSubmit(input, options) needs to be passed a submit element via options');
|
||||
}
|
||||
@ -247,7 +242,7 @@
|
||||
};
|
||||
|
||||
input.addEventListener('keypress', doSubmit);
|
||||
|
||||
|
||||
return {
|
||||
scope: input,
|
||||
destroy: function() {
|
||||
|
||||
@ -37,6 +37,9 @@
|
||||
|
||||
if (isAlreadySetup) {
|
||||
console.warn('Trying to setup a JS utility that\'s already been set up', { utility: utilName, scope, options });
|
||||
if (!options.force) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
<div .container>
|
||||
<h1>Uni2work - Admin Demopage
|
||||
|
||||
<section>
|
||||
<p data-tooltip="Solch ein Tooltip kann mit dem <em>data-tooltip</em> Attribut erzeugt werden. Funktioniert aber nur in Block-Elementen die einen sinnvollen Wrapper haben.">
|
||||
Diese interne Seite dient lediglich zum Testen diverser Funktionalitäten
|
||||
und zur Demonstration der verschiedenen Hilfsfunktionen/Module.
|
||||
|
||||
Der Handler sollte jeweils aktuelle Beispiele für alle möglichen Funktionalitäten enthalten, so dass man immer weiß, wo man nachschlagen kann.
|
||||
|
||||
|
||||
<div .container.js-show-hide>
|
||||
<section>
|
||||
<h2 .js-show-hide__toggle>Teilweise funktionierende Abschnitte
|
||||
|
||||
<ul .js-show-hide__target>
|
||||
<ul>
|
||||
<li .list-group-item>
|
||||
<a href=@{UsersR}>Benutzer Verwaltung
|
||||
|
||||
@ -22,7 +19,7 @@
|
||||
<li .list-group-item>
|
||||
<a href=@{CourseNewR}>Kurse anlegen
|
||||
|
||||
<div .container>
|
||||
<section>
|
||||
<h2>Funktionen zum Testen
|
||||
|
||||
<ul>
|
||||
|
||||
@ -474,7 +474,7 @@ ul.list--inline {
|
||||
/* DEFINITION LIST */
|
||||
.deflist {
|
||||
display: grid;
|
||||
grid-template-columns: 100% ;
|
||||
grid-template-columns: 100%;
|
||||
}
|
||||
.deflist__dt,
|
||||
.deflist__dd {
|
||||
@ -488,6 +488,10 @@ ul.list--inline {
|
||||
.deflist__dd {
|
||||
font-size: 18px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
> p {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
@ -507,7 +511,6 @@ ul.list--inline {
|
||||
|
||||
.deflist__dt,
|
||||
.deflist__dd {
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
padding: 12px 0;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
@ -527,16 +530,14 @@ ul.list--inline {
|
||||
}
|
||||
|
||||
section {
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
|
||||
+ section {
|
||||
margin-top: 20px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
<section>
|
||||
UniWorX erfahrene Veranstalter finden
|
||||
hier die wichtigsten Neuerungen.
|
||||
|
||||
UniWorX erfahrene Veranstalter finden
|
||||
hier die wichtigsten Neuerungen.
|
||||
<section>
|
||||
<h2>Bekannte Probleme in Bearbeitung
|
||||
|
||||
@ -178,4 +179,4 @@ hier die wichtigsten Neuerungen.
|
||||
Planmäßige Wartungen werden ohne Ankündigung
|
||||
immer um 2:00h nachts durchgeführt.
|
||||
Es wird daher empfohlen, keine kritischen Abgabefristen
|
||||
um oder kurz nach dieser Zeit einzustellen.
|
||||
um oder kurz nach dieser Zeit einzustellen.
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
.table-filter {
|
||||
border-bottom: 1px solid #d3d3d3;
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
|
||||
@ -1,18 +1,19 @@
|
||||
$newline never
|
||||
$# Wrapper for all kinds of forms
|
||||
<form ##{formId} method=#{decodeUtf8 (renderStdMethod formMethod)} action=#{fromMaybe "" formActionUrl} enctype=#{formEncoding} *{formAttrs}>
|
||||
$# Distinguish different falvours of submit button layouts here:
|
||||
$case formSubmit
|
||||
$of FormNoSubmit
|
||||
^{formWidget}
|
||||
$of FormSubmit
|
||||
^{formWidget}
|
||||
^{submitButtonView}
|
||||
$of FormDualSubmit
|
||||
^{submitButtonView}
|
||||
^{formWidget}
|
||||
^{submitButtonView}
|
||||
$of FormAutoSubmit
|
||||
^{formWidget}
|
||||
<button type=submit data-autosubmit>
|
||||
^{btnLabel BtnSubmit}
|
||||
<section>
|
||||
<form ##{formId} method=#{decodeUtf8 (renderStdMethod formMethod)} action=#{fromMaybe "" formActionUrl} enctype=#{formEncoding} *{formAttrs}>
|
||||
$# Distinguish different falvours of submit button layouts here:
|
||||
$case formSubmit
|
||||
$of FormNoSubmit
|
||||
^{formWidget}
|
||||
$of FormSubmit
|
||||
^{formWidget}
|
||||
^{submitButtonView}
|
||||
$of FormDualSubmit
|
||||
^{submitButtonView}
|
||||
^{formWidget}
|
||||
^{submitButtonView}
|
||||
$of FormAutoSubmit
|
||||
^{formWidget}
|
||||
<button type=submit data-autosubmit>
|
||||
^{btnLabel BtnSubmit}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user