I'm starting to learn AngularJs but faced with one problem. The ng Include directive won't work inside jQuery popover. Here is code example: (http://jsfiddle.net/kgupkx87/13/)
As you can see, $scope.loaded function has been executed, but HTML hasn't been included inside popover template.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<title>ng-include issue</title>
</head>
<body>
<div data-ng-app="myApp" data-ng-controller="defaultCtrl">
<button data-my-directive data-popover-title="Settings" data-popover-template="settings.html" data-popover-placement="right">
Settings
</button>
<script type="text/ng-template" id="settings.html">
<p>{{mainFormTmpl}}</p>
<ul>
<li data-ng-repeat="num in [1,2,3]">{{num}}</li>
</ul>
<span ng-include="mainFormTmpl" onload="loaded()"></span>
</script>
<script type="text/ng-template" id="main-form.html">
<p>List of directives</p>
</script>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script type="text/javascript" src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.controller("defaultCtrl", ["$scope", function($scope) {
$scope.mainFormTmpl = "main-form.html";
$scope.loaded = function() { console.log("Loaded"); }
}]);
app.directive("myDirective", ["$templateCache", "$compile", function($templateCache, $compile) {
return {
scope: true,
restrict: "A",
controller: function($scope) {
$scope.save = function(e) {}
$scope.cancel = function(e) {}
},
link: function(scope, el, attrs) {
var tpl = $templateCache.get(attrs.popoverTemplate);
el.popover({
trigger: 'click',
html: true,
title: attrs.popoverTitle,
content: $compile(tpl)(scope),
placement: attrs.popoverPlacement
});
}
}
}]);
</script>
</body>
</html>
I would be grateful for any hints
You need to work on ng-include likewise:
<p><ng-include src="mainFormTmpl" /></p>
instead
<p>{{mainFormTmpl}}</p>
Demo
Related
I am new to AngualrJS and I am having trouble getting a ng-click working inside a ng-repeat that sits inside a directive.
I use ng-repeat to display a list of PDFs and currently just trying to be able to click them to pop up an alert window. But I don't seem to be able to get any ng-click working within the directive.
The Angular code:
var app = angular.module("aria", []);
app.directive("rdnglist", function(){
return {
restrict: 'E',
templateUrl: "rdnglist.html",
controller: function(){
this.pdfs = pdflist;
this.test = function() {
$window.alert("hi");
};
},
controllerAs: "plist",
};
});`
The HTML:
<div class="fullsect">
<div class="pdflist" ng-repeat="pdf in plist.pdfs">
<h3>{{pdf.name}}</h3>
<img ng-src="{{pdf.image}}" ng-click="test()"/>
<p>Class: {{pdf.class}}</p>
<div id="commentNo">{{pdf.comments}}</div>
</div>
<div class="pdflist">
<h3>New File</h3>
<a ng-click="test()">Open</a>
<img src="/pictures/addnew.png"/>
</div>
I assume it has something to do with the scope of the controller but I'm unsure. As I'm new, I learned to use ControllerAs over $scope, is this the issue?
Here is a working plunker based on your code.
I changed the directive to inject $window ... see ['$window, function($window) to make the alert work. I also initialize with dummy data:
The app:
var app = angular.module('plunker', []);
app.directive("rdnglist", ['$window', function($window){
return {
restrict: 'E',
templateUrl: "rdnglist.html",
controller: function(){
this.pdfs = [{'name':'abc'}];
this.test = function() {
$window.alert("hi");
};
},
controllerAs: "plist",
};
}]);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
And the rdnglist.htm... as you are using ControllerAs, you need plist.test(). To reduce my work I hardcoded an AngularJS image:
<div class="fullsect">
<div class="pdflist" ng-repeat="pdf in plist.pdfs">
<h3>{{pdf.name}}</h3>
<a ng-click="plist.test()"><img ng-src="http://code-maven.com/img/angularjs.png" /></a>
<p>Class: {{pdf.class}}</p>
<div id="commentNo">{{pdf.comments}}</div>
</div>
<div class="pdflist">
<h3>New File</h3>
<a ng-click="test()">Open</a>
<img src="/pictures/addnew.png"/>
</div>
</div>
index.html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<rdnglist></rdnglist>
</body>
</html>
let us know if that helps.
I want to use UI Bootstrap Collapse in my custom directive <collapse>
However, I get this Error: [ng:areq] Argument 'CollapseDemoCtrl' is not a function, got undefined
Here is my Plunkr
What am I doing wrong?
Remove ng-controller from template.
Define controller inline:
controller: ['$scope', function($scope){
$scope.isCollapsed = false;
}]
Plunk
Another option is to define controller:
.controller('CollapseDemoCtrl', function($scope){
$scope.isCollapsed = false;
});
and refer to it in directive: controller: 'CollapseDemoCtrl'
Plunk
angular.module('myApp.collapse', []);
angular.module('myApp', [
'ngAnimate',
'myApp.collapse',
'ui.bootstrap'
]);
(function(){
'use strict';
angular.module('myApp.collapse',[])
.controller('CollapseDemoCtrl', CollapseDemoCtrl)
.directive('collapse', function(){
return {
restrict: 'E',
templateUrl: 'collapse.html',
controller: 'CollapseDemoCtrl'
};
});
function CollapseDemoCtrl($scope){
$scope.isCollapsed = false;
}
})();
<!doctype html>
<html ng-app="myApp">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.1.0.js"></script>
<script src="app.js"></script>
<script src="collapse-module.js"></script>
<script src="collapse-directive.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<collapse></collapse>
</body>
</html>
<div>
<button type="button" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">Toggle collapse</button>
<hr>
<div uib-collapse="isCollapsed">
<div class="well well-lg">Some content</div>
</div>
</div>
angular.module('myApp.collapse', []);
angular.module('myApp', [
'ngAnimate',
'myApp.collapse',
'ui.bootstrap'
]);
(function(){
'use strict';
angular.module('myApp.collapse').
directive('collapse',['$http', function($http){
console.log("Test")
return {
restrict: 'E',
templateUrl: 'collapse.html',
controller: function ($scope) {
$scope.isCollapsed = false;
}
};
}]);
})();
<!doctype html>
<html ng-app="myApp">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.1.0.js"></script>
<script src="app.js"></script>
<script src="collapse-module.js"></script>
<script src="collapse-directive.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<collapse></collapse>
</body>
</html>
<div>
<button type="button" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">Toggle collapse</button>
<hr>
<div uib-collapse="isCollapsed">
<div class="well well-lg">Some content</div>
</div>
</div>
I want to use Angular to create a popover that contains a <textarea> and a <button> to perform an action.
I followed this guide to create my popover with a custom directive.
My problem is that the content in the popover doesn't appear to be attached to the main controller anymore when it is inserted. The contents of the <textarea> does not display with {{ textarea }}, and the ng-click="click()" does not trigger the $scope.click function defined in the controller.
Maybe this is due to the fact that the content of the popover is being set in the directive, instead of being declared in the view1.html document? Any help would be appreciated.
I've made this JSFiddle which demonstrates the issue - it is very slightly simplified from the code below, but the problem is demonstrated just fine.
directives.js:
module.directive('customPopover', [function(){
return {
restrict: 'A',
link: function (scope, el, attrs) {
$(el).popover({
trigger: attrs.popoverTrigger,
html: true,
content: function() {return $('#popover_content').html();},
placement: attrs.popoverPlacement
});
}
};
}]);
pages/view1.html:
<div>
<div id="controls">
<a custom-popover class="btn"
tabindex="0"
popover-html="copyPaste"
popover-placement="right"
popover-trigger="click"
role="button">Copy & paste data</a>
</div>
<div id="popover_content" style="display:none;">
<textarea id="textBox" type="text" ng-model="textarea"></textarea>
<button id="submitDataBtn" ng-click="click()" type="button">Submit</button>
</div>
{{ textarea }}
</div>
controller.js
var module = angular.module("moduleName", ['ngRoute']);
module.controller("SimpleController", function ($scope, gsatfFactory, $sce, $location) {
$scope.click = function() {
$scope.table = $sce.trustAsHtml(gsatfFactory.parseData($scope.textarea));
$location.path('view2');
};
});
module.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'pages/view1.html',
controller: 'SimpleController'
})
.when('/view2', {
templateUrl: 'pages/view2.html',
controller: 'SimpleController'
})
.otherwise({ redirectTo: '/' });
}]);
index.html
<!DOCTYPE html>
<html ng-app="moduleName">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
crossorigin="anonymous"></script>
<script src="js/controller.js"></script>
<script src="js/factory.js"></script>
<script src="js/directives/directives.js"></script>
</head>
<body>
<div data-ng-view></div>
</body>
</html>
Your content html isn't angular compiled. Use this to compile it:
$compile($('#popover_content').html())(scope);
your directive:
mod.directive('customPopover', function($compile){
return {
restrict: 'A',
link: function (scope, el, attrs) {
$(el).popover({
trigger: attrs.popoverTrigger,
html: true,
content: function() {return $compile($('#popover_content').html())(scope);},
placement: attrs.popoverPlacement
});
}
};
});
With the code below, I see my button (angular 1.3.15, DevExtreme 15.1.4)
HTML :
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>Testing</title>
<link href="Content/dx.common.css" rel="stylesheet" />
<link href="Content/dx.light.css" rel="stylesheet" />
</head>
<body>
<script src="/Scripts/jquery-1.11.3.min.js"></script>
<script src="/Scripts/jquery.globalize/globalize.js"></script>
<script src="/Scripts/angular.min.js"></script>
<script src="/Scripts/angular-sanitize.min.js"></script>
<script src="/Scripts/angular-ui-router.min.js"></script>
<script src="/Scripts/dx.webappjs.js"></script>
<script src="/app/app.js"></script>
<div ng-controller="myCtrl">
<div dx-button="{text: 'Test Button'}"></div>
</div>
</body>
</html>
app.js file :
var myApp = angular.module('myApp', ['dx']);
(function () {
angular.module('myApp')
.controller('myCtrl', ['$scope','dx', myCtrl]);
function myCtrl($scope, dx) {
var vm = this;
}
}());
I see the button and no error but when I add the controller in the div :
<div ng-controller="myCtrl">
<div dx-button="{text: 'Test Button'}"></div>
</div>
I get this error :
Error: [$injector:unpr] http://errors.angularjs.org/1.3.15/$injector/unpr?p0=dxProvider%20%3C-%20dx%20%3C-%20myCtrl
R/<#http://localhost:51314/Scripts/angular.min.js:6:417
You are attempting to inject the dx module into your myCtrl controller. Try removing it:
var myApp = angular.module('myApp', ['dx']);
(function () {
angular.module('myApp')
.controller('myCtrl', ['$scope', myCtrl]);
function myCtrl($scope) {
var vm = this;
}
}());
For future reference, following the link given in an Angular error can help reveal problems like these.
This is my code for popover using angular js and
I want to know that how we can add our styling in custom-popover popover-HTML
as I am not able to bind any element in the HTML part
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<div ng-app="customDirectives">
<div> <span custom-popover popover-html="Some Popover Text" popover-placement="bottom" popover-label="label"></span>
</div>
</div>
<script>
customDirectives = angular.module('customDirectives', []);
customDirectives.directive('customPopover', function () {
return {
restrict: 'A',
template: '<span>{{label}}</span>',
link: function (scope, el, attrs) {
scope.label = attrs.popoverLabel;
$(el).popover({
trigger: 'click',
html: true,
content: attrs.popoverHtml,
placement: attrs.popoverPlacement
});
}
};
});
angular.module('CustomComponents', ['customDirectives']);
</script>
</body>
</html>
Check this example (added popover-some-var to Your code) :
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<div ng-app="customDirectives">
<div> <span custom-popover popover-html="Some Popover Text" popover-placement="bottom" popover-label="label" popover-some-var="BLABLABLA"></span>
</div>
</div>
<script>
customDirectives = angular.module('customDirectives', []);
customDirectives.directive('customPopover', function () {
return {
restrict: 'A',
template: '<span>{{label}}</span>',
link: function (scope, el, attrs) {
scope.label = attrs.popoverLabel;
var someVar = attrs.popoverSomeVar; // HERE IS VARIABLE
$(el).popover({
trigger: 'click',
html: true,
content: attrs.popoverHtml + " " + someVar,
placement: attrs.popoverPlacement
});
}
};
});
angular.module('CustomComponents', ['customDirectives']);
</script>
</body>
</html>