peech
peech

Reputation: 1001

AngularJS - Automatically update md-autocomplete search list based on another md-autocomplete input

I have two <md-autocomplete> drop-downs. I would like to update the search list of the second drop-down based on the selection of the first dropdown.

Here is a prepared non-working plunker : http://plnkr.co/edit/GxQujjAcxYdawlANJd9O?p=preview

Description of wanted behavior:
when a user selects let's say "This is an A" from the first drop-down, I would like to update options to $scope.numbersA, that is [1, 2, 3]. For input "This is a B" the corresponding number array is $scope.numbersB, etc.

I cannot get this to work properly, on my app there is $http request for every change on the first drop-down. As specified here I am using .then() and not .success(). I have simplified the example in plunker because there is less code :)

Edit: I have just noticed the searchText in plunker is not working properly, that's because of my search function. This is not an issue, it works as it should on my app.

Upvotes: 2

Views: 3759

Answers (1)

Rayon
Rayon

Reputation: 36599

Use md-no-cache to invoke the search handler every time user types value in second autocomplete.

Pass first autocomplete selected value as argument for search handler of second autocomplete

Try this:

// Code goes here
var app = angular.module('app', ['ngMaterial']);

app.controller('ctrl', ['$scope',
  function($scope) {
    $scope.letters = [{
      'display': 'This is an A',
      'value': 'a'
    }, {
      'display': 'This is a B',
      'value': 'b'
    }, {
      'display': 'This is a C',
      'value': 'c'
    }];
    $scope.numbersA = [1, 2, 3];
    $scope.numbersB = [4, 5, 6];
    $scope.numbersC = [7, 8, 9];

    $scope.getMatchesLetter = function(query) {
      if (query === null || query === "" || query === undefined)
        return $scope.letters;

      var results = query ? $scope.letters.filter(createFilterFor(query)) : $scope.letters;
      return results;
    };

    $scope.getMatchesNumber = function(query, selected) {
      var arrToSearch;
      switch (selected.value.toUpperCase()) {

        case 'A':
          arrToSearch = $scope.numbersA;
          break;

        case 'B':
          arrToSearch = $scope.numbersB;
          break;

        case 'C':
          arrToSearch = $scope.numbersC;
          break;

      }
      if (query === null || query === "" || query === undefined)
        return arrToSearch;

      var results = query ? arrToSearch.filter(createFilterFor(query)) : arrToSearch;
      return results;
    };

    $scope.itemChange = function(item, whichOne) {
      switch (whichOne) {
        case 'A':
          $scope.numbersA = item;
          break;
        case 'B':
          $scope.numbersB = item;
          break;
        case 'C':
          $scope.numberC = item;
          break;
      }
    };

    function createFilterFor(query) {
      var lowercaseQuery = angular.lowercase(query);
      return function filterFn(state) {
        //return (state.value.indexOf(lowercaseQuery) === 0); // startsWith()
        return (state.value.search(lowercaseQuery) != -1); // contains()
      };
    }

  }
]);;
<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>


  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.11.2/angular-material.min.css">
  <script src="script.js"></script>
</head>

<body ng-app='app' ng-controller='ctrl'>
  <md-autocomplete md-selected-item="selectedItemLetter" md-search-text="searchTextLetter" md-selected-item-change="itemChange(item)" md-items="item in getMatchesLetter(searchTextLetter)" md-item-text="item.display" md-min-length="0" placeholder="Select letter">
    <md-item-template>
      <span md-highlight-text="searchTextLetter">{{item.display}}</span>
    </md-item-template>
    <md-not-found>No matches found.</md-not-found>
  </md-autocomplete>

  <br>
  <br>

  <md-autocomplete md-selected-item="selectedItemNumber" md-search-text="searchTextNum" md-selected-item-change="itemChange(item)" md-items="item in getMatchesNumber(searchTextNumber,selectedItemLetter)" md-no-cache="true" md-item-text="item" md-min-length="0"
  placeholder="Select number">
    <md-item-template>
      <span md-highlight-text="searchTextNumber">{{item}}</span>
    </md-item-template>
    <md-not-found>No matches found.</md-not-found>
  </md-autocomplete>
</body>

</html>

Upvotes: 4

Related Questions