2

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>
6
  • Why do you have ng-model="selectedCountry" on the options of the select? Commented Apr 12, 2017 at 14:34
  • And what do you see when you add console.log('model one hidden Templt_Kind_ID=' + $scope.selectedCountry); in the hide() function? Commented Apr 12, 2017 at 14:38
  • >>Why do you have ng-model="selectedCountry" on the options of the select? I hate to say, but I have been working on this for a day and a half and do not remember why I put it in there. >>And what do you see when you add console.log('model one hidden Templt_Kind_ID=' + $scope.selectedCountry); -1 Commented Apr 12, 2017 at 14:41
  • Well I don't know how or from where you call the hide() function, but there is an implementation of the bootstrap components for angular, you might want to try the native modal - angular-ui.github.io/bootstrap/#!#modal it should probably solve your issue Commented Apr 12, 2017 at 14:47
  • I call the hide() function from a button in the modal popup <modal-footer> <button class="btn btn-primary" ng-click="hide()">Save</button> </modal-footer> Commented Apr 12, 2017 at 14:50

1 Answer 1

0

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>

Sign up to request clarification or add additional context in comments.

7 Comments

I am going to press the issue of angular-ui-bootstrap because it seems there are 2 $scope levels when using native bootstrap. Hey, after a day and a half, what is another day. <smile> Thanks Alon.
What do you mean by press the issue of angular-ui-bootstrap? If you can demonstrate the issue of the 2 level scope then I might be able to help, but as you can see from my answer - Using a native solution allows you to implement your requirements easily without having to handle the inner scope level (Well, at least with the details provided in your original question).
The 2 level scope comes from $scope.Templt_Kind_ID = ddlID not actually = 34 AFTER the modal closes. var ddlID = $scope.selectedCountry; // << contains correct value $scope.Templt_Kind_ID = ddlID; // << $scope.Templt_Kind_ID = 34 as it should be $scope.Templt_Kind_ID is not giving me an error, it just reverts to its original = -1 . So I say "2 level scope" because it reverts to -1 eventhough it is set to = 34 upon close. scope.Templt_Kind_ID = ddlID seems to be going somewhere else.
I did discover a work-around with app.factory('factEdit', function () { return { selectedCountry: '' }; }); I think your solution is the correct solution... use the native library and will mark yours as solved. Tommorow, I will post my work around though in case it will help someone else. And shalom for you. Thanks very much.
I ran into another problem with the AngularJS validation and closing the popup after the SAVE button is clicked. Finding workarounds for the implementation I was told to work with is just too costly. Alon was correct. Using angular-ui-bootstrap instead of Bootstrap UI is the correct way to implement the code. Thanks Alon.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.