Bind array of boolean in angularjs directive - angularjs

In my view, I have:
<input my-directive
inputs="[userData.var1, userData.var2]"
type="checkbox"
ng-model="userData.myModel"
id="vegetarian"
class="v3-custom-checkbox" />
In the directive, I have:
myDirectives.directive('myDirective', function() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
inputs: '='
},
link: function(scope, element, attrs, ngModel) {
scope.$watch(function () {
return ngModel.$modelValue;
}, function(newValue) {
if(newValue) {
for (var i = 0; i < scope.inputs.length; i++) {
scope.inputs[i]=false;
}
console.log(scope.inputs);
}
});
}
}
This gives me an error expression in attribute 'inputs' is non-assignable!
Angular version is 1.6.4.

Related

How to get value from ng-model in directive?

I have code:
<input check-value-type-array type-value="node.type_value" type-element="node.type" ng-value="item" class="form-control">
And directive:
.directive('checkValueTypeArray', function() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
typeElement: '=',
typeValue: '=',
ngModel: '='
},
link: function(scope, element, attrs, ngModel) {
ngModel.$validators.required = function(v) {}
}
How to get ng-model inside directive and do validation:
ngModel.$validators.required = function (v) {
}
Minor alteration, you're looking for ngModel.$modelValue:
ngModel.$validators.required = (value) => {
// the value of the model will be ngModel.$modelValue
}

writing own directive with AngularJS

I have a problem with showing error message when the user enters a wrong number. I tried to write my own directive for that but i m getting an error
"Cannot read property 'value' of undefined".
I m totally a newbie, just trying to learn directives. Any idea where did i made a mistake or how should i made it ?
Template :
<div ng-controller="performanceController">
<input type="number" name="performance" class="typo-xl-l input-power"
ng-model="performance" min-performance="10" max-performance="30">
<span id = "errorText"></span>
</div>
Controller :
'use strict';
angular.module('myApp', [
'ngRoute'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/inputView.html'
})
}])
.controller('performanceController', function($scope) {
})
.directive("maxPerformance", [function() {
return {
restrict: "A",
link: function(scope, elem, attrs) {
var limit = parseInt(attrs.maxPerformance);
if (this.value.length > limit) {
document.getElementById('errorText').innerText("wrong number");
}
}
}
}])
.directive("minPerformance", [function() {
return {
restrict: "A",
link: function(scope, elem, attrs) {
var limit = parseInt(attrs.minPerformance);
if (this.value.length < limit) {
document.getElementById('errorText').innerText("wrong number");
}
}
}
}]);
UPDATE :
.directive("maxPerformance", [function() {
return {
restrict: "A",
require: 'ngModel', //this will make ng-model attribute compulsary on directive element.
link: function(scope, elem, attrs, ngModel) { //injected ngModel here 4th parameter
var limit = parseInt(attrs.maxPerformance);
angular.element(elem).on("keydown", function() {
if (ngModel.$viewValue.length > limit) {
document.getElementById('errorText').innerText("wrong number");
}
});
}
}
}])
.directive("minPerformance", [function() {
return {
restrict: "A",
require: 'ngModel',
link: function(scope, elem, attrs, ngModel) { //injected ngModel here 4th parameter
var limit = parseInt(attrs.minPerformance);
angular.element(elem).on("keydown", function() {
if (ngModel.$viewValue.length < limit) {
document.getElementById('errorText').innerText("wrong number");
}
});
}
}
}]);
Still not working..
While getting the value of ngModel inside your directive you could actually have require: ngModel option inside directive which will give ngModelController value inside link function. And then easily you could fetch value of it using ngModel.$viewValue
.directive("maxPerformance", [function() {
return {
restrict: "A",
require: 'ngModel', //this will make ng-model attribute compulsary on directive element.
link: function(scope, elem, attrs, ngModel) { //injected ngModel here 4th parameter
var limit = parseInt(attrs.maxPerformance);
if (ngModel.$viewValue.length > limit) {
document.getElementById('errorText').innerText = "wrong number";
}
}
}
}])
.directive("minPerformance", [function() {
return {
restrict: "A",
require: 'ngModel',
link: function(scope, elem, attrs, ngModel) { //injected ngModel here 4th parameter
var limit = parseInt(attrs.minPerformance);
if (ngModel.$viewValue.length < limit) {
document.getElementById('errorText').innerText = "wrong number";
}
}
}
}]);
Update
Rather going for creating custom directive, you could handle such a small thing by using ng-min & ng-max attributes on the input element which is of type="number".
<form name="myForm" ng-controller="performanceController">
<input type="number" name="performance" class="typo-xl-l input-power" ng-model="performance" min="10" max="30" />
<span id="errorText" ng-show="myForm.performance.$error.min || myForm.performance.$error.max">
Wrong Number
</span>
</form>
Demo Plunkr

Passing Date/moment object via attribute in AngularJS

I have a directive and I'm trying to pass Date/moment object via attribute. I'm passing it like this: (I know, that I can create isolated-scope and bind it, it is not the case)
<form name="form">
<input name="field" ng-model="fieldModel" form-field-directive field-date="{{fieldDateModel}}" />
</form>
Without curly brackets the result is obvious, but with I'm getting such quoted string "2015-07-03T10:35:13.691Z".
Is there anyway to work with it?
UPDATE:
angular.module('app', [])
.controller('AppCtrl', function($scope) {
$scope.fieldDateModel = moment(); // new Date()
});
angular.module('app')
.directive('formFieldDirective', function() {
return {
restrict: 'A',
require: '^ngModel',
link: function(scope, iElement, iAttrs, ngModelCtrl) {
ngModelCtrl.$validators.fieldDate = function() {
if (angular.isUndefined(iAttrs.fieldDate)) {
return true;
}
console.log(iAttrs.fieldDate);
};
}
};
});
You can actually pull the value from the parent scope using $parse which is more reliable.
angular.module('app')
.directive('formFieldDirective', function($parse) {
return {
restrict: 'A',
require: '^ngModel',
link: function(scope, iElement, iAttrs, ngModelCtrl) {
ngModelCtrl.$validators.fieldDate = function() {
if (angular.isUndefined(iAttrs.fieldDate)) {
return true;
}
console.log(($parse(iAttrs.fieldDate)(scope)).format());
};
}
};
});
http://jsbin.com/qoheraloge/1/edit?js,console,output

How to incorporate a custom directive into angular's validation framework

I have a directive that is designed to be assigned to a normal text input.
<input type="text" ng-model="fooModel" foo-input size="30"
placeholder="insert value"></input>
I have lots of validation functions for it like testing the precision of the numbers and I use a $parsers to control the value that is submitted.
myApp.directive('fooInput', function () {
return {
restrict: 'A',
require: 'ngModel',
controller: function ($scope, $element, $attrs) {
this.errorMessage = ""
},
link: function (scope, element, attrs, ctrl)
return ctrl.$parsers.push(function (inputValue) {
var originalVal = element.val();
if (!testForOverPrecision(numericVal)) {
//do something here to set the directive as invalid
}
if (originalVal != inputValue) {
ctrl.$setViewValue(res);
ctrl.$render();
}
});
I have 2 questions:
How do I get this to work with the isValid service and do I have to have a controller scope for the error message
Is it correct for me to push the $parser inside a return statement
I am using Angular 1.2x and I created a directive to determine if the text contains the # symbol.
.directive('noAt', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if (/#/.test(viewValue)) {
ctrl.$setValidity('noAt', false);
return undefined;
} else {
ctrl.$setValidity('noAt', true);
return viewValue;
}
});
}
};
})

AngularJS directive use required controller in controller

Say I have the following two directives that work with each other
directive('parent', function() {
return {
scope: {},
require: 'ngModel',
controller: function($scope) {
this.doSomething = function() {
//How to use ngModelController here?
};
},
link: function(scope, element, attr, ngModelController) {
}
};
});
directive('child', function() {
return {
scope: {},
require: '^parent',
link: function(scope, element, attr, parent) {
parent.doSomething();
}
};
});
How can I use the ngModelController from within the controller of parent? I suppose I could do scope.ngModelController = ngModelController inside the link function but that seems hacky. Is there a better solution?
Is this any less hacky?
directive('parent', function() {
var ngModelCtrl = null;
return {
scope: {},
require: 'ngModel',
controller: function($scope) {
this.doSomething = function() {
//How to use ngModelController here?
if (ngModelCtrl) {
}
};
},
link: function(scope, element, attr, ngModelController) {
ngModelCtrl = ngModelController;
}
};
});

Resources