Angular inserted HTML not attached to controller - javascript

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

Related

ng-click on ng-repeat in a directive

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.

UI Bootstrap custom directive controller is not a function

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>

Cant seem to get Angular Routing working on some occasions?

I have been attempting to get angular routing working and everytime I create a new project and It does not work. I have had it working in some projects but I can never see why my newly created project does not work.
Its probably something obvious, thanks for any help in advance.
<!DOCTYPE html>
<html ng-app="app">
<head>
<title></title>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<link href="Content/Styles.css" rel="stylesheet" />
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-route.min.js"></script>
</head>
<body>
<a href="#/">
<button class="btn btn-danger">Homepage</button></a>
<a href="#/about">
<button class="btn btn-success">About</button></a>
<a href="#/date">
<button class="btn btn-warning">Date</button></a>
<div class="row">
<div ng-view>
</div>
</div>
<script src="SinglePageApp/app.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
</body>
</html>
app.js file
var app = angular.module('app', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
//default page
.when('/', {
templateUrl: "pages/homepage.html",
controller: 'HomeCtrl'
})
//about page
.when('/about', {
templateUrl: "pages/about.html",
controller: 'AboutCtrl'
})
//date page
.when('/date', {
templateUrl: "pages/date.html",
controller: 'DateCtrl'
});
});
app.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.homepage = "Homepage";
}]);
app.controller('AboutCtrl', ['$scope', function ($scope) {
$scope.about = "Lorem ipsum............";
}]);
app.controller('DateCtrl', ['$scope', function ($scope) {
$scope.dateNow = new Date();
}]);
Try this plunker:
http://embed.plnkr.co/L6E4GCe3O0Jh1vqKyGFD/
I've used the example at the angularJS documentation to create your usecase.
You should change the template filepaths, with your own. I also haven't included bootstrap.
If you want to use buttons, then you can use this example in plunkr based on this answer by Josh David Miller(upvote him if you use his directive). Directives are a way to customize html, and here we're using one as an html attribute (you can also use them as standalone elements) to create a hyperlink button.
Here's fiddle for you that works as expected
Not sure why your code is not working, angular has pretty bad debugging tool.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-route.js"></script>
<div>
<a href="#/">
<button class="btn btn-danger">Homepage</button>
</a>
<a href="#/about">
<button class="btn btn-success">About</button>
</a>
<a href="#/date">
<button class="btn btn-warning">Date</button>
</a>
<div class="row">
<div ng-view></div>
</div>
</div>
<script type="text/ng-template" id="pages/homepage.html">
{{homepage}}
</script>
<script type="text/ng-template" id="pages/about.html">
{{about}}
</script>
<script type="text/ng-template" id="pages/date.html">
{{dateNow}}
</script>
Script file looks like this
var app = angular.module('app', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
//default page
.when('/', {
templateUrl: "pages/homepage.html",
controller: 'HomeCtrl'
})
//about page
.when('/about', {
templateUrl: "pages/about.html",
controller: 'AboutCtrl'
})
//date page
.when('/date', {
templateUrl: "pages/date.html",
controller: 'DateCtrl'
})
.otherwise({redirectTo:'/'});
});
app.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.homepage = "Homepage";
}]);
app.controller('AboutCtrl', ['$scope', function ($scope) {
$scope.about = "Lorem ipsum............";
}]);
app.controller('DateCtrl', ['$scope', function ($scope) {
$scope.dateNow = new Date();
}]);
angular.bootstrap(document.body, ['app']);

AngularJs. ngInclude inside jQuery popover

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

Angular ui modal with controller in separate js file

I am trying to make a modal which can be instantiated from multiple places in the app. from the example given here: Angular directives for Bootstrap the modal controller is in the same file as the controller who instantiates the modal. I want to separate the modal controller from the "app" controller.
index.html:
<!DOCTYPE html>
<html ng-app="modalTest">
<head>
<link rel="stylesheet" type="text/css" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body ng-controller="modalTestCtrl">
<button ng-click="openModal()">Modal</button>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.10.0/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="modalTest.js"></script>
</body>
</html>
The controller:
var app = angular.module('modalTest', ['ui.bootstrap']);
app.controller('modalTestCtrl', ['$scope', '$modal', function($scope, $modal) {
$scope.openModal = function() {
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'modalCtrl',
size: 'sm'
});
}
}]);
// I want this in another JavaScript file...
app.controller('modalCtrl', ['$scope', function($scope) {
$scope.hello = 'Works';
}]);
modal.html:
<div ng-controller="modalCtrl">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<h1>{{hello}}</h1>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</div>
Is there any way to put the modalCtrl in another JavaScript file and somehow inject the controller (modalCtrl) into the modalTestCtrl ?
BR
Of course, you can do it. First of all you should use a function declaration.
// modalCtrl.js
// This file has to load before modalTestCtrl controller
function modalCtrl ($scope) {
$scope.hello = 'Works';
};
Then, change the modalTestCtrl like:
app.controller('modalTestCtrl', ['$scope', '$modal', function($scope, $modal) {
$scope.openModal = function() {
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: modalCtrl, //This must be a referance, not a string
size: 'sm'
});
}
}]);
With the changes above, you code has to work.

Categories

Resources