Select with search


#1

Recently i had to make a kind of select element with search, here is the result…
http://jsfiddle.net/cristoferdomingues/KR7KV/10/

Maybe this will help somebody else.

cya!


#2

Hey thanks for sharing this, looks really great :smile:


#3

Wow this is awesome, thanks for sharing! I might try to modify it so that you can end up with a list of items selected in the dropdown (think ios text message recipient selector).


#4

I was thinking the same thing!


#5

I used this with a more recent version of ionic. Needed to fix one of the functions in the angular code.

Added “&& newValue.id” in the if statement. This fixed an issue where typing in the search box erased the characters as you typed.

  scope.$watch('ngModel',function(newValue){
    if(newValue && newValue.id)
      element.find('input').val(newValue[scope.labelField]);

  });

#6

I Think that this will fix it, i put a dynamic filter also

http://jsfiddle.net/cristoferdomingues/KR7KV/19/


#7

Hello! I modified your directive as such but when i use it to choose a value, then change to another view, and come back to it : I see [object Object] instead of the chosen value. I think it has to do with the line : scope.ngValue = scope.ngValue !== undefined ? scope.ngValue : "item"; How can I tell it to display the sub-object (in your example : nmPlaca) whose name is passed in labelField?

I tried item[labelField] and “item[labelField]”… I will make a codepen tomorrow to illustrate this problem… it’s to late now… Tell me if you understand a bit what I mean! :slight_smile: thanks !

 angular.module('ionicSelect', [])
.directive('ionSelect', function($timeout, $ionicScrollDelegate, $location) {
  return {
    restrict: 'EAC',
    scope: {
      label: '@',
      labelField: '@',
      provider: '=',
      scrollto:'@',
      ngModel: '=?',
      ngValue: '=?',

    },
    require: '?ngModel',
    transclude: false,
    replace: false,
    template:   '<label class="item-input" id="'+'{{scrollto}}'+'">' +'<span class="input-label">{{label}}</span>'+
    '<input id="filtro" type="search"  ng-model="ngModel" ng-value="ngValue" ng-keydown="onKeyDown()"/>' +
    '</label>'+
     '<div class="optionList" ng-show="showHide">' + '<ion-scroll>' +
    '<ul class="list">' + '<li class="item" ng-click="selecionar(item)" ng-repeat="item in provider | dynamicFilter:[labelField,ngModel]">{{item[labelField]}}</li>' +
    '</ul>' + '</ion-scroll>' + '</div>',

    link: function(scope, element, attrs, ngModel) {
      scope.ngValue = scope.ngValue !== undefined ? scope.ngValue : "item";
      console.log(scope.ngValue);
      scope.selecionar = function(item) {
        ngModel.$setViewValue(item);
        scope.showHide = false;
      };

      element.bind('click', function() {
        //element.find('input').focus();
      });

      scope.scrollToMe = function(){
        // $ionicScrollDelegate.scrollBottom();
        //console.log();
        var location = $location.hash(scope.scrollto);
        $timeout( function(){
          $ionicScrollDelegate.anchorScroll("#"+location);
        });
      };

      scope.open = function() {
        scope.ngModel = undefined;
        $timeout(function() {
          scope.scrollToMe();
          return scope.showHide = !scope.showHide;

        }, 150);
      };
      scope.onKeyDown = function() {
        scope.showHide = true;
        scope.scrollToMe();
      };

      scope.$watch('ngModel', function(newValue, oldValue) {
        if (newValue !== oldValue) {
          if (scope.showHide === false) {
            element.find('input').val(newValue[scope.labelField]);
            scope.scrollToMe();
          }
        }
        if (!scope.ngModel) {
          scope.showHide = false;
          //scope.scrollToMe();
        }
      });

    }
  };
}).filter('dynamicFilter', ["$filter", function ($filter) {
    return function (array, keyValuePairs) {
        var obj = {}, i;
        for (i = 0; i < keyValuePairs.length; i += 2) {
            if (keyValuePairs[i] && keyValuePairs[i+1]) {
                obj[keyValuePairs[i]] = keyValuePairs[i+1];
            }
        }
        return $filter('filter')(array, obj);
    };
}]);

#8

Hello boltex,
Sorry for the delay, do you could solve your problem?


#9

Yes! thank you for your inspiration . I coded myself a new directive for my needs of a select box with an array of choices. I will give you my code if you want it! :smile:


#10

Nice! i would like to see your code my friend.
Thanks!


#11

@cristofer If I have two or more of these in one form, what would be the best to ensure only one is ever opened at any time. I.e. if open an ionSelect then close the rest?

Thanks


#13

This code works with ionic current version?
Anyone have an updated example where used for?

Now I get the following error:
" element.find(…).focus is not a function
element.find(‘input’).focus();"

Thanks.


#14

try
element.find(‘input’).triggerHandler(‘focus’);
instead of
element.find(‘input’).focus();


#15

Hey thanks for sharing Cristofer, this really help me, however I could not make it work on my project. I have got few issues.

  1. when I click arrow to open list it doesn’t do anything
  2. only display select box rest of form controls disappear

can you or anyone help on this please?

Thank you.


#16

@tamang: I ran into the same issue. It may be way too late to help you, or you might have figured it out already, but to others who are experiencing the same problem hopefully this will help. The first child of the selectContainer div must be a div, not a label. You can leave the same classes associated with the label to give the div the same look. The properties of the label element override the button ng-click method.

'<div class="selectContainer">' + '<div class="item item-input item-stacked-label">' + '<span class="input-label">{{label}}</span>' + '<div class="item item-input-inset">' + '<label class="item-input-wrapper">' + '<i class="icon ion-ios-search placeholder-icon"></i>' + '<input id="location_filter" class="search" type="search" ng-model="ngModel" ng-value="ngValue" ng-keydown="onKeyDown()"/>' + '</label>' + '<button class="button button-small button-clear" ng-click="open_list()">' + '<i class="icon ion-chevron-down"></i>' + '</button>' + '</div>' + '</div>' + '<div class="optionList padding-left padding-right" ng-show="showHide">' + '<ion-scroll>' + '<ul class="list">' + '<li class="item" ng-click="q_selection(item)" ng-repeat="item in provider | dynamicFilter:[labelField,ngModel]">{{item[labelField]}}</li>' + '</ul>' + '</ion-scroll>' + '</div>' + '</div>',

Cheers! :smiley:


#17

@joallen09 thank you for your reply. However that did not help either. When click on the open list arrow does nothing as before after adding your template. any suggestion ???

thank you


#18

@tamang: In my testing I actually updated the ng-click function to be “open_list()” instead of “open()”. Double-check that, and either change the function in the directive, or in the ng-click. Hope that helps.


#19

@joallen09: I had the same issue and your solution worked for me, thanks!


#21

I’m trying to get this working in an app I am building, when I click on the arrow my list is displayed, but I can’t select anything.

I’m trying to use his/her sample in my code before using my own data.

If I declare “veiculo” (it doesn’t seem to be declare in the sample code?) I get an error saying
TypeError: Cannot read property ‘nmPlaca’ of undefined

For here
element.find(‘input’).val(newValue[scope.labelField]);

But if I don’t declare “veiculo” I don’t get any errors, I just can’t select anything.

Anyone have any ideas, or alternative dropdown lists with a search in them like this? It looks nice and I wouldn’t mind using it.

Thanks


#22

Hey cristofer…
i want implement this same thing in ionic 2. how i do?