3

I have seen a design interface here, and I liked it.

enter image description here

I was doing it with AngularJS, and ui-router which allows to have multiple views on a single page.

I have an issue for smartphone, because I want to display only one view, not two like tablets/desktops.

Question : What would be the best way to display only one view for small screens, and two for larger screens ?

I had basic ideas :

Idea 1 (not so so good) : I was thinking to create multiple routes, then route to one or the other route depending the screen size.

Inside angular config

app.config(function($stateProvider) {
  $stateProvider
    .state('listForLargeScreens', {
      url: "/listForLargeScreens",
      views: {
        "primary": { templateUrl: "list.html" },
        "secondary": { templateUrl: "detail.html" }
      }
    })
    .state('listForSmallScreens', {
      url: "/listForSmallScreens",
      views: {
        "primary": { templateUrl: "list.html" }
      }
    })
    ...;

Inside a random controller

app.controller('RandomCtrl', function ($scope, $state) {
   $scope.changePage = function () {
       if (isLargeScreen) {
           $state.go('indexForLargeScreens');
       } else {
           $state.go('indexForSmallScreens');
       }
   }
});

Problem : this idea seems to me too "dirty" for maintaining.

Idea 2 : I was thinking to declare primary and secondary views, then I could hide with CSS the secondary one with CSS :

Inside angular config

app.config(function($stateProvider) {
  $stateProvider
    .state('list', {
      url: "/",
      views: {
        "primary": { templateUrl: "list.html" },
        "secondary": { templateUrl: "detail.html" }
      }
    })
    .state('detail', {
      url: "/detail/:id",
      views: {
        "secondary": { templateUrl: "list.html" },
        "primary": { templateUrl: "detail.html" }
      }
    })
    ...;

Inside html

 <div ui-view="main"></div>
 <div ui-view="secondary"></div> <!-- For small screens, hide this view with CSS -->

Problem : different URLS can have the same views, but with inverted priorities, see :

enter image description here

So, on small screens, it could work, but on larger screens, in some URLs, views can be inverted, (see the image above), so in HTML, list.html and detail.html templates will be inverted too.

It could solve the problem if I could invert <div ui-view="primary"></div> and <div ui-view="secondary"></div> on some views...

Jacques Cornat
  • 1,612
  • 1
  • 19
  • 34
  • Could you take the `directive` approach? Inject each view into a directive and then based on screen size disable that directive attribute/element. – tcasey Aug 02 '16 at 22:06
  • `Inject each view into a directive` : how would you do that ? (approximately) – Jacques Cornat Aug 02 '16 at 22:23
  • I think what @tcasey means, is that you create one View/Page for both scenarios. Essentially, create the view for a "desktop" size, and then use `media` queries to show/hide/resize elements for screens smaller than a certain size ("mobile") - see this link for information on CSS media queries: https://www.smashingmagazine.com/2010/07/how-to-use-css3-media-queries-to-create-a-mobile-version-of-your-website/ – Geoff James Aug 03 '16 at 09:25
  • Creating and then maintaining 2 separate views and controller actions for the same situation is ultimately counter-productive. Think when you need to update one view, you have to match the methods and data output for both - at some point the two are going to become out of sync and something is going to get missed out. Use the same view for both situations, and just make it responsive to screen size changes – Geoff James Aug 03 '16 at 09:27
  • `Use the same view for both situations, and just make it responsive to screen size changes` : If I use the same view for both situations, there will be code duplication isn'it ? Because, currently, on two different URL, I use the same views, but primary and secondary templates are just inverted, as shown in the image above – Jacques Cornat Aug 03 '16 at 10:11

1 Answers1

0

I've just found on scotch.io a piece of code which is the key for that problem.

The idea 2 on the question was almost the answer, but I had a problem with different URLs which where using same views, but with inverted priorities.

ui-router allows with multiple named views, to get ancestors, so I have to create a piece of html which declares ui-views :

Inside angular config :

$stateProvider.state('list', {
    url: '/list',
    views: {
        '': { templateUrl: 'partial-list.html' },
        'primary@list': { 
            templateUrl: 'list.html',
            controller: 'ListCtrl as ctrl'
        },
        'secondary@list': { 
            templateUrl: 'detail.html',
            controller: 'DetailCtrl as ctrl'
        }
    }
}).state('detail', {
    url: '/detail/:id',
    views: {
        '': { templateUrl: 'partial-detail.html' },
        'primary@list': { 
            templateUrl: 'detail.html',
            controller: 'DetailCtrl as ctrl'
        },
        'secondary@list': { 
            templateUrl: 'list.html',
            controller: 'ListCtrl as ctrl'
        }
    }
});

Inside partial-list.html :

<div ui-view="primary"></div>
<div ui-view="secondary" class="hide-it-for-small-screens"></div>

Inside partial-detail.html :

<div ui-view="secondary" class="hide-it-for-small-screens"></div>
<div ui-view="primary"></div>

It works ! :)

Jacques Cornat
  • 1,612
  • 1
  • 19
  • 34