I am facing issues while closing the Modal in Angular JS
HTML
<div class="container">
<div class="col-md-12" id="gridSet">
<div class="gridStyle adjustViewPort" ng-grid="gridOptions"></div>
// Here is the HTML template for MODAL.
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-body">
<p>No Events Found</p>
<p><button class="btn btn-primary" ng-click="myClickEvent()">OK</button></p>
</div>
</script>
</div>
</div>
And in controller.js looks like
$scope.modalInstance=$modal.open({templateUrl: 'myModalContent.html'});
//This should run. But, every time only Cancelled is logged.
$scope.modalInstance.result.then(function() {
console.log('Success'); // This is never executed.
}, function() {
console.log('Cancelled');
})['finally'](function(){
$scope.modalInstance = undefined
});
I have tried to hide the modal by this.$hide(); in myClickEvent But, the function is not called at all.
Code from Plunker from which I have copied the code.
Looking for 1) Hide the modal after few seconds using $timeout
2) Close the modal when user selects OK.
UPDATE
Issue is the Code in Plunker Shows $modalInstance as dependency which I am not able to inject.
Function 'ng-click="myClickEvent()"' calls a function in controller which is as below.
$scope.myClickEvent=function(){
alert('the function is called.');
}
But, the there is no alert.
Thanks for help in advance.
Use close() method:
$scope.close = function () {
$modalInstance.close();
};
<button class="btn btn-warning" ng-click="close()">Close</button>
Related
I have a basic Angular.js app which is using ocLazyLoad for loading the application files. I am using the skeleton of the sbAdminApp template.
My problem is that when I use a template with an ng-click event, the click event is not being fired. It is not a scope problem because when I print the function's content to the view it is shown.
Here is some of my code:
For loading the files using ocLazyLoad:
$stateProvider.state('dashboard.importLotteries', {
templateUrl: '/Scripts/app/views/importLotteries.html',
url: '/importLotteries',
controller: 'LotteriesCtrl',
resolve: {
loadMyFiles: function ($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'sbAdminApp',
files: [
'/Scripts/app/scripts/services/lotteriesService.js',
'/Scripts/app/scripts/controllers/lotteries.js'
]
})
}
}
}
This is the importLotteries.html template file:
<!-- /.row -->
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
Import Lotteries
</div>
{{importLotteries.toString()}}
<div class="panel-body">
<input type="button" ng-click="importLotteries()" value="Import"/>
<span ng-model="importStatus">
</span>
</div>
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
and this is the controller's code:
'use strict';
angular.module('sbAdminApp')
.controller('LotteriesCtrl', function ($scope, lotteriesService) {
$scope.importLotteries = function () {
alert("importing");
$scope.importStatus = "Loading...";
};
});
The result view looks like this:
So as you can see, the function exists on the scope but the click event is not firing and I don't get any errors.
I tried to search for a solution online for sometime now and couldn't find one, so any help will be greatly appreciated!
After further investigating the issue, I see that the event function (importLotteries) is undefined in the scope, but when I change the value to a string instead of a function the scope value is correct.
Try attaching a ng-href or href to the link and it'll be fired.
<input type="button" ng-click="importLotteries()" ng-href='#' value="Import"/>
Source:
[1] Angular ng-click with call to a controller function not working
I have the following markup inside my .cshtml Partial View and it is placed in the Views/Shared folder:
_Modal.cshtml
<div class="loadingOverlay">
<button class="btn loading-button" disabled><i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i></button>
</div>
And also the External JavaScript (different file from the Partial View .cshtml):
Modal.js
var Modal;
Modal = Modal || (function () {
var loadingDiv = $('.loadingOverlay');
return {
Loading: function () {
loadingDiv.css('display', 'block');
$('body').prepend(loadingDiv);
},
LoadingDismiss: function () {
loadingDiv.fadeOut('500');
},
};
})();
And I call from my page like below:
Index.cshtml
<!DOCTYPE html>
<html>
<head>
#Styles.Render("~/Content/font-awesome", "~/Content/css")
</head>
<body>
<div class="container-fluid">
<div class="container">
<div class="row">
<button id="showOverlay" class="btn btn-default"></button>
</div>
</div>
</div>
#Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
$(document).ready(function () {
$('#showOverlay').click(function () {
Modal.Loading();
});
})
</script>
</body>
</html>
My problem is: whenever I clicked the button, nothing happens. But it works when I put the html element not inside _Modal.cshtml (Refer to the below code).
My question is: how can I get the class name in the _Modal.cshtml using JavaScript or JQuery?
I can do this in the Modal.js (Note that it is same as I put that into _Modal.cshtml) but that would be hard to maintain and I would like to put all of the content in the Partial View, and call it when needed by class name, instead of write string that will converted to JavaScript Object:
var loadingDiv = $('<div class="loadingOverlay"><button class="btn loading-button" disabled>'
+ '<i class="fa fa-spinner fa-pulse fa-2x fa-fw"></i></button></div>');
Your answer much appreciated.
Edit:
Question on 31st of May 2016:
What's the difference between #Html.Partial("_Modal") with #Html.Partial("~/Views/Shared/_Modal.cshtml"). is it just to better understand for where the compiler get the partial views from?
Answered on 1st of June 2016 by #Guruprasad Rao:
There is nothing difference between two except the mentioning of partialview name. The one I suggested was providing fully qualified path which helps compiler from where to fetch the partialview. To one you use will search in all the directories under the View folder. So the one I mentioned will be good in the aspect of performance.
Thanks for the #Guruprasad Rao for the answer and the explanation.
Cheers~
You should import the partialview first from server to client browser first and then you can manipulate it with jquery. Otherwise there would be no element with the selector you are trying to find. User, #Html.Partial or #Html.RenderPartial to import it, hide it at initial state and show it on click. Take a below example:
<body>
<div class="container-fluid">
<div class="container">
<div class="row">
<button id="showOverlay" class="btn btn-default"></button>
</div>
</div>
</div>
#Html.Partial("~/Views/Shared/_Modal.cshtml")
<!--I assume that the content inside this will be initially in hidden state-->
#Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
$(document).ready(function() {
$('#showOverlay').click(function() {
Modal.Loading();
});
})
</script>
</body>
Modal.js changes
var Modal;
Modal = Modal || (function () {
var loadingDiv = $('.loadingOverlay');
return {
Loading: function () {
loadingDiv.css('display', 'block');
//$('body').prepend(loadingDiv);
//No need to prepend here since we are importing it through partial method
},
LoadingDismiss: function () {
loadingDiv.fadeOut('500');
},
};
})();
What I'm doing feels wonky to me, and I would love to know if there is a better way to do this: I'm using
<compose view-model.bind="modalModel.viewModel"></compose>
in my app.html. When I need to display a modal, whatever viewmodel is active will fire off an event-aggregator publish event with a modal model which contains three things. Modal title, an array of buttons (strings), and a module path to a view/viewmodel. In app.js, I'm subscribing to the modal event and when one comes through, I set the app's
this.modalModel = modalModel;
which immediately binds and loads the view and viewmodel, then I display the modal (bootstrap modal). This works, but there are a few problems which tells me that there must be a better way to do it:
canDeactivate() and deactivate() are never called on the modal's viewmodel that is loaded, when the app.js's modalModel is reset.
I don't think I can pass any parameters into the activate() method in the modal viewmodel.
It just feels wonky.
Would there happen to be a better way to dynamically load in a view and viewmodel, bound and everything, in such a way that it can be properly deactivated upon closing the modal?
Relevant Code:
<template>
<require from="./app-head"></require>
<require from="./main-nav"></require>
<!-- actual site content removed for this example -->
<div class="modal" id="main-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-ajax"></div>
<div class="modal-header">
<button type="button" class="close" click.delegate="modalButtonClick('Cancel')">×</button>
<h4 class="modal-title">${modalModel.title}</h4>
</div>
<div class="modal-body">
<!-- EMPHASIS HERE: -->
<compose view-model.bind="modalModel.viewModel"></compose>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-default" repeat.for="button of modalModel.buttons"
click.delegate="modalButtonClick(button)">
${button}
</button>
</div>
</div>
</div>
</div>
</template>
export class App {
//...
attached() {
//...
this.listen('show-modal', this.displayModal.bind(this));
this.listen('hide-modal', this.closeModal.bind(this));
this.listen('show-modal-loader', this.showModalLoader.bind(this));
this.listen('hide-modal-loader', this.hideModalLoader.bind(this));
}
displayModal(modalModel) {
this.modalModel = modalModel;
$('#main-modal').modal();
}
closeModal() {
$('#main-modal').modal('hide');
this.modalModel = null;
}
showModalLoader() {
document.querySelector('#main-modal .modal-ajax').style.display = 'block';
}
hideModalLoader() {
document.querySelector('#main-modal .modal-ajax').style.display = 'none';
}
listen(event, fn) {
this.eventAggregatorSubscriptions.push(this.ea.subscribe(event, fn));
}
}
Use the aurelia-dialog plugin.
To install: jspm install aurelia-dialog
To activate: in main.js configure(), call aurelia.use.plugin('aurelia-dialog');
Usage: https://github.com/aurelia/dialog#using-the-plugin
I am searching how to show a div with AngularJS. I read some topic on StackOverflow but when I try to apply them, it doesn't works for my case...
This is my HTML code :
<div id="myPanel" ng-controller="controllerDependance" ng-show="myvalue" class="ng-cloak">
Blablabla
</div>
<div id="DivWhereIsMyButton" class="clearfix" ng-controller="controllerBubble">
Another div where is my button
<div id="containerButton" ng-controller="controllerDependance">
<button class="btn btn-danger btn-lg pull-right"
ng-click="showAlert()">View dependances
</button>
</div>
</div>
This is the controller :
d3DemoApp.controller('controllerBubble', function () {
});
d3DemoApp.controller('controllerDependance', function ($scope) {
$scope.myvalue = false;
$scope.showAlert = function(){
$scope.myvalue = true;
};
});
I initially thought, it is controllerOther take the hand and cancel the controllerDiv but even if I separate the both, it doesn't works. The problem is I am obligated to put the both in two differents controllers.
I have two controllers, controllerDependance and controllerBubble. My div to show is in the controllerDependance. My button is in a div controllerBubble and I can't move it. So I would like to wrap it in a div controllerDependance.
I make a Plunker to show you the problem : https://plnkr.co/edit/z1ORNRzHbr7EVQfqHn6z?p=preview
Any idea ?
Thanks.
Put the div you want to show and hide inside the controller. It needs to be within the scope of the controller, otherwise your controller function cant see it. Also, consider what you are trying to accomplish with the nested controllers, I often find them unnecessary.
<div id="divButton" class="clearfix" ng-controller="controllerOther">
<div id="buttonToShowDiv" ng-controller="controllerDiv">
<button class="btn btn-danger btn-lg pull-right" ng-click="showAlert()">Show my div</button>
<div id="myDiv"ng-show="myvalue" class="ng-cloak">
Blablabla
</div>
</div>
</div>
I notice in your original example you are declaring ng-controller="controllerDependance" twice in the DOM. I have never tried this before, but I can imagine this will cause problems. From the angular documentation on controllers
When a Controller is attached to the DOM via the ng-controller directive, Angular will instantiate a new Controller object, using the specified Controller's constructor function. A new child scope will be created and made available as an injectable parameter to the Controller's constructor function as $scope
I imagine that this is what is causing you problems. You have to have the div you want to show/hide within the scope of your controller.
I got your plunkr working, you can see my version here: https://plnkr.co/edit/NXbsVFMNHR8twtL8hoE2?p=preview
The problem was stemming from you declaring the same controller twice, and more importantly, the div to show/hide was using ng-show with a value from your mainController. But your div was outside that controller. So ng-show cant see the value. The div has to be withing the scope of the controller
You are using two different controllers which have different $scopes therefore their values are not connected! To show or hide a div is really simple in angular:
<div id="divButton" class="clearfix" ng-controller="myController">
<div id="buttonToShowDiv">
<button class="btn btn-danger btn-lg pull-right" ng-click="showAlert()">Show my div</button>
</div>
<div id="myDiv" ng-show="myvalue" class="ng-cloak">
Blablabla
</div>
</div>
And the script side just almost the same:
d3DemoApp.controller('myController', function AppCtrl ($scope) {
$scope.myvalue = false;
$scope.showAlert = function(){
$scope.myvalue = true;
};
});
Since you question was how to show elements using angular, I took the liberty of using just one controller.
Create a factory that will return an object and let your controllers work with a reference to the same object:
var d3DemoApp = angular.module('app', [])
d3DemoApp.factory('MyValue', function () {
return { value: false };
});
d3DemoApp.controller('controllerBubble', function ($scope, MyValue) {
$scope.myvalue = MyValue;
});
d3DemoApp.controller('controllerDependance', function ($scope, MyValue) {
$scope.myvalue = MyValue;
$scope.showAlert = function(){
$scope.myvalue.value = true;
};
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-app="app">
<div ng-controller="controllerBubble" class="clearfix">
<div id="myPanel" ng-controller="controllerDependance" ng-show="myvalue.value" class="ng-cloak">
Blablabla
</div>
</div>
<div id="DivWhereIsMyButton" class="clearfix" ng-controller="controllerBubble">
Another div where is my button
<div id="containerButton" ng-controller="controllerDependance">
<button class="btn btn-danger btn-lg pull-right" ng-click="showAlert()">View dependances</button>
</div>
</div>
</div>
</body>
</html>
I am using angular bootstrap ui modal box it says to give a new $modalInstance for new controller.I want to use the same controller where i have initialized the modal box.I searched but no success.I found this links but no success -
How to use the same controller for modal and non-modal form in Angular UI Bootstrap?
Angular-ui bootstrap modal without creating new controller
app.controller('UserCtrl',['$scope','$filter','ngTableParams','$modal',function($scope, $filter, ngTableParams,$modal) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl', //Instead of this i want to use the same controller 'UserCtrl'
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
};
} ]);
So that i can call the save function on this same controller which is called on save click of modal box
It was possible in older version of UI-Bootstrap 0.10.0
Download Library.Even latest version,it works for me
index.html
<!-- if you are using Bower -->
<script src="bower_components/angular-bootstrap/ui-bootstrap.min.js">
</script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js">
</script>
<!-- button click opens modal-->
<button ng-click="openModal()">Button test</button>
<!-- modal -->
<!-- look at 'type' and 'id' values -->
<script type="text/ng-template" id="myTestModal.tmpl.html">
<div class="modal-header">
<h3>Modal Header</h3>
</div>
<div class="modal-body">
<p>Modal Body</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="close()" data-dismiss="modal">Close
</button>
<button type="button" class="btn btn-primary" ng-click="doSomething()">Do Something
</button>
</div>
</script>
modalDemoController.js
$scope.openModal=function(){
$scope.modalInstance=$modal.open({
templateUrl: 'myTestModal.tmpl.html',
scope:$scope
});
}
$scope.close=function(){
$scope.modalInstance.dismiss();//$scope.modalInstance.close() also works I think
};
$scope.doSomething=function(){
//any actions to take place
console.log("Do Something");
}
I had a similar issue, but I managed to fix it by removing the controller inside of the $uibModal.open({])