fonteva-design-guide
Version:
## Dev, Build and Test
425 lines (393 loc) • 13.9 kB
JavaScript
import { LightningElement, api, track } from 'lwc';
import Is_Required from '@salesforce/label/c.Pfm_Is_Required';
import { fireEvent, parseToObject } from 'c/utils';
import getFieldType from '@salesforce/apex/Framework.InputFieldController.getFieldType';
import { registerListener, unregisterAllListeners } from 'c/pubsub';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import BASE from '@salesforce/resourceUrl/PFM_Base';
import lookup from './lookup.html';
import pfmInput from './pfmInput.html';
import validateWcag from 'c/wcag';
// WCAG
// Labels are required on all inputs, either in the <legend> of a <fieldset>, or for the <label> related to a field.
export default class PfmInput extends LightningElement {
// text, checkbox, radio, picklist, multipicklist, date, time, lookup, number, address
set type(value) {
this._type = value;
this.isLightningInput = false; // setFieldType will set this to true when type is blank
this.setFieldType();
}
get type() {
return this._type;
}
_type;
format;
label;
group;
readOnly = false;
name;
tabIndex;
objectName;
get disable() {
return this.disable;
}
set disable(value) {
this.disabled = value;
}
// QA_name is the main name of the input field assigned by the system
get QA_name() {
return this.dataName;
}
set QA_name(value) {
this.dataName = value;
}
// extensions of the QA_name value to include the type of visual that is on the page
// e.g. someName-label or someName-input
QA_name_Label;
QA_name_Input;
QA_label;
fieldId;
field;
isValid;
required = false;
helpText;
otherAttributes = {};
labels;
backend;
customErrorMessage;
min;
max;
step = 1;
variant = 'standard';
align;
labelHidden;
// date attributes: need to clean
delimiter;
locale;
minYear;
maxYear;
maxReset; // if set and this.val > this.maxReset then force value to this.maxReset
minReset; // if set and this.val < this.minReset then force value to this.minReset
/**
* @deprecated
* Should be @track, but we can't remove @api currently; stupid SFDC
*/
get localValue() {
return this._localValue;
}
_localValue;
get options() {
return this.localOptions;
}
set options(val) {
this.localOptions = val;
}
localOptions = [];
isLightningInput = false;
isRichText = false;
isPicklist = false;
isRadio = false;
isCheckbox = false;
isMultiPicklist = false;
isTextArea = false;
isFileUpload = false;
isLookup = false;
isAddress = false;
isDate = false;
errorMessage;
disabled = false;
overrideValidation = false;
get hasLabel() {
if (this.label == null || this.label === '') {
return false;
}
return true;
}
_val;
set val(value) {
this._val = value;
if (value) {
this.updateValue(value[this.name], true);
}
}
get val() {
return this._val;
}
toggleFieldStatus(readOnly) {
this.disabled = readOnly;
}
handleDateChange(evt) {
this._localValue = evt.detail;
fireEvent(
this,
'valuechange',
{ field: this.name, value: this._localValue, group: this.group },
{ bubbles: true, composed: true }
);
}
connectedCallback() {
this.QA_name_Input = this.QA_name + '-input';
this.QA_name_Label = this.QA_name + '-label';
this.QA_label = this.QA_label || this.label;
this.setAttribute('aria-live', 'polite');
this.loadDependentStyles();
if (!this.backend) {
this.classList.add('pfm-input_portal');
}
this.errorMessage = Is_Required.replace('{0}', this.label);
registerListener('RefreshInputField', this.handleRefreshInputField, this);
// known issue, raises `[LWC warning]: If property _localValue decorated with @api`
this._localValue = this._val ? this._val[this.name] : undefined;
if (this.type == null && this.objectName != null && this.field != null) {
getFieldType({ sObjectName: this.objectName, fieldName: this.field })
.then(resultObj => {
if (resultObj.isAccessible) {
this.type = resultObj.fieldType;
this.format = resultObj.format;
let localLabel = resultObj.label;
if (this.objectName.toLowerCase() === 'contact') {
localLabel = localLabel.replace(' Code', '');
}
this.label = localLabel;
this.helpText = resultObj.helpText;
if (!this.required) {
this.required = resultObj.isRequired;
}
if (
!this.otherAttributes ||
(this.otherAttributes && !this.otherAttributes.parentControllingFieldKey)
) {
this.localOptions = resultObj.picklistOptions;
}
this.disable = !resultObj.isUpdateable;
if (!resultObj.isUpdateable) {
this.overrideValidation = true;
}
// known issue, raises `[LWC warning]: If property _localValue decorated with @api`
// this._localValue = this.val[this.name];
if (resultObj.defaultValue != null && this._localValue == null) {
this._localValue = resultObj.defaultValue;
}
this.setFieldType();
}
})
.catch(error => {
console.error(
'Error received: code ' +
error.errorCode +
', ' +
(error.body ? 'message ' + error.body.message : '')
);
});
} else {
this.localOptions = this.options;
this.setFieldType();
}
}
renderedCallback() {
let self = this;
const isValid = validateWcag(self, 'input');
console.debug('IS VALID:', self, isValid);
if (!this.hasLabel) {
// console.error('The label attribute is empty, this is an accessibility violation. Please add a relevant label to this field.', this, this.template.innerHTML);
}
if (this.backend && self.template.querySelector('c-pfm-text')) {
self.template.querySelector('c-pfm-text').classList.add('pfm-text_backend');
}
if (this.align) {
this.setAttribute('class', 'pfm-input-align_' + this.align);
}
}
disconnectedCallback() {
unregisterAllListeners(this);
}
setFieldType() {
if (this.type == null) {
this.type = 'text';
}
switch (this.type) {
case 'richtext':
this.isRichText = true;
break;
case 'picklist':
this.isPicklist = true;
break;
case 'textarea':
this.isTextArea = true;
break;
case 'fileupload':
this.isFileUpload = true;
break;
case 'reference':
case 'lookup':
this.isLookup = true;
break;
case 'radiogroup':
this.isRadio = true;
break;
case 'checkbox':
this.isCheckbox = true;
break;
case 'address':
this.isAddress = true;
break;
case 'multipicklist':
this.otherAttributes = parseToObject(this.otherAttributes);
// this.localOptions = this.otherAttributes.options;
this.isMultiPicklist = true;
break;
case 'date':
this.isDate = true;
break;
default:
this.isLightningInput = true;
break;
}
}
handleRefreshInputField(evt) {
if (this.group === evt.group) {
this.updateValue(evt.data[this.name]);
}
}
validate() {
let input = this.getInput();
if (input) {
this.isValid = input.checkValidity();
input.reportValidity();
}
return this.isValid;
}
setErrorMessage(message) {
if (!this.isRichText && !this.isPicklist) {
let input = this.getInput();
this.callInputFunction(input, 'setCustomValidity', message);
this.callInputFunction(input, 'reportValidity');
}
}
updateValue(value, noChangeEvent = false) {
let input = this.getInput();
if (!input) {
return;
}
this._localValue = value;
if (this.isLightningInput && input) {
input.value = value;
}
if (!noChangeEvent) {
fireEvent(
this,
'valuechange',
{ field: this.name, value: value },
{ bubbles: true, composed: true }
);
}
if (input) {
this.callInputFunction(input, 'updateValue', value, noChangeEvent);
this.callInputFunction(input, 'setCustomValidity', '');
}
}
callInputFunction(input, functionName, param1, param2) {
try {
if (typeof input[functionName] === 'function') {
input[functionName](param1, param2);
}
} catch (exp) {}
}
setSelectOptions(options, val) {
this.getInput().updateOptions(options, val);
}
clearValue() {
this._localValue = null;
fireEvent(
this,
'valuechange',
{ field: this.name, value: this._localValue },
{ bubbles: true, composed: true }
);
if (this.isLookup) {
this.getInput().removeValue();
}
}
getChildComponents(selector) {
return this.template.querySelectorAll(selector);
}
getInput() {
let input;
if (this.isLightningInput || this.isCheckbox) {
input = this.template.querySelector('lightning-input');
} else if (this.isTextArea) {
input = this.template.querySelector('lightning-textarea');
} else if (this.isRichText) {
input = this.template.querySelector('lightning-input-rich-text');
} else if (this.isPicklist) {
input = this.template.querySelector('c-pfm-input-picklist');
} else if (this.isFileUpload) {
input = this.template.querySelector('c-fileinput');
} else if (this.isLookup) {
input = this.template.querySelector('c-pfm-input-lookup');
} else if (this.isAddress) {
input = this.template.querySelector('c-pfm-input-address');
} else if (this.isDate) {
input = this.template.querySelector('c-pfm-input-date');
}
return input;
}
valueChangedEvent(evt) {
this.setErrorMessage('');
if (this.type !== 'checkbox') {
this._localValue = evt.detail ? evt.detail.value : evt.target.value;
} else {
this._localValue = this.getInput().checked;
}
if (this.maxReset && parseFloat(this._localValue) > this.maxReset) {
this.updateValue(String(this.maxReset), true);
}
if (this.minReset && parseFloat(this._localValue) < this.minReset) {
let minResetValue = this.minReset === true ? '0' : this.minReset;
this.updateValue(String(minResetValue), true);
}
fireEvent(
this,
'valuechange',
{ field: this.name, value: this._localValue, group: this.group },
{ bubbles: true, composed: true }
);
}
handleBlurEvent(evt) {
fireEvent(
this,
'blur',
{ field: this.name, value: this._localValue, group: this.group },
{ bubbles: true, composed: true }
);
}
loadDependentStyles() {
if (!window.pfmInputStylesLoaded) {
loadStyle(this, BASE + '/css/component/input/lightning-input.css');
window.pfmInputStylesLoaded = true;
}
}
render() {
if (this.type != null) {
switch (this.type) {
case 'lookup':
return lookup;
default:
return pfmInput;
}
}
return pfmInput;
}
}