javascripthtmlangularjsng-messages

Custom wrapper reusable directive for ngMessages to minimize HTML : Dynamic name to directive


Trying to minimize to write the html for showing the ngMessages module by wrapping into to a custom directive and showing the message.

I wrote the below implementation seems to work fine. My challenge is to make it reusable and dynamic.

angular.module('app').directive('myNgMsg', function () {
    var tpls ='<div ng-messages="form.field1.$error" ng-if="form.field1.$touched" style="color:red;font-weight: bold;" role="alert">'+ 
        '<div ng-message="required" class="error-message">Required Field</div>'+
        '<div ng-message="pattern">Invalid Input</div>'+
        '<div ng-message="minlength" class="error-message" >minimum 5</div>'+
        '<div ng-message="maxlength" class="error-message" >Maximum 10</div></div>';
    return {
         restrict: 'E',
         replace: true,
         transclude: true,
         template: tpls
   }
});

HTML

<div class="form-group">
   <label  astr>request num</label>
        <input type="text"  name="field1"class="form-control" required  ng-minlength="5" ng-pattern="/^[-a-zA-Z0-9@\.+_]+$/" ng-model="ngObject.request.field1"/>
                            <my-ng-msg> </my-ng-msg>
</div>
<div class="form-group">
   <label  astr>name</label>
        <input type="text"  name="field2"class="form-control" required  ng-minlength="5" ng-pattern="/^[-a-zA-Z0-9@\.+_]+$/" ng-model="ngObject.request.field2"/>
                            <my-ng-msg> </my-ng-msg>
</div>
<div class="form-group">
   <label  astr>home</label>
        <input type="text"  name="field3"class="form-control" required  ng-minlength="5" ng-pattern="/^[-a-zA-Z0-9@\.+_]+$/" ng-model="ngObject.request.field3"/>
                            <my-ng-msg> </my-ng-msg>
</div>

So there can be many number of fields having similar validations but the names would be different, can you help me how to send the name dynamically and append it in my directive so that my custom directive takes name and work on that particular element.

form.field1.$error should be taking field name as field name fieldname1,fieldname2 .

Once I have a way to do that i can change my HTML dynamically which is in the variable tpls

Any pointers or help.


Solution

  • I tried to use Link and Compile function but sadly none of those worked because it was executing asynchronously and I could not use the variable value in my template it was coming undefined.

    I got a solution from other answer here , just for the completeness posting how I am getting it.

    angular.module('app').directive('myNgMsg', function () {
    
        return {
             restrict: 'E',
             replace: true,
             transclude: true,
            template: function(element, attrs) {
                 var ctrlname=attrs.name;
                 var tpls ="form.'+ctrlname+'.$error" ng-if="form.'+ctrlname+'.$touched" style="color:red;font-weight: bold;" role="alert">'+ 
            '<div ng-message="required" class="error-message">Required Field</div>'+
            '<div ng-message="pattern">Invalid Input</div>'+
            '<div ng-message="minlength" class="error-message" >minimum 5</div>'+
            '<div ng-message="maxlength" class="error-message" >Maximum 10</div></div>'; 
       }
    });
    

    HTML

    <div class="form-group">
       <label  astr>request num</label>
            <input type="text"  name="field1"class="form-control" required  ng-minlength="5" ng-pattern="/^[-a-zA-Z0-9@\.+_]+$/" ng-model="ngObject.request.field1"/>
                                <my-ng-msg> </my-ng-msg>
    </div>