0

I'm an angularjs newbie building my first app. I have a list of users that I can filter and sort:

<button ng-click="order='lastname'; reverse=!reverse">Sort by name</button>
<button ng-click="order='id'; reverse=!reverse">Sort by id</button>
<input type="text" ng-model="filter.user">
  <ul class="userlist" ng-class="{blur: currentUser}">
    <li ng-repeat="user in users | orderBy:order:reverse | filter:filter.user">
      {{user.id}} / {{user.firstname}} {{user.lastname}}
      <a href="#/user/{{user.id}}">Show details</a>
      <div ng-click="showDetails(user)">Show details in overlay</div>
    </li>
  </ul>   
  <div ng-show="details">
    <div ng-click="details=!details">close</div>
    {{user.custom}}
  </div>
  <div ng-show="currentUser" id="overlay">
    {{currentUser.firstname}} {{currentUser.lastname}} {{currentUser.custom}}
    <div ng-click="closeOverlay()">close</div>
  </div>

I can click on a user to get his details. Now I want to realize the following scenario: When I press the enter key in the filter text input I want to show the details of the first <li /> in the list at the current time. So in jQuery I would bind a keypress event to the input which would check for the key code (13) and then would trigger: $('li').eq(0).click() which would call showDetails() on that particular user - easy.
How can I build such functionality with angular? I tried using the ng-keypress directive which lets me bind a function to a certain keypress but now I'm stuck because I don't know how to trigger the showDetails() function on the first element. Any help greatly appreciated!

Horen
  • 11,184
  • 11
  • 71
  • 113

3 Answers3

0

This is a workaround you can give a try for the time being: make your ng- keypress handler create a list of your filtered results (that is, reapply your filters on a copy of your user list in your controller) and then call the showDetails for the first egg element of that list.

Is it ugly? Yes. It's it a bad decision if you are working with big lists? Certainly. But it will get you going till you find another way / better stackoverflow answer.

GonchuB
  • 705
  • 5
  • 8
0

The following should work. Inside your ng-keypress handler set a property that enter was pressed, e.g. enterPressed. Then use ng-init as follows:

<li ng-init="isFirst($first, user)" ng-repeat="user in users | orderBy:order:reverse | filter:filter.user">
  {{user.id}} / {{user.firstname}} {{user.lastname}}
  <a href="#/user/{{user.id}}">Show details</a>
  <div ng-click="showDetails(user)">Show details in overlay</div>
</li>

And then in your controller have something like:

$scope.isFirst = function(first, user) {
  if (first && enterPressed) {
    enterPressed = false;
    $scope.showDetails(user);
  }
}
Beyers
  • 8,968
  • 43
  • 56
0

I figured out a pretty elegant solution:
In the ng-repeat you can assign an additional variable (I called it filteredUser to the current result set:

<li ng-repeat="user in (filteredUser = (users | orderBy:order:reverse | 
filter:filter.user))" ng-click="showDetails(user)">

This way it is super easy to access the first item in that result set (filteredUser[0]) and pass it to a function:

<input type="text" ng-model="filter.user" ng-keypress="$event.keyCode == 13 ? 
showDetails(filteredUser[0]) : null">
Horen
  • 11,184
  • 11
  • 71
  • 113