Open page url in modal on a page (Facebook Photo URLs)
Asked Answered
C

1

1

P.S. I am using html5Mode to remove '#' in routing in below scenario Removing the fragment identifier from AngularJS urls (# symbol)

Consider I have two main pages.One is photos where thumbnails are provided and whose url is /someSlug/photos. Other is the url of a single photo '/someSlug/photos/somePhotoId' which shows a bigger view of a particular photo.

My problem is to show the /someSlug/photos/somePhotoId page in modal when user clicked on somePhoto thumbnail in photos page (and yes the url should change to /someSlug/photos/somePhotoId). But if user access it directly like this /someSlug/photos/somePhotoId single photo page should come. I am able to include the single photo template into my modal but facing issues with routing. Not able to change the url while opening the modal to /someSlug/photos/somePhotoId because it opens up new page.

I have two modules for this:
A-> Used and handles routes of photos page
B-> used and handle routes of single photo

Since B single photo template is used in 'A', I have put dependency of 'B' into 'A'. So whenever I try to change the url to /someSlug/photos/somePhotoId while in modal. B's routing overrides the job and open the page. Best example for this is facebook photos. Tried to create a fiddle but its not giving me routing access. Just have a look on facebook photos URL and you will come to know about it. If you needs more inputs, please let me know :)

I am very new to angularJS (Basics->Advanced Stage). Any help would be highly appreciated.

Claiborn answered 17/6, 2015 at 18:56 Comment(0)
V
1

This can be achieved by creating two states with same URL.

For the state that opens the modal , create a hidden parameter , using params option. This is used to find weather the user came from clicking or directly. If user comes by clicking ,then we set a value for the hidden parameter via ui-sref and show the modal (using UI Bootstrap's $modal). In case user comes directly to the URL, then we redirect them to the other state with same URL but different template and controller. All this is done inside the onEnter function which is called when this state gets opened. As this state has no template or templateUrl , therefore it doesn't change the view.

The state configuration

.state('gallery', {
    url: "/",
    templateUrl: "gallery.html",
    controller: 'galleryCtrl'
})
.state('gallery.photoModal', {
    url: "photo/:id",
    params: {
        fromGallery: null
    },
    onEnter: ['$stateParams', '$state', '$modal', function($stateParams, $state, $modal) {
        if ($stateParams.fromGallery === true) {
            console.log('Goes To Modal View');
            $modal.open({
                templateUrl: 'modal.html',
                controller: 'modalCtrl',
                size: 'lg'
            }).result.finally(function() {
                $state.go('gallery'); // Parent state
            });
        } else {
            console.log('Goes To Full View');
            $state.go('gallery.photoFull', {
                id: $stateParams.id
            });
        }
    }],
    onExit: ['$modalStack', function($modalStack) {
        // Dismisses Modal if Open , to handle browser back button press
        $modalStack.dismissAll();
    }]
})
.state('gallery.photoFull', {
    url: 'photo/:id',
    templateUrl: "photo.html",
    controller: 'photoCtrl'
})

The template for the parent state , from where we click to show the modal

<div class="spacing" ui-view>
  <div class="contain" >
    <div ng-repeat='photos in gallery.photos'>
      <a ui-sref="gallery.photoModal({id: photos.id,fromGallery:true})">
        <img ng-src="{{photos.photoURL}}" width="200" height="200" />
      </a>
    </div>
  </div>
</div>

The parent controller , contains dummy data which is used for ngRepeat

.controller('galleryCtrl', ['$scope', function($scope) {
    $scope.gallery = {
      photos: [{
        photoURL: 'https://placeholdit.imgix.net/~text?txtsize=40&txt=200%C3%97200&w=200&h=200',
        id: '1'
      }]
   };
}])

The template for the Modal State

<div class="spacing">
  <a ng-click="dismiss.modal()" class="pull-right" href>Close</a>
  <img ng-src="{{photo.photoURL}}" width="500" height="500" />
</div>

The controller for modal state , contains method to dismiss the modal & dummy data

.controller('modalCtrl', ['$scope', '$modalInstance', function($scope, $modalInstance) {
    $scope.dismiss = {
      modal: function() {
        $modalInstance.dismiss('cancel');
      }
    };
    $scope.photo = {
      photoURL: 'https://placeholdit.imgix.net/~text?txtsize=80&txt=500%C3%97500&w=500&h=500',
      id: '1'
    };
}])

You can check a working example at Plunker , check http://run.plnkr.co/plunks/wRqwPr/#/ to see the changes in URL

Veritable answered 20/6, 2015 at 20:51 Comment(3)
Thanks for the answer. Will implement it and let you know abt the resultsClaiborn
Not completely working but very close to achieve the desired result. Some tweaks in my code and it worked :) Thanks a lot :)Claiborn
Also please don' remove the plunker. I need it for my future reference :)Claiborn

© 2022 - 2024 — McMap. All rights reserved.