forked from extern/egroupware
Switch Et2Template to extend SlInput instead of LionInput
Also includes changes to how validation messages are handled to use our own stuff
This commit is contained in:
parent
e4f8c88e1e
commit
379ceeb3e5
@ -1,8 +1,9 @@
|
||||
import {et2_IInput, et2_IInputNode, et2_ISubmitListener} from "../et2_core_interfaces";
|
||||
import {Et2Widget} from "../Et2Widget/Et2Widget";
|
||||
import {css, dedupeMixin, LitElement, PropertyValues} from "@lion/core";
|
||||
import {ManualMessage} from "../Validators/ManualMessage";
|
||||
import {Required} from "../Validators/Required";
|
||||
import {ManualMessage} from "../Validators/ManualMessage";
|
||||
import {LionValidationFeedback} from "@lion/form-core";
|
||||
|
||||
/**
|
||||
* This mixin will allow any LitElement to become an Et2InputWidget
|
||||
@ -320,9 +321,100 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Massively simplified validate, as compared to what ValidatorMixin gives us, since ValidatorMixin extends
|
||||
* FormControlMixin which breaks SlSelect's render()
|
||||
*/
|
||||
async validate()
|
||||
{
|
||||
let validators = [...(this.validators || []), ...(this.defaultValidators || [])];
|
||||
let fieldName = this.id;
|
||||
let feedbackData = [];
|
||||
let resultPromises = [];
|
||||
this.querySelector("lion-validation-feedback")?.remove();
|
||||
const doValidate = async function(validator, value)
|
||||
{
|
||||
if(validator.config.fieldName)
|
||||
{
|
||||
fieldName = await validator.config.fieldName;
|
||||
}
|
||||
// @ts-ignore [allow-protected]
|
||||
return validator._getMessage({
|
||||
modelValue: value,
|
||||
formControl: this,
|
||||
fieldName,
|
||||
}).then((message) =>
|
||||
{
|
||||
feedbackData.push({message, type: validator.type, validator});
|
||||
});
|
||||
}.bind(this);
|
||||
const doCheck = async(value, validator) =>
|
||||
{
|
||||
const result = validator.execute(value, validator.param, {node: this});
|
||||
if(result === true)
|
||||
{
|
||||
resultPromises.push(doValidate(validator, value));
|
||||
}
|
||||
else if(result !== false && typeof result.then === 'function')
|
||||
{
|
||||
result.then(doValidate(validator, value));
|
||||
resultPromises.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
validators.map(async validator =>
|
||||
{
|
||||
let values = this.value;
|
||||
if(!Array.isArray(values))
|
||||
{
|
||||
values = [values];
|
||||
}
|
||||
if(!values.length)
|
||||
{
|
||||
values = [''];
|
||||
} // so required validation works
|
||||
|
||||
// Run manual validation messages just once, doesn't usually matter what the value is
|
||||
if(validator instanceof ManualMessage)
|
||||
{
|
||||
doCheck(values, validator);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Validate each individual item
|
||||
values.forEach((value) => doCheck(value, validator));
|
||||
}
|
||||
});
|
||||
await Promise.all(resultPromises);
|
||||
|
||||
if(feedbackData.length > 0)
|
||||
{
|
||||
let feedback = <LionValidationFeedback>document.createElement("lion-validation-feedback");
|
||||
feedback.feedbackData = feedbackData;
|
||||
feedback.slot = "help-text";
|
||||
this.append(feedback);
|
||||
// Not always visible?
|
||||
(<HTMLElement>this.shadowRoot.querySelector("#help-text")).style.display = "initial";
|
||||
}
|
||||
}
|
||||
|
||||
set_validation_error(err : string | false)
|
||||
{
|
||||
// ToDo - implement Lion validators properly, most likely by adding to this.validators
|
||||
/* Shoelace uses constraint validation API
|
||||
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#the-constraint-validation-api
|
||||
|
||||
if(err === false && this.setCustomValidity)
|
||||
{
|
||||
// Remove custom validity
|
||||
this.setCustomValidity('');
|
||||
return;
|
||||
}
|
||||
this.setCustomValidity(err);
|
||||
|
||||
// must call reportValidity() or nothing will happen
|
||||
this.reportValidity();
|
||||
|
||||
*/
|
||||
|
||||
if(err === false)
|
||||
{
|
||||
|
@ -18,7 +18,6 @@ import {Et2WithSearchMixin} from "./SearchMixin";
|
||||
import {Et2Tag} from "./Tag/Et2Tag";
|
||||
import {LionValidationFeedback} from "@lion/form-core";
|
||||
import {RowLimitedMixin} from "../Layout/RowLimitedMixin";
|
||||
import {ManualMessage} from "../Validators/ManualMessage";
|
||||
|
||||
// export Et2WidgetWithSelect which is used as type in other modules
|
||||
export class Et2WidgetWithSelect extends RowLimitedMixin(Et2widgetWithSelectMixin(SlSelect))
|
||||
@ -437,83 +436,6 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
|
||||
return [...this.querySelectorAll<SlMenuItem>(this.optionTag)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Massively simplified validate, as compared to what ValidatorMixin gives us, since ValidatorMixin extends
|
||||
* FormControlMixin which breaks SlSelect's render()
|
||||
*/
|
||||
async validate()
|
||||
{
|
||||
let validators = [...(this.validators || []), ...(this.defaultValidators || [])];
|
||||
let fieldName = this.id;
|
||||
let feedbackData = [];
|
||||
let resultPromises = [];
|
||||
this.querySelector("lion-validation-feedback")?.remove();
|
||||
const doValidate = async function(validator, value)
|
||||
{
|
||||
if(validator.config.fieldName)
|
||||
{
|
||||
fieldName = await validator.config.fieldName;
|
||||
}
|
||||
// @ts-ignore [allow-protected]
|
||||
return validator._getMessage({
|
||||
modelValue: value,
|
||||
formControl: this,
|
||||
fieldName,
|
||||
}).then((message) =>
|
||||
{
|
||||
feedbackData.push({message, type: validator.type, validator});
|
||||
});
|
||||
}.bind(this);
|
||||
const doCheck = async(value, validator) =>
|
||||
{
|
||||
const result = validator.execute(value, validator.param, {node: this});
|
||||
if(result === true)
|
||||
{
|
||||
resultPromises.push(doValidate(validator, value));
|
||||
}
|
||||
else if(result !== false && typeof result.then === 'function')
|
||||
{
|
||||
result.then(doValidate(validator, value));
|
||||
resultPromises.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
validators.map(async validator =>
|
||||
{
|
||||
let values = this.value;
|
||||
if(!Array.isArray(values))
|
||||
{
|
||||
values = [values];
|
||||
}
|
||||
if(!values.length)
|
||||
{
|
||||
values = [''];
|
||||
} // so required validation works
|
||||
|
||||
// Run manual validation messages just once, doesn't usually matter what the value is
|
||||
if(validator instanceof ManualMessage)
|
||||
{
|
||||
doCheck(values, validator);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Validate each individual item
|
||||
values.forEach((value) => doCheck(value, validator));
|
||||
}
|
||||
});
|
||||
await Promise.all(resultPromises);
|
||||
|
||||
if(feedbackData.length > 0)
|
||||
{
|
||||
let feedback = <LionValidationFeedback>document.createElement("lion-validation-feedback");
|
||||
feedback.feedbackData = feedbackData;
|
||||
feedback.slot = "help-text";
|
||||
this.append(feedback);
|
||||
// Not always visible?
|
||||
(<HTMLElement>this.shadowRoot.querySelector("#help-text")).style.display = "initial";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override parent to always call validate(), as our simple implementation needs to validate on clear as well.
|
||||
*
|
||||
|
@ -10,22 +10,30 @@
|
||||
|
||||
|
||||
import {css, PropertyValues} from "@lion/core";
|
||||
import {LionInput} from "@lion/input";
|
||||
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
||||
import {Regex} from "../Validators/Regex";
|
||||
import {SlInput} from "@shoelace-style/shoelace";
|
||||
import shoelace from "../Styles/shoelace";
|
||||
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
||||
|
||||
export class Et2Textbox extends Et2InputWidget(LionInput)
|
||||
export class Et2Textbox extends Et2InputWidget(SlInput)
|
||||
{
|
||||
|
||||
static get styles()
|
||||
{
|
||||
return [
|
||||
...shoelace,
|
||||
...super.styles,
|
||||
css`
|
||||
:host([type="hidden"]) {
|
||||
display: none;
|
||||
}
|
||||
`,
|
||||
:host([type="hidden"]) {
|
||||
display: none;
|
||||
}
|
||||
.input__control {
|
||||
border: none;
|
||||
}
|
||||
.input:hover:not(.input--disabled) .input__control {
|
||||
color: var(--input-text-color, inherit);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ registerIconLibrary('default', {
|
||||
|
||||
/**
|
||||
* Customise shoelace styles to match our stuff
|
||||
* External CSS will override this
|
||||
* External CSS & widget styles will override this
|
||||
*/
|
||||
export default [sl_css, css`
|
||||
:root,
|
||||
|
@ -2102,6 +2102,8 @@ div.message.floating, lion-validation-feedback[type] {
|
||||
position: absolute;
|
||||
margin: 0px;
|
||||
z-index: 1;
|
||||
top: 100%;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.message.validation_error, lion-validation-feedback[type="error"] {
|
||||
|
Loading…
Reference in New Issue
Block a user