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?