4

I am trying to make a statefull modal using angular ui route and and angular ui modal.

lets say i want to fill a sign up form which consist of 4 pages. All of these pages are in a modal.

I am able to open modal on state change. But after that i want to open each pages of the modal on the bases of state.

    $stateProvider.state('signup', {
  url: '/signup',
  template: '<ui-view />',
  abstract: true
})
.state('signup.modal', {
  url: '',
  resolve: {
    modalInstance: function($modal) {
      return $modal.open({
        template: '<div ui-view="modal"></div>',
        controller: 'signUp',
        windowClass: 'signup-edit-modal',
        backdrop: 'static'
      })
    }
  },
  onEnter: ['modalInstance', '$timeout', '$state',function(modalInstance,$timeout, $state) {
    modalInstance.opened.then(function(status){
      if(status){
        $timeout(function(){
          // changing color of background / backdrop of modal for signup
          angular.element('.reveal-modal-bg').css('backgroundColor','rgba(255, 255, 255, .9)');
        })
      }
    })
    $state.go('signup.welcome')
  }],
  onExit: function(modalInstance) {
    modalInstance.close('dismiss');
    angular.element('.reveal-modal-bg').css('backgroundColor','rgba(0, 0, 0, 0.45)');
  }
})
.state('signup.welcome', {
  url: "/welcome",
    views: {
      modal: {
        templateUrl: 'main/signup/welcome.html',
        controller: 'signupWelcome'
      }
    }
}).state('signup.step1', {
  url: "/step1",
    views: {
      modal: {
        templateUrl: 'main/signup/step1.html',
        controller: 'signupStep1'
      }
    }
})

the above code able to open the modal and it also change the state to welcome but for some reason the template is not loading inside the modal. i have assign the template to a ui-view=modal it should open but not.

please help me. thanks in advance

Faheem Alam
  • 515
  • 4
  • 20

2 Answers2

6

I have finally able to view the modal on the bases of state. I agree with @Obi Onuorah that the concept of modals is to hold the state and perform some action with requirement. But if you need to show the modal on the bases of state it is possible.

Thanks to awesome documentations of angular-ui route https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views#view-names---relative-vs-absolute-names which beautifully explains the different between the absolute naming vs relative naming of ui-view.

here is the sample code of UI route

    $stateProvider
  .state('list', {
    url: '/',
    template: '<ul><li ng-repeat="test in testObj"><a ui-sref="view({id: test.id})">{{ test.name }}</a></li></ul>',
    controller: function($scope) {
      $scope.testObj = testObj;
    }
  })
  .state('modal', {
    abstract: true,
    parent: 'list',
    url: '',
    onEnter: ['$modal', '$state', function($modal, $state) {
        console.log('Open modal');
        $modal.open({
          template: '<div ui-view="modal"></div>',
          backdrop: false,
          windowClass: 'right fade'
        }).result.finally(function() {
          $state.go('list');
      });
    }]
  })
  .state('view', {
    url: ':id',
    parent: 'modal',
    views: {
      'modal@': {
        template: '<h1>{{ test.name }}</h1><br />\
        <a ui-sref="edit({id: test.id})">Edit</a><br />\
        <a href="#" ng-click="$close()">Close</a>',
        controller: function($scope, test) {
          $scope.test = test;
        },
        resolve: {
          test: function($stateParams) {
            return testObj[$stateParams.id];
          }
        }
      }
    }
  })
  .state('edit', {
    url: ':id/edit',
    parent: 'modal',
    views: {
      'modal@': {
        template: '<h1>Edit {{ test.name }}</h1><br /> \
          <a ui-sref="view({id: test.id})">View</a> <br />\
          <a href="#" ng-click="$close()">Close</a>',
        controller: function($scope, test) {
          $scope.test = test;
        },
        resolve: {
          test: function($stateParams) {
            return testObj[$stateParams.id];
          }
        }
      }
    }
  });

i have made a simple plunker. http://plnkr.co/edit/hw9x7B?p=preview

Faheem Alam
  • 515
  • 4
  • 20
  • you can mark this as the answer by selecting the tick box beside the up-down vote. Really interesting solution by the way – Obi Sep 02 '15 at 08:13
1

That's the wrong way to do it.

You routes represent what state your application is in. The very concept of modals is to hold the state while capturing what might be an entirely separate process. What you should do is build your own step transitions for your modal and load the required 'template' for each transition into view using ng-if (I prefer this) or ng-show (there might be other ways).

If you want to use routes then don't use a modal basically.

Obi
  • 3,091
  • 4
  • 34
  • 56
  • your saying that there is no option to make state-full modal? the solution you are proposing right now am doing that. by using ng-if or ng-show the controller become so messed up. i want some other solution. – Faheem Alam Jun 18 '15 at 08:09
  • I don't think you can change the template in your modal based on the route because your modal does not participate in the state...at least not using ui-router. And if your controller seems to be getting messed up, refactor your code so that you have a different class which handles the page transitions and collecting the data input and it can hand that off to the controller when it's done. – Obi Jun 18 '15 at 08:45
  • thanks for the answer. But i am able to view the content on the bases of state. as i declare a new ui-view as modal. I make the view abstract like `modal@: { templateUrl://url for template }`. this works for me – Faheem Alam Jun 18 '15 at 10:14
  • This is interesting, I didn't think that was possible. I will definitely experiment with it. Could you post an answer to your question with details of your solution and accept it as the answer so other's (including myself) could learn from your experience. Thanks for sharing. – Obi Jun 18 '15 at 11:27