Topic: Angular form validation

David Reymers pro asked 4 years ago

How do I make form input controls validation messages work with Angular MDB?I want to trigger an error message (or ok message) to display under the input control.

JaronRH pro answered 4 years ago

I found that the label for the form is supposed to have data-error="message" and data-success="message" attributes to display the text below the element.  Also, adding the class 'valid' or 'invalid' to the form input took care of the coloring.  You can then make your own directive to manage the state for you (I'd share the code here if the forums code element actually let me without over-mangling it!). Keep in mind though that the CSS is not complete for MDB form validation.  For example, displaying a message on a non-active label causes some nasty display issues.  Also, if you have spaces in your message, word wrapping will be an issue.  Finally, data-*="message" will never display correctly for a multi-line textarea. I had to add this to my global CSS to fix the line-wrapping and hide the text when not active:
label:after {
white-space: nowrap;
display: none!important;
} {
display: inherit!important;
Good luck!


ryandavie pro commented 4 years ago

You can add your own custom messages by changing the file at: angular-bootstrap-mdinputsinput-validate.directive.ts Add the field: @Input() errorMsg = ''; change: this.wrongTextContainer.innerHTML = 'wrong'; this.wrongTextContainer.innerHTML = this.errorMsg; Then you can add your own error with:   \<input mdbActive type="email" class="form-control" id="form9" name="email" mdbInputValidate [errorMsg]="'My custom error'"\>

Moises Trigueros free commented 4 years ago

I have a question, I made this change in a similar way in version 6.1.6, but it does not work for me, the message it shows is the same that I sent initially, this message does not change dynamically to how I need it, what I want to say is that I have multiple error messages to validate the input, but only recognizes the first message. Could you help me apply this change? <pre><div class="md-form input-group padding-input"> <input type="text" id="nombreproducto" mdbInputDirective [errorMsg] ="getMessageError(formAddProducto.controls['nombreProducto'])" formControlName="nombreProducto" [(ngModel)]="formAddProducto.value.nombreProducto" class="form-control letras" autocomplete="off" placeholder="Nombre del Producto" style="margin-right: 5%;"> <div class="input-group-btn"> <button type="button" class="btn orange-chang px-3 add-img-position" (click)="showCardImg()" mdbTooltip="Agregar Imagen" placement="bottom" id="btn-animation" style="margin-left: -20%;"> <i class="fa fa-file-photo-o" aria-hidden="true"></i> </button> </div> </div> changes in ng-uikit-pro-standard.js</pre> <pre>ngOnInit() { // Inititalise a new <span> wrong/right elements and render it below the host component. // this.wrongTextContainer = this._renderer.createElement(this.el.nativeElement.parentElement, 'span'); this.wrongTextContainer = this._renderer.createElement('span'); this._renderer.addClass(this.wrongTextContainer, 'inputVal'); this._renderer.addClass(this.wrongTextContainer, 'text-danger'); this._renderer.appendChild(this._elRef.nativeElement.parentElement, this.wrongTextContainer); const /** @type {?} */ textWrong = this._elRef.nativeElement.getAttribute('data-error'); this.wrongTextContainer.innerHTML = (textWrong ? textWrong : this.errorMsg); this._renderer.setStyle(this.wrongTextContainer, 'visibility', 'hidden'); // this.rightTextContainer = this._renderer.createElement(this.el.nativeElement.parentElement, 'span'); this.rightTextContainer = this._renderer.createElement('span'); this._renderer.addClass(this.rightTextContainer, 'inputVal'); this._renderer.addClass(this.rightTextContainer, 'text-success'); this._renderer.appendChild(this._elRef.nativeElement.parentElement, this.rightTextContainer); const /** @type {?} */ textSuccess = this._elRef.nativeElement.getAttribute('data-success'); this.rightTextContainer.innerHTML = (textSuccess ? textSuccess : 'success'); this._renderer.setStyle(this.rightTextContainer, 'visibility', 'hidden'); if (this.isBrowser) { this.changes = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (/** @type {?} */ (['classList'].contains('ng-touched')) && /** @type {?} */ (['classList'].contains('ng-invalid')) && !/** @type {?} */ (['classList'].contains('counter-danger'))) { if (this.mdbValidate) { this._renderer.addClass(this._elRef.nativeElement, 'counter-danger'); this._renderer.removeClass(this._elRef.nativeElement, 'counter-success'); this._renderer.setStyle(this.rightTextContainer, 'visibility', 'hidden'); this._renderer.setStyle(this.wrongTextContainer, 'visibility', 'visible'); this._renderer.setStyle(this.rightTextContainer, 'top', this._elRef.nativeElement.offsetHeight + 'px'); this._renderer.setStyle(this.wrongTextContainer, 'top', this._elRef.nativeElement.offsetHeight + 'px'); } } else if (/** @type {?} */ (['classList'].contains('ng-touched')) && /** @type {?} */ (['classList'].contains('ng-valid')) && !/** @type {?} */ (['classList'].contains('counter-success'))) { if (this.mdbValidate) { this._renderer.removeClass(this._elRef.nativeElement, 'counter-danger'); this._renderer.addClass(this._elRef.nativeElement, 'counter-success'); this._renderer.setStyle(this.rightTextContainer, 'visibility', 'visible'); this._renderer.setStyle(this.wrongTextContainer, 'visibility', 'hidden'); this._renderer.setStyle(this.rightTextContainer, 'top', this._elRef.nativeElement.offsetHeight + 'px'); this._renderer.setStyle(this.wrongTextContainer, 'top', this._elRef.nativeElement.offsetHeight + 'px'); } } // if (<DOMTokenList>['classList'].contains('ng-pristine') && // <DOMTokenList>['classList'].contains('ng-invalid')) { // any) => { // if (element.classList.contains('text-danger') || element.classList.contains('text-success')) { // this._renderer.setStyle(element, 'visibility', 'hidden'); // } // }); // if (<DOMTokenList>['classList'].contains('counter-danger')) { // this._renderer.removeClass(this._elRef.nativeElement, 'counter-danger') // } else if (<DOMTokenList>['classList'].contains('counter-success')) { // this._renderer.removeClass(this._elRef.nativeElement, 'counter-success') // } // } }); }); this.changes.observe(this._elRef.nativeElement, { attributes: true, }); } }</pre>

Dawid Adach pro answered 4 years ago

Dear David, if you would like to add your custom validations please check following file: [mdb-location]/free/inputs/input-validate.directive.ts You can use email/password example to create your own custom validation rules.

JaronRH pro commented 4 years ago

Any plans to take advantage of Angular's Reactive Form validation? I would find that far more useful for my development!

Dawid Adach pro commented 4 years ago

Dear JaronRH, definitely yes, we are working on extended documentation however as for now I cannot provide you with expected delivery date.

Please insert min. 20 characters.


Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.



Specification of the issue

  • User: Pro
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: -
  • Device: -
  • Browser: -
  • OS: -
  • Provided sample code: No
  • Provided link: No