I have the following kendoDatePicker included in an AngularJS directive; the directive is supposed to show the picker opening the calendar but it doesn't. What's wrong with this code? This is the plunk.
HTML:
<dir2></dir2>
Javascript:
var app = angular.module("app", [ "kendo.directives" ]);
function MyCtrl($scope) {
}
app.directive('dir2', function() {
var directive = {};
directive.restrict = 'A';
directive.template = '<input kendo-date-picker="picker" />';
directive.link = function (scope, element, attrs) {
scope.picker.open();
};
return directive;
});
You should define directive.restrict = 'E' instead of 'A'.
'A' refers for attribute, 'E' for element.
app.directive('dir2', function() {
var directive = {};
directive.restrict = 'E';
directive.template = '<input kendo-date-picker="picker" />';
directive.link = function (scope, element, attrs) {
scope.picker.open();
};
return directive;
});
This is the solution:
where it says
scope.picker.open();
it should say
$timeout(function() {
scope.picker.open();
}, 1);
Related
I have simple scenario with costume directive in angularjs. In which if there will be only one item in drop down it would be selected by default else it work as normal drop down list.
for that I try below code,
var app = angular.module("testapp", []);
(function () {
'use strict';
angular.module('testapp').controller('TestCtrl', ['$scope', TestCtrl]);
function TestCtrl($scope) {
$scope.Test=[];
$scope.Test.id=0;
$scope.data = [{
"id": 1,
"name": "abc"
}];
}
})()
angular.module('testapp').directive('advanceDropdown', function () {
var directive = {}
directive.restrict = 'A';
directive.require = 'ngModel';
directive.scope = {
items: '=advanceDropdown'
}
directive.link = function (scope, element, attrs, ctrl) {
if (scope.items.length == 1) {
element.val(scope.items[0]);
}
}
return directive;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.min.js"></script>
<div ng-app="testapp" ng-controller="TestCtrl">
<select name="ddlTest" ng-model="Test.id" ng-options="d.id as d.name for d in data" advance-dropdown="data" required>
<option value="" ng-selected="selected" disabled>--Select--</option>
</select>
</div>
but it can't works. what I missing in the code.
Your code is correct, only a small issue inside directive, try the following please
directive.link = function (scope, element, attrs, ctrl) {
if (scope.items.length == 1) {
element.val = scope.items[0];
}
}
Demo
I have the following directive that has two children divs. The second div (created with angular.element) should be clickeable. Since I created it with angular.element, I'm trying to add ng-click with the attr function, but this doesn't work. What's wrong with this code?
app.directive('mydir', function () {
var directive = {};
directive.restrict = 'EA';
directive.replace = true;
directive.scope = {
control: '=',
};
directive.template = '<div id="root"></div>';
directive.link = function (scope, element, attrs) {
var wrap = angular.element('<div id="wrap"></div>');
element.append(wrap);
var node = angular.element('<div id="node"></div>');
node.attr('ng-click', 'toggle()'); // <--- this doesn't work
wrap.append(node);
scope.toggle = function () {
alert('clicked');
};
});
return directive;
});
The element has to be compiled using angular's $compile service:
app.directive('mydir', function ($compile) { // added dependency here
var directive = {};
directive.restrict = 'EA';
directive.replace = true;
directive.scope = {
control: '=',
};
directive.template = '<div id="root"></div>';
directive.link = function (scope, element, attrs) {
var wrap = angular.element('<div id="wrap"></div>');
element.append(wrap);
var node = angular.element('<div id="node"></div>');
node.attr('ng-click', 'toggle()'); // <--- this doesn't work
var content = $compile(node)(scope);
wrap.append(content);
scope.toggle = function () {
alert('clicked');
};
});
return directive;
});
Here's a short tutorial on using $compile. Hope that helps
This is part of my AngularJS application
.controller('Littlebear',function($scope) {
$scope.spread='<h1>this is the</h1> Littlebear spread.'+
'<img ng-src="src/images/retro.png" alt="picture" ng-click="click()">';
})
.directive('spread', function($compile) {
var templateTemp='<p> try again </p>';
var directive = {};
directive.compile = function(element, attributes) {
var linkFunction = function($scope, element, atttributes) {
// bind element to data in $scope
templateTemp=$scope.spread;
return templateTemp;
};
return linkFunction;
};
directive.restrict = 'E'; /* restrict this directive to elements */
directive.template = templateTemp;
return directive;
})
I would like to set template = $scope.spread inside the directory.
If I console.log the templateTemp inside the linkFunction the value of templateTemp is exacly what I am looking for but ouside of that function is templateTemp=' try again ';
can anyone suggest any solution?
(PS: as you might imagine I am quite new to AngularJS)
Thanks Vincent
In link function you can do something as below.
In link function, I have compiled the desired html and replaced the directive element with the same.
.controller('Littlebear',function($scope) {
$scope.spread='<h1>this is the</h1> Littlebear spread.'+
'<img ng-src="src/images/retro.png" alt="picture" ng-click="click()">';
})
.directive('spread', function($compile) {
var templateTemp='<p> try again </p>';
var directive = {};
directive.compile = function(element, attributes) {
var linkFunction = function($scope, element, atttributes) {
// you can change and compile the html like this
//element.replaceWith($compile($scope.spread)); //Please Check this line<-----
//Please try this.
var html =$scope.spread;
var e =$compile(html)($scope);
element.replaceWith(e);
};
return linkFunction;
};
directive.restrict = 'E'; /* restrict this directive to elements */
directive.template = templateTemp;
return directive;
})
I am newer in angularjs. I am just trying to update the input txt value using custom Directive. But i cant. Here i have showed my code What i did wrong this code. Some one help me and explain how it is working.
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
myApp.controller('MyCtrl',MyCtrl);
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.myTime = '10:59';
}
myApp.directive('myDirective', function () {
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
scope.$watch(attrs.ngModel, function (v) {
console.log('value changed, new value is: ' + v);
ngModel.$setViewValue('11')
//scope.ngModel = '11'
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="MyCtrl">
Hello, {{name}}!
<input type="text" my-directive ng-model="myTime" name="customTime">
</div>
You should register your MyCtrl controller in your myApp module like below.
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl',MyCtrl);
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.myTime = '10:59';
}
If you need to update the text field value to some desired value, once you're done with the update in the watcher using $setViewValue(), you need to call $render() as well on NgModelController.
link: function (scope, element, attrs, ngModel) {
scope.$watch(attrs.ngModel, function (v) {
console.log('value changed, new value is: ' + v);
ngModel.$setViewValue('11');
ngModel.$render();
});
}
Here's a Pen to check this change.
I have two angularjs directives (extWindow and taskBar) and want to inject taskBar's controller into extWindow in order to access it's scope. Because they don't share the same scope I used
require : '^$directive'
syntax to include it.
Doing so I could get rid of the error 'Controller 'taskBar', required by directive 'extWindow', can't be found!' but TaskBarCtrl is still undefined in link(..) method of the extWindow directive.
Any suggestions how to fix it?
var mod = angular.module('ui', [])
.directive('taskBar', function() {
var link = function(scope, el, attrs) {
$(el).css('display', 'block');
$(scope.titles).each(function(i,t) {
el.append('<span>' + t + '</span>')
});
};
return {
scope: {},
restrict : 'E',
controller: function($scope, $element, $attrs) {
$scope.titles = [];
this.addTitle = function(title) {
$scope.titles.push(w);
};
this.removeTitle = function(title) {
$scope.titles = jQuery.grep(function(n,i) {
return title != n;
});
}
},
link: link
};
}).directive('extWindow', function() {
return {
scope: {},
require: '^?taskBar',
restrict: 'E',
transclude: true,
template: '<div class="ui-window">\
<div class="ui-window-header"><span>{{windowTitle}}</span><div class="ui-window-close" ng-click="close()">X</div></div>\
<div class="ui-window-content" ng-transclude></div>\
</div>',
link: function(scope, element, attrs, taskBarCtrl) {
scope.windowTitle = attrs['windowTitle'];
scope.close = function() {
$(element).css('display', 'none');
}
//taskBarCtrl is not recognized!!!
taskBarCtrl.addTitle(scope.windowTitle);
}
}
});
http://jsfiddle.net/wa9fs2nm/
Thank you.
golbie.
If you have a controller for your parent directive and you need something like.
this.scope = $scope;
this.attrs = $attrs;
And in your in you link function for the child you need something like
var Ctrl = ctrl || scope.$parent.tBarCtrl;
Here's a Plunker