Angular js : how to use loop in directive - javascript

I am creating directive for form controls, there is fix json with all possible from question and there options.
Html
<text-control-dir data="que.QuestionData" default="{{[_attributename]}}"></text-control-dir>
controlDirective.js
(function () {
"use strict";
angular
.module("autoQuote")
.directive('textControlDir', [textControlDir])
.directive('selectControlDir', [selectControlDir])
.directive('radioControlDir', [radioControlDir])
.directive('hiddenControlDir', [hiddenControlDir]);
function textControlDir()
{
return {
transclude: true,
restrict: 'E',
scope: {
data: '=data'
},
template: "<div ng-transclude></div><label>{{data._text}} </label><input type='text' name='{{data._attributeName}}' id='{{data._attributeName}}' value='' >"
,
link: function (scope, element, attrs)
{
//console.log(scope.data);
}
};
}
function selectControlDir()
{
return {
transclude: true,
restrict: 'E',
scope: {
data: '=data',
default: '=default'
},
template: ""
,
link: function (scope, element, attrs)
{
consoile.log('link data');
console.log(scope.default);
}
};
}
function radioControlDir()
{
console.log('here in radio directive');
return {
transclude: true,
template: "<h1>Made by a radio directive!</h1>"
};
}
function hiddenControlDir()
{
return {
transclude: true,
restrict: 'E',
scope: {
data: '=data'
},
template: "<div ng-transclude></div><label>{{data._text}} </label><input type='hidden' name='{{data._attributeName}}' id='{{data._attributeName}}' value='' >"
,
link: function (scope, element, attrs)
{
//console.log(scope.data);
}
};
}
}());
I am not getting how to loop to create select options.

In your template's ng-repeat you have to use in instead of as here:
template: "<div ng-transclude></div><label>{{data._text}} </label><select type='text' name='{{data._attributeName}}' id='{{data._attributeName}}' >\n\
<option ng-repeat='ans in data.QuestionData._answerOptions'>{{ans._promptText}}</option></select>",
Your updated plnkr.

Here's a working plunker
http://plnkr.co/edit/bc7cii5gkyNhhT4NS3uv?p=preview
It's better to use ngOptions directive because it's much faster!
Avoid options with label 'Please Select' - look at my example.

Related

Illegal use of ngTransclude directive in the template when using compile in directive controller

I'm using compile in my directive controller to get the first directive element and compile it and then use it for other purpose I don't want to use the linking method of my directive, is there anyway to get rid this error ?
I've reproduced the issue in this JSFIDDLE:
var app = angular.module('app', []);
app.directive('panel', function ($compile) {
return {
restrict: "E",
replace: true,
transclude: true,
template: "<div><h1>handrouss</h1><div ng-transclude ></div></div>",
controller: function($scope, $element) {
var el = $compile($element.find('div')[0])($scope); // <--- this causing the issue
$scope.handrouss = el.html();
},
link: function (scope, elem, attrs) {
}
}
});
app.directive('panel1', function ($compile) {
return {
restrict: "E",
replace:true,
transclude: true,
template:"<div ng-transclude></div>",
link: function (scope, elem, attrs) {
elem.children().wrap("<div>");
}
}
});
HTML :
<div data-ng-app="app">
<panel1>
<panel>
<input type="text" ng-model="firstName" />{{firstName}}
</panel>
<input type="text" ng-model="lastname" />
</panel
Remove the ng-transclude attribute from the element before compiling in the controller.
app.directive('panel', function ($compile) {
return {
restrict: "E",
replace: true,
transclude: true,
template: "<div><h1>handrouss</h1><div ng-transclude ></div></div>",
controller: function($scope, $element) {
var div = $element.find('div');
//REMOVE ng-transclude attribute
div.removeAttr('ng-transclude');
var el = $compile(div[0])($scope);
$scope.handrouss = el.html();
},
link: function (scope, elem, attrs) {
}
}
});
As the transclusion has already been done in the compile phase of the directive the ng-transclude directive is no longer needed when compiling in the controller.
The DEMO on JSFiddle

Angularjs ng-click clear input and update scope

1. Directive:
app.directive('inputField', function() {
return {
restrict: 'E',
require: 'ngModel',
scope: {
words: '=ngModel'
},
transclude: true,
template: "<input type='text' ng-model='words' placeholder='Translate' />"
};
});
2. ng-click function:
$scope.clear = function() {
$scope.words = { word: '' };
};
3. View looks like this:
<input-field id='inputWord' value='' name="data1" ng-model="words.word"></input-field>
After click clear() {{words.word}} and value in input still exist and $scope is broken.
Please tell me how I can clear all inputs ng-repeat and update scope?
Try like this.
var app = angular.module('app',[])
app.controller('ctrl',function($scope){
$scope.words = [ {word : 'input1'}, {word : 'input2'}, {word : 'input3'}];
$scope.clear = function() {
$scope.words =[ {word : ''}, {word : ''}, {word : ''}];
};
});
app.directive('inputField', function() {
return {
restrict: 'E',
require: 'ngModel',
scope: {
words: '=ngModel'
},
transclude: true,
template: "<input type='text' ng-model='words' placeholder='Translate' />"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="word in words">
<input-field id='inputWord' name="data1" ng-model="word.word"></input-field>
</div>
<button ng-click="clear()">Clear</button>
</div>

How to have dynamic template in angularjs directive

I want to create a directive that be dynamic. In this directive define a template that have an input element. In fact this element ng-model must be dynamic, and use $scope.name in controller.
app.directive('helloWorld', function() {
return {
restrict: 'E',
replace: true,
scope: {
name: '#',
path:'#',
},
template: '<input\
type="text"\
name="{{name}}"\
ng-model="{{name}}"\
/>\,
link: function(scope, elem, attrs) {
},
controller:{
$scope.$watch($scope.name, function (newValue, oldValue) {
}
}
});
A working JSFiddle
Code
var app = angular.module('app',[])
app.directive('helloWorld', function() {
return {
restrict: 'E',
scope: {
name: '#',
path:'#',
},
template: '<input type="text" name="{{name}}" ng-model="name"/> {{name}}',
controller: function($scope) {
$scope.name = "initial value";
$scope.$watch('name', function (newValue, oldValue) {
console.log("newValue: ",newValue);
})
}
}
});
Firstly, your directive syntax is wrong, here is the right one:
app.directive('helloWorld', function() {
return {
restrict: 'E',
scope: {
name: '#',
path:'#',
},
template: '<input type="text" name="{{name}}" ng-model="name">',
link: function(scope, elem, attrs) {
},
controller: function($scope) {
$scope.name = 'asd';
$scope.$watch('name', function (newValue, oldValue) {
})
}
}
});
Secondly, if you are looking to have a dynamic model, you should use scope: {name: '='} as # is for one-time binding
edit
changed name="name in template to name="{{name}}"
And here is a demo

Adding Multiple 'require' Options for Angular Directive

Usually in Directives, I use require: 'ngModel' if I want to pass the scope to it. This works fine. But I am now creating a directive that creates 5 different HTML elements each with different ngModels that is passed from parent. The ngmodels that needs to be passed as attribute are ngModel1, ngModel2, ngModel3, ngModel4, ngModel5. How do I add multiple options in the require condition inside the directive?
I tried these and it doesnt work:
require: ['ngModel1', 'ngModel2', 'ngModel3', 'ngModel4', 'ngModel5'],
and
require: {'ngModel1', 'ngModel2', 'ngModel3', 'ngModel4', 'ngModel5'},
and
require: 'ngModel1', 'ngModel2', 'ngModel3', 'ngModel4', 'ngModel5',
and
require: 'ngModel1, ngModel2, ngModel3, ngModel4, ngModel5'},
How do I add multiple require options?
EDIT:
HTML code:
<div get-vehicles-checkbox
cars-ng-model="formData.cars"
bikes-ng-model="formData.bikes"
trucks-ng-model="formData.trucks"
van-ng-model="formData.van"
bus-ng-model="formData.bus"
></div>
Directive:
app.directive('getVehiclesCheckbox', function($compile) {
return {
restrict: 'A',
replace:true,
// require: ?
scope: {
carsNgModel: '=',
bikesNgModel: '=',
trucksNgModel: '=',
vanNgModel: '=',
busNgModel: '='
},
controller: 'SomeController',
link: function(scope, element, attrs, carsNgModel, bikesNgModel, trucksNgModel, vanNgModel, busNgModel) {
scope.carsNgModel = {},
scope.bikesNgModel = {},
scope.trucksNgModel = {},
scope.vanNgModel = {},
scope.busNgModel = {}
var html = '<span ng-repeat="car in cars">' +
'<input type="checkbox" ng-model="carsNgModel[car.code]"> {{ car.number }} {{ car.description }}' +
'</span>' +
'<span ng-repeat="bike in bikes">' +
'<input type="checkbox" ng-model="bikesNgModel[bike.code]"> {{ bike.number }} {{ bike.description }}' +
'</span>';
//.... etc.. etc.....
// COMPILE HTML
//... .... ...
}
}
});
app.directive('myDirective', function() {
return {
restrict: "A",
require:['^parentDirective', '^ngModel'],
link: function ($scope, $element, $attrs, controllersArr) {
// parentDirective controller
controllersArr[0].someMethodCall();
// ngModel controller
controllersArr[1].$setViewValue();
}
}
});

AngularJS : Interpolating attributes

Say I have the following two directives:
angular.module('foo').directive('outer', [function(){
return {
restrict: 'E',
scope: {
inner: '#',
innneParams: '#'
},
template: "<div {{inner}}{{innerParams}}></div>",
link: function(scope, elem, attrs){
console.debug("I AM IN YOUR OUTER DIRECTIVE PASSING YOUR D00DZ!")
}
}
}]);
angular.module('foo').directive('innerDir', [function(){
return {
restrict: 'EA',
scope: {
innerParam: '='
},
template: "<div>{{massagedInner}}</div>",
link: function(scope, elem, attrs){
console.debug('I AM IN YOUR INNER DIRECTIVE MASSAGING YOUR D00DS!')
scope.massagedInner = scope.innerParam + "FROM YOUR DOGE!"
}
}
}]);
And the following HTML:
<outer inner="inner-dir" my-awesome-scope-value="myAwesomeScopeValue" inner-params="inner-param='myAwesomeScopeValue'"></outer>
The outer directive console debug triggers, the inner one does not. Is there a good way for me to achieve this kind of behaviour?
Plunk: http://plnkr.co/edit/jXbtWvYvtFXCTWiIZUDW?p=preview
There are quite a few things you're doing wrong. I've made the changes that I thought are close to what you wanted it to do and you can change the code from here.
Here's a working version
And this is what script.js now looks like;
angular.module('foo', []);
angular.module('foo').controller('fooController', ['$scope', function(scope){
scope.myAwesomeScopeValue = 'O HAI THERE'
}]);
angular.module('foo').directive('outer', [function(){
return {
restrict: 'E',
scope: {
// inner: '#',
// innnerParams: '#'
innerParam: '#'
},
template: "<div inner {{inner}} {{inner-param}}></div>",
link: function (scope) {
console.log('OUTER', scope.innerParam);
}
}
}]);
angular.module('foo').directive('inner', [function(){
return {
restrict: 'A',
// scope: {
// innerParam: '='
// },
replace: false,
template: "<div>{{massagedInner}}</div>",
link: function(scope, elem, attrs){
scope.massagedInner = scope.innerParam + "FROM YOUR DOGE!"
console.log('INNER');
}
}
}]);
For brevity, I've left some of your lines commented out. I hope this helps.

Categories