0

I am trying to understand the angularJS filter mechanics to try and extend its initial functionality. Currently from what I can tell, when you perform the filter, it will search the value attribute on each html element for a match. This works all great in most cases. Where this falls apart is dropdown lists. If you set the text of an option to Hello world and the value = 1, the search is looking at the value attribute of the <option> instead of the text. This breaks the expected results thus why I need to find a way to make the filter include the Text properties of dropdown lists. Looking for advice on how to handle this or just further details of the filter function underneath. Below is the code i am trying to apply this too.

<div ng-app="CategoryFieldApproversApp">

Search:<input id="txtSearch" ng-model="search" type="text" placeholder="Search" />

@using (Html.BeginForm("CategoryFieldApprovers", "Maintenance", FormMethod.Post))
{
    <div ng-controller="CategoryFieldApproversCtrl">
        <table class="table table-striped table-hover">
            <thead>
                <tr>
                    <th width="1%"></th>
                    <th ng-click="sort('Name')" width="200">Category Field</th>
                    <th ng-click="sort('Name')" width="150">Approver</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                <tr dir-paginate="categoryFieldApprover in categoryFieldApprovers|orderBy:sortKey:reverse|itemsPerPage:5" ng-show="ddlVisibility(categoryFieldApprover)">
                    <td>
                        <input type="hidden" name="CategoryFieldApprovers[{{$index}}].CategoryFieldApproverID" ng-model="categoryFieldApprover.CategoryFieldApproverID" value="{{categoryFieldApprover.CategoryFieldApproverID}}" />
                        <input type="hidden" id="hdnIsDirty" name="CategoryFieldApprovers[{{$index}}].IsDirty" value="{{categoryFieldApprover.IsDirty}}" />
                    </td>
                    <td>
                        <input class="hdnCategoryFieldID" type="hidden" name="CategoryFieldApprovers[{{$index}}].CategoryFieldID" value="{{categoryFieldApprover.CategoryFieldID}}" />
                        <select ng-model="categoryFieldApprover.CategoryFieldID" ng-options="categoryField.CategoryFieldID as categoryField.Name for categoryField in categoryFields | filter:{Name :search}"></select>
                    </td>
                    <td>
                        <input class="hdnApproverOneUserID" type="hidden" name="CategoryFieldApprovers[{{$index}}].ApproverOneUserID" value="{{categoryFieldApprover.ApproverOneUserID}}" />
                        <select ng-model="categoryFieldApprover.ApproverOneUserID" ng-options="user.UserID as user.DisplayName for user in users | filter:{DisplayName :search}"></select>
                    </td>
                    <td>
                        <input type="button" ng-click="remove($index)" ng-show="categoryFieldApprover.ShowRemove" value="Remove" />
                    </td>
                </tr>
            </tbody>
        </table>
        <dir-pagination-controls max-size="5"
                                 direction-links="true"
                                 boundary-links="true">
        </dir-pagination-controls>
        <br />
        <a class="btn btn-default" ng-click="add()">Add Field Approver</a>
        <input class="btn-primary btn-sm" ng-click="save()" type="button" value="Save" />
    </div>
}
</div>

<script>
var App = angular.module('CategoryFieldApproversApp', ['angularUtils.directives.dirPagination']).controller('CategoryFieldApproversCtrl', function ($scope, $http) {

    $http.get("@Url.Action("GetCategoryFieldApprovers", "Maintenance")").success(function (response) {
        $scope.categoryFieldApprovers = response;  //ajax request to fetch data into $scope.data
    });

    $http.get("@Url.Action("GetCategoryFields", "Maintenance")").success(function (response) {
        $scope.categoryFields = response;  //ajax request to fetch data into $scope.data
    });

    $http.get("@Url.Action("GetUsers", "Maintenance")").success(function (response) {
        $scope.users = response;  //ajax request to fetch data into $scope.data
    });

    $scope.sort = function (keyname) {
        $scope.sortKey = keyname;   //set the sortKey to the param passed
        $scope.reverse = !$scope.reverse; //if true make it false and vice versa
    }

    $scope.remove = function (index) {
        $scope.categoryFieldApprovers.splice(index, 1);
    };

    $scope.add = function () {
        $scope.categoryFieldApprovers.splice(0, 0, {
            CategoryFieldApproverID: 0,
            CategoryFieldID: 0,
            ApproverOneUserID: 0,
            ApproverTwoUserID: 0,
            ShowRemove: true
        });
    };

    $scope.save = function () {
        $('tbody tr').find('.ng-dirty').each(function (i, dirtyElement) {
            $(dirtyElement).closest('tr').find('#hdnIsDirty').val(true);
        });

        $('form').submit();
    };

    $scope.ddlVisibility = function (categoryFieldApprover) {

        if ($('#txtSearch').val() != "" && (categoryFieldApprover.CategoryFieldID == null && categoryFieldApprover.ApproverOneUserID == null)) {
            return false;
        }
        else {
            return true;
        }
    }
});

</script>

UPDATES: Removed the |filter:search from the tr element. Then added the filter:{Name: search} for each dropdown. It will now correctly filter and show/hide rows for those that pass the check. The only remaining problem now is that when the filter function executes, if the dropdowns selected item fails the test, it sets the selected index to 0 which is the blank item. How can I prevent it from changing the selection just because it failed to be included from the filter?

1 Answer 1

0

Please see this small demo here. If you are looking for same functionality then you just need to specify property inside filter which you want to search.

filter:{Name :search}

e.g.

<select ng-model="categoryFieldApprover.CategoryFieldID" ng-options="categoryField.CategoryFieldID as categoryField.Name for categoryField in categoryFields | filter:{Name :search}"></select>
Sign up to request clarification or add additional context in comments.

10 Comments

When i run your demo, the dropdown clears out the selection once you type in the number part of the name. Type in "test" and then when you keypress the number, the selection disappears. I added this code in mine and when i perform the search, it has similar effects where it clears the selection of one of the drop downs in the grid and doesn't filter properly still.
making progress!!! I'll update the html code above now so you can see what i have along with edit notes.
I dont know how your page looks or works completely but to hide TR itself you will have to use ng-show or ng-if attribute on TR tag with expression. That expression should return true or false based on content or you can make use of additional filter on row with same search.
This page is a maintenance screen. It's a simple grid that the user will be selecting/updating the selections for each dropdownlist in each cell of every row to save to the database. The search feature is there so they can quickly find the item they want to change in the table.
Please check this post stackoverflow.com/questions/21731161/…. It will give you better idea. I think you need similar logic.
|

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.