advanced angular filters

by Ryan

HTML

<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
<div ng-app="app" ng-controller="MainController">
    Filter <select 
        x-ng-model="filterDimension"
        x-ng-options="o as o.label for o in filterDimensions"></select>
    <input type="text" x-ng-model="filterText"></input>
    Sort By <select
        x-ng-model="orderByDimension"
        x-ng-options="o as o.label for o in orderByDimensions"></select>
    
    <div>
        <table>
            <thead><tr><th>a</th><th>b</th><th>c</th></tr></thead>
            <tbody>
                <tr x-ng-repeat="e in elements | filter:filter | orderBy:orderByDimension.id">
                    <td>{{e.a}}</td><td>{{e.b}}</td><td>{{e.c}}</td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

CSS

body { font: 12px sans-serif; }
td {
    border: 1px solid;
    padding: 2px 10px 1px 10px;
}

JavaScript

var app = angular.module('app', []);

function MainController($scope, $log) {
    // Dimensions of the data
    $scope.filterDimensions = [ 
        { id: "a", label: "A" }, 
        { id: "b", label: "B" }, 
        { id: "c", label: "C" }
    ];
    $scope.filterDimension = $scope.filterDimensions[0];
    
    // The filter to apply
    $scope.filter = undefined;
    // The text of the filter to apply
    $scope.filterText = "";
    
    // Dimensions to order by (could be different from filter dims)
    $scope.orderByDimensions = [ 
        { id: "a", label: "A" },
        { id: "b", label: "B" },
        { id: "c", label: "C" }
    ];
    $scope.orderByDimension = $scope.orderByDimensions[0];
    
    // Data elements
    $scope.elements = [
        { a: "A1", b: "B5", c: 1 },
        { a: "A2", b: "B4", c: 2 },
        { a: "A3", b: "B3", c: 3 },
        { a: "A4", b: "B2", c: 4 },
        { a: "A5", b: "B1", c: 5 }
    ];

    // Watch the filter dimension and filter text and rebuild the filter if it changes
    $scope.$watch('filterDimension', function(){
        if(undefined !== $scope.filterDimension){
            $scope.filter = {};
            $scope.filter[$scope.filterDimension.id] = $scope.filterText;
        } else {
            $scope.filter = $scope.filterText;
        }
    });
    $scope.$watch('filterText', function(){
        if(undefined !== $scope.filterDimension){
            $scope.filter[$scope.filterDimension.id] = $scope.filterText;
        } else {
            $scope.filter = $scope.filterText;
        }
    });
}