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
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
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>
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
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();
}
}
});
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.