If I do something like this in my directive:
template: '<button ng-click="Done()">DONE</button>'
Then where do I put my $scope.Done() function? I have it in a controller here but that doesn't seem to work
<!DOCTYPE html>
<html>
<head>
</head>
<body ng-app="myApp" ng-controller="myctrl">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
<div mydiv></div>
<script>
angular.module("myApp", [])
.controller("myctrl", function($scope) {
$scope.Done = function() {
alert('Done');
};
});
angular.module("myApp", [])
.directive("mydiv", function() {
return {
template: '<button ng-click="Done()">DONE</button>'
};
});
</script>
</body>
</html>
Doing something like this will serve your purpose. Give a try ..
angular.module("myApp", [])
.directive("mydiv", function() {
return {
template: '<button ng-click="Done()">DONE</button>',
link: function (scope, element, attrs) {
scope.Done = function () {
alert('Done');
}
}
};
});
Remove below fuction from controller.
$scope.Done = function() {
alert('Done');
};
Not good approach to set the function directly, you need to bind it.
<!DOCTYPE html>
<html>
<head>
</head>
<body ng-app="myApp" ng-controller="myctrl">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.7/angular.min.js"></script>
<div mydiv on-done="Done()"></div>
<script>
angular.module("myApp", [])
.controller("myctrl", function($scope) {
$scope.Done = function() {
alert('Done');
};
});
angular.module("myApp", [])
.directive("mydiv", function() {
return {
scope: {
onDone: '&'
},
template: '<button ng-click="onDone()">DONE</button>'
};
});
</script>
</body>
</html>
Here's a working example:
http://jsfiddle.net/ADukg/17585/
Related
I have input(s) text inside a string and need to convert if found any characters like ## to <input type="text" />. I have no problems to return the value if I used ng-bind-html. However, ng-model value did not return using mathjax-bind.
How to solve this issue? Thanks.
HTML codes:
<script type="text/x-mathjax-config"> MathJax.Hub.Config({ tex2jax: {inlineMath: [['`','`'], ['\\(','\\)']]} }); </script>
<div ng-controller="MyCtrl">
\(-3\times 4=\)
<br/>
<br/>
<br/>
<div mathjax-bind="output">
</div>
<br/>
<button ng-click="check_answer()">
Check Answer
</button>
</div>
Controller:
var myApp = angular.module('myApp',[]);
myApp.directive("mathjaxBind", function() {
return {
restrict: "A",
controller: ["$scope", "$element", "$attrs",
function($scope, $element, $attrs) {
$scope.$watch($attrs.mathjaxBind, function(texExpression) {
$element.html(texExpression);
MathJax.Hub.Queue(["Typeset", MathJax.Hub, $element[0]]);
});
}]
};
});
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.form = {};
var output = 'Answer: <br/> ##';
$scope.output = output.replace('##','<input type="text" ng-model="form.data.input1" />');
$scope.check_answer = function()
{
alert($scope.form.data.input1);
}
}
Mathjax-bind with angularjs model fiddle
I got the solution. I just need to compile again...the code:
myApp.directive("mathjaxBind", function($compile) {
return {
restrict: "A",
controller: ["$scope", "$element", "$attrs",
function($scope, $element, $attrs) {
$scope.$watch($attrs.mathjaxBind, function(texExpression) {
$element.html(texExpression);
$compile($element.html(texExpression).contents())($scope);
MathJax.Hub.Queue(["Typeset", MathJax.Hub, $element[0]]);
});
}]
};
});
Here's the working fiddle.
Could you please let me know what is wrong with my code? I get the initial HTML page, but when I click on "Open", nothing happens. Not even the console logs an error, or any other change.
app.js
var app = angular.module('carApp', ['ui.bootstrap']);
ctrl.js
app.controller('carCtrl', function($scope, $http, $uibModal) {
$http.get('jobs.json').success(function(data) {
$scope.data = data;
$scope.open = function() {
var modalContent = $uibModal.open({
templateUrl: 'careersTpl.html',
controller : modalContentCtrl,
resolve: {
items: function() {
return $scope.data;
}
}
})
}
});
});
var modalContentCtrl = function ($scope, $modalInstance, data) {
$scope.data = data;
$scope.selected = {
item: $scope.data.specs
};
};
JSON:
{
"specs":[
{
"job-title":"TITLE",
"job-apply":"applink",
"job-body":"JOB BODY"
}
]
}
HTML:
<div class="car-up">
<script type="text/ng-template" id="careersTpl.html">
<div class="modal-header">
<h3>Lorem Ipsum</h3>
</div>
<div class="modal-body">
<p ng-repeat="item in data">{{item}}</p>
</div>
</script>
<button class="btn" ng-click="open()">Open</button>
</div>
I'm new to AngularJS, but I have linked the app.js and ctrl.js... thanks.
EDIT: after I've placed ng-controller="carCtrl" in the html file, I receive this error:
Error: [$injector:unpr]
http://errors.angularjs.org/1.5.7/$injector/unpr?p0=%24modalInstanceProvider%20%3C-%20%24modalInstance
O/<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:6:412
db/n.$injector<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:43:84
d#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:40:344
db/V<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:43:144
d#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:40:344
e#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:41:78
h/<.invoke#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:41:163
gf/this.$gethttps://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:89:397
resolveSuccess#https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.2.0/ui-bootstrap-tpls.js:4422:34
e/<#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:130:409
vf/this.$gethttps://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:145:103
vf/this.$gethttps://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:142:165
vf/this.$gethttps://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:145:399
Lc[b]https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:274:444
Sf#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:37:31
Rf/d#https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js:36:486
Please find working demo
angular.module('carApp', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
var app = angular.module('carApp');
app.controller('carCtrl', function($scope, $http, $uibModal) {
//$http.get('jobs.json').success(function(data) {//Uncomment
//$scope.data = data; Uncomment
//Remove below line from code when you are using this in your project
$scope.data = {
"specs": [{
"job-title": "TITLE",
"job-apply": "applink",
"job-body": "JOB BODY"
}]
}
$scope.open = function() {
var modalContent = $uibModal.open({
templateUrl: 'careersTpl.html',
controller: 'ModalInstanceCtrl',
controllerAs: '$ctrl',
resolve: {
items: function() {
return $scope.data;
}
}
})
}
//});//Uncomment
});
app.controller('ModalInstanceCtrl', function($uibModalInstance, items, $scope) {
$scope.data = items;
console.log($scope.data);
$scope.selected = {
item: $scope.data.specs
};
});
<!doctype html>
<html ng-app="carApp">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.3.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="carCtrl" class="modal-demo">
<script type="text/ng-template" id="careersTpl.html">
<div class="modal-header">
<h3>Lorem Ipsum</h3>
</div>
<div class="modal-body">
<p ng-repeat="(k,v) in data.specs">
<span>Title: {{v["job-title"]}}<br/> </span>
<span>Link: {{v["job-apply"]}}<br/> </span>
<span>Body: {{v["job-body"]}}<br/> </span>
</p>
</div>
</script>
<button class="btn" ng-click="open()">Open</button>
</div>
</body>
</html>
Try defining the controller like this outside,
app.controller('modalContentCtrl ', function($scope, $modalInstance, data) {
$scope.data = data;
$scope.selected = {
item: $scope.data.specs
};
}
I am very new to js overall so please be patient with me.
I need to make a simple task which is stated in the topic. I have done some research and tried to make using ui.router but since I am not very good with coding something went wrong.
I want that this information from url would be displayed inside the modal dialogue http://prntscr.com/ashi5e
So here is the code:
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
};
};
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
<!doctype html>
<html ng-app="plunker">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<script src="js/example.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>Log</h3>
</div>
<div class="modal-body">
Content
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
</script>
<button class="btn" ng-click="open()">Log</button>
</div>
</body>
</html>
You need to get the data (eg. with a service) and put it into $scope.items. In your modal do the same: get items and bind it to your scope. That's all
angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log, $http) {
/* Get data here with a service or smth */
$scope.items = '';
$scope.open = function () {
$http.get("YOUR_URL")
.then(function(response) {
$scope.items = response.data
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
}
}
});
});
};
};
var ModalInstanceCtrl = function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
<!doctype html>
<html ng-app="plunker">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<script src="js/example.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3>Log</h3>
</div>
<div class="modal-body">
{{items}}
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
</script>
<button class="btn" ng-click="open()">Log</button>
</div>
</body>
</html>
You didn't registered modalDemoCtrl and ModalInstanceCtrl at first you need to register both controller like: myApp.controller('modalDemoCtrl', ModalDemoCtrl); where myApp is angular module like: var myApp = angular.module('plunker', ['ui.bootstrap']);.
you can use a service to get data from an url by using$http and that service inject in your modalInstance controller. in my example create dataService and a function named getData and called this function from modalInstance controller. like: dataService.getData().then(.. and use then function to get response. and store response data in to $scope.infos variable so you can use this $scope.infos in your modal.
var myApp = angular.module('plunker', ['ui.bootstrap']);
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
};
};
myApp.controller('modalDemoCtrl', ModalDemoCtrl);
myApp.factory('dataService', function($http) {
return {
getData: function() {
return $http.get('http://prnt.sc/ashi5e');
}
};
});
var ModalInstanceCtrl = function ($scope, $modalInstance, items, dataService) {
dataService.getData().then(function(response) {
$scope.infos = response.data;
});
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
myApp.controller('ModalInstanceCtrl', ModalInstanceCtrl);
So i still new to angular and java script but i read it was good practical to wrap the everything into functions.
This is what i have done.
in comment is the previous version
app.js
//var app = angular.module('app',['ngRoute','ngResource','routes']);
(function(angular) {
angular.module("app.directives", []);
angular.module("app.controllers", []);
angular.module("app", ['ngRoute','ngResource','routes','app.directives','app.controllers']);
}(angular));
directives.js
/*
app.directive('footer', function () {
return {
replace: true,
templateUrl: "/template/main_footer.html",
controller: ['$scope', '$filter', function ($scope, $filter) {
}]
}
});
*/
(function(angular) {
var footer = function () {
return {
replace: true,
templateUrl: "/template/main_footer.html",
controller: ['$scope', '$filter', function ($scope, $filter) {
}]
};
};
footer.$inject = [];
angular.module("app.directives").controller("footer", footer);
});
controller.js
/*app.controller('HeaderController',function($scope, $location) {
$scope.isActive = function (viewLocation) {
var active = (viewLocation === $location.path());
return active;
};
});*/
(function(angular) {
var HeaderController = function($scope,$location){
$scope.isActive = function(viewLocation){
var active = (viewLocation === $location.path());
return active;
};
}
HeaderController.$inject = ['$scope','$location'];
angular.module("app.controllers").controller("HeaderController", HeaderController);
})
and how should i proceed for routes.js
angular.module('routes', []).config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'pages/home.html'
})
.when('/second', {
templateUrl: 'pages/second.html'
})
.when('/third', {
templateUrl: 'pages/third.html'
})
.when('/123', {
templateUrl: 'pages/123.html'
})
.otherwise({
redirectTo: '/'
});
});
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/custom.css">
<script type="text/javascript" src="https://code.angularjs.org/1.4.4/angular.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.4.4/angular-resource.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.4.4/angular-route.js"></script>
<script type="text/javascript" src="js/routes.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/controllers.js"></script>
<script type="text/javascript" src="js/directives.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
But it does not work. And i find it hard to find what went wrong because i don't get a error with the development tools on google chrome
Update
Now i do call the function at the end.
But i still can't see the footer. I also added the footer.html just in case there would something i forgot there.
directives.js
(function(angular) {
var footer = function () {
return {
replace: true,
templateUrl: "/template/main_footer.html",
controller: ['$scope', '$filter', function ($scope, $filter) {
}]
};
};
footer.$inject = [];
angular.module("app.directives").controller("footer", footer);
}(angular));
home.html
<div>
<div>
<h3>This is the homepage</h3>
</div>
<div footer></div>
</div>
In the 'directives.js' and 'controller.js' files, you forgot (angular) at the end, like in 'app.js'.
If you write a function like this:
function f() {
// do stuff...
}
it's never going to run unless you call it somewhere: f();. Now, if you want to wrap a bit of code in a function, you still want it to run immediately as if it had not been wrapped. So what you do is you call the wrapping function immediately like this:
(function f() {
// do stuff...
})();
or like this (same thing):
(function f() {
// do stuff...
}());
In that second way of writing things, the outermost parentheses are useless for the program but they help the reader see that the function will be immediately run (or "evaluated", or "called").
You can also pass anything that lives outside of the function into the function, for example angular:
(function f(angular) {
// do stuff...
}(angular));
That is because you're missing the function invocation in some of those wrappings. For example, controller.js needs to be:
(function(angular) {
var HeaderController = function($scope,$location){
$scope.isActive = function(viewLocation){
var active = (viewLocation === $location.path());
return active;
};
}
HeaderController.$inject = ['$scope','$location'];
angular.module("app.controllers").controller("HeaderController", HeaderController);
})(angular); // CALL FUNCTION
Note in the last line I added (angular); to actually call the function.
I have a loading div that I'd like to share across several controllers. Is there a way to accomplish this without placing this template in every other template?
For example:
<div ng-show="loading" class="loading">Loading</div>
Now in my controller I turn this off and on my using $scope.loading = true/false.
In my main page I use this:
<div class="container" ng-app="myApp">
<div ng-view>
</div>
</div>
I'm using routing so, right now I have to place the loading div in each template that is called by the router so it is inserted in ng-view. All I want is one location for the loading div. How do I accomplish this?
Set up the loading div as a custom directive, check out this example from the angularjs documentation:
angular.module('docsSimpleDirective', [])
.controller('Controller', ['$scope', function($scope) {
$scope.customer = {
name: 'Naomi',
address: '1600 Amphitheatre'
};
}])
.directive('myCustomer', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}}'
};
});
http://plnkr.co/edit/?p=preview
There's quite a few ways to do this.
What I've come up with is to use a service to register an AppController callback. Then in each of my page's controllers I inject that service, and call the callback with true/false.
The full code is below, but the main lines to focus on is:
myApp.service('LoadingService', function() {
var controllerCallback = function() {};
this.setControllerCallback = function(callback) {
controllerCallback = callback;
};
this.setLoading = function(bool) {
controllerCallback(bool);
};
});
And in your AppController:
LoadingService.setControllerCallback(function(bool) {
$scope.loading = bool;
});
Then to show the loading div, just inject that service into a controller and call
LoadingService.setLoading(true) //or false
This allows for the service to be reused in any controller that needs to toggle the loading div.
// Code goes here
var myApp = angular.module('app', ['ngRoute']);
myApp.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/page1', {
templateUrl: 'page1.html',
controller: 'PageOneController'
})
.when('/page2', {
templateUrl: 'page2.html',
controller: 'PageTwoController'
})
});
myApp.controller('AppController', function($scope, LoadingService) {
$scope.loading = false;
LoadingService.setControllerCallback(function(bool) {
$scope.loading = bool;
});
});
myApp.controller('PageOneController', function($timeout, LoadingService) {
LoadingService.setLoading(true);
$timeout(function() {
LoadingService.setLoading(false);
}, 2000);
});
myApp.controller('PageTwoController', function($timeout, LoadingService) {
LoadingService.setLoading(true);
$timeout(function() {
LoadingService.setLoading(false);
}, 3000);
});
myApp.service('LoadingService', function() {
var controllerCallback = function() {};
this.setControllerCallback = function(callback) {
controllerCallback = callback;
};
this.setLoading = function(bool) {
controllerCallback(bool);
};
});
<!DOCTYPE html>
<html ng-app="app">
<head>
</head>
<body ng-controller="AppController">
<h1>Title</h1>
Page 1
Page 2
<div ng-if="loading">Loading...</div>
<div ng-view></div>
<script src="https://code.angularjs.org/1.4.3/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular-route.min.js"></script>
<script type="text/ng-template" id="page1.html">
<div>You're on page one</div>
</script>
<script type="text/ng-template" id="page2.html">
<div>You're on page two</div>
</script>
</body>
</html>