Skip to content

Commit

Permalink
feat: esl-select basic form element proxy and reset handler fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ala-n committed Feb 22, 2021
1 parent 505b617 commit 85f2f78
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 20 deletions.
67 changes: 64 additions & 3 deletions src/modules/esl-forms/esl-select-list/core/esl-select-wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {ESLBaseElement} from '../../../esl-base-element/core';
import {EventUtils} from '../../../esl-utils/dom/events';
import {bind} from '../../../esl-utils/decorators/bind';

export interface ESLSelectOption {
text: string;
Expand All @@ -13,7 +14,7 @@ export interface ESLSelectModel {
/** Get list of options */
options: ESLSelectOption[];
/** Get list of selected options */
selected: ESLSelectOption[];
selectedOptions: ESLSelectOption[];

/** Toggle option with passed value to the state */
setSelected(value: string, state: boolean): void;
Expand All @@ -40,8 +41,14 @@ export abstract class ESLSelectWrapper extends ESLBaseElement implements ESLSele
this._onTargetChange(select, prev);
}

protected connectedCallback() {
super.connectedCallback();
this.ownerDocument.addEventListener('reset', this._onReset);
}

protected disconnectedCallback() {
super.disconnectedCallback();
this.ownerDocument.removeEventListener('reset', this._onReset);
if (this._$select) this._$select.removeEventListener('change', this._onChange);
}

Expand All @@ -52,14 +59,20 @@ export abstract class ESLSelectWrapper extends ESLBaseElement implements ESLSele
if (newTarget) newTarget.addEventListener('change', this._onChange);
}

@bind
protected _onReset(event: Event) {
if (!event.target || event.target !== this.form) return;
setTimeout(() => this._onChange(event));
}

public get multiple() {
return this.$select && this.$select.multiple;
}

public get options(): ESLSelectOption[] {
return this.$select ? Array.from(this.$select.options) : [];
}
public get selected(): ESLSelectOption[] {
public get selectedOptions(): ESLSelectOption[] {
return this.options.filter((item) => item.selected);
}

Expand All @@ -86,7 +99,55 @@ export abstract class ESLSelectWrapper extends ESLBaseElement implements ESLSele

public setAllSelected(state: boolean) {
if (!this.multiple) return false;
this.options.forEach((item) => item.selected = state);
this.options.forEach((item: HTMLOptionElement) => item.selected = state);
EventUtils.dispatch(this.$select, 'change');
}

// Proxy select methods and values
public get value() {
return this.$select?.value;
}
public get values() {
return this.selectedOptions.map((item: HTMLOptionElement) => item.value);
}

public get form(): HTMLFormElement | null {
return this.$select?.form;
}

public get name(): string {
return this.$select?.name;
}
public set name(name: string) {
this.$select && (this.$select.name = name);
}

public get required(): boolean {
return this.$select?.required;
}
public set required(required: boolean) {
this.$select && (this.$select.required = required);
}

// Validation API values
public get validity(): ValidityState {
return this.$select?.validity;
}
public get validationMessage(): string {
return this.$select?.validationMessage;
}
public get willValidate(): boolean {
return this.$select?.willValidate;
}

// Validation API methods
public checkValidity(): boolean {
return this.$select?.checkValidity();
}
public reportValidity(): boolean {
return this.$select?.reportValidity();
}
public setCustomValidity(error: string): void {
this.$select?.setCustomValidity(error);
}
}
3 changes: 3 additions & 0 deletions src/modules/esl-forms/esl-select/core.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
@esl-select-disabled: #aaa;
@esl-select-empty-color: #aaa;

@esl-select-invlalid-border: 1px solid @esl-select-invlalid-border-color;
@esl-select-invlalid-border-color: #b22;

// ESL Select parts
@import "./core/esl-select.less";
@import "./core/esl-select-renderer.less";
Expand Down
6 changes: 3 additions & 3 deletions src/modules/esl-forms/esl-select/core/esl-select-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ export class ESLSelectRenderer extends ESLBaseElement {

protected bindEvents() {
if (!this.owner) return;
this.owner.addEventListener('change', this.render);
this.owner.addEventListener('esl:value:change', this.render);
this.$remove.addEventListener('click', this._onClear);
window.addEventListener('resize', this._deferredRerender);
}
protected unbindEvents() {
if (!this.owner) return;
this.owner.removeEventListener('change', this.render);
this.owner.removeEventListener('esl:value:change', this.render);
this.$remove.removeEventListener('click', this._onClear);
window.removeEventListener('resize', this._deferredRerender);
}
Expand All @@ -81,7 +81,7 @@ export class ESLSelectRenderer extends ESLBaseElement {
@bind
public render() {
if (!this.owner) return;
const selected = this.owner.selected;
const selected = this.owner.selectedOptions;
this.hasValue = !!selected.length;
this.toggleAttribute('multiple', this.owner.multiple);
this.applyItems(selected.map((item) => item.text));
Expand Down
11 changes: 9 additions & 2 deletions src/modules/esl-forms/esl-select/core/esl-select.less
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
& [esl-select-target] {
/* Visually hidden */
position: absolute;
width: 0;
height: 0;
border: 0;
padding: 0;
overflow: hidden;
opacity: 0;
clip: rect(0,0,0,0);

width: 100%;
height: 100%;
pointer-events: none;
}

&[disabled] {
Expand Down Expand Up @@ -51,4 +54,8 @@
&[open] .esl-select-renderer::after {
transform: rotateX(180deg);
}

[esl-select-target]:invalid + .esl-select-renderer {
border: @esl-select-invlalid-border;
}
}
18 changes: 10 additions & 8 deletions src/modules/esl-forms/esl-select/core/esl-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {bind} from '../../../esl-utils/decorators/bind';
import {CSSUtil} from '../../../esl-utils/dom/styles';
import {ENTER, SPACE} from '../../../esl-utils/dom/keys';
import {ExportNs} from '../../../esl-utils/environment/export-ns';
import {EventUtils} from '../../../esl-utils/dom/events';

import {ESLSelectRenderer} from './esl-select-renderer';
import {ESLSelectDropdown} from './esl-select-dropdown';
Expand Down Expand Up @@ -38,13 +39,13 @@ export class ESLSelect extends ESLSelectWrapper {
/** Pin to top marker */
@boolAttr() public pinSelected: boolean;

protected $text: ESLSelectRenderer;
protected $renderer: ESLSelectRenderer;
protected $dropdown: ESLSelectDropdown;

constructor() {
super();

this.$text = document.createElement(ESLSelectRenderer.is) as ESLSelectRenderer;
this.$renderer = document.createElement(ESLSelectRenderer.is) as ESLSelectRenderer;
this.$dropdown = document.createElement(ESLSelectDropdown.is) as ESLSelectDropdown;
}

Expand Down Expand Up @@ -89,15 +90,15 @@ export class ESLSelect extends ESLSelectWrapper {
}

protected _prepare() {
this.$text.className = this.$select.className;
this.$text.emptyText = this.emptyText;
this.$text.moreLabelFormat = this.moreLabelFormat;
this.$renderer.className = this.$select.className;
this.$renderer.emptyText = this.emptyText;
this.$renderer.moreLabelFormat = this.moreLabelFormat;
this.$dropdown.owner = this;
this.appendChild(this.$text);
this.appendChild(this.$renderer);
}
protected _dispose() {
this.$select.className = this.$text.className;
this.removeChild(this.$text);
this.$select.className = this.$renderer.className;
this.removeChild(this.$renderer);
}

protected _updateDisabled() {
Expand All @@ -110,6 +111,7 @@ export class ESLSelect extends ESLSelectWrapper {
@bind
protected _onChange(event: Event) {
this._onUpdate();
EventUtils.dispatch(this, 'esl:value:change', {detail: {event}});
}

@bind
Expand Down
5 changes: 3 additions & 2 deletions test-server/views/pages/esl-forms/esl-select-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@
</div>
<div class="form-group">
<button class="btn btn-primary">Submit</button>
<button type="reset" class="btn btn-danger">Reset</button>
</div>
</form>
</div>
Expand All @@ -313,13 +314,13 @@
function upd() {
var data = {};
var formData = new FormData(form);
formData.forEach(((value, key) => {
formData.forEach(function (value, key) {
if (key in data) {
data[key] = [].concat(data[key]).concat(value);
} else {
data[key] = value;
}
}));
});

info.textContent = JSON.stringify(data, null, 2);
info.removeAttribute('hidden');
Expand Down
5 changes: 3 additions & 2 deletions test-server/views/pages/esl-forms/esl-select.html
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@
</div>
<div class="form-group">
<button class="btn btn-primary">Submit</button>
<button type="reset" class="btn btn-danger">Reset</button>
</div>
</form>
</div>
Expand All @@ -654,13 +655,13 @@
function upd() {
var data = {};
var formData = new FormData(form);
formData.forEach(((value, key) => {
formData.forEach(function (value, key) {
if (key in data) {
data[key] = [].concat(data[key]).concat(value);
} else {
data[key] = value;
}
}));
});

info.textContent = JSON.stringify(data, null, 2);
info.removeAttribute('hidden');
Expand Down

0 comments on commit 85f2f78

Please sign in to comment.