0

I'm writing a combobox as a directive, and am having some trouble with it. Its setup so when someone clicks the input, it shows all options in a dropdown, and as you type, it filters the results. If you click on a result, it should populate the input with that value.

Unfortunately, I seem to have done something wrong, so when you click on a result, it populates the field, but if you erase the values of the field, rather than returning to the original search, it now ONLY parses through the result you selected. it shows all the values but typing only searches through values that match the search text AND the previously clicked value.

How the directive is called:

<combobox data="combobox.systems" results="systemSearch" placeholder="System"></combobox>

Directive html:

<div class="combobox" ng-click="$event.stopPropagation()">
    <input type="text" ng-model="search.value" search-id="search.id" ng-class="{ resultsOpen: showDropdown }" ng-change="revealDropdown()" ng-focus="revealDropdown()" ng-blur="hideDropdown()">
    <a class="dropdown" ng-click="toggleDropdown($event)"></a>
    <div class="results" ng-show="showDropdown">
        <a ng-repeat="set in data | filter: { value: search.value }" ng-mousedown="setBox($event, set)" ng-bind-html="set.value | trustHTML"></a>
    </div>
</div>

Directive code:

directive('combobox', ['$filter', function ($filter) {
    return {
        restrict: 'E',
        templateUrl: 'combobox.html',
        scope: {
            'data': '=data',
            'search': '=results'
        },
        link: function (scope, element, attrs) {
            scope.search = { id: '', value: '' };
            if (typeof attrs.placeholder != 'undefined') 
                element.find('input').attr('placeholder', attrs.placeholder);
            scope.showDropdown = false;
            if (typeof scope.data == 'undefined') 
                scope.data = [];

            scope.toggleDropdown = function ($event) {
                $event.stopPropagation();
                scope.showDropdown = scope.showDropdown?false:true;
            };
            scope.revealDropdown = function () {
                if ((isNaN(scope.search) || scope.search.length == 0) && $filter('filter')(scope.data, scope.search).length) 
                    scope.showDropdown = true;
                else 
                    scope.showDropdown = false;
            };
            scope.hideDropdown = function () {
                scope.showDropdown = false;
            };
            $('html').click(function () {
                scope.hideDropdown();
                scope.$apply();
            });

            scope.setBox = function ($event, set) {
                scope.search = set;
            }
        }
    }
}])

I did figure out that changing the setBox method to

scope.setBox = function ($event, set) {
    scope.search = angular.copy(set);
}

This helped a little, but didn't nearly solve the problem. I've made a Plunker to try to help: http://plnkr.co/edit/wYfveGDYaVUpzcOWDbSz

What have I done wrong?

1 Answer 1

0

This should work:

scope.setBox = function ($event, set) {
    scope.search.value = set.value;
};

And if you need to keep record of the selected item:

scope.setBox = function ($event, set) {
    scope.search.value = set.value;
    scope.selected = angular.copy(set);
};

Also, you don't really need to pass $event and set into your setBox method, you could do something like:

scope.setBox = function () {
    scope.search.value = this.set.value;
    scope.selected = angular.copy(this.set);
};
Sign up to request clarification or add additional context in comments.

Comments

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.