forked from extern/egroupware
Hide server-side validation messages while widget has focus. If the value did not change, put messages back
This commit is contained in:
parent
ffb26cb2f1
commit
1163f9e31d
@ -56,6 +56,8 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
|
|||||||
protected defaultValidators : Validator[];
|
protected defaultValidators : Validator[];
|
||||||
// Promise used during validation
|
// Promise used during validation
|
||||||
protected validateComplete : Promise<undefined>;
|
protected validateComplete : Promise<undefined>;
|
||||||
|
// Hold on to any server messages while the user edits
|
||||||
|
private _messagesHeldWhileFocused : Validator[];
|
||||||
|
|
||||||
protected isSlComponent = false;
|
protected isSlComponent = false;
|
||||||
|
|
||||||
@ -66,16 +68,19 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
|
|||||||
...super.styles,
|
...super.styles,
|
||||||
css`
|
css`
|
||||||
/* Allow actually disabled inputs */
|
/* Allow actually disabled inputs */
|
||||||
|
|
||||||
:host([disabled]) {
|
:host([disabled]) {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Needed so required can show through */
|
/* Needed so required can show through */
|
||||||
|
|
||||||
::slotted(input), input {
|
::slotted(input), input {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used to allow auto-sizing on slotted inputs */
|
/* Used to allow auto-sizing on slotted inputs */
|
||||||
|
|
||||||
.input-group__container > .input-group__input ::slotted(.form-control) {
|
.input-group__container > .input-group__input ::slotted(.form-control) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@ -162,10 +167,14 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
|
|||||||
|
|
||||||
this.validators = [];
|
this.validators = [];
|
||||||
this.defaultValidators = [];
|
this.defaultValidators = [];
|
||||||
|
this._messagesHeldWhileFocused = [];
|
||||||
|
|
||||||
this.__readonly = false;
|
this.__readonly = false;
|
||||||
|
|
||||||
this.isSlComponent = typeof (<any>this).handleChange === 'function';
|
this.isSlComponent = typeof (<any>this).handleChange === 'function';
|
||||||
|
|
||||||
|
this.handleFocus = this.handleFocus.bind(this);
|
||||||
|
this.handleBlur = this.handleBlur.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback()
|
connectedCallback()
|
||||||
@ -177,12 +186,17 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
|
|||||||
{
|
{
|
||||||
this.addEventListener(this.isSlComponent ? 'sl-change' : 'change', this._oldChange);
|
this.addEventListener(this.isSlComponent ? 'sl-change' : 'change', this._oldChange);
|
||||||
});
|
});
|
||||||
|
this.addEventListener("focus", this.handleFocus);
|
||||||
|
this.addEventListener("blur", this.handleBlur);
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback()
|
disconnectedCallback()
|
||||||
{
|
{
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
this.removeEventListener(this.isSlComponent ? 'sl-change' : 'change', this._oldChange);
|
this.removeEventListener(this.isSlComponent ? 'sl-change' : 'change', this._oldChange);
|
||||||
|
|
||||||
|
this.removeEventListener("focus", this.handleFocus);
|
||||||
|
this.removeEventListener("blur", this.handleBlur);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -236,6 +250,41 @@ const Et2InputWidgetMixin = <T extends Constructor<LitElement>>(superclass : T)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When input receives focus, clear any validation errors.
|
||||||
|
*
|
||||||
|
* If the value is the same on blur, we'll put them back
|
||||||
|
* The ones from the server (ManualMessage) can interfere with submitting.
|
||||||
|
* @param {FocusEvent} _ev
|
||||||
|
*/
|
||||||
|
handleFocus(_ev : FocusEvent)
|
||||||
|
{
|
||||||
|
if(this._messagesHeldWhileFocused.length > 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._oldValue = this.value;
|
||||||
|
|
||||||
|
// Collect any ManualMessages
|
||||||
|
this._messagesHeldWhileFocused = (this.validators || []).filter((validator) => (validator instanceof ManualMessage));
|
||||||
|
|
||||||
|
this.set_validation_error(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the value is unchanged, put any held validation messages back
|
||||||
|
* @param {FocusEvent} _ev
|
||||||
|
*/
|
||||||
|
handleBlur(_ev : FocusEvent)
|
||||||
|
{
|
||||||
|
if(this._messagesHeldWhileFocused.length > 0 && this.value == this._oldValue)
|
||||||
|
{
|
||||||
|
this.validators = this.validators.concat(this._messagesHeldWhileFocused);
|
||||||
|
this._messagesHeldWhileFocused = [];
|
||||||
|
this.validate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set_value(new_value)
|
set_value(new_value)
|
||||||
{
|
{
|
||||||
this.value = new_value;
|
this.value = new_value;
|
||||||
|
@ -402,6 +402,19 @@ export class Et2Select extends Et2WithSearchMixin(Et2WidgetWithSelect)
|
|||||||
<sl-menu-item value="">${this.emptyLabel}</sl-menu-item>`;
|
<sl-menu-item value="">${this.emptyLabel}</sl-menu-item>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override Et2InputWidget blur handler to avoid doing our blur stuff when internal controls blur
|
||||||
|
*
|
||||||
|
* @param {FocusEvent} ev
|
||||||
|
*/
|
||||||
|
handleBlur(ev : FocusEvent)
|
||||||
|
{
|
||||||
|
if(ev.target == this)
|
||||||
|
{
|
||||||
|
super.handleBlur(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag used for rendering options
|
* Tag used for rendering options
|
||||||
* Used for finding & filtering options, they're created by the mixed-in class
|
* Used for finding & filtering options, they're created by the mixed-in class
|
||||||
|
Loading…
Reference in New Issue
Block a user