Zooly
Zooly

Reputation: 4787

Filter (ngRepeat) in a table not working on all columns

I want to filter my table generated with a ng-repeat.

        <tbody>
            <tr ng-repeat="x in contact.listeContacts | filter:contact.searchText track by $index">
                <td>
                    <b>{{x.gd$name.gd$fullName.$t}}</b>
                </td>
                <td>
                    <p>{{contact.listeContacts[$index].gd$name.gd$familyName.$t}}</p>
                </td>
                <td>
                    <p>{{contact.listeContacts[$index].gd$name.gd$givenName.$t}}</p>
                </td>
                <td>
                    <p>{{contact.listeContacts[$index].gd$email[0].address}}</p>
                </td>
                <td>
                    <p>{{contact.listeContacts[$index].gd$phoneNumber[0].$t}}</p>
                </td>
                <td>
                    <p>{{contact.listeContacts[$index].gd$organization[0].gd$orgTitle.$t}}{{contact.listeContacts[$index].gd$organization[0].gd$orgName.$t}}</p>
                </td>
            </tr>
        </tbody>

My issue is that my filter seems to be applied only on the first column.

Imagine I have these three objects to display :

obj1 = {
'name':'obj1',
'age':10
}

obj2 = {
    'name':'obj2',
    'age':1000
}

obj3 = {
    'name'='obj3',
    'age':100000
}

If my searchText is "obj3", the table will display something like this obj3 / 10

instead of obj3 / 100000

I don't understand why behaving like this.

EDIT: John Joseph, Xun Chao & tanmay helped me to resolve my first problem, check their answers.

Now, I don't understand why my search filter is not working as expected. Please see this Plunker : https://plnkr.co/edit/SfaYdgVkSfhOdI5enpOd?p=preview

Upvotes: 1

Views: 232

Answers (4)

tanmay
tanmay

Reputation: 7911

While all provided answers are correct, none of them has explained why this happened. When you filter with "obj3", it displays only one item in the ng-repeat but your contact.listeContacts array still has length say 3. So, while searching for third item's text (here obj3), it tries to show contact.listeContacts[0] because filtered array has only one element.

You have two ways to solve this:

  1. As mentioned by all other answers, put x instead of contact.listeContacts[$index]
  2. You can have a reference to filtered array like this:

    <tr ng-repeat="x in mycontacts = (contact.listeContacts | filter:contact.searchText) track by $index">

    And, instead of contact.listeContacts[$index] you can then use mycontacts[$index] which points to filtered array and not actual array

Upvotes: 1

SinDeus
SinDeus

Reputation: 516

Your problem lies in the $index you use for accessing your items. Whenever your list in ng-repeat is filtered, the index property is looping on your filtered list.

You just have to use your local variable, named x in your case.

See this codepen for a live example:

<td>{{contact.name}}</td>
<td>{{contacts[$index].name}}</td> <!-- may not be the same -->

Upvotes: 1

Xun Chao
Xun Chao

Reputation: 82

You have used contact.listeContacts[$index] instead of x...

        <tbody>
        <tr ng-repeat="x in contact.listeContacts | filter:contact.searchText track by $index">
            <td>
                <b>{{x.gd$name.gd$fullName.$t}}</b>
            </td>
            <td>
                <p>{{x.gd$name.gd$familyName.$t}}</p>
            </td>
            <td>
                <p>{{x.gd$name.gd$givenName.$t}}</p>
            </td>
            <td>
                <p>{{x.gd$email[0].address}}</p>
            </td>
            <td>
                <p>{{x.gd$phoneNumber[0].$t}}</p>
            </td>
            <td>
                <p>{{x.gd$organization[0].gd$orgTitle.$t}}{{x.gd$organization[0].gd$orgName.$t}}</p>
            </td>
        </tr>
    </tbody>

Upvotes: 1

John
John

Reputation: 1489

You are directly accessing the contact.listeContacts for the rest of the columns instead of the looped variable x. That should be the problem. Try the following, replace contact.listeContacts[$index] with x.

    <tbody>
        <tr ng-repeat="x in contact.listeContacts | filter:contact.searchText track by $index">
            <td>
                <b>{{x.gd$name.gd$fullName.$t}}</b>
            </td>
            <td>
                <p>{{x.gd$name.gd$familyName.$t}}</p>
            </td>
            <td>
                <p>{{x.gd$name.gd$givenName.$t}}</p>
            </td>
            <td>
                <p>{{x.gd$email[0].address}}</p>
            </td>
            <td>
                <p>{{x.gd$phoneNumber[0].$t}}</p>
            </td>
            <td>
                <p>{{x.gd$organization[0].gd$orgTitle.$t}}{{x.gd$organization[0].gd$orgName.$t}}</p>
            </td>
        </tr>
    </tbody>

Upvotes: 1

Related Questions