Skip to content
This repository was archived by the owner on Oct 2, 2019. It is now read-only.
This repository was archived by the owner on Oct 2, 2019. It is now read-only.

search result items should have priority over model items in selected #1989

Open
@aurelienlt

Description

@aurelienlt

Hi

I'm having troubles with how are displayed multiple choices. My model is an array of objects with only their id, whereas the search result items are complete items with the id and properties. The first search request taking time, ui-select will fill $select.selected with the model first, and then never use the search results once they come.

Example:

model = [{"iso": "FR"}, {"iso": "DE"}]
search = [{"iso": "FR", "name": "France"}, {"iso": "DE", "name": "Germany"}, {"iso": "ES", "name": "Spain"}, ...]

ui-select will keep displaying FR - and DE - instead of FR - France and DE - Germany if the search request is too long.

I located the bug in the formatter:

      ngModel.$formatters.unshift(function (inputValue) {
        var data = $select.parserResult && $select.parserResult.source (scope, { $select : {search:''}}), //Overwrite $search
            locals = {},
            result;
        if (!data) return inputValue;
        var resultMultiple = [];
        var checkFnMultiple = function(list, value){
          if (!list || !list.length) return;
          for (var p = list.length - 1; p >= 0; p--) {
            locals[$select.parserResult.itemName] = list[p];
            result = $select.parserResult.modelMapper(scope, locals);
            if($select.parserResult.trackByExp){
                var propsItemNameMatches = /(\w*)\./.exec($select.parserResult.trackByExp);
                var matches = /\.([^\s]+)/.exec($select.parserResult.trackByExp);
                if(propsItemNameMatches && propsItemNameMatches.length > 0 && propsItemNameMatches[1] == $select.parserResult.itemName){
                  if(matches && matches.length>0 && result[matches[1]] == value[matches[1]]){
                      resultMultiple.unshift(list[p]);
                      return true;
                  }
                }
            }
            if (angular.equals(result,value)){
              resultMultiple.unshift(list[p]);
              return true;
            }
          }
          return false;
        };
        if (!inputValue) return resultMultiple; //If ngModel was undefined
        for (var k = inputValue.length - 1; k >= 0; k--) {
          //Check model array of currently selected items
          if (!checkFnMultiple($select.selected, inputValue[k])){
            //Check model array of all items available
            if (!checkFnMultiple(data, inputValue[k])){
              //If not found on previous lists, just add it directly to resultMultiple
              resultMultiple.unshift(inputValue[k]);
            }
          }
        }
        return resultMultiple;
      });

Inversing the two calls of checkFnMultiple solves the problem.

        for (var k = inputValue.length - 1; k >= 0; k--) {
          //Check model array of all items available
          if (!checkFnMultiple(data, inputValue[k])){
            //Check model array of currently selected items
            if (!checkFnMultiple($select.selected, inputValue[k])){
              //If not found on previous lists, just add it directly to resultMultiple
              resultMultiple.unshift(inputValue[k]);
            }
          }
        }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions