How do I display the inner html of directive inside a dialog? - angularjs

What do I want to do?
I want to have a directive with some html inside. The directive renders a button and when the button is clicked I open a modal dialog. I want to display the html declared inside the directive in the dialog. Different spots where I use the directive might have different html messages in the modal dialog.
Here is the code that I've got.
app.js:
var app = angular.module('plunker', ['ngResource', 'ui.bootstrap', 'ui.bootstrap.modal']);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
})
.controller('dialogController', ['$scope', '$modalInstance', 'params', function ($scope, $modalInstance, params) {
$scope.info = params.info;
$scope.close = function () {
$modalInstance.dismiss('cancel');
};
}])
.directive('someDirective', ['$modal', '$timeout', function ($modal, $timeout) {
return {
scope: {
title: '#title'
},
restrict: 'AE',
replace: true,
templateUrl: 'someDirective.html',
transclude: true,
link: function ($scope, $element, attr, controller, transclude) {
//transclude(function(clone, scope) {
// debugger;
// });
$scope.info = "test"; // I would like to set this to the value within the inner html of the directive.
$scope.openDialog = function () {
var modalInstance = $modal.open({
templateUrl: 'dialog.html',
controller: 'dialogController',
backdrop: 'static',
windowClass: 'ie-app-modal-window-narrow',
resolve: {
params: function () {
return {
info: 'SomeHtml' //<-- here I want to it to the html from inside someDirective
};
}
}
});
modalInstance.result.then(function () {
},
function () { });
};
}
};
}])
;
dialog.html:
<!DOCTYPE html>
<html>
<head>
<title>Add attachment</title>
<meta charset="utf-8"/>
</head>
<body>
<div class="modal-header">
<button type="button" class="close"><span aria-hidden="true" ng-click="close()">×</span></button>
<strong>Add Attachment</strong>
</div>
<div class="modal-body">
<!-- Text input-->
<div class="alert alert-info" role="alert">
{{info}}
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div style="float: left">
<button class="btn btn-default" ng-click="close()" ng-disabled="isDisabled">Close</button>
</div>
</div>
</div>
</body>
</html>
index.html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="jquery#2.2.4" data-semver="2.2.4" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link data-require="bootstrap#3.3.7" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script data-require="bootstrap#3.3.7" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script data-require="angular-ui#0.4.0" data-semver="0.4.0" src="http://rawgithub.com/angular-ui/angular-ui/master/build/angular-ui.js"></script>
<script data-require="angular-ui-bootstrap#1.3.3" data-semver="0.12.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.min.js"></script>
<script data-require="angular-resource#1.2.28" data-semver="1.2.28" src="https://code.angularjs.org/1.2.28/angular-resource.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<some-directive title="Hello">
<b>Testing</b>
</some-directive>
</body>
</html>
someDirective.html:
<div class="panel panel-default" >
<div class="panel-heading">
{{title}}
</div>
<div class="panel-body" ng-style="loadingStyle">
<button class="btn btn-sm btn-default" ng-click="openDialog();" type="button">Open</button>
</div>
</div>
I found this: How to get inner html of custom directive? but I don't know exactly how it would work in my case. I am not using the compile method.
Plnker
Thanks

To Pass value from someDirective to dialog.
First inject $rootScope into someDirective like so:
directive('someDirective', ['$modal', '$timeout', '$rootScope', function ($modal, $timeout, $rootScope) {
Now we create a new scope and add a value to it (in this case, $scope.info), and pass it into the modalScope. angular will then pass this along to the modal's controller as the $scope variable.
$scope.info = "test";
$scope.openDialog = function () {
var modalScope = $rootScope.$new();
modalScope.info = $scope.info;
var modalInstance = $modal.open({
scope: modalScope,
templateUrl: 'dialog.html',
controller: 'dialogController',
backdrop: 'static',
windowClass: 'ie-app-modal-window-narrow',
});
modalInstance.result.then(function () {
},
function (result) {
});
};
So inside the modal's controller we have access to variable we just passed in!
.controller('dialogController', ['$scope', '$modalInstance', function ($scope, $modalInstance) {
console.log($scope.info); //prints "test"
$scope.close = function () {
$modalInstance.dismiss('cancel');
};
}])
Now the opposite. To pass from modal back to someDirective:
There's several ways but in my opinion the best way is to use the promises. modalInstance.result returns a promise. This promise is resolved if the modal is closes and rejected if the modal is dismissed. Whether resolved or rejected, a value/object can be passed along as a parameter.
Example, opening the dialog as before:
$scope.info = "test";
$scope.openDialog = function () {
var modalScope = $rootScope.$new();
modalScope.info = $scope.info;
var modalInstance = $modal.open({
scope: modalScope,
templateUrl: 'dialog.html',
controller: 'dialogController',
backdrop: 'static',
windowClass: 'ie-app-modal-window-narrow',
});
modalInstance.result.then(function (returnStuff) {
//This is called when the modal is closed.
//returnStuff is whatever you want to return from the dialog when it's closed
},
function (returnStuff) {
//This is called when the modal is dismissed.
//returnStuff is whatever you want to return from the dialog when it's dismissed
});
};
And to actually close/cancel the dialog:(from inside the dialog)
//pass any value you want back
$modalInstance.close({foo:"Ayyylmao", bar:42});
$modalInstance.dismiss('dismissed');

If I understood it correctly, this is what you want, http://plnkr.co/edit/tOe8tZ5VWfOCkocQaEKo?p=preview
$scope.info = $element.get(0).innerHTML.trim();

Based on this posting, I managed to find something that works for the specific angularjs versions that I am using. I made another plnkr.
The relevant changes are:
dialog.html: I used <div ng-bind-html="info"></div>
<!DOCTYPE html>
<html>
<head>
<title>Add attachment</title>
<meta charset="utf-8"/>
</head>
<body>
<div class="modal-header">
<button type="button" class="close"><span aria-hidden="true" ng-click="close()">×</span></button>
<strong>Add Attachment</strong>
</div>
<div class="modal-body">
<!-- Text input-->
<div class="alert alert-info" role="alert">
<div ng-bind-html="info"></div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div style="float: left">
<button class="btn btn-default" ng-click="close()" ng-disabled="isDisabled">Close</button>
</div>
</div>
</div>
</body>
</html>
app.js - I added the controller property in the someDirective directive and the code grabs the html and sets the info property.
var app = angular.module('plunker', ['ngResource', 'ui.bootstrap', 'ui.bootstrap.modal']);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
})
.controller('dialogController', ['$scope', '$modalInstance', 'params', function($scope, $modalInstance, params) {
$scope.info = params.info;
$scope.close = function() {
$modalInstance.dismiss('cancel');
};
}])
.directive('someDirective', ['$modal', '$timeout', '$sce', function($modal, $timeout, $sce) {
return {
scope: {
title: '#title',
html: '#'
},
restrict: 'AE',
replace: true,
templateUrl: 'someDirective.html',
transclude: true,
controller: function($scope, $element, $attrs, $transclude) {
$transclude(function(clone,scope){
$scope.info = angular.element('<div>').append(clone).html().trim();
});
},
link: {
pre: function (scope, iElement, iAttrs, controller) {
//debugger;
},
post: function($scope, $element, attr, controller) {
//transclude(function(clone, scope) {
// debugger;
// });
//debugger;
//$scope.info = "test"; // I would like to set this to the value within the inner html of the directive.
//debugger;
$scope.openDialog = function() {
var modalInstance = $modal.open({
templateUrl: 'dialog.html',
controller: 'dialogController',
backdrop: 'static',
windowClass: 'ie-app-modal-window-narrow',
resolve: {
params: function() {
return {
info: $sce.trustAsHtml($scope.info) //<-- here I want to set it to the html from inside someDirective
};
}
}
});
modalInstance.result.then(function() {},
function() {});
};
}
}
};
}])
;

Related

Angular Bootstrap modal with embedded directive -- can't get value out?

I have a pretty simple custom directive which presents a form to enter a numeric value. This directive is embedded inside a modal dialog box that is triggered when required. While I can pass data into the dialog through the modal, I am having trouble getting data entered in the input element within the directive back out when the user clicks "OK". I imagine it has something to do with the scope of the directive, since I am using isolate scope, but I marked the name with '=' in the scope section, so I'm not sure what is going wrong.
Here is the plunker that demonstates the issue. Plunker example
var app = angular.module('plunker', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
app.controller('MainCtrl', function($scope, $uibModal, $log, $document) {
var self = this;
var $ctrl = self;
$ctrl.modalresult = "no result";
$ctrl.name = 'World';
$ctrl.myvalue = "-99";
$ctrl.openGetConstantDialog = function(varname, parentSelector, size) {
var parentElem = parentSelector ?
angular.element($document[0].querySelector(parentSelector)) : undefined;
$ctrl.modalInstance = $uibModal.open({
animation: $ctrl.animationsEnabled,
template: `<get-numeric-dialog title="Define a New Constant"
prompt="Enter a value for constant"
varname="${varname}" placeholder="Enter a numeric value">
</get-numeric-dialog>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="$ctrl.ok(myvalue)">OK</button>
<button class="btn btn-warning" type="button" ng-click="$ctrl.cancel()">Cancel</button>
</div>`,
controller: 'ModalInstanceCtrl',
controllerAs: '$ctrl',
size: 'sm',
appendTo: parentElem
});
$ctrl.modalInstance.result.then(function(value) {
$ctrl.modalresult = $ctrl.myvalue;
console.log("modal instance returned value: ", $ctrl.myvalue);
},
function() {
$ctrl.modalresult = "no value returned"
}
);
}
});
app.controller('ModalInstanceCtrl', function($uibModalInstance, $scope) {
var $ctrl = this;
$ctrl.value = undefined;
$ctrl.ok = function() {
$uibModalInstance.close($ctrl.newValue);
};
$ctrl.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
});
app.directive('getNumericDialog', [function() {
return {
templateUrl: 'get_numeric_dialog.html',
restrict: 'E',
scope: {
title: '#',
prompt: '#',
varname: '#',
placeholder: '#',
myvalue: '='
}
};
}]);
Here's the directive template:
<div class="modal-header">
<h5 class="modal-title" id="modal-title">{{title}}</h5>
</div>
<div class="modal-body" id="modal-body">
<p>{{prompt}} '<span class="bold">{{varname}}</span>'</p>
<input type='text' placeholder='{{placeholder}}' ng-model="value"><br>
</div>
I managed to get this working after a couple of days, not quite structured as above, because an embedded directive ultimately wasn't worth the additional complexity, but in case anybody else is having trouble, solution below.
var app = angular.module('plunker', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
app.controller('MainCtrl', function($scope, $uibModal, $log, $document) {
var self = this;
var $ctrl = self;
$scope.modalresult = "no result";
$scope.openModal = function() {
var getConstantTemplate = function(title, prompt, buttonCaption, varName) {
let template = `<div class="modal-header">
<h5 class="modal-title" id="modal-title">${title}</h5>
</div>
<div class="modal-body" id="modal-body">
<p>Value for constant '<span class="bold">${varName}</span>':</p>
<input type='text' varname="weeks" placeholder='Enter a number' ng-model="$ctrl.newValue">
<br>
</div>
<div class = "modal-footer" id="modal-footer">
<button class="btn btn-primary" type="button" ng-click="$ctrl.ok()">${buttonCaption}</button>
<button class="btn btn-warning" type="button" ng-click="$ctrl.cancel()">Cancel</button>
</div>`
return template;
}
var modalInstance = $uibModal.open({
animation: true,
template: getConstantTemplate("New Constant", "a", "Save", "months"),
controller: 'ModalInstanceCtrl',
controllerAs: '$ctrl',
size: 'sm'
});
modalInstance.result.then(function(result) {
console.log('modalInstance got result ' + result);
$scope.modalresult = result;
});
};
});
app.controller('ModalInstanceCtrl', function($scope, $uibModalInstance) {
var $ctrl = this;
$ctrl.prompt = "Enter a value for constant ";
$ctrl.varname = "weeks";
$ctrl.placeholder = "Enter a number";
$ctrl.ok = function() {
console.log("OK has been called with newValue " + $ctrl.newValue);
$uibModalInstance.close($ctrl.newValue);
};
$ctrl.cancel = function() {
console.log("Cancel has been called");
$uibModalInstance.close("model closed cancelled");
};
})
<!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 src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<script src="app2.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body ng-app="plunker">
<div ng-controller="MainCtrl as ctrl">
<button ng-click="openModal()">Open the modal please</button>
<br>
<br>
<p>modalresult = {{modalresult}} </p>
</div>
</body>
</html>

Blank preloader before my ng-view is loaded

I know there are a lot of questions regarding this, but a lot of them are old (some doesn't work anymore with the new Angular version) and others are not related to what I'm trying to achieve.
Basically I have an ng-view:
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 bg-body">
<div ng-view></div>
</main>
in which I display data after an http.get done with routing and partials. As written in the title I would like to display a blank (white) page inside the ng-view with a spinner ( <i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i> ) in the center while my data are loading.
I tryed with a directive, but it seems not working:
AngularJS:
var app = angular.module('app', ['plangular','ngRoute', 'ngSanitize', 'slick']);
app.directive('loading', function () {
return {
restrict: 'E',
replace:true,
template: '<i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>',
link: function (scope, element, attr) {
scope.$watch('loading', function (val) {
if (val)
$(element).show();
else
$(element).hide();
});
}
}
});
HTML:
<main class="col-sm-9 offset-sm-3 col-md-10 offset-md-2 bg-body">
<loading></loading>
<div ng-view></div>
</main>
What could be the best approach?
Do this and replace /homeroute with your template and do not remove ng-if in /home template and it must be your home page
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="jquery#3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script data-require="angularjs#1.5.5" data-semver="1.5.5" src="https://code.angularjs.org/1.5.5/angular.js"></script>
<script data-require="angular-router#1.4.0-beta.3" data-semver="1.4.0-beta.3" src="https://code.angularjs.org/1.2.16/angular-route.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<script src="script.js"></script>
</head>
<body>
<main ng-controller="mainCtrl">
<loading ng-if="showSpin"></loading>
<div ng-view="" ng-if="!showSpin"></div>
<!--<i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>-->
</main>
</body>
</html>
script.js
// Code goes here
angular.module('app', ['ngRoute'])
.controller('mainCtrl', function($rootScope,$scope, $timeout) {
$rootScope.showSpin = true;
$rootScope.$on('$routeChangeStart', function(event, toState, toParams, fromState, fromParams){
$timeout(function(){$rootScope.showSpin = true;
$scope.showSpin = true;}, 5000); // Just addedto show loader, you can remove the `$timeout`
});
$rootScope.$on('$routeChangeSuccess', function(event, toState, toParams, fromState, fromParams){
$timeout(function(){$rootScope.showSpin = false;
$scope.showSpin = false;}, 5000); // Just addedto show loader, you can remove the `$timeout`
});
})
.directive('loading', function() {
return {
restrict: 'E',
replace: true,
template: '<i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>',
link: function(scope, element, attr) {
scope.$watch('showSpin', function(newVal) {
if (newVal)
$(element).show();
else
$(element).hide();
});
}
}
})
.config(function($routeProvider) {
$routeProvider
.when('/home', {
url: '/home',
template: '<div>Hello world!</div>',
controller: function($scope) {
}
})
.when('/example', {
url: '/example',
template: '<div>Hello Example!</div>',
controller: function($scope) {
}
})
.otherwise({ redirectTo: '/example' })
})
UPDATED ANSWER
I have updated the answer. Please check
Working plunker

AngularJS: External Modal Templates

I read Agularjs - include external html file into modals, but it didn't include much code or explanation and just pointed to docs that I've read. So, I will go into more detail.
I have a main html file for a SPA (Single Page Application). I want to use modals for more detailed views.
<html>
<head>
<meta charset='utf-8'>
<script src="js/angular.js"></script>
<script src="js/angular-ui-bootstrap-modal.js"></script>
<script src="js/app.js"></script>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body ng-app="MyApp" ng-controller="MyCtrl">
<button class="btn" ng-click="open()">Open Modal</button>
<!-- want this to be in a separate html file -->
<div modal="showModal" close="cancel()">
<div class="modal-header">
<h4>Modal Dialog</h4>
</div>
<div class="modal-body">
<p>Example paragraph with some text.</p>
</div>
<div class="modal-footer">
<button class="btn btn-success" ng-click="ok()">Okay</button>
<button class="btn" ng-click="cancel()">Cancel</button>
</div>
</div>
<!-- -->
</body>
</html>
And my app.js file:
var app = angular.module("MyApp", ["ui.bootstrap.modal"]);
app.controller("MyCtrl", function($scope) {
$scope.open = function() {
$scope.showModal = true;
};
$scope.ok = function() {
$scope.showModal = false;
};
$scope.cancel = function() {
$scope.showModal = false;
};
});
What would I need to add to app.js in order for it to be able to display external html files as modals on my main html page?
I've done this plnkr so as to explain it better
To open the modal defined in a dedicated html template :
1. The following is declared in the controller responsible for the button opening the modal :
$modal.open({
templateUrl: 'myModalTemplate.html',
controller: 'MyModalController'
});
2. This is in the controller of the modal :
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
See also ui bootstrap doc
Please take look the documentation carefully here
You can do something like this with templateUrl
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});

ng-hide breaking my directive in angular 1.3.16

I'm trying to migrate from angular 1.2.28 to angular 1.3.16, however my code broke.
Angular 1.2.28 working: http://plnkr.co/edit/XfVakwA3Upm7Z2wosHCQ?p=preview
Angular 1.3.16 not working: http://plnkr.co/edit/4VxcHL0MHddobkmu9DMG?p=preview
JS
var app = angular.module('app', []);
app.run(function($rootScope, $timeout){
$rootScope.loading = true;
$timeout(function(){
$rootScope.items = ['Angular', '1.3.16', 'doesnt work'];
$rootScope.loading = false;
}, 3000);
});
app.directive('refresh', function(){
return {
restrict: 'A',
require: '^myDirective',
link: function(scope, element, attrs, ctrl){
if(scope.$last)
ctrl.init();
}
};
});
app.directive('myDirective', function(){
return {
restrict: 'E',
replace: true,
transclude: true,
template: '<div class="my-directive"><p>Height: {{myHeight}}</p> <div ng-transclude></div></div>',
controller: function($scope, $element){
this.init = init;
function init(){
$scope.myHeight = $('.my-directive').height();
}
}
};
});
HTML
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.3.16" data-semver="1.3.16" src="https://code.angularjs.org/1.3.16/angular.js"></script>
<script data-require="jquery#1.11.0" data-semver="1.11.0" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Angular 1.3.16</h1>
<div ng-show="loading">Loading...</div>
<my-directive ng-hide="loading">
<div ng-repeat="item in items" refresh>
<p>{{item}}</p>
</div>
</my-directive>
</body>
</html>
The idea is to only run certain code when the inner html is outputted.
Height is 0 in angular 1.3.16.
However, if I remove ng-hide="loading" from <my-directive ng-hide="loading"> in angular 1.3.16, height gets the appropriated value.
Any ideas how can I solve this?
Inject $timeout into your directive and put the init code block in $timeout(function(){ ... }) like this:
app.directive('myDirective', function($timeout){
return {
restrict: 'E',
replace: true,
transclude: true,
template: '<div class="my-directive"><p><b>Height: {{myHeight}}</b></p> <div ng-transclude></div></div>',
controller: function($scope, $element){
this.init = init;
function init(){
$timeout(function(){
$scope.myHeight = $('.my-directive').height();
});
}
}
};
});
var app = angular.module('app', []);
app.run(function($rootScope, $timeout) {
$rootScope.loading = true;
$timeout(function() {
$rootScope.items = ['Angular', '1.3.16', ' work'];
$rootScope.loading = false;
}, 1000);
});
app.directive('myDirective', function($timeout) {
return {
restrict: 'E',
replace: true,
transclude: true,
template: '<div class="my-directive"><p>Height: {{myHeight}}</p> <div ng-transclude></div></div>',
link: function($scope, $element) {
$element.on('DOMAttrModified DOMSubtreeModified', init);
function init() {
$scope.$apply(function() {
$scope.myHeight = $element.height();
});
}
}
};
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="jquery#1.11.0" data-semver="1.11.0" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script data-require="angular.js#1.3.16" data-semver="1.3.16" src="https://code.angularjs.org/1.3.16/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Angular 1.3.16</h1>
<div ng-show="loading">Loading...</div>
<my-directive ng-hide="loading">
<div ng-repeat="item in items" refresh>
<p>{{item}}</p>
</div>
</my-directive>
</body>
</html>
You have to set the height in the correct angular directive phase/lifecycle. You should set the hight in the link or even postlink phase. Usually the two phases are the same if you don't use prelink This is when all the content has already been rendered. See angular $compile or google for angular post link
The controller is for the logic and the link is for html/dom manipulations.
EDIT:
You can bind 'DOMAttrModified DOMSubtreeModified` events to trigger changes.

AngularJS textbox returns undefined value

When I press my button check in bootstrap modal, I want to print the value of my textbox in my console. But my textbox returns a undefined. It seems that all of the code are working perfect.
<!doctype html>
<html ng-app="app" ng-controller="ModalDemoCtrl">
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>
<script src="example1.js"></script>
</head>
<body>
<div ><button class="btn btn-default" ng-click="open('lg')" >Large modal</button>
<script type="text/ng-template" id="myModalContent">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<input type="text" ng-model="new1" /><button ng-click="check()" >check</button>
<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>
</script>
</div>
</body>
</html>
This is my javascript
var app = angular.module('app', ['ui.bootstrap']);
//var ModalDemoCtrl = function ($scope, $modal, $log) {
app.controller('ModalDemoCtrl',['$scope', '$modal','$log','$rootScope',
function controller($scope, $modal, $log, $rootScope)
{
$scope.open = function (size) {
$scope.val = "";
var modalInstance = $modal.open({
templateUrl: 'myModalContent',
controller: ModalInstanceCtrl,
size: size,
backdrop: 'static',
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}]);
var ModalInstanceCtrl = function ($scope,$rootScope, $modalInstance) {
$scope.check = function()
{
console.log($scope.new1);
};
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
In order to access the $scope variable you need to use $parent as it is creating a child scope in the modal
HTML Code (This is changed):
<input type="text" ng-model="$parent.new" /><button ng-click="check()" >check</button>
Working Fiddle
declare new property on object initialize instead of scope:
var ModalInstanceCtrl = function ($scope,$rootScope, $modalInstance) {
$scope.model= {};
$scope.check = function()
{
alert($scope.model.new);
};
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
http://plnkr.co/edit/A6I158T9I5kGyChgIDK2?p=preview
You can pass the ng-model as parameter in "Check" function
<input type="text" ng-model="new1" /><button ng-click="check(new1)" >check</button>
$scope.check = function(new1)
{
console.log("value..."+new1);
};

Resources