Trigger bootstrap modal by AngularJs and then get data by $http.post - angularjs

I have a list of customers each customer have button more info.
I want , when i click on it then showing bootstrap modal by AngularJs controller and then request data by $http.post and getting some more info about this customer and showing info inside modal.
How can i do this purpose ?
this button :
<button type='button' class='btn btn-primary btn-sm'
data-ng-click='moreinfo(customer.id)' >more info</button>

You can first pass each customer info variable to each more info.
Button like this :
<button type='button' class='btn btn-primary btn-sm btnmargin'
data-toggle='modal' data-target='#cInfo' data-ng-click='moreinfo(customer)'
>more info</button>
then you should write this code inside controller :
$scope.customerinfo=[];
$scope.moreinfo= function(customer){
$scope.customerinfo= customer;
};
Html bootstrap modal :
<!-- Modal start -->
<div class='modal fade' id='cinfo' tabindex='-1' role='dialog'
aria-labelledby='myModalLabel' aria-hidden='true'>
<div class='modal-dialog modal-lg' role='document'>
<div class='modal-content'>
<div class='modal-header'>
<button type='button' class='close' data-dismiss='modal'>
<span aria-hidden='true'>×</span>
<span class='sr-only'>Close</span></button>
<h4 class='modal-title text-danger'
id='myModalLabel'>customer info</h4>
</div>
<div class='modal-body'>
{{customerinfo.firstName}}
</div>
<div class='modal-footer'>
<button type='button' class='btn btn-default'
data-dismiss='modal'>close</button>
</div>
</div>
</div>
</div>
<!-- Modal end -->
Now you can click on each row button more info and see info in inside modal body.

Use ngDialog instead of bootstrap modal.
It is easy to implement in angularjs and you can have different controller for it as well and you can definitely transfer data from main page to this ngDialog.
https://github.com/likeastore/ngDialog

I will suggest you to go with ui-bootstrap but looking at other answers and considering you do not want to add any more JS library/plugin
Hope this helps you
Add a directive called bootstrap-modal as following
app.directive('bootstrapModal', ['$rootScope', '$http', function ($rootScope, $http) {
"use strict";
return {
restrict: "A",
//add isolated scope if you want
//scope: {
//},
link: function (scope, element) {
scope.$on('showModal', function (event, object) {
//fire your ajax here
$http.get('url').then(function(response){
//process your response alter DOM and show modal
element.modal('toggle');
});
});
}
};
}]);
and in your moreInfo function in controller
$scope.moreInfo = function(){
$rootScope.$broadCast('showModal', dataToPassToListener)
}
You should use the directive with the div which you want to show as modal. As in the same div where you would have given role="dialog" if you would have used simple bootstrap.js

I know that you don't want more JS plugin but I suggest you to use the UI Bootstrap for Angularjs:
https://angular-ui.github.io/bootstrap/
It's basically a set of pre-defined directives you can use to load Bootstrap component.
In your case, the thing can end like that:
<button type="button" class="btn btn-primary" ng-click = "moreinfo(customer.id)"> More Info </button>
In your controller :
angular.module('myApp').controller('CustomerInfoCtrl',['$uibModalInstance','$scope', function($uibModalInstance,$scope){
$scope.moreinfo = function(id){
var InfoModal = $uibModalInstance.open({
templateUrl : 'route/to/my/template.html,
controller: 'MoreInfoCtrl',
scope: $scope,
resolve: {
customerId : function(){
return id;
}
}
});
InfoModal.result.then(function(){
//callback when modal closed
},function(){
//callback when clicked on cancel to dismiss the modal
});
}]);
Then you create another controller, MoreInfoCtrl:
angular.module('myApp').controller('MoreInfoCtrl',['$http','$scope','id', function($http, $scope, id){
//Do your http call with the variable id (i.e the customer.id )
}]);
You have plenty of options. You can easily pass variables, scope or do callback process.
I'm using it a lot in a project and it really helps a lot.
I suggest you to try it. And it's not really heavy (from above link):
Whichever method you choose the good news that the overall size of a
download is fairly small: 122K minified for all directives with
templates and 98K without (~31kB with gzip compression, with
templates, and 28K gzipped without)

Related

How to trigger multiple Click events on one click angular js

I am having different ng-clicks events, I want all those to be triggered at once on click of a button
Example
<div ng-controller="one">
<input type="button" id="one" ng-click="firstBtnClick(a,b)" class="fstClass"/>
</div>
<div ng-controller="two">
<input type="button" id="two" ng-click="SecBtnClick(c,d)" class="SecClass"/>
</div>
<div ng-controller="three">
<input type="button" id="three" ng-click="ThirdBtnClick(e,f)" class="ThirdClass"/>
</div>
Now I want to hit all this click functions on other button
<div ng-controller="final">
<input type="button" id="final" ng-click="finalBtnClick" class="FinalClass"/>
</div>
Final Controller code
$timeout(function () {
angular.element('.fstClass', '.SecClass').triggerHandler('click');
}, 0);
But I am unable to achieve, Any suggestions??
Why do you want to do this in the view? You are calling controller functions with every button click.
So just have a ng-click="everyClick()" and inside this controller
function, call every function you want to call.
So:
$scope.finalBtnClick = function() {
$scope.firstBtnClick();
$scope.SecBtnClick();
$scope.ThirdBtnClick();
}
If the functions are in the same controller you can chain together like this:
<input type="button" id="final" ng-click="firstBtnClick+SecBtnClick+ThirdBtnClick" class="FinalClass"/>
For communication across controllers you can create and inject a shared service to each controller, nest controllers, use $rootscope or use $emit:
function FirstController($scope)
{
$scope.$on('clickFirst', function(event, args) {
firstBtnClick(args)//click first button
});
// another controller or even directive
}
function FinalController($scope)
{
$scope.$emit('clickFirst', args);
}

Capture hide event in $modal of angular strap

I am using angular Strap to create a modal like :
$modal({
template : "/templ/alert-with-title.html",
content : content,
title : title,
show : true,
backdrop : true,
placement : 'center'
});
I have the written the following :
$scope.$on("modal.hide.before",function() {
console.log("Closing1");
});
$scope.$on("modal.hide",function() {
console.log("Closin2");
});
My /templ/alert-with-title.html is like this :
<div aria-hidden="true" aria-labelledby="windowTitleLabel" role="dialog"
tabindex="-1" class="modal hide fade in modal" id="">
<div class="modal-header">
<a class="fui-cross pull-right" ng-click="$hide()"></a>
<h3 ng-bind="title"></h3>
</div>
<div class="modal-body">
<div class="divDialogElements" >
<span ng-bind="content"></span>
</div>
</div>
<div class="modal-footer">
<div>
<button type="button" ng-click="$hide()"
class="btn btn-default btn-gray-l gray pull-left mar_t-4">OK</button>
</div>
</div>
</div>
However even after all this, I get no console logs when i click Ok. Why is this?
so the solution is very simple, I had to provide the scope to the $modal.
$modal({
template : "/templ/alert-with-title.html",
content : content,
title : title,
show : true,
backdrop : true,
placement : 'center',
scope : $scope
});
But what I do not understand that why for an event that is "$emit" , $on of the outside scope would not work
$emit and $broadcast are angular event handling mechanisms are distinct from events that are found in pure JavaScript. The latter traverse the DOM of your web page. the $event in angular traverses the scope hierarchy present in your module. With that being said here is an excerpt from the source code of angular-strap modal :
function ModalFactory(config) {
var $modal = {};
// Common vars
var options = $modal.$options = angular.extend({}, defaults, config);
var promise = $modal.$promise = $bsCompiler.compile(options);
var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();
the parameters you pass as the argument for your $modal service is the config object. the default object contains the default values for the parameters. The line of interest is the last line .
There it checks wether you have provided a scope object as one of the parameters. If so then a child of that scope is created via scope.$new. Else it creates a scope which is the child of the top most scope in the heirarchy.
Therfore any events which are bubbled up via $emit, from this particular scope can only be caught by the $rootScope.
In the code you posted in the question you did not provide any scope object in the parameters. Hence a child of the $rootScope is created, not of the current $scope you were working in. In the second code you posted , a child scope of your current $scope is created. That is the reason why you are able to handle the 'model.hide' and other events from your current $scope
Hope this helps :)

AngularJS Modal not showing up when templateUrl changes

So far, what I have is straight off the Angular UI example:
Controller:
var ModalDemoCtrl = function ($scope, $modal) {
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl
});
};
};
var ModalInstanceCtrl = function ($scope, $modalInstance) {
$scope.close = function () {
$modalInstance.dismiss('cancel');
};
};
And this section, which is just in sitting in the .html for the whole page this modal is on.
Html:
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
<button class="btn btn-warning" ng-click="close()">X</button>
</div>
<div class="modal-body">
Stuff
</div>
</script>
This works just fine. But I'm trying to refactor some things out and organize my code, so I would like to move the modal html to its own file. When I do so, and try to use it as by changing the templateUrl to the path: \tmpl\myModalContent.html, it doesn't show up. The backdrop still appears and inspecting the page shows that it loaded correctly, but just won't show up.
I've tried changing the css for the modal per these suggestions with no difference.
My question is, why does this work fine if the script tag is in the main html, but not at all if it is in it's own file?
Here is a plnkr that shows what I mean. If you copy what is in the template.html and place it right above the button in the index.html file, it works...
Remove template declaration for template.html and just put raw HTML in there like this:
<!--script type="text/ng-template" id="template.html"-->
<div class="modal-body">
Hello
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="cancel()">OK</button>
</div>
<!--/script-->
Your plnkr worked fine with second click to the button. It'd show the modal as expected. The reason it showed up with second click is because Angular would load up the 'uncompiled' template the first time, then it compiled the template to raw HTML which is ready for your subsequent clicks.
EDIT: Also, when you put the template code right in index.html, Angular compiles the template during its initial pass through the DOM; that's why the modal seemed to work.
Well I am clearly a dummy. All I had to do was include my new file in the main view.
<div ng-include="'path-to-file.html'"></div>
Then calling it from the controller was easy, all I needed was the id (modalContent.html) as the templateUrl.
Just keep swimming, and you'll eventually get there :)

AngularStrap close modal with controller

I'm using AngularStrap with bootstrap.
I have a modal dialog that uses it's own controller. How can I close the modal using this local controller?
I instantiate the controller on a button like this:
<button type="button"
class="btn btn-success btn-lg"
bs-modal="modal"
data-template="user-login-modal.html"
data-container="body"
ng-controller="userLoginController"
>Click here to log in</button>
and the userLoginController has this:
$scope.authenticate = function(){
this.hide(); // this doesn't work
}
This is obviously just a demo, I want it to close on successful login, but this is where the code I'd use to close it would go.
I've tried instantiating the modal programmatically (use the $modal service to create the modal) but I haven't been able to figure out how to inject the controller through that method.
If I were to do something like emit an event from the modal using the bs-modal directive, how can I reference the modal to close it?
here's my plnkr:
http://plnkr.co/edit/m5gT1HiOl1X9poicWIEi?p=preview
When in the on-click function do
$scope.myClickEvent = function () {
this.$hide();
}
Figured out a good method:
I moved the ng-controller to the TEMPLATE and instantiate the modal using the provided modal service. I then use a rootscope broad cast to let everyone know that someone successfully logged in.
new controller code:
var loginModal = $modal({template:'/template.html', show:false});
$scope.showLogin = function(){
loginModal.$promise.then(loginModal.show);
}
$scope.$on("login", function(){
loginModal.$promise.then(loginModal.hide);
});
the button just looks like this now:
<button type="button"
class="btn btn-success btn-lg"
ng-click="showLogin()"
>Click here to log in</button>
and my template has the old ng-controller in the first tag.
I am probably too late, but just wish to share my answer. If all you need is hiding the modal after form success, then bind that $hide function to one of controller varriable.
<div class="modal" data-ng-controller="Controller" data-ng-init="bindHideModalFunction($hide)">
In the controller:
// Bind the hiding modal function to controller and call it when form is success
$scope.hideModal;
$scope.bindHideModalFunction =function(hideModalFunction){
$scope.hideModal = hideModalFunction;
}
I found all of the above answers way too complicated for your use case (and mine when I ran into this problem).
All you need to do, is chain the ng-click to use the built in $hide() function that angular strap bundles.
So your ng-click would look like: ng-click="authenticate();$hide()"
Using Angular and bootstrap if you want to submit data to controller then have the modal close just simply add onclick="$('.modal').modal('hide')" line to the submit button. This way it will hit the controller and close the modal. If you use data-dismiss="modal" in the button submit never hits the controller. At least for me it didn't. And this is not to say my method is a best practice but a quick one liner to get data to at least submit and close out the modal.
<div class="modal fade" id="myModal" ng-controller="SubmitCtrl">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<form ng-submit="submit()">
<input type="text" ng-model="name" />
<button type="submit" onclick="$('.modal').modal('hide')">Submit</button>
</form>
</div>
</div>
</div>
</div>
Perhaps open it with the service on click and have it close itself on the $destroy event?
$scope.openModal = function()
{
$scope.modal = $modal({
template: "user-login-modal.html",
container="body"
});
}
$scope.$on("$destroy", function()
{
if ($scope.modal)
{
$scope.modal.hide();
}
});

is there a shortcut to get window.history.back()

AFAIK, the only way to get Angular mimick a back button behavior is via a call to $window.history.back.
Now, I have a form with two buttons: submit and cancel. When I submit, I have some custom logic, and in the end I can easily call the back() method. But how could I achieve the same without a custom method for the cancel button?
This is my current html
<div class="form-group">
<button class="btn btn-primary" ng-click="save(berlet)">Ok</button>
<a class="btn btn-warning" ui-sref="jogasok">Cancel</a>
</div>
I would like to have a back() behavior when clicking the <a> tag. Are there any recommendations for it? My preferred syntax would be something like: `Cancel :)
Make a simple directive, to keep your controller free from redundant $window pollution:
PLUNKER
app.directive('goBack', function($window){
return function($scope, $element){
$element.on('click', function(){
$window.history.back();
})
}
});
<a go-back>Cancel</a>
My best idea until now is to attach the $window service to my directive, and call the back button through the $scope.
<a class="btn btn-warning" ng-click="window.history.back()">Cancel</a>
and in my directive I have
$scope.window = $window;

Resources