Reputation: 418
I have some input fields inside custom directive. I'm trying to use ng-message to display validation error text for the fields inside custom directive.
When I do submit, validation messages inside custom directive is not shown.
My question is, can I use ng-message inside directive, and trigger it using parent action from form controller, and the message is shown?
My app.js source sample
var app = angular.module('plunker', ['ngMessages']);
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.identity = {};
vm.save = function() {
console.log('form data will submited to server');
}
});
app.directive('nameInfo', function() {
return {
templateUrl: 'name.html',
scope: {
name: '=',
submitted: '='
}
};
});
My html code
<form name="plnkrForm" novalidate ng-submit="plnkrForm.$valid && vm.save()">
<div class="form-group">
<button type="submit" class="btn" data-ng-click="submitted=true">
Update
</button>
</div>
<div class="form-group">
<input type="text" class="form-control" id="addressOne" name="addressOne"
placeholder="Address line 1" required="required" ng-model="vm.identity.addressOne" />
<div role="alert" ng-messages="plnkrForm.addressOne.$error"
data-ng-if="submitted && plnkrForm.addressOne.$invalid">
<span class="error" ng-message="required">Required</span>
</div>
</div>
<name-info name="vm.identity.name" submitted="submitted"></name>
</form>
My directive template
<div class=form-group>
<input type="text" class="form-control" placeholder="Firstname" id="firstname"
name="firstname" ng-model="name.firstname" required="required" />
<div role="alert" ng-messages="plnkrForm.firstname.$error"
data-ng-if="submitted && plnkrForm.firstname.$invalid">
<span class="error" ng-message="required">Required</span>
</div>
</div>
<div class=form-group>
<input type="text" class="form-control" placeholder="Middlename" id="middlename"
name="middlename" ng-model="name.middlename" required="required" />
<div role="alert" ng-messages="plnkrForm.middlename.$error"
data-ng-if="submitted && plnkrForm.middlename.$invalid">
<span class="error" ng-message="required">Required</span>
</div>
</div>
<div class=form-group>
<input type="text" class="form-control" placeholder="Lastname" id="lastname"
name="lastname" ng-model="name.lastname" required="required" />
<div role="alert" ng-messages="plnkrForm.lastname.$error"
data-ng-if="submitted && plnkrForm.lastname.$invalid">
<span class="error" ng-message="required">Required</span>
</div>
</div>
Here is my plunker for the question.
Upvotes: 2
Views: 1985
Reputation: 8404
You have explicitly defined isolated scope for your directive, so plnkrForm
does not exist. Quickest way to fix this is that you drop the isolated scope. Based on your example, you don't need it anyway.
So directive becomes
app.directive('nameInfo', function() {
return {
templateUrl: 'name.html'
};
});
And this being the case, directive is a bit of an overkill. You could get same result using ng-include
, too. So you could replace this
<name-info
name="vm.identity.name"
submitted="submitted">
</name-info>
with this
<div ng-include="'name.html'"></div>
If you insist doing this using a directive and isolated scope, here's how it's done. Pass form into directive and use it in your template/link/controller and change template accordingly.
In your "main" page
<name-info form="plnkrForm" name="name"></name-info>
JavaScript
app.directive('nameInfo', function() {
return {
templateUrl: 'name.html',
scope: {
form: '=',
name: '='
}
};
});
Directive template
<div class=form-group>
<input type="text"
class="form-control"
placeholder="Firstname"
name="firstname"
ng-model="name.firstname"
required="true">
<div role="alert"
ng-messages="form.firstname.$error"
data-ng-if="form.$submitted && form.firstname.$invalid">
<span class="error" ng-message="required">Required</span>
</div>
</div>
Now, I know your intentions are good as you want to avoid "DRY". If you study the examples, you'll notice that you get same result, functionality and reusability by using simple
ng-include
. Here we have achieved nothing but added, unnecessary complexity.
Upvotes: 4