Ng-click not working on selected list item in autocomplete?

I am unable to select a list item using ng-click. When I clicked on the selected item, I should get the ID of the selected item and the selected item should appear in the search box. But it works fine for key entry, but I also want the selected item to be in the search box on ng-click.

Here is my code.

JS:

angular.module("hmautocomplete", [])
.directive('hmAutocomplete', function ($timeout) {
  return {
      scope: {
          selectedIndex: '=',
          hmSuggestions: '=',
          hmDropdownid: '@',
          hmSelect: '&'
      },

      link: function (scope, element) {

          scope.selectedIndex = 0;

          var elem = angular.element(document.getElementById('autotext'));
          var list = 
        angular.element(document.getElementById(scope.hmDropdownid));

          list.css('display', 'none');

          elem.bind('focus', function () {
              scope.selectedIndex = 0;
              scope.$apply();
              list.css('display', 'block');
          });

          elem.bind('blur', function () {
              $timeout(
                function () {
                    list.css('display', 'none');
                }, 100
              )
          });

          elem.bind("keydown", function (event) {


              if (list.css('display') === 'none') {
                  list.css('display', 'block');
              }

              if (event.keyCode === 40) { //down key, increment 
         selectedIndex
                  event.preventDefault();
                  if (scope.selectedIndex + 1 === 
        scope.hmSuggestions.length) {
                      scope.selectedIndex = 0;
                  } else {
                      scope.selectedIndex++;
                  }
                  scope.$apply();
              } else if (event.keyCode === 38) { //up key, decrement 
         selectedIndex
                  event.preventDefault();

                  if (scope.selectedIndex === 0) {
                      scope.selectedIndex = scope.hmSuggestions.length - 1;
                  } else {
                      scope.selectedIndex--;
                  }
                  scope.$apply();

              } else if (event.keyCode === 13 || event.keyCode === 9) { 
       //enter pressed or tab

                  elem.val(scope.hmSuggestions[scope.selectedIndex].Name);
                  list.css('display', 'none');
                  scope.hmSelect(scope.hmSuggestions[scope.selectedIndex]);
                  scope.$apply();

              } else if (event.keyCode === 27) {
                  list.css('display', 'none');
              }
          })

      }
  };
    }).directive('hoverClass', function () {
  return {
      restrict: 'A',
      link: function (scope, element, attr) {

          element.on('mouseenter', function () {

   angular.element(document.getElementsByClassName(attr.hoverClass)).removeClass(attr.hoverClass);
              element.addClass(attr.hoverClass);
          });

          element.on('mouseleave', function () {
              element.removeClass(attr.hoverClass);
          });

      }
  };
  })

.directive('hmSelectDown', function () {
return {
    restrict: 'A',
    scope: {
        hmSelectDown: '&'
    },
    link: function (scope, elem, attr) {
        var list = angular.element(document.getElementById(scope.hmDropdownid));
        elem.bind('click', function () {
            scope.hmSelectDown();
            list.css('display', 'none');
        });
    }
};
  })

  .filter('highlight', function ($sce) {
   return function (text, phrase) {
    if (phrase)
        text = text.replace(new RegExp('(' + phrase + ')', 'gi'), '<span 
class="highlighted">$1</span>');
    return $sce.trustAsHtml(text);
}
  }).controller('demo', function ($scope) {


$scope.fnAutocompleteQuestion = function () {
    $scope.items = [{
        'Name': 'India'
    }, { 'Name': 'United States' },
        { 'Name': 'England' },
        { 'Name': 'Germany' },
        { 'Name': 'London' }, {
            'Name': 'Pakistan'
        }, {
            'Name': 'Nepal'
        }, {
            'Name': 'Bangladesh'
        }];
}
$scope.onselect = function (obj) {
    alert(JSON.stringify(obj));
    console.log(obj);
}

 });

      

Html:

  <div ng-controller="demo">
    <hm-autocomplete selected-index="selectedIndex"
                     hm-textboxid="autotext"
                     hm-dropdownid="dropdown"
                     hm-suggestions="items"
                     hm-select="onselect(items[selectedIndex])">
        <input type="text" id="autotext" class="form-control" ng-model="strSearch"  ng-change="fnAutocompleteQuestion(strSearch)" />
        <ul id="dropdown" class="ngcomplete-dropdown">
            <li ng-repeat="item in items | filter: strSearch" 
                hover-class='ngcompleterowactive'
                ng-mouseover='selectedIndex==$index'
                ng-class="{'ngcompleterowactive':selectedIndex==$index}"
                ng-bind-html="item.Name | highlight:strSearch"
                hm-select-down="onselect(item)">
            </li>
        </ul>
    </hm-autocomplete>
</div>

      

+3


source to share


2 answers


I think you could try this

Js

 }).controller('demo', function($scope) {

     //  code..

     $scope.selectedItem;

     $scope.selectItem = function(item){
        $scope.selectedItem = item;
         $scope.strSearch = $scope.selectedItem.Name;
     }

     // code..
})

      

Html

    <li ng-repeat="item in items | limitTo:10"
                class="ngcompleterow"
                hover-class='ngcompleterowactive'
                ng-click="selectItem(item)"
                ng-mouseover='selectedIndex==$index'
                ng-class="{'ngcompleterowactive':selectedIndex==$index}"
                        ng-bind-html="item.Name | highlight:strSearch"
                hm-select-down="onselect(item)"
            >
    </li>

      

UPDATE

I found why it is not selected by the first click, the reason is because you have this construct:

      elem.bind('focus', function () {
          scope.selectedIndex = 0;
          scope.$apply();
          list.css('display', 'block');
      });

      elem.bind('blur', function () {
          $timeout(
            function () {
                list.css('display', 'none');
            }, 100
          )
      });

      



So, if you remove it and refactor this:

JS:

  .controller('demo', function($scope) {

  // code

  $scope.blurDropdown = function(){
     // same thing as $timeout
     setTimeout(function(){
        $scope.showDropdown = false;
        $scope.$apply();
     }, 100)

    // code

  });

      

}

And HTML

   <input ng-focus="showDropdown = true" ng-blur="blurDropdown()" type="text" id="autotext" class="form-control" ng-model="strSearch" />

   <ul id="dropdown" data-ng-show="showDropdown" class="ngcomplete-dropdown">

      

After this fix, I can click on any item that matches the search pattern.

Plunker Example

+2


source


If you want the selected item to appear in the search or text box, update your method as shown below,



 $scope.onselect = function(obj) {
      alert(JSON.stringify(obj));
      $scope.strSearch = obj.Name;
      console.log(obj);
 }

      

0


source







All Articles