Here im trying to Binding directive but why i'm getting error during the Binding
<input type="text" class="form-control" ng-model="User.Password" name="psw" />
<input type="text" class="form-control" ng-model="User.conPassword" name="cpsw"
data-apple-psw="User.Password" required />
crl.Js
app.directive('applePsw', function () {
return {
require: " ngModel",
scope: {
//passwordVerify: "="
applePsw: "="
},
link: function (scope, element, attr, ctrl) {
Related
How can I write custom directives when I use thymeleaf?
Off-topic: For example I saw that if you use required in your input tag you should change it with th:required="required"
How can I do it for a custom directive because I receive this error:
org.xml.sax.SAXParseException: Open quote is expected for attribute
"is-email" associated with an element type "input".
When I use this tag:
<input type="email" id="clientEmail" name="clientEmail" class="form-control" ng-model="c.email" th:required="required" minlength="5"
is-email={{c.email}} />
Custom directive:
angular.module('app')
.directive('isEmail', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attributes, ctrl) {
ctrl.$validators.isEmail = function(modelValue, viewValue) {
if (viewValue) {
var re = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(viewValue);
}
}
}
}
})
<input type="email" id="clientEmail" name="clientEmail" class="form-control" ng-model="c.email" th:required="required" minlength="5"
is-email={{c.email}} />
change this to
<input type="email" id="clientEmail" name="clientEmail" class="form-control" ng-model="c.email" th:required="required" minlength="5"
is-email="{{c.email}}" />
You just forgot to mention "{{c.email}}" quotes
I have this input with lots of directives on it:
<input class="form-control"
mobile-number
limit-characters
number-only
dir="ltr"
ng-class="{'error-form-control': vm.form.step2.phoneNumber.$invalid && (vm.form.step2.phoneNumber.$dirty || vm.form.step2.phoneNumber.$touched)}"
required
ng-model="vm.formData.phoneNumber"
name="phoneNumber"
type="text">
How can I make it into a reusable directive like so:
<phone-number ng-model="vm.formData.phoneNumber"></phone-number>
and how can I use angular form validation with this directive?
I guees it will look like this
app.directive('phoneNumber', function(){
return {
scope: {
ngModel: '='
classValidation: '=',
inputName: '#'
},
template: ' <input class="form-control" mobile-number limit-characters number-only dir="ltr" ng-class="classValidation" required ng-model="ngModel" name="{{inputName}}" type="text">',
link: function(scope, elem, attr, ctrl) {
}
}
})
HTML
<phone-number ng-model="vm.formData.phoneNumber" input-name="phoneNumber" class-validation="{'error-form-control': vm.form.step2.phoneNumber.$invalid && (vm.form.step2.phoneNumber.$dirty || vm.form.step2.phoneNumber.$touched)}"></phone-number>
I want to show two different inputs depending on a toggle attribute.
No I have the problem that I should define each attribute/property of the input in my directive, but the binding doesn't work.
Directive:
angular.module('directive')
.directive('inputBlock', function () {
return {
restrict: 'AEC',
replace: true,
scope: {
model: '=',
modernStyle:'=',
name:'=',
type:'=',
label:'='
},
link: function (scope, elem, attrs, ctrl) {},
templateUrl: 'views/templates/inputBlockTemplate.html'
};
});
Template:
<div>
<div ng-if="!modernStyle">
<label>{{label}}</label>
<input ng-model="model" name="{{name}}" type="{{type}}"/>
</div>
<md-input-container ng-if="modernStyle">
<label>{{label}}</label>
<input ng-model="model" name="{{name}}" type=" {{type}}"/>
</md-input-container>
</div>
Usage:
<input-block model="name" label="'firstname'" modern-style="true" name="'firstname'" type="'text'">
</input-block>
Is it possible to do something like a toggle in directives?
Furthermore is it possible to redirect the bindings to directives?
ng-if creates a new child scope, try change by ng-show/ng-hide
Understanding Scopes
Other considerations:
As you use name,label and type as text inside your directive is not necesary that it will be binding, I recomend use # instead of =, or access it directly from the attrs link argument.
The scope.model could be set as ngModel to use the default angular directive.
Javascript:
angular.module("directive").directive("inputBlock", function () {
return {
restrict: "AEC",
replace: true,
scope: {
ngModel: "=",
modernStyle:"#",
//name:"#",
//type:"#",
//label:"#"
},
link: function (scope, elem, attrs, ctrl) {
scope.type=attrs.type;
scope.name=attrs.name;
scope.label=attrs.label;
},
templateUrl: "views/templates/inputBlockTemplate.html"
};
});
Template:
<div>
<div ng-show="!scope.modernStyle">
<label>{{scope.label}}</label>
<input ng-model="scope.model" name="{{scope.name}}" type="{{scope.type}}"/>
</div>
<md-input-container ng-show="scope.modernStyle">
<label>{{scope.label}}</label>
<input ng-model="scope.model" name="{{scope.name}}" type={{scope.type}}"/>
</md-input-container>
</div>
Usage:
<input-block ng-model="name" label="firstname" modern-style="true" name="firstname" type="text">
</input-block>
I would like to set the validity of a form element based on a custom boolean value. Consider the following password fields:
<input type="password" name="password" ng-model="user.password" required>
<input type="password" name="passwordRepeat" ng-model="user.passwordRepeat" required>
I would like to mark the second input field valid if the repeated password matches the original password. Something like:
<input type="password" name="passwordRepeat" ng-model="user.passwordRepeat" my-validation-check="user.passwordRepeat === user.password" required>
I was not able to find any Angular directive for this purpose. Any ideas? Perhaps create my own directive for this? Unfortunately, I'm not an Angular expert... it should be something like this:
angular.module('app').directive('myValidationCheck', function() {
return {
scope: true,
require: 'ngModel',
link: function(scope, elm, attrs, ngModel) {
// eval and watch attrs.myValidationCheck
// and use ngModel.$setValidity accordingly
}
};
});
Thanks!
I have spent quite a bit of time finding the best answer based on your answers below (thanks a lot!). What did the trick for me was simply:
angular.module('myApp').directive('myValidationCheck', function() {
return {
scope: {
myValidationCheck: '='
},
require: 'ngModel',
link: function(scope, elm, attrs, ngModel) {
scope.$watch('myValidationCheck', function(value) {
ngModel.$setValidity('checkTrue', value ? true : false);
});
}
};
});
for
<input type="password" name="passwordRepeat" my-validation-check="user.password === user.passwordRepeat" ng-model="user.passwordRepeat" required>
And this is really flexible. You can use anything you want in my-validation-check, e.g. make sure a checkbox is checked or any more complex expression is true.
Hope this helps not just myself.. :-)
Why do you need special directive for it?
Why not make so:
<div ng-controller="MyCtrl">
<form name="myForm" ng-submit="processForm()">
<input type="password" ng-model="password" placeholder="password" required/>
<input type="password" ng-model="repeatedPassword" placeholder="repeat password" required/>
<input type="Submit" value="Submit" ng-disabled="passwordsMissmatched()"/>
<span ng-show="passwordsMissmatched()">
Password mismatched
</span>
</form>
</div>
And your JS:
function MyCtrl($scope) {
$scope.passwordsMissmatched = function(){
return $scope.password && $scope.repeatedPassword
&& ($scope.password != $scope.repeatedPassword);
}
$scope.processForm = function(){
if($scope.password == $scope.repeatedPassword){
alert("Form processing..");
}
};
}
This approach should work like a charm.
I've created JSFiddle for you.
Please see demo below
var app = angular.module('app', []);
app.directive('mcheck', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ngModel) {
scope.$watch(attrs.ngModel, function(value) {
if (value == attrs.mcheck) {
ngModel.$setValidity('notEquals', true);
} else {
ngModel.$setValidity('notEquals', false);
}
});
}
};
});
app.controller('fCtrl', function($scope) {
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="fCtrl">
<form novalidate name="login">
<input type="text" name="password" ng-model="user.password" mcheck="{{user.passwordRepeat}}" required>
<input type="text" name="passwordRepeat" ng-model="user.passwordRepeat" mcheck="{{user.password}}" required>
<HR/>
<span ng-show="login.password.$error.notEquals && login.passwordRepeat.$error.notEquals && login.$dirty">Passwords are not equal</span>
<HR/>
</form>
</div>
</div>
I'm trying to build an Angular directive that renders radio inputs and the associated labels. The HTML for the directive looks like this:
<d-radio name="gender" value="male" label="I'm a male"></d-radio>
<d-radio name="gender" value="female" label="I'm a female"></d-radio>
I'd like it render the equivalent of this:
<input type="radio" name="gender" id="male" value="male" ng-model="gender"><label for="male">I'm a male</label>
<input type="radio" name="gender" id="female" value="female" ng-model="gender"><label for="female">I'm a female</label>
And here's the JS code:
app.directive('dRadio', function() {
return {
restrict: 'E',
scope: true,
template: '<input type="radio" id="{{value}}" name="{{name}}" value="{{value}}"><label for="{{value}}">{{label}}</label>',
link: function(scope, element, attrs) {
scope.name = attrs.name;
scope.value = attrs.value;
scope.label = attrs.label;
}
};
});
The only thing missing from my directive is the ng-model portion. Since each directive creates an isolated scope, I'm not sure how to bind the model to it.
There is a similar Stack Overflow question here:
Isolating directive scope but preserve binding on ngModel
I tried this solution, but I couldn't get it to work. Any ideas? Thanks!
If you want to have a bi-directional binding you will need to add an model: '=' to your scope. That will allow you to have a model variable in your scope which will be binded with the one you indicate in the html
app.directive('dRadio', function() {
return {
restrict: 'E',
scope: { model: '=' },
template: '<input type="radio" ng-model="{{model}}" id="{{value}}" name="{{name}}" value="{{value}}"> <label for="{{value}}">{{label}}</label>',
link: function(scope, element, attrs) {
scope.name = attrs.name;
scope.value = attrs.value;
scope.label = attrs.label;
}
};
});
And in your html
<d-radio name="gender" value="male" label="I'm a male" model="gender"></d-radio>