ng-repeat refreshed while modal dialog open- modal disappears - angularjs

When I have a modal dialog open and the ng-repeat underneath is refreshed via a websocket, the modal disappears. The websocket call back refreshes the underlying ng-repeat. This causes the modal dialog to disappear and I have to refresh the browser, which goes back to the ng-repeat data. Basically, how can I prevent this modal from disappearing when the underlying ng-repeat is refreshed? Code Snippets:
In Controller:
app.controller('mainController', function($scope, $http, adminService) {
// Setup
$scope.viewData = [];
// Get Events & Alarms
function getClientDetails() {
adminService.getView()
.success(function(newViewData) {
$scope.viewData = newViewData;
})
.error(function() {
console.log('Client retrieval failed.');
});
};
In Service:
app.service('adminService', function ($http, $q, $rootScope) {
// interface
var service = {
events: [],
getView: getView
};
function getView() {
return $http({
method: 'GET',
url: 'app/services/data.php',
params: {
'act': 'getAFView'
},
}).
success(function(data) {
service.events = data.data;
return (data.data);
}).
error(function(data) {
console.log('error getting client data');
});
};
Some of the Markup:
<tr ng-repeat="data in viewData | orderBy:'-EventId'| offset : currentPage*itemsPerPage |
limitTo: itemsPerPage | filter:search">
<td ng-class="{'danger': data.AckState === 'Unacknowledged',
'active': data.AckState === 'Acknowledged',
'info': data.AckState === 'Closed'}">
<button type="button" class="btn"
data-toggle="modal" data-target="#editEventWindow{{$index}}" ng-click="Clear(data)">
View
</button>
<div class="modal fade" id="editEventWindow{{$index}}" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="addContactLabel">Details</h4>
</div>

Related

How do I open a modal from a controller using Angular-materialize

I am using Materialize CSS and the Angular-materialize directives:
http://materializecss.com/modals.html
http://krescruz.github.io/angular-materialize/#modals
I am trying to do the following
User clicks button
Controller action gets fired and we go get data from an api
Modal is displayed to user and data returned is displayed
I have the following button
<a href="#MyModal" modal class="my-modal-trigger waves-effect waves-green btn right"Show Data/a>
and modal
<div id="MyModal" class="modal">
<div class="modal-content center">
<div class="row">
<div class="row left">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">Data</span>
</div>
<div>
<ul class="collection">
//loop the data
</ul>
</div>
</div>
<a class="modal-action modal-close waves-effect waves-green btn">Close</a>
</div>
</div>
</div>
</div>
and i have the following in my JS
var app = angular.module("MyApp", ['ngRoute', 'ui.materialize']);
How can i call a controller method to pop up the modal and fill it with data, from my controller
app.controller('mainController', function ($scope, $location, $http, AppConfig) {
var params = { some stuff}
$http({
method: 'POST',
url: myURL,
headers: {
'Content-Type': 'text/html',
'Accept': 'application/json'
},
params: params
})
.success(function (data) {
//pop up the modal and show the data
Materialize.toast('Awesome, we got the data', 4000);
})
.error(function (status) {
Materialize.toast('Bad stuff happened', 4000);
});
});
Angular-materialize lets you set an option open in your trigger. Use it to specify a variable that, when true, will launch your modal. Set it to false initially in your controller.
Use ng-click to call a function in your controller that fetches data from your API then sets the open variable to true on success.
Trigger:
<a href="#MyModal" class="btn" modal open="openModal"
ng-click="getDataOpenModal()">Show Data</a>
In Controller:
$scope.openModal = false;
$scope.getDataOpenModal = function() {
$http({
method: 'POST',
url: '/myUrl',
headers: {
'Content-Type': 'text/html',
'Accept': 'application/json'
},
params: params
})
.success(function(data) {
$scope.data = data;
$scope.openModal = true;
Materialize.toast('Awesome, we got the data', 4000);
})
.error(function(status) {
Materialize.toast('Bad stuff happened', 4000);
});
}
EDIT: There are two other options you can set in your trigger, ready and complete
HTML
<a href="#MyModal" class="btn" modal open="openModal"
ready="readyCallback()" complete="completeCallback()"
ng-click="getDataOpenModal()">Show Data</a>
JS
$scope.readyCallback = function() {
Materialize.toast("Modal ready", 4000);
}
$scope.completeCallback = function() {
Materialize.toast("Modal complete", 4000);
}
Worked for me with $scope.$apply() after $scope.openModal = true;
I was fighting with this too, but no solution worked for me. I had to change html side.
My html:
<i class="zmdi zmdi-eye"></i>
In controller:
$scope.openModal = false
$scope.get_info_log = function(){
$scope.openModal = true;
}
Data-target should match your modal id:
!-- Modal Structure-->
<div id="log_detail" class="modal modal-fixed-footer setup-modal">
<div class="modal-content">
</div>
</div>
<div class="modal-footer">
<a class=" modal-action modal-close waves-effect waves-light btn">Close</a>
</div>
</div>

Disable button in angular js

I have 2 buttons in my page "Save Set" & "Load Set".
"Save Set" button has ng-disabled=isSaveDisabled()
.....
.controller('saveLoadSetToolbarBtn', ['$scope','$modal','propertiesModified',
function ($scope,$modal,propertiesModified) {
$scope.loadTuneSet = function () {
$modal.open({
templateUrl: 'loadSetDlg.html',
controller: 'loadSetCtrl'
});
};
$scope.isSaveDisabled = function() {
return !propertiesModified.get();
};
.......
When I click Load Set, it will open a popup and their I'll have OK button. On this click, I should disable the "Save Set" button
OK Button,
.controller('loadSetCtrl', ['$scope', '$modalInstance', 'generalDataService',
function ($scope, $modalInstance, generalDataService) {
$scope.items = [];
$scope.selectedSet = undefined;
$scope.ok = function () {
//doing some logic
closeDialog();
$modalInstance.close();
};
If any value changes happen in my page then this "Save Set" button will be enabled. problem is if I change any value in my page this button is enabling (as expected). If I click "Load Set" button, popup will open and on OK button click (available on Popup) then this "Save Set" should go back to Disable state. I should be able to return boolean value true through this isSaveDisabled function on OK button click.
Simple:
<button ng-model="btnSaveSet" ng-disabled="btnSaveSet_disabled"
ng-click="btnSaveSet_disabled=true">SaveSet</button>
I think you're trying to code a Modal View, like the Demo of this page : http://angular-ui.github.io/bootstrap/ .
I recommend to try this demo and modify it to fit your needs, because there is not much to change. I try to give you some hints in the comments of the code:
This is the JavaScript Code:
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['tuneSet', 'tuneSet2','tuneSet3'];
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'loadSetDlg.html', // name it like the Template for the Modal
controller: 'loadSetCtrl', // name it like the used controller for the Modal
size: size, // not necessary for you
resolve: {
items: function () { // this will pass in your items into the ModalCtrl
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) { // here is the callback, when the
$scope.selected = selectedItem; // Modal get closed
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
// Here you can implement your logic depending on the user-input that is available on $scope.selected
// it is an object.
console.log($scope.selected); // here you can see it in the console.
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('ui.bootstrap.demo').controller('loadSetCtrl', function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0] // this will catch the user input (click on link)
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item); // this will pass the chosen tuneSet back to
}; // ModalDemoCtrl
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
And this is the HTML you need:
<div ng-controller="ModalDemoCtrl">
<script type="text/ng-template" id="loadSetDlg.html">
<div class="modal-header">
<h3 class="modal-title">TuneSet selection!</h3>
</div>
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<a ng-click="selected.item = item">{{ item }}</a>
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</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>
</script>
<button class="btn btn-default" ng-click="open()">Open me!</button>
<button class="btn btn-default" ng-click="open('lg')">Large modal</button>
<button class="btn btn-default" ng-click="open('sm')">Small modal</button>
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
</div>

How to render html on ui modal (bootstrap)

i have a modal ui (bootstrap for angular), calls by a popupService, i want passing an html code to my popupService.open methode.
The result isn't what i expect, only some values are html formated but my button isn't render...
<b>hello</b> <button class="btn btn-green" ng-click="$close(null)">Close</button>
It should be green but i have only the text...
My code :
popupService.js
appServices.service('popupService', [ '$modal','$sanitize',
function($modal, $sanitize, $scope) {
this.open = function(title, message, size, footer){
$modal.open({
templateUrl: 'view/component/popup.html',
size: size,
scope : $scope,
transclude : true,
controller : function($scope){
$scope.title = title;
$scope.templatemessage = message;
$scope.templatefooter = footer;
}
});
}
}
]);
popup.html
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" ng-click="$close(null)">×</button>
<h3 class="modal-title">{{title}}</h3>
</div>
<div class="modal-body" modal-transclude ng-bind-html="templatemessage">
</div>
<div class="modal-footer" ng-bind-html="templatefooter">
<div ng-include="view/partial/test.html"></div>
</div>
app.js in my app controller
$scope.$watch('error', function() {
//check the error value for load the message by code in current language
console.log('error : '+ $scope.error);
if($scope.error != null && $scope.error > 0){
//display error in popup
$scope.errorMessage = errorService.GetMessageByCode($scope.error);
popupService.open($scope.Translate.error, $scope.errorMessage, 'sm', '<b>hello</b> <button class="btn btn-green" ng-click="$close(null)">Close</button>')
$scope.error = null;
}
});
how to fix this ?

AngularJs - Modal dialog that embed views by ui-view

My goal is to have a modal view with couple of buttons and a ui-view. When clicking one of those buttons it will load the specific view + controller.
Reading from the angular-ui router project (https://github.com/angular-ui/ui-router/wiki) they control ui-views with states. How could I do that with a modal?
Below you can get a better idea of what i am aiming for. I tried also using states (abstract state to load layout template with buttons leaving a ui-view directive) but it didnt work. Any ideas on how to organize the code to accomplish it?
This is the code to launch the modal view:
$scope.launchModalView = function(data){
var modalInstance = $modal.open({
controller: 'coversModalController',
size: 'lg',
templateUrl: 'partials/covers.modal.html',
resolve: {
data: function(){
return data;
}
}
});
modalInstance.result.then(function (data) {
console.log('Got it! Song = ' + JSON.stringify(data));
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
}
Here the coversModalController:
admintoolApp.controller('coversModalController',function($scope, $modalInstance, data){
// Modal functionality
$scope.data = data;
$scope.submit = function () {
$modalInstance.close($scope.data);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Here we have the template "partials/covers.modal.html":
<div class="modal-header">
<h3 class="modal-title">Select one method to choose images</h3>
</div>
<div class="modal-body" style="overflow: hidden;">
<div style="float:left;">
<ul>
<li>From Private Library</li>
<li>From External Resource</li>
<li>Upload image</li>
</ul>
</div>
<div style="float:left;" ui-view>
<h4>Choose one of the options from your left</h4>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="submit()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>

Angular data from controller into modal

I have a controller that looks as following:
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.items = [{name:'Category1', children:['SPCH-1311','SPCH-1315','SPCH-1321','ARAB-1311','ARAB-1312',
'CHIN-1312','CHIN-1411','CHIN-1412','CZEC-1311','CZEC-1312',
'FREN-1311','FREN-1312','FREN-1411','GERM-1311','GERM-1312',
'GERM-1411','GREE-1412','ITAL-1412','JAPN-1412','KORE-1412',
'LATI-1412','PORT-1412','RUSS-1412','SGNL-1301','SGNL-1302',
'SPAN-1311','SPAN-1312','SPAN-1411','SPAN-1412','VIET-1311',
'VIET-1312','VIET-1411','VIET-1412']},
{name:'Category2', children:['SPCH-1311','SPCH-1315','SPCH-1321','ARAB-1311','ARAB-1312',
'CHIN-1312','CHIN-1411','CHIN-1412','SPAN-1311','SPAN-1312','SPAN-1411','SPAN-1412','VIET-1311',
'VIET-1312','VIET-1411','VIET-1412']}];
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
};
and my modal looks like the following:
<a class="btn btn-default pull-right" data-toggle="modal" data-target="#myModal">Add Course <span class="glyphicon glyphicon-plus"></span></a>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">{{subcategory.name2}}</h4>
</div>
<div class="modal-body" align="center">
<font size="2" align="center">Required Credits : <span class="badge badge-machb">{{subcategory.required2}} </span>
Completed Credits : <span class="badge badge-machb">{{subcategory.completed2}} </span>
Planned Credits : <span class="badge badge-machb">{{subcategory.planned2}} </span></font>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
The question is how do i define buttons in such a way that it display it displays the children of the contents of "Category1" when a button named "category1" is clicked ina a modal and "Category2" when the corresponding is clicked?
The planned, required and completed credits in the above modal are from another controller and hence it can be neglected!
The answer is quite straightforward. See plunker to get a complete view of my discussion below.
Iterate the items via ng-repeat and display each item.category as a button which is bound by an ng-click event and pass the index of the item to be used for the modal to resolve.
HTML
<body ng-controller="ModalDemoCtrl">
<button ng-repeat="item in items" ng-bind="item.name" ng-click="open($index)"></button>
</body>
The html fragment above suggests that the ng-click event callback open() must accept the current $index of the iterated items. Use the $index to get the specific category and pass it to the modal's controller ModalInstanceCtrl $scope to be used by the myModalContent.html template.
JAVASCRIPT
var ModalDemoCtrl = function ($scope, $modal, $log) {
$scope.items = [{name:'Category1', children:['SPCH-1311','SPCH-1315','SPCH-1321','ARAB-1311','ARAB-1312',
'CHIN-1312','CHIN-1411','CHIN-1412','CZEC-1311','CZEC-1312',
'FREN-1311','FREN-1312','FREN-1411','GERM-1311','GERM-1312',
'GERM-1411','GREE-1412','ITAL-1412','JAPN-1412','KORE-1412',
'LATI-1412','PORT-1412','RUSS-1412','SGNL-1301','SGNL-1302',
'SPAN-1311','SPAN-1312','SPAN-1411','SPAN-1412','VIET-1311',
'VIET-1312','VIET-1411','VIET-1412']},
{name:'Category2', children:['SPCH-1311','SPCH-1315','SPCH-1321','ARAB-1311','ARAB-1312',
'CHIN-1312','CHIN-1411','CHIN-1412','SPAN-1311','SPAN-1312','SPAN-1411','SPAN-1412','VIET-1311',
'VIET-1312','VIET-1411','VIET-1412']}];
$scope.open = function ($index) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
item: function() {
return $scope.items[$index];
}
}
});
};
};
var ModalInstanceCtrl = function ($scope, $modalInstance, item) {
$scope.item = item;
};
I'm not sure if this is the answer you're looking for, but here it goes. It seems like you want it so that when you click a button, it will display the children of one of your categories. So, here's the code for that.
HTML to display a button for each category:
<button ng-repeat="item in items" ng-click="displayChildren(item)" ng-bind="item.name"></button>
UL to display the children when you select the button:
<ul>
<li ng-repeat="child in children" ng-bind="child"></li>
</ul>
The code in the controller:
$scope.items = [
{
name: "category1",
children: [
"CHIN-1",
"CHIN-2",
"CHIN-3"
]
},
{
name: "category2",
children : [
"VIET-1",
"VIET-2",
"VIET-3"
]
}];
$scope.displayChildren = function(item){
$scope.children = item.children;
}

Resources