gd-bs
Version:
Bootstrap JavaScript, TypeScript and Web Components library.
917 lines (846 loc) • 41.2 kB
text/typescript
import {
IFormControl, IFormControlProps, IFormControlPropsCheckbox,
IFormControlPropsDropdown, IFormControlPropsDropdownButton, IFormControlPropsDropdownCheckbox,
IFormControlPropsListBox, IFormControlPropsMultiCheckbox,
IFormControlPropsMultiDropdown, IFormControlPropsMultiDropdownButton, IFormControlPropsMultiDropdownCheckbox,
IFormControlPropsMultiListBox,
IFormControlPropsRange, IFormControlPropsTextField, IFormControlValidationResult
} from "./controlTypes";
import { ICheckboxGroup, ICheckboxGroupValue } from "../checkboxGroup/types";
import { IDropdown } from "../dropdown/types";
import { IInputGroup } from "../inputGroup/types";
import { IListBox } from "../listBox/types";
import { CheckboxGroup, CheckboxGroupTypes } from "../checkboxGroup";
import { CustomControls } from "./custom";
import { Dropdown } from "../dropdown";
import { InputGroup, InputGroupTypes } from "../inputGroup";
import { ListBox } from "../listBox";
import { FormControlTypes, FormValidationTypes } from ".";
import { IFormProps } from "./formTypes";
/**
* Form Control
*/
export class FormControl implements IFormControl {
private _cb: ICheckboxGroup = null;
private _custom: any = null;
private _el: HTMLElement = null;
private _elDesc: HTMLElement = null;
private _elLabel: HTMLLabelElement = null;
private _formProps: IFormProps = null;
private _ddl: IDropdown = null;
private _isRendered: boolean = false;
private _lb: IListBox = null;
private _props: IFormControlProps;
private _tb: IInputGroup = null;
// Constructor
constructor(props: IFormControlProps, formProps: IFormProps, elLabel?: HTMLLabelElement) {
// Save the parameters
this._formProps = formProps;
this._props = props;
this._elLabel = elLabel;
// See if there is a rendering event
if (typeof (this._props.onControlRendering) === "function") {
// Call the event and see if a promise is returned
let returnVal = this._props.onControlRendering(Object.assign({}, this._props));
if (returnVal && typeof (returnVal["then"]) === "function") {
// Wait for it to complete
returnVal["then"](newProps => {
// Update the properties
this._props = newProps || this._props;
// Create the control
this.create();
});
}
else {
// Create the control
this.create();
}
} else {
// Create the control
this.create();
}
}
// Configure the control
private configure() {
// Ensure a control was created
if (this.control) {
// Set the element
this._el = this.control.el as HTMLElement;
// See if an error message exists
if (this._props.errorMessage) {
// Get the group
let elGroup = this._el.querySelector(".input-group") || this._el.querySelector(".form-check:last-child");
if (elGroup) {
// Add the error message
let elErrorMessage = document.createElement("div");
elErrorMessage.className = "invalid-feedback";
elErrorMessage.innerHTML = this._props.errorMessage;
elGroup.appendChild(elErrorMessage);
}
}
// See if an element was defined to render to
if (this._props.el) {
// Append the control to the element
this._props.el.appendChild(this._el);
}
// See if the label is set
if (this._elLabel && this._formProps.isFloating && this._el.id) {
// Set the attributes
this._elLabel.setAttribute("for", this._el.id);
}
}
}
// Creates the control
private create() {
// Parse the custom classes to add
let className = this._props.controlClassName || "";
// Set the value
let formValue = this._formProps.value ? this._formProps.value[this._props.name] : null;
let value = typeof (this._props.value) === "undefined" ? formValue : this._props.value;
// Render the control based on the type
switch (this._props.type) {
// Checkbox
case FormControlTypes.Checkbox:
let cbProps = this._props as IFormControlPropsCheckbox;
// Add the checkbox group
this._cb = CheckboxGroup({
className,
colSize: cbProps.colSize,
hideLabel: true,
isInline: cbProps.isInline,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
items: cbProps.items,
onChange: cbProps.onChange,
required: this._props.required,
title: this._props.title,
type: CheckboxGroupTypes.Checkbox,
value
});
break;
// Color Picker
case FormControlTypes.ColorPicker:
// Add the input
this._tb = InputGroup({
appendedDropdown: (this.props as IFormControlPropsTextField).appendedDropdown,
appendedLabel: (this.props as IFormControlPropsTextField).appendedLabel,
className,
id: this._props.id,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
onChange: (this._props as IFormControlPropsTextField).onChange,
placeholder: (this._props as IFormControlPropsTextField).placeholder,
prependedDropdown: (this.props as IFormControlPropsTextField).prependedDropdown,
prependedLabel: (this.props as IFormControlPropsTextField).prependedLabel,
required: this._props.required,
title: this._props.title,
type: InputGroupTypes.ColorPicker,
value
});
break;
// Datalist
case FormControlTypes.Datalist:
// Add the dropdown
this._ddl = Dropdown({
className,
formFl: true,
id: this._props.id,
isDatalist: true,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsDropdown).items,
onChange: (this._props as IFormControlPropsDropdown).onChange,
required: this._props.required,
title: this._props.title,
value
});
break;
// Dropdown
case FormControlTypes.Dropdown:
// Add the dropdown
this._ddl = Dropdown({
className,
formFl: true,
id: this._props.id,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsDropdown).items,
onChange: (this._props as IFormControlPropsDropdown).onChange,
onMenuRendering: (this._props as IFormControlPropsDropdown).onMenuRendering,
required: this._props.required,
title: this._props.title,
value
});
break;
// Dropdown
case FormControlTypes.DropdownButton:
// Add the dropdown
this._ddl = Dropdown({
className,
formFl: false,
id: this._props.id,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsDropdownButton).items,
label: (this.props as IFormControlPropsDropdownButton).placeholder,
onChange: (this._props as IFormControlPropsDropdownButton).onChange,
onMenuRendering: (this._props as IFormControlPropsDropdownButton).onMenuRendering,
placement: (this._props as IFormControlPropsDropdownButton).placement,
required: this._props.required,
title: this._props.title,
value
});
break;
// Dropdown
case FormControlTypes.DropdownCheckbox:
// Add the dropdown
this._ddl = Dropdown({
className,
formFl: false,
id: this._props.id,
isCheckbox: true,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsDropdownCheckbox).items,
label: (this.props as IFormControlPropsDropdownCheckbox).placeholder,
onChange: (this._props as IFormControlPropsDropdownCheckbox).onChange,
onMenuRendering: (this._props as IFormControlPropsDropdownCheckbox).onMenuRendering,
placement: (this._props as IFormControlPropsDropdownCheckbox).placement,
required: this._props.required,
title: this._props.title,
value
});
break;
// Email
case FormControlTypes.Email:
// Add the input
this._tb = InputGroup({
appendedDropdown: (this.props as IFormControlPropsTextField).appendedDropdown,
appendedLabel: (this.props as IFormControlPropsTextField).appendedLabel,
className,
id: this._props.id,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
onChange: (this._props as IFormControlPropsTextField).onChange,
placeholder: (this._props as IFormControlPropsTextField).placeholder,
prependedDropdown: (this.props as IFormControlPropsTextField).prependedDropdown,
prependedLabel: (this.props as IFormControlPropsTextField).prependedLabel,
required: this._props.required,
title: this._props.title,
type: InputGroupTypes.Email,
value
});
break;
// File
case FormControlTypes.File:
// Add the input
this._tb = InputGroup({
appendedDropdown: (this.props as IFormControlPropsTextField).appendedDropdown,
appendedLabel: (this.props as IFormControlPropsTextField).appendedLabel,
className,
id: this._props.id,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
onChange: (this._props as IFormControlPropsTextField).onChange,
placeholder: (this._props as IFormControlPropsTextField).placeholder,
prependedDropdown: (this.props as IFormControlPropsTextField).prependedDropdown,
prependedLabel: (this.props as IFormControlPropsTextField).prependedLabel,
required: this._props.required,
title: this._props.title,
type: InputGroupTypes.File,
value
});
break;
// List Box
case FormControlTypes.ListBox:
// Add the list box
this._lb = ListBox({
id: this._props.name,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsListBox).items,
onChange: (this._props as IFormControlPropsListBox).onChange,
placeholder: (this._props as IFormControlPropsListBox).placeholder,
required: this._props.required,
value
});
break;
// Multi-Checkbox
case FormControlTypes.MultiCheckbox:
let cbMultiProps = this._props as IFormControlPropsMultiCheckbox;
// Add the checkbox group
this._cb = CheckboxGroup({
className,
colSize: cbMultiProps.colSize,
hideLabel: true,
isDisabled: this._props.isDisabled,
isInline: cbMultiProps.isInline,
isReadonly: this._props.isReadonly,
items: cbMultiProps.items,
multi: true,
onChange: cbMultiProps.onChange,
required: this._props.required,
title: this._props.title,
type: CheckboxGroupTypes.Checkbox,
value
});
break;
// Multi-Dropdown
case FormControlTypes.MultiDropdown:
// Add the dropdown
this._ddl = Dropdown({
className,
formFl: true,
id: this._props.id,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsMultiDropdown).items,
multi: true,
onChange: (this._props as IFormControlPropsMultiDropdown).onChange,
onMenuRendering: (this._props as IFormControlPropsMultiDropdown).onMenuRendering,
required: this._props.required,
title: this._props.title,
value
});
break;
// Multi-Dropdown Button
case FormControlTypes.MultiDropdownButton:
// Add the dropdown
this._ddl = Dropdown({
className,
formFl: false,
id: this._props.id,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsMultiDropdownButton).items,
label: (this._props as IFormControlPropsMultiDropdownButton).placeholder,
multi: true,
onChange: (this._props as IFormControlPropsMultiDropdownButton).onChange,
onMenuRendering: (this._props as IFormControlPropsMultiDropdownButton).onMenuRendering,
placement: (this._props as IFormControlPropsMultiDropdownButton).placement,
required: this._props.required,
title: this._props.title,
value
});
break;
// Multi-Dropdown Checkbox
case FormControlTypes.MultiDropdownCheckbox:
// Add the dropdown
this._ddl = Dropdown({
className,
formFl: false,
id: this._props.id,
isCheckbox: true,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsMultiDropdownCheckbox).items,
label: (this._props as IFormControlPropsMultiDropdownCheckbox).placeholder,
multi: true,
onChange: (this._props as IFormControlPropsMultiDropdownCheckbox).onChange,
onMenuRendering: (this._props as IFormControlPropsMultiDropdownCheckbox).onMenuRendering,
placement: (this._props as IFormControlPropsMultiDropdownCheckbox).placement,
required: this._props.required,
title: this._props.title,
value
});
break;
// Multi-List Box
case FormControlTypes.MultiListBox:
// Add the list box
this._lb = ListBox({
id: this._props.name,
isReadonly: this._props.isReadonly || this._props.isDisabled,
items: (this._props as IFormControlPropsMultiListBox).items,
multi: true,
onChange: (this._props as IFormControlPropsMultiListBox).onChange,
placeholder: (this._props as IFormControlPropsMultiListBox).placeholder,
required: this._props.required,
value
});
break;
// Multi-Radio
case FormControlTypes.MultiRadio:
// Add the checkbox group
this._cb = CheckboxGroup({
className,
colSize: (this._props as IFormControlPropsMultiCheckbox).colSize,
hideLabel: true,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
items: (this._props as IFormControlPropsMultiCheckbox).items,
multi: true,
onChange: (this._props as IFormControlPropsMultiCheckbox).onChange,
required: this._props.required,
title: this._props.title,
type: CheckboxGroupTypes.Radio,
value
});
break;
// Multi-Switch
case FormControlTypes.MultiSwitch:
// Add the checkbox group
this._cb = CheckboxGroup({
className,
colSize: (this._props as IFormControlPropsMultiCheckbox).colSize,
hideLabel: true,
isDisabled: this._props.isDisabled,
isInline: (this._props as IFormControlPropsCheckbox).isInline,
isReadonly: this._props.isReadonly,
items: (this._props as IFormControlPropsMultiCheckbox).items,
multi: true,
onChange: (this._props as IFormControlPropsMultiCheckbox).onChange,
required: this._props.required,
title: this._props.title,
type: CheckboxGroupTypes.Switch,
value
});
break;
// Password
case FormControlTypes.Password:
// Add the input
this._tb = InputGroup({
appendedDropdown: (this.props as IFormControlPropsTextField).appendedDropdown,
appendedLabel: (this.props as IFormControlPropsTextField).appendedLabel,
className,
id: this._props.id,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
onChange: (this._props as IFormControlPropsTextField).onChange,
placeholder: (this._props as IFormControlPropsTextField).placeholder,
prependedDropdown: (this.props as IFormControlPropsTextField).prependedDropdown,
prependedLabel: (this.props as IFormControlPropsTextField).prependedLabel,
required: this._props.required,
title: this._props.title,
type: InputGroupTypes.Password,
value
});
break;
// Radio
case FormControlTypes.Radio:
// Add the checkbox group
this._cb = CheckboxGroup({
className,
colSize: (this._props as IFormControlPropsCheckbox).colSize,
hideLabel: true,
isDisabled: this._props.isDisabled,
isInline: (this._props as IFormControlPropsCheckbox).isInline,
isReadonly: this._props.isReadonly,
items: (this._props as IFormControlPropsCheckbox).items,
onChange: (this._props as IFormControlPropsCheckbox).onChange,
required: this._props.required,
title: this._props.title,
type: CheckboxGroupTypes.Radio,
value
});
break;
// Range
case FormControlTypes.Range:
// Add the input
this._tb = InputGroup({
className,
id: this._props.id,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
min: (this._props as IFormControlPropsRange).min || 0,
max: (this._props as IFormControlPropsRange).max || 100,
onChange: (this._props as IFormControlPropsRange).onChange,
placeholder: (this._props as IFormControlPropsRange).placeholder,
required: this._props.required,
step: (this._props as IFormControlPropsRange).step,
title: this._props.title,
type: InputGroupTypes.Range,
value
});
break;
// Read Only
case FormControlTypes.Readonly:
// Add the input
this._tb = InputGroup({
appendedDropdown: (this.props as IFormControlPropsTextField).appendedDropdown,
appendedLabel: (this.props as IFormControlPropsTextField).appendedLabel,
className,
id: this._props.id,
isDisabled: this._props.isDisabled,
isReadonly: true,
onChange: (this._props as IFormControlPropsTextField).onChange,
placeholder: (this._props as IFormControlPropsTextField).placeholder,
prependedDropdown: (this.props as IFormControlPropsTextField).prependedDropdown,
prependedLabel: (this.props as IFormControlPropsTextField).prependedLabel,
required: this._props.required,
title: this._props.title,
type: InputGroupTypes.TextField,
value
});
break;
// Switch
case FormControlTypes.Switch:
// Add the checkbox group
this._cb = CheckboxGroup({
className,
colSize: (this._props as IFormControlPropsCheckbox).colSize,
hideLabel: true,
isDisabled: this._props.isDisabled,
isInline: (this._props as IFormControlPropsCheckbox).isInline,
isReadonly: this._props.isReadonly,
items: (this._props as IFormControlPropsCheckbox).items,
onChange: (this._props as IFormControlPropsCheckbox).onChange,
required: this._props.required,
title: this._props.title,
type: CheckboxGroupTypes.Switch,
value
});
break;
// Text Area
case FormControlTypes.TextArea:
// Add the input
this._tb = InputGroup({
appendedDropdown: (this.props as IFormControlPropsTextField).appendedDropdown,
appendedLabel: (this.props as IFormControlPropsTextField).appendedLabel,
className,
id: this._props.id,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
onChange: (this._props as IFormControlPropsTextField).onChange,
placeholder: (this._props as IFormControlPropsTextField).placeholder,
prependedDropdown: (this.props as IFormControlPropsTextField).prependedDropdown,
prependedLabel: (this.props as IFormControlPropsTextField).prependedLabel,
required: this._props.required,
rows: (this._props as IFormControlPropsTextField).rows,
title: this._props.title,
type: InputGroupTypes.TextArea,
value
});
break;
// Text Field
case FormControlTypes.TextField:
// Add the input
this._tb = InputGroup({
appendedDropdown: (this.props as IFormControlPropsTextField).appendedDropdown,
appendedLabel: (this.props as IFormControlPropsTextField).appendedLabel,
className,
id: this._props.id,
isDisabled: this._props.isDisabled,
isReadonly: this._props.isReadonly,
onChange: (this._props as IFormControlPropsTextField).onChange,
placeholder: (this._props as IFormControlPropsTextField).placeholder,
prependedDropdown: (this.props as IFormControlPropsTextField).prependedDropdown,
prependedLabel: (this.props as IFormControlPropsTextField).prependedLabel,
required: this._props.required,
title: this._props.title,
type: InputGroupTypes.TextField,
value
});
break;
// Custom Type
default:
// Create the default element
this._el = document.createElement("div");
this._el.className = className;
// See if there is a custom type
let custom = CustomControls.getByType(this._props.type);
if (custom && typeof (custom) === "function") {
// Set the default value
this._props.value = this._props.value || value;
// Execute the event
this._custom = custom(this._props, this._formProps);
}
break;
}
// See if a checkbox was rendered and an id was set
if (this.control && this._props.id) {
// Set the id
this.control.el.id = this._props.id;
}
// Configure the control
this.configure();
// Wait before executing the rendered event, otherwise the controls will be null
setTimeout(() => {
// Execute the events
this._props.onControlRendered ? this._props.onControlRendered(this) : null;
this._formProps.onControlRendered ? this._formProps.onControlRendered(this) : null;
// Set the flag
this._isRendered = true;
}, 10);
}
/**
* Public Interface
*/
get el() { return this._el; }
// The checkbox control
get checkbox() { return this._cb; }
// The dropdown control
get dropdown() { return this._ddl; }
// The textbox control
get control() { return this._cb || this._ddl || this._lb || this._tb || this._custom }
// The control label
get label() { return this._elLabel; }
// The listbox control
get listbox() { return this._lb; }
// The textbox control
get textbox() { return this._tb; }
// Method to get the form control value
getValue() {
// See if there is an override event
if (this._props.onGetValue) {
return this._props.onGetValue(this._props);
}
// See if this is a checkbox
if (this._cb) {
// See if this is a multi-checkbox
if (this._props.type == FormControlTypes.MultiCheckbox || this._props.type == FormControlTypes.MultiRadio || this._props.type == FormControlTypes.MultiSwitch) {
// Return the selected items
return this._cb.getValue().selectedItems;
}
// Return a boolean
return this._cb.getValue().selectedItems ? true : false;
}
// See if this is a dropdown
if (this._ddl) {
// Return the value
return this._ddl.getValue();
}
// See if this is a list box
if (this._lb) {
// Return the value
return this._lb.getValue();
}
// See if this is a textbox
if (this._tb) {
// See if this is a file
if (this._props.type == FormControlTypes.File) {
// Return the file information
return this._tb.getFileInfo();
}
// Return the value
return this._tb.getValue();
}
}
// Hides the control
hide() {
// Ensure an element exists
if (this._el) {
// See if this is a row
if (this._el.parentElement && this._el.parentElement.parentElement && this._el.parentElement.parentElement.classList.contains("row")) {
// See if there are other controls in this row
if (this._el.parentElement.parentElement.querySelectorAll(".col").length > 1) {
// Hide the column element
this._el.parentElement.classList.add("d-none");
} else {
// Hide the row element
this._el.parentElement.parentElement.classList.add("d-none");
}
}
// Else, ensure the parent element exists
else if (this._el.parentElement) {
// Hide the group element
this._el.parentElement.classList.add("d-none");
}
}
}
// Is loaded
isLoaded(): PromiseLike<void> {
// Return a promise
return new Promise(resolve => {
// Wait for the control to be created
let id = setInterval(() => {
// See if the control has been rendered
if (this.isRendered) {
// Stop the loop
clearInterval(id);
// Resolve the promise
resolve();
}
}, 10);
});
}
// Flag indicating the control is loaded
get isRendered(): boolean { return this._isRendered; }
// Validates the control
get isValid(): boolean {
let validation: IFormControlValidationResult = { isValid: true };
// Get the element and value
let elControl = (this._cb || this._ddl || this._lb || this._tb) ? (this._cb || this._ddl || this._lb || this._tb).el : this._el;
let value = this.getValue();
// See if this control is required
if (this._props.required) {
// See if a value doesn't exists
if (value == null) {
// Set the flag
validation.isValid = false;
}
// Else, see if the value is an array
else if (typeof (value.length) === "number") {
// Set the flag
validation.isValid = value.length > 0;
}
// Else, see if this is a single checkbox
else if (this._cb && typeof (value) === "boolean") {
// Set the flag
validation.isValid = value;
}
// Else, see if this is a dropdown and ensure it has a value
else if (this._ddl && !this._ddl.isMulti && value) {
// Set the flag to ensure a text/value exists
validation.isValid = value.text || value.value ? true : false;
}
}
// See if an event exists
if (this._props.onValidate) {
// Call the event
let returnValue = this._props.onValidate(this._props, { value });
if (typeof (returnValue) === "boolean") {
// Set the flag
validation.isValid = returnValue;
}
// Else, ensure it exists
else if (returnValue) {
// Set the validation
validation = { ...validation, ...returnValue };
}
}
// Update the validation
this.updateValidation(elControl, validation);
// Return the flag
return validation.isValid;
}
// The form control properties
get props(): IFormControlProps { return this._props; }
// Sets the description of the control
setDescription(value: string) {
// Get the element
let elDesc = this._el?.parentElement?.querySelector(".form-text");
if (elDesc) {
// Update the description
elDesc.innerHTML = value || "";
}
}
// Sets the form control label
setLabel(value: string) {
// Update the label
this._elLabel ? this._elLabel.innerHTML = value || "" : null;
}
// Sets the custom control
setControl(control) {
// Set the custom control
this._custom = control;
}
// Sets the form control value
setValue(value) {
// Set the value
this.control ? this.control.setValue(value) : null;
}
// Shows the control
show() {
// Ensure an element exists
if (this._el) {
// See if this is a row
if (this._el.parentElement && this._el.parentElement.parentElement && this._el.parentElement.parentElement.classList.contains("row")) {
// See if there are other controls in this row
if (this._el.parentElement.parentElement.querySelectorAll(".col").length > 1) {
// Show the column element
this._el.parentElement.classList.remove("d-none");
} else {
// Show the row element
this._el.parentElement.parentElement.classList.remove("d-none");
}
}
// Else, ensure the parent element exists
else if (this._el.parentElement) {
// Show the group element
this._el.parentElement.classList.remove("d-none");
}
}
}
// Updates the control validation
updateValidation(elControl: Element, validation: IFormControlValidationResult) {
// See if this is a checkbox/switch
let isCheckbox = elControl.querySelectorAll(".form-check").length > 0;
// Get the form controls
let elFormControls = isCheckbox ? [elControl] : elControl.querySelectorAll(".form-control");
elFormControls = elFormControls.length == 0 ? elControl.querySelectorAll(".form-select") : elFormControls;
// Parse the form controls
for (let i = 0; i < elFormControls.length; i++) {
// Ensure the control exists
let elFormControl = elFormControls[i] as HTMLElement;
if (!isCheckbox) {
// Clear the invalid/valid classes
elFormControl.classList.remove("is-invalid");
elFormControl.classList.remove("is-valid");
// Set the class
elFormControl.classList.add(validation.isValid ? "is-valid" : "is-invalid");
} else {
let validateControls = (controls: Array<HTMLElement>) => {
// Parse the controls
for (let i = 0; i < controls.length; i++) {
let control = controls[i];
// Clear the invalid/valid classes
control.classList.remove("is-invalid");
control.classList.remove("is-valid");
// Set the class
control.classList.add(validation.isValid ? "is-valid" : "is-invalid");
}
}
// Get the checkboxes
let elCheckboxes = elControl.querySelectorAll(".form-check-input");
if (elCheckboxes.length > 0) {
// Validate the controls
validateControls(elCheckboxes as any);
// Set the form control
elFormControl = elCheckboxes.length > 0 ? elCheckboxes[elCheckboxes.length - 1] as any : elFormControl;
}
// Get the custom controls
let elCustomControls = elControl.querySelectorAll(".custom-control-input");
if (elCustomControls.length > 0) {
// Validate the controls
validateControls(elCustomControls as any);
// Set the form control
elFormControl = elCustomControls.length > 0 ? elCustomControls[elCustomControls.length - 1] as any : elFormControl;
}
}
// Ensure the form control exists
if (elFormControl) {
let useTooltip = this._formProps.validationType == FormValidationTypes.Tooltip;
// Clear the old valid message if it exists
let validClassName = useTooltip ? "valid-tooltip" : "valid-feedback";
let elMessage = elFormControl.parentNode.querySelector("." + validClassName) as HTMLElement;
if (elMessage) {
// Clear the message
elMessage.innerHTML = "";
elMessage.style.display = "";
}
// Clear the old valid message if it exists
let invalidClassName = useTooltip ? "invalid-tooltip" : "invalid-feedback";
elMessage = elFormControl.parentNode.querySelector("." + invalidClassName) as HTMLElement;
if (elMessage) {
// Clear the message
elMessage.innerHTML = "";
elMessage.style.display = "";
}
// See if there is invalid feedback
if (validation.invalidMessage || this._props.errorMessage) {
// Get the element
let invalidClassName = useTooltip ? "invalid-tooltip" : "invalid-feedback";
elMessage = elFormControl.parentNode.querySelector("." + invalidClassName) as HTMLElement;
if (elMessage == null) {
// Create the element
elMessage = document.createElement("div");
elMessage.className = invalidClassName;
elFormControl.parentNode.appendChild(elMessage);
}
// Set the message
elMessage.innerHTML = validation.invalidMessage || this._props.errorMessage;
// Update the display
elMessage.style.display = validation.isValid ? "" : "block";
}
// See if there is valid feedback
if (validation.validMessage) {
// Get the element
let validClassName = useTooltip ? "valid-tooltip" : "valid-feedback";
elMessage = elFormControl.parentNode.querySelector("." + validClassName) as HTMLElement;
if (elMessage == null) {
// Create the element
elMessage = document.createElement("div");
elMessage.className = validClassName;
elFormControl.parentNode.appendChild(elMessage);
}
// Set the message
elMessage.innerHTML = validation.validMessage;
// Update the display
elMessage.style.display = validation.isValid ? "block" : "";
}
}
}
}
}