2

I am complete beginner in AngularJS. Now I want to create the chains of dialogs using ui.bootstrap $uibModal service. I want to receive the data to the dialogs from the .txt file. That means, I won't know initially the quantity of dialogs in the chain, it will depend on the .txt data. For now I tried to do that with the loop, but it`s dumb and then I won't be able to have such functional as "previous", "next", ok and cancel. Is there any wise solution to do that? Thank you in advance for the answer.

var app = angular.module('myApp', ['ui.bootstrap']);

angular.module('myApp').config(['$uibModalProvider', function($uibModalProvider) {
  $uibModalProvider.options.windowClass = 'show';
  $uibModalProvider.options.backdropClass = 'show';
}]);



app.factory('modalDialog', function($uibModal) {
    var arr_items = [];

    var showModalDialog =function(items) {
      return $uibModal.open({
         templateUrl:  'test.html', //just the dialog body for the info
         animation: true,
          size: 'sm',
          ariaLabelledBy: 'modal-title',
          ariaDescribedBy: 'modal-body',
          controller: 'dialogCtrl',
          controllerAs: "$ctrl",
          resolve: { items: function () { console.log("items before travelling" + JSON.stringify(items));
          return items; } }
        });
      
    }

     return {showModalDialog: showModalDialog};


});


app.controller('TestCtrl', function($scope, $http, modalDialog){
  $scope.cancelled = false;
  $scope.test = function(){
    $http.get('test.txt')
        .then(function(response) {
           $scope.items=response.data;
           for (var i=0; i<$scope.items.length; i++) {
            console.log($scope.cancelled); 
            if ($scope.cancelled) return ;
           var showModalDialog = function() {
              console.log("here");
              modalDialog.items = $scope.items[i];
              modalDialog.showModalDialog($scope.items[i]);
            };
            showModalDialog();
          };
        });
  };
});


app.controller('dialogCtrl', function ($scope, $uibModalInstance, items) {
  var $ctrl =this;
  console.log("here are my items" + items.request + " " + JSON.stringify(items));

  $scope.items = items;

  $ctrl.ok = function () {
    $uibModalInstance.close($scope.items);
  };

    $ctrl.cancel = function () {
      console.log("cancel");
      $scope.cancelled = true;
      return $uibModalInstance .dismiss('cancel');
  };
});
<!doctype html>
<html ng-app="myApp">
  <head>
   <meta charset="utf-8">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>
    <script src="ui-bootstrap-tpls-2.5.0.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
<div ng-controller="TestCtrl">
    <button class="btn btn-primary" ng-click="test()">Test</button>
</div>

 <script type="text/ng-template" id="test.html">
  <div><div class="modal-header">
  <h1 class="modal-title">Test Modal</h1>
</div>
<div class="modal-body">
  Test Data:
<div>{{items}}</div>
</div>
<div class="modal-footer">
    <button class="btn btn-primary" type="button" ng-click="$ctrl.ok()">OK</button>
    <button class="btn btn-primary" type="button" ng-click="$ctrl.cancel()">Cancel</button>
</div>
</div>

 </script>



    <script src="script.js"></script>


  </body>
</html>

Here is my test.txt file:

[{
        "request": "new user",
        "dialogs": [
            ["input", "checkbox"],
            ["input", "radiobutton"],
            ["input", "input"]
        ]
    },
    {
        "request": "new project",
        "dialogs": [
            ["input", "input"],
            ["radiobutton", "radiobutton"],
            ["input", "input"]
        ]
    },
    {
        "request": "delete project",
        "dialogs": [
            ["checkbox", "checkbox"],
            ["input", "radiobutton"],
            ["input", "input"]
        ]
    }
]
Shashank Vivek
  • 16,888
  • 8
  • 62
  • 104
Yarycka
  • 165
  • 1
  • 10
  • I think you can achieve it by using `resolve` param which can be retrieved by controller. You can pass the value selected in modal to the controller (then insert it into array) and accordingly open next modal and do the same. Break out of the loop if user selects `cancel` in one of the modals. Let me know if u are able to achieve it or else I'll try to work it out in a plunkr. Ur code in plunkr: https://plnkr.co/edit/JNLdyklmZOvbg5qE1bNd?p=preview – Shashank Vivek Mar 25 '18 at 05:16
  • check out https://angular-ui.github.io/bootstrap/#!#options-parameter . `resolve` (Type: Object) - Members that will be resolved and passed to the controller as locals; it is equivalent of the resolve property in the router. – Shashank Vivek Mar 25 '18 at 05:17
  • @ShashankVivek thank you for the response. What do you mean by the value selected in modal? It is not clear for me: should I invoke the new dialog in the loop, like in the initial version? And the array is needed to then go back and forward, right? – Yarycka Mar 25 '18 at 18:47
  • I have provided an answer. Do let me know if it’s what you were looking for. :) – Shashank Vivek Mar 27 '18 at 19:45
  • 1
    thank you for the help! That solves the problem. Another approach I found is to do one modal dialog, where we initialize all the fields needed. We can change a little bit the json data: make flat array instead of array of arrays and define for each field in json the step on which it should be displayed. Then we define var current_step and change it in functions next() and previous(). Then we can use ng-show to dynamically show the needed field if its step number is equal to current step. – Yarycka Mar 27 '18 at 20:11

1 Answers1

1

Here you go ! Check this plunkr.

The main logic for loop resides in

function initiateModal(itemList,index){
  modalDialog.showModalDialog(itemList[index]).result
    .then(function(resp){
              if(resp === 'cancel'){ // if user cancel the process in between
                $scope.userSeletion.length = 0;
                return ;
              }else if(itemList.length === (index+1)){ // for pushing the last modal data into array
                $scope.userSeletion.push(resp);
                return ;
              }else{
                $scope.userSeletion.push(resp);
                index++;
                initiateModal (itemList,index);
              }
       })
} 

which waits for the promise of earlier modal to open the next one.

For now, I am passing userInput as a data, which i can fill depending on the user form input

Shashank Vivek
  • 16,888
  • 8
  • 62
  • 104