ExtJs fields have validation mechanisms but they make the field invalid. To implement a field prompt mechanisms I have improved existing code and migrated it to 6.6.0 version.
In the following sample you can see the form bound “Submit” button, which will be disabled on standard error validation and enabled on minor validation. The border color, text color and icon are also changed to less aggressive orange.
Overriden classes:
Ext.define('overrides.form.field.Base', { override: 'Ext.form.field.Base', warningCls: Ext.baseCSSPrefix + 'form-warning', validateValue: function (value) { var isValid = this.callParent(arguments); if (isValid) { var warnings = this.getWarnings(), hasWarnings = !Ext.isEmpty(warnings); if (hasWarnings) { this.showWarnings(warnings); } else { this.clearWarnings(); } } else { this.clearWarnings(); } return isValid; }, getWarnings: function (value) { value = arguments.length ? (value == null ? '' : value) : this.processRawValue(this.getRawValue()); var warnings = [], warnator = this.warnator, wtype = this.wtype, vtypes = Ext.form.field.VTypes if (Ext.isFunction(warnator)) { msg = warnator.call(this, value); if (msg !== true) { warnings.push(msg); } } if (wtype) { if (!vtypes[wtype](value, this)) { warnings.push(this.wtypeText || vtypes[wtype + 'Text']); } } return warnings; }, showWarnings: function (warnings) { this.setActiveWarnings(Ext.Array.from(warnings)); }, clearWarnings: function () { this.unsetActiveWarning(); }, getActiveWarning: function () { return this.activeWarning || ''; }, hasActiveWarning: function () { return !!this.getActiveWarning(); }, setActiveWarning: function (msg) { this.setActiveWarnings(msg); }, getActiveWarnings: function () { return this.activeWarnings || []; }, setActiveWarnings: function (warnings) { var errorWrapEl = this.errorWrapEl, msgTarget = this.msgTarget, isSide = msgTarget === 'side', isQtip = msgTarget === 'qtip', actionEl, activeWarning, tpl, targetEl; warnings = Ext.Array.from(warnings); tpl = this.lookupTpl('activeErrorsTpl'); this.activeWarnings = warnings; activeWarning = this.activeWarning = tpl.apply({ fieldLabel: this.fieldLabel, errors: warnings, listCls: Ext.baseCSSPrefix + 'list-plain' }); this.renderActiveWarning(); if (this.rendered) { actionEl = this.getActionEl(); if (isSide) { this.errorEl.dom.setAttribute('data-errorqtip', activeWarning); } else if (isQtip) { actionEl.dom.setAttribute('data-errorqtip', activeWarning); } else if (msgTarget === 'title') { actionEl.dom.setAttribute('title', activeWarning); } if (msgTarget !== 'title') { this.ariaErrorEl.dom.innerHTML = warnings.join('. '); actionEl.dom.setAttribute('aria-describedby', this.ariaErrorEl.id); } if (isSide || isQtip) { Ext.form.Labelable.initTip(); } if (!this.msgTargets[msgTarget]) { targetEl = Ext.get(msgTarget); if (targetEl) { targetEl.dom.innerHTML = activeWarning; } } } if (errorWrapEl) { errorWrapEl.setVisible(warnings.length > 0); if (isSide && this.autoFitErrors) { this.labelEl.addCls(this.topLabelSideErrorCls); } this.updateLayout(); } }, unsetActiveWarning: function () { var errorWrapEl = this.errorWrapEl, msgTarget = this.msgTarget, restoreDisplay = this.restoreDisplay, actionEl, targetEl; if (this.hasActiveWarning()) { delete this.activeWarning; delete this.activeWarnings; this.renderActiveWarning(); if (this.rendered) { actionEl = this.getActionEl(); if (msgTarget === 'qtip') { actionEl.dom.removeAttribute('data-errorqtip'); } else if (msgTarget === 'title') { actionEl.dom.removeAttribute('title'); } if (msgTarget !== 'title') { this.ariaErrorEl.dom.innerHTML = ''; actionEl.dom.removeAttribute('aria-describedby'); } if (!this.msgTargets[msgTarget]) { targetEl = Ext.get(msgTarget); if (targetEl) { targetEl.dom.innerHTML = ''; } } if (errorWrapEl) { errorWrapEl.hide(); if (msgTarget === 'side' && this.autoFitErrors) { this.labelEl.removeCls(this.topLabelSideErrorCls); } this.updateLayout(); if (restoreDisplay) { this.el.dom.style.display = 'block'; this.restoreDisplay(); } } } } }, renderActiveWarning: function () { var activeWarning = this.getActiveWarning(), hasError = !!activeWarning; if (activeWarning !== this.lastActiveWarning) { this.lastActiveWarning = activeWarning; this.fireEvent('errorchange', this, activeWarning); } if (this.rendered && !this.destroyed && !this.preventMark) { this.toggleWarningCls(hasError); if (this.errorEl) { this.errorEl.dom.innerHTML = activeWarning; } } }, toggleWarningCls: function (hasError) { this.el[hasError ? 'addCls' : 'removeCls'](this.warningCls); } });
Ext.define('overrides.form.field.Text', { override: 'Ext.form.field.Text', triggerWrapWarningCls: Ext.baseCSSPrefix + 'form-trigger-wrap-default', inputWrapWarningCls: Ext.baseCSSPrefix + 'form-trigger-wrap-warning', toggleWarningCls: function(hasError) { var method = hasError ? 'addCls' : 'removeCls'; this.callParent(arguments); this.triggerWrap[method](this.triggerWrapWarningCls); this.inputWrap[method](this.inputWrapWarningCls); } });
.x-form-trigger-wrap-default .x-form-trigger-wrap-warning { border-color: orange !important; } .x-form-warning .x-form-invalid-under-default { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABqklEQVR4XqWTvWsUURTFf+/tx7DmA5sUmyB+EGQDCkFRxCFosYWCFgELm2ApCBYW/gOCFpYSrUMsBIv4BwTSCSqaWgsTEDRV2EVBZWffvXIYwhZOEdgLhzmcc+7h3WKCuzPOhI+P80rDzE7WwmAHIHnzVIxxl4qJVaKbkYrBxvyVZQRxaYcq0EmehvePzp5YnD67hCAuzd0PUWB2JNQazzo377D7+auAuDR51QWjZWxYvD2e34DsJw+fbwviSJOnTHWBO5aGt6fa84szF67CzguCIYgjTZ4yuP9fYGqO2avO8j348hSKff4OkiAuDXnKKDsqGD1989jSLWJvA/58g+YUv34Xgrg0eSij7MEpsXx66k62O932wjT030NjAuotXj/YE8SlyUMZZbWj3ejmEFubp69fg711yCYha0GWcXftjCAuTZ4yKKsd7dbNfHXuUk6jeAPNCSBCAJpGb78PiGel7gCmLHMXc76/21oNn57kfm5lFg0W0KBPDag7GoYBEuCUE0uy/fIH4cOjy27J0SlI56DEiSVFFi4dEUUIMRBrQZTzjDFj/87/ACmm3+QFX8sKAAAAAElFTkSuQmCC'); color: orange !important; }
Working sample.