0

I am writing an angular app which has a Search products page which shows a list of products. When any product is clicked in the search results, the details of the product should appear below the search results. I am implementing this using angular-ui-router with named views. There are separate templates and controllers for search-product and view-product and the controllers share data using a service. Now I want to show the viewProduct view to only appear when a search-result is clicked on and remain hidden if nothing is clicked. How can I accomplish this ?

Following is the implementation:

$stateProvider
    .state('home', {
        templateUrl: "search.html"
     })
     .state('home.search',{
         url:'/search',
         views:{
             'searchProducts':{
                 templateUrl: 'search-products.html',
                 controller: 'SearchProductsController'
             },
             'viewProduct':{
                 templateUrl: 'view-product.html',
                 controller: 'ViewProductController'
              }
      })

search.html

<div ui-view="searchProducts"></div>
<div ui-view="viewProduct"></div>

index.html

<div ui-view></div>
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
vjain27
  • 3,514
  • 9
  • 41
  • 60

2 Answers2

2

There is a working example

I would split 'search' state into two states - view products 'results' is its child:

.state('home', {
  templateUrl: "search.html"
})
.state('home.search', {
    url: '/search',
    views: {
      'searchProducts': {
        templateUrl: 'search-products.html',
        controller: 'SearchProductsController'
      }
    }
  })
  .state('home.search.results', {
    url: '/results',
    views: {
      'viewProduct@home': {
        templateUrl: 'view-product.html',
        controller: 'ViewProductController'
      }
    }
  });

This would be the 'search-products.html' - which forces view to be reloaded on each search click (read more here in the doc):

<div>
  <button
    ui-sref="home.search.results"
    ui-sref-opts="{reload:true}">search</button>

</div>

And we can even introduce Clear and hide this child state - the 'view-product.html' template:

<div>
  <button ui-sref="home.search" >clear</button>
  // results      
</div>

Check it in action here

And what would do that with the data? child has access to parent scope. Check more here:

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • 1
    According to spec in OP there is a parameter required for `.results` state which will indicate the selected product to be shown. In this case `reload: true` is not required. But the idea with a sub-state is awesome – Kirill Slatin Aug 13 '15 at 03:59
  • Thanks a lot for the reply! I have another related question. The view-product views contains scroll-bars and I always want to scroll to the top in that view whenever a search result is clicked on. How can I achieve that ? – vjain27 Aug 14 '15 at 00:57
  • Glad to see that this helped. I would really suggest... close this question and create new (linked to this if needed) and ask for issue with scroll... Because you would target larger audience and that's why I am sure you will get the answer to your new question soon... Hope it helps a bit ;) – Radim Köhler Aug 14 '15 at 06:05
0

You can achieve this simply by adding a controller to your home url. Since it is a parent to the home.search state, they will inherit its scope. (doc)

Therefore, you can have an object on your parent scope called home (you dont want to add properties directly to the scope as it would be ambiguous) and refer to it from the childs controllers/views to hide or show the viewProduct.

Simply to illusatrate the idea, it could look as follow:

In your home controller

$scope.home = {viewProductOpen: false}

In your searchResults html

<any ng-click="home.viewProductOpen = true" > </any>

In your home html

<div ui-view="searchProducts"></div>
<div ui-view="viewProduct" ng-show="home.viewProductOpen"></div>
Anthony Garant
  • 614
  • 7
  • 13