AngularJS $scope.variable not changing after modal bootstrap popup closes - angularjs

Why is $scope.Templt_Kind_ID not changing after the bootstrap popup is closed?
Note: I do not close the popup until I retrieve the dropdown value from the popup.
I call a bootstrap popup with edit controls.
After a user changes a dropdown value, it calls
the $scope.onSelectChangeTemplate_kind = function ()
In the function below,
var ddlID = $scope.selectedCountry; contains the correct value.
$scope.Templt_Kind_ID = ddlID; // << $scope.Templt_Kind_ID = 34 as it should be
Upon closing the popup, I expected $scope.Templt_Kind_ID = 34
but it contains -1 which is what it was first initialized to.
Why? $scope.Templt_Kind_ID should = 34
JavaScript
app.controller('APIController', function ($scope, $window, $element, $log, $http, APIService) {
$scope.Templt_Kind_ID = -1; // << Initial value
// Bootstrap popup. After dropdown in bootstrap is changed, this is called.
// I tried a number of things including $scope.onSelectChangeTemplate_kind = function ($scope)
$scope.onSelectChangeTemplate_kind = function () {
var ddlID = $scope.selectedCountry; // << contains correct value
$scope.Templt_Kind_ID = ddlID; // << $scope.Templt_Kind_ID = 34 as it should be
}
// Bootstrap popup is closed.
// Why is $scope.Templt_Kind_ID=-1 although it shuold be 34 ?????
// Why is $scope.Templt_Kind_ID=-1 although it shuold be 34 ?????
$scope.hide = function () {
console.log('model one hidden Templt_Kind_ID=' +
$scope.Templt_Kind_ID); // <<<<<<
// << $scope.Templt_Kind_ID is still -1 although it shuold be 34
$scope.showModal1 = false;
}
})
<html>
<modal-body>
<div ng-controller="APIController">
<select id="ddlSelectedCountry" ng-model="selectedCountry" ng-change="onSelectChangeTemplate_kind()">
#*3-SP Insert*#
<option value="">Select Account</option>
<option
ng-model="selectedCountry"
ng-repeat="item in list_Template_kind" value="{{item.Templt_Kind_ID}}"
>
{{item.Templt_Kind_ID}}-{{item.Templt_Kind_Name}}
</option>
</select>
</div>
</modal-body>
</html>

As I recommended in the comments, you can use the native angular module.
Here you open the modal and select the template, when you click OK the modal return the selected template back to the controller:
var app = angular.module('app', ['ui.bootstrap']);
app.controller('ctrl', ['$scope', '$uibModal', '$log', function($scope, $uibModal, $log) {
// function to open the Modal from the view, the function accept "selection" argument that will be sent to the model's controller
$scope.openModal = function (selection) {
var modalInstance = $uibModal.open({
templateUrl: 'modal.html',
resolve: {
// Pass a pre selection template to the Model's controller (pass null if you don't want to pre select)
selection: function() { return selection; }
},
controller: function($scope, $uibModalInstance, selection) {
// save the preselected template and display it on the model's select box
$scope.selectedTemplate = selection;
// Mock of the actual list of templates
$scope.list_Template_kind = [
{ Templt_Kind_ID: 1, Templt_Kind_Name: 'Template 1' },
{ Templt_Kind_ID: 2, Templt_Kind_Name: 'Template 2' },
{ Templt_Kind_ID: 3, Templt_Kind_Name: 'Template 3' },
{ Templt_Kind_ID: 4, Templt_Kind_Name: 'Template 4' }
];
// OK button was clicked
$scope.ok = function () {
// Send the selected template back to the main controller
$uibModalInstance.close($scope.selectedTemplate);
};
// CANCEL button was clicked
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
});
// The "$uibModal.open()" returns a promise that resolves when called "$uibModalInstance.close()" from the model's controller
// or rejected when you call "$uibModalInstance.dismiss()".
// You can pass any value to those promise functions from the Model controller and use it in the resolve/reject callbacks
modalInstance.result.then(function (selectedItem) {
// Get the selected template sent back from the modal ($uibModalInstance.close($scope.selectedTemplate);)
$scope.selected = selectedItem;
}, function () {
// The user clicked on the "cancel" button
$log.info('modal-component dismissed at: ' + new Date());
});
}
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<div ng-app="app" ng-controller="ctrl">
<script type="text/ng-template" id="modal.html">
<div class="modal-header">
<h3 class="modal-title">The modal!</h3>
</div>
<div class="modal-body">
<select id="selectedTemplate" ng-model="selectedTemplate" ng-change="onSelectChangeTemplate_kind()">
<option value="">Select Account</option>
<option ng-repeat="item in list_Template_kind" value="{{item.Templt_Kind_ID}}">
{{item.Templt_Kind_ID}}-{{item.Templt_Kind_Name}}
</option>
</select>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</script>
<! -- Call "openModal" and pass "null" so no pre selection is displayed in the modal -->
<button ng-click="openModal(null)">Open</button>
<! -- Call "openModal" and pass "2" so "Template 2" will be preselected in the modal -->
<button ng-click="openModal('2')">Open (Preselect 2)</button>
<! -- Call "openModal" and pass the {{ selected }} property so the last template selected since you last closed the modal will be shown in the modal -->
<button ng-click="openModal(selected )">Open (Preselect last selected)</button>
<! -- Show the last selected template in the view (For debugging purposes) -->
<span ng-if="selected">{{ 'selected - ' + selected }}</span>
</div>

Related

Save Form data from Popover in Angularjs

var App = angular.module('myApp', []);
App.controller('myPopoverCtrl',
function($scope){
$scope.myPopover = {
isOpen: false,
open: function open() {
$scope.myPopover.isOpen = true;
},
close: function close() {
// alert('hi');
$scope.myPopover.isOpen = false;
}
};
$scope.SaveNotes = function() {
console.log('hi');
console.log($scope.noteText);
//getting undefined here
return false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app = "App">
<a uib-popover-template="'AddNote.html'"
popover-title="AddNote"
popover-trigger="'outsideClick'"
ng-controller="myPopoverCtrl"
popover-is-open="myPopover.isOpen"
ng-click="myPopover.open()">Add
</a>
</div>
<script type="text/ng-template" id="AddNote.html">
<div>
<textarea class="form-control height-auto"
ng-model="noteText"
placeholder="This is a new note" ></textarea>
<input class="btn btn-outline btn-primary"
type="button"
ng- click="SaveNotes();" value="Save">
</div>
</script>
I have web a page where i have a button and when click the button popover appears.In that popover i have textarea but when i click save button i want get the text in my controller but i am getting undefined using $scope.modelname
How can i get that data?
I think you want to use a modal rather than a popover like so, as a popover is really just to display text :-
var modalInstance = $modal.open({
animation: $rootScope.animationsEnabled,
templateUrl: 'views/myTemplate.html',
size: 'md'
}).result.then(function(result) {
$scope.result = result;
});
This is what it's designed for more info here.

Angularjs modal dialog form not recognizing click event from Datepair

I'm using bootstrap modal with angularjs along with datepair.
http://jonthornton.github.io/Datepair.js/
I'm working on creating a single page leave request calendar where I can add leave request to the calendar via a modal dialog box. When the box pops up, you pick your date and time you'll be absent from work. I'm experiencing an issue where the datepair doesn't work when nested within the modal dialog template.
The modal dialog works in the following code, but a click doesn't seem to trigger the calendar or time popup like in the demo link provided above. Everything works fine outside of the angularjs / modal template.
var app = angular.module('myModule', ['ui.bootstrap']);
app.controller('ModalDemoCtrl', function ($scope, $uibModal, $log) {
$scope.animationsEnabled = true;
$scope.open = function (size) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.toggleAnimation = function () {
$scope.animationsEnabled = !$scope.animationsEnabled;
};
});
//Please note that $modalInstance represents a modal window (instance) dependency.
//It is not the same as the $uibModal service used above.
app.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, items) {
$http.get('./requestType.json')
.success(function (data) {
$scope.requestTypeList = data;
});
// initialize input widgets first
$('#requestForm .time').timepicker({
'showDuration': true,
'timeFormat': 'g:ia'
});
$('#requestForm .date').datepicker({
'format': 'm/d/yyyy',
'autoclose': true
});
// initialize datepair
var requestForm = document.getElementById('requestForm');
var datepair = new Datepair(requestForm);
$scope.ok = function () {
$uibModalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
html
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<form ng-submit="submitForm()" form-autofill-fix name="form">
<p id="requestForm">
<label>Request Type</label>
<select ng-model="formData.requestType" ng-options="rt.name for rt in requestTypeList track by rt.id" required class="form-control">
<option value="">- Select Request Type</option>
</select>
<label>Start Date</label><input type="text" class="form-control date start" ng-model="formData.startDate" required/>
<label>Start Time</label> <input type="text" class="form-control time start" ng-model="formData.startTime" required/>
<label>End Time</label><input type="text" class="form-control time end" ng-model="formData.endTime" required/>
<label>End Date</label><input type="text" class="form-control date end" ng-model="formData.endDate" required/>
<ul>
<li ng-repeat="item in items">
{{ item }}
</li>
</ul>
</p>
<input type="submit" value="Add to Agenda" class="btn btn-success"/>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
</script>
Now requestTypeList works perfectly to load the select menu, but if I click the date field, nothing pops up. What might be wrong?
I think the problem is that ModalInstanceCtrl is executing before template inserted to the DOM. The first rule of angular: do not use angular do not do DOM Manipulations from controllers, services or anywhere else but from directives.
So instead of doing this
$('#requestForm .time').timepicker({
'showDuration': true,
'timeFormat': 'g:ia'
});
from modal's controller make an directive for this:
(function () {
'use strict';
angular
.module('xp-timepicker', [])
.directive('xpTimepicker', timepicker);
function timepicker() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.timepicker({
showDuration: true,
timeFormat: 'g:ia'
});
}
};
}
}());
// to use your directive in your app include it's module as dependency for your app module
angular
.module('app', ['xp-timepicker']);
Then place this directive on input fields you need:
<input type="text" ng-model="time" xp-timepicker>
I made a working plunker for you.
the z-index of bootstrap modal by default is 1050
the z-index of the date widget seems to be 1000 by default
hence the date widget will be "under" the modal.
you will have to do some css fixes if you want the date widget to be visible above the modal window

Getting `undefined` when using ng-repeat and radio buttons

I am encountering a strange behavior when using Angular's ng-repeat on a Bootstrap UI modal.
I have this dummy method in my customerService.js factory:
app.factory('customerService', [ function() {
customerFactory.getCustomers =
function () {
return [{ "name": "Terry Tibbs" },
{ "name": "Bobby Halls" },
{ "name": "Garry Brisket" }]
};
return customerFactory;
}]);
This the customerSelectionModal.html modal template:
<div>
<div class="modal-header">
<h3 class="modal-title">Select a customer</h3>
</div>
<div class="modal-body">
<label data-ng-repeat="cust in customers">
<input name="customer" type="radio" value="{{cust}}" ng-model="$parent.selected.item" />{{cust.name}}
</label>
<div ng-show="selected">You have selected: {{ selected }}</div>
<div ng-show="selected">name: {{ selected.item.name }}</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-default" ng-click="cancel()">Cancel</button>
</div>
</div>
</div>
This is the customerController.js file:
'use strict';
appModule.controller('customerController',
['$scope', '$modal', '$log', 'customerService', function ($scope, $modal, $log, customerService) {
$scope.customers = customerService.getCustomers();
$scope.selectCustomer = function () {
var modalInstance = $modal.open({
templateUrl: paths.templates + 'customerSelectionModal.html',
controller: 'modalInstanceController',
resolve: {
customers: function () {
return $scope.customers;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.customerName = selectedItem.name;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}]);
Finally the modalInstanceController.js controller for the modal form:
app.controller('modalInstanceController',
function ($scope, $modalInstance, customers) {
$scope.customers = customers;
$scope.selected = {
item: $scope.customers[0]
};
$scope.ok = function () {
alert($scope.selected.item.name);
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
When the modal dialog is displayed initially I get You have selected: {"item":{"name":"Terry Tibbs"}} displayed correctly as this is the default customer
selected by the modalInstanceController controller. However, when I select a customer I get You have selected: {"item":"{\"name\":\"Terry Tibbs\"}"} and clicking the OK button just displays undefined in the alert
window and I don't know why.
The only possible clue is when a customer is selected the name property and it's value are escaped using a \ for some odd reason that I haven't been able to figure out.
Has anyone any clue as to what's going on here?
Lastly, is it possible to set the radio button to the selected customer as it doesn't put a selection against the customer?
I am using the following:
AngularJS v1.3.9
Twitter Bootstrap v3.3.1
Angular UI Bootstrap v0.12.0
Anyway, in the radio button, try to use ng-value instead value attribute.

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>

ng-model is not working inside a ui bootstrap modal window and angular

I'm using this modal window using angular and bootstrap ui
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">Cambia Palmare {{descPalmare}} ( {{descProgetto}} )</h3>
</div>
<div class="modal-body">
<ul>
<li >
<select id="soluzioneDlg" name="soluzioneDlg"
class="required"
ng-options="soluzione.id as soluzione.denominazione for soluzione in soluzioni"
ng-model="soluzioneCorrente"
ng-change="filtroSoluzione()"></select>
</li>
<select id="progettoDlg" name="progettoDlg"
class="required"
ng-options="progetto.id as progetto.denominazione for progetto in progetti"
ng-model="progettoCorrente"></select>
<li>
</li>
</ul>
</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>
I'm opening the dialog correctly and the soluzioneDlg select is filled correctly.
When the selection is changed, the filtroSoluzione method is correctly called but the scope variable bound using ng-model is undefined.
$scope.filtroSoluzione = () => {
alert($scope.soluzioneCorrente);
var progettoPromise = progetti.progettiSoluzione($scope.soluzioneCorrente);
progettoPromise.then(function (progetti: Factories.Progetto[]) {
$scope.progetti = progetti;
},
function (reason) {
alert('errore in recupero lista dispositivi: ' + reason);
}, function (update) {
alert('Got notification: ' + update);
});
}
Am I missing something? I used this code in other pages and is working correctly.
Thanks,
Luca
this is the angular code that calls the $modal.open
// cambia assegnazione, apro la finestra di assegnazione
$scope.cambiaAssegnazione = (palmare: number) => {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: assegnaDispIspettoreDialog,
size: '(large)',
resolve: {
palmareDaAggiornare: function () {
return palmare;
},
dispositivi: function () {
return dispositivi;
},
soluzioni: function () {
return soluzioni;
},
progetti: function () {
return progetti;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selectedItem = selectedItem;
}, function () {
alert('Modal dismissed at: ' + new Date());
});
}
when I click a link in a list the mg_chnage change this code that open the dialog: in the resolve I send the reference of a few services I created, because I have to fill the listbox in the modal dialog.
the descPalmare, descProgetto and soluzioni scope properties are handled correctly: the only problem is in the soluzioneCorrente member
I created the full repro here:
http://plnkr.co/edit/G8qygJWkYCqiYZK5FcgN
The modal uses a child scope, see Understanding Scopes in the Angular.js Wiki. Try changing the ng-model for both in the page and in the modal to model.soluzioneCorrente instead and set the scope property of the $modal.open to the current $scope.
http://plnkr.co/edit/h3HIeM7oDwo42LK3CZie?p=preview

Resources