jbduzan
jbduzan

Reputation: 1126

Angular, ng-messages not showing inside angular material design dialog (md-dialog)

I'm working on a form to add a credit card in angularJS, with angular material (https://material.angularjs.org/latest/#/).

For all my other forms, i used ng-messages (https://docs.angularjs.org/api/ngMessages/directive/ngMessages) to show validation errors, and it worked fine.

When i embded the form inside a md-dialog, my ng-messages are not displaying, the input became invalid, but no error displayed. I've got the problem with basic validation directive and custom validation directive.

My dialog template :

<md-dialog>
<md-dialog-content style="max-width:800px;max-height:810px; ">
    <h2 i18n="add_card_button"></h2>
    <form name="form">
        <md-input-container>
            <label i18n="card_number"></label>
            <input  name="card_number"
                    type="text" 
                    ng-model="ctrl.newCard.cc_number"
                    class="md-input" 
                    required
                    card-number>
            <div ng-messages="form.card_number.$error">
                <div ng-message="cardNumber">test message</div>
                <div ng-message="required">test message 2</div>
            </div>
        </md-input-container>
        ...
    </form>
</md-dialog-content>
<div class="md-actions" layout="row">           
    <md-button ng-click="">
        <i18n>ok_button</i18n>
    </md-button>
    <md-button ng-click="cancel()" style="margin-right:20px;">
        <i18n>cancel_button</i18n>
    </md-button>
</div>

My dialog definition :

$mdDialog.show({
            controller : dialogController,
            controllerAs : "ctrl",
            bindToController : true,
            templateUrl : "creditCards/assets/templates/add_credit_card_dialog.html",
            parent : angular.element(document.body),
            targetEvent : event,
            clickOutsiteToClose : true,
            locals : {
                cardTypes : vm.cardTypes
            }
        });

and my custom directive definition

angular
    .module('app.core')
    .directive("cardNumber", cardNumber);

/* @ngInject */
function cardNumber () {
    var directive = {
        link: link,
        restrict: 'A',
        require : "ngModel"
    };
    return directive;

    function link(scope, element, attrs, ngModel) {
        ngModel.$validators.cardNumber = cardNumber;

        scope.$watch("cardNumber", function(){
            ngModel.$validate();
        });

        // Validate visa, mastercard, amex, concate new regex to validate more card
        var reg = new RegExp(/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})$/);

        function cardNumber(modelValue){
            if(!modelValue){
                return true;
            }

            modelValue = modelValue
                            .replace(/-/g, "")
                            .replace(/\s/g, "")
                            .replace(/,/g, "");

            return reg.test(modelValue);
        }
    }
}

And a screenshot of the result where you can see the invalid field but no error message : enter image description here

Upvotes: 8

Views: 8063

Answers (6)

Chris Nguyen
Chris Nguyen

Reputation: 2900

I think, you should catch error ng-model form.cc_number.$error, same code here:

<input name="card_number" type="text" class="md-input" card-number required ng-model="ctrl.newCard.cc_number">
<div ng-messages="form.cc_number.$error">
    <div ng-message="cardNumber">test message</div>
    <div ng-message="required">test message 2</div>
</div>

Upvotes: 0

Casey Williams
Casey Williams

Reputation: 4073

There are two possible fixes detailed here: https://github.com/angular/material/issues/8037

  1. Make sure the ng-app directive is on the body tag of your page.

  2. Remove the line parent: angular.element(document.body) from your $mdDialog.show() options.

Upvotes: 6

Elisha
Elisha

Reputation: 4951

is it possible that you have two form tags?
if you copied the demos from Angular site, you may have form inside form. this can cause this exact problem.

Upvotes: 2

David Kruger
David Kruger

Reputation: 83

I was able to make this work.

  1. Add Angular Messages to the bower and index
  2. Add the Module ngMessages to your app
  3. On a md-input-container did this
<md-input-container flex md-is-error="signupForm.emailAddress.$invalid && (signupForm.$submitted || signupForm.emailAddress.$dirty)">
  <label>Email Addresss</label>
  <input name="emailAddress" ng-model="registerInfo.emailAddress" type="email" required/>
  <div ng-messages="signupForm.emailAddress.$error" ng-if='signupForm.$submitted || signupForm.emailAddress.$touched'>
    <div ng-message="required">This is required.</div>
    <div ng-message="email">Enter valid email address.</div>
  </div>
</md-input-container>

And for a custom directive I did this

<div ng-messages="signupForm.verify.$error" ng-if='signupForm.verify.$dirty || signupForm.verify.$touched'>
  <div ng-message="required">This is required.</div>
  <div ng-message="passwordVerify">Doesn't Match.</div>
</div>

Upvotes: 3

Simon H
Simon H

Reputation: 21005

Have a try with

<div ng-messages="form.card_number.$error" md-auto-hide="false">

That fixed my similar issue

Upvotes: 4

Abhimanyu Dikshit
Abhimanyu Dikshit

Reputation: 11

Guys, I was facing the same issue. The problem in my case was that I hadn't removed an enclosing tag from the sample md-dialog code. That was probably interfering with the messages.

Hope that helps you too.

Abhimanyu

Upvotes: 0

Related Questions