1

I'm creating a search page where the user can search for data using pre-selected search criteria listed in the first drop-down. In the example below those criteria are 'First Name', 'Country' and 'Nationality'.

When the user selects Country or Nationality, a second drop-down appears to select one of the countries/nationalities. To fill this drop-down i use ng-options with a variable inside that points to a string defined in the controller.

But when one of those two options is selected and you want to switch to the other, the second drop-down does not get updated. The value inside ngOptions does get updated in the HTML, just the data inside the dropdown isn't.

When you select 'First Name' in between there is no issue. Does anyone know what I can use so the values inside the second dropdown gets updated?

Below is my code and a working plunker: http://plnkr.co/edit/LYpOdoLpgiMeHxlGzmub?p=preview

var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope) {
  
    var vm = this;
    
    vm.search = {id:0, criteria: {}, value: ''};
    
    vm.referenceData = {
      countries: [
        {COUNTRY_ID:1, COUNTRY_NAME: 'UNITED KINGDOM'},
        {COUNTRY_ID:2, COUNTRY_NAME: 'AUSTRALIA'},
        {COUNTRY_ID:3, COUNTRY_NAME: 'SOUTH AFRICA'},
        {COUNTRY_ID:4, COUNTRY_NAME: 'NETHERLANDS'},  
      ],
      nationalities: [
        {NATIONALITY_ID: 1, NATIONALITY_NAME: "BRITISH"},
        {NATIONALITY_ID: 2, NATIONALITY_NAME: "AUSTRALIAN"},
        {NATIONALITY_ID: 3, NATIONALITY_NAME: "SOUTH AFRICAN"},
        {NATIONALITY_ID: 4, NATIONALITY_NAME: "DUTCH"},  
        ]
    };
    
    vm.criteriaList = [
        { name: 'First Name', key: 'FIRST_NAME'},
        { name: 'Country', key: 'COUNTRY_ID', options:'o.COUNTRY_ID as o.COUNTRY_NAME for o in ctrl.referenceData.countries' },
        { name: 'Nationality', key: 'NATIONALITY', options:'o.NATIONALITY_ID as o.NATIONALITY_NAME for o in ctrl.referenceData.nationalities' }
    ];
});
<!DOCTYPE html>
<html>

<head>
  <script data-require="[email protected]" data-semver="1.6.2" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-app="myApp" ng-controller="SomeController as ctrl">


  <p>Criteria:</p>
  <select ng-model="search.criteria" ng-change="search.value = ''" ng-options="criteria as criteria.name for criteria in ctrl.criteriaList">
    <option value="">- Select Criteria -</option>
  </select>
  
  
  <p>Value:</p>
  <!-- TEXT INPUT -->
  <input type="text" ng-model="search.value" placeholder="Search Value" ng-if="!search.criteria.options" />
  <!-- DROPDOWN INPUT -->
  <select ng-model="search.value" ng-if="search.criteria.options" ng-options="{{search.criteria.options}}"></select>

</html>

3
  • is the first time i see an expression inside ng-options, i see the plnkr and im concerned to why dont refresh. maybe cause is ng-options not handling bindig data that whay. Maybe with an a directive could solve, forcing refresh component. Commented Aug 9, 2017 at 20:22
  • a non elegant solution is handle two dropdowns one for, nationality and other for cities. i know thats isnt you are looking for. Commented Aug 9, 2017 at 20:23
  • here is a solution with directive like i say stackoverflow.com/a/27857228/8303694 Commented Aug 9, 2017 at 20:25

1 Answer 1

1

This is an easy fix you just need a variable that can if out the second dropdown everytime you switch. The dom needs something to force it to refresh since there isnt a scope.$apply happening.

Plunker Working

Try this:

var myApp = angular.module('myApp', []);
myApp.controller("SomeController", function($scope, $timeout) {

    var vm = this;
    vm.somVal = false; ///ADD THIS
    vm.search = {id:0, criteria: {}, value: ''};

    vm.triggerSomeVal = function(){ ///ADD THIS
      vm.someVal = true;
      $timeout(function(){vm.someVal = false}, 100)
    };

    vm.referenceData = {
      countries: [
        {COUNTRY_ID:1, COUNTRY_NAME: 'UNITED KINGDOM'},
        {COUNTRY_ID:2, COUNTRY_NAME: 'AUSTRALIA'},
        {COUNTRY_ID:3, COUNTRY_NAME: 'SOUTH AFRICA'},
        {COUNTRY_ID:4, COUNTRY_NAME: 'NETHERLANDS'},  
      ],
      nationalities: [
        {NATIONALITY_ID: 1, NATIONALITY_NAME: "BRITISH"},
        {NATIONALITY_ID: 2, NATIONALITY_NAME: "AUSTRALIAN"},
        {NATIONALITY_ID: 3, NATIONALITY_NAME: "SOUTH AFRICAN"},
        {NATIONALITY_ID: 4, NATIONALITY_NAME: "DUTCH"},  
        ]
    };

    vm.criteriaList = [
        { name: 'First Name', key: 'FIRST_NAME'},
        { name: 'Country', key: 'COUNTRY_ID', options:'o.COUNTRY_ID as o.COUNTRY_NAME for o in ctrl.referenceData.countries' },
        { name: 'Nationality', key: 'NATIONALITY', options:'o.NATIONALITY_ID as o.NATIONALITY_NAME for o in ctrl.referenceData.nationalities' }
    ];
});

<p>Criteria:</p>
  <select ng-model="search.criteria" ng-change="search.value = ''; ctrl.triggerSomeVal()" ng-options="criteria as criteria.name for criteria in ctrl.criteriaList">
    <option value="">- Select Criteria -</option>
  </select>


  <p>Value:</p>
  <!-- TEXT INPUT -->
  <input type="text" ng-model="search.value" placeholder="Search Value" ng-if="!search.criteria.options" />
  <!-- DROPDOWN INPUT ADD !someVal-->
  <select ng-model="search.value" ng-if="search.criteria.options && !ctrl.someVal" ng-options="{{search.criteria.options}}"></select>
Sign up to request clarification or add additional context in comments.

4 Comments

do you test the solution? i copy the code and it doesnt work.
That should work now. I forgot about adding $timeout to the controller and ctrl context to the html.
You can also change the time out to 100 so it is very fast
Yes, this seems to do the trick :) Thank you very much! Answer has been marked

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.