Just observe below Image. There is JSON object which does have children elements. If you want search one item, you need to dig into all children elements. If the most children element match with input text then you need to display its parent elements too. Okay, now observe the below image , When user gives no input, it displays the whole JSON and when user gives "os" as input text, It shows "cse > os".

Markup

The template 'tree_item_renderer.html' is for displaying tree view. showFilteredData is for displaying and hiding main data and filtered data. mainData consists of original data and filteredData consists of filtered data from main data based on user's input text. searchVal is the user's input text.
<html data-ng-app="myApp" data-ng-controller="MyCtrl">
.......
<script src="angular.min.js"></script>
.......
        <script type="text/ng-template" id="tree_item_renderer.html">
            <li>{{data.name}}</li>
            <li data-ng-if="data.CHILDREN.length > 0">
               <ul data-ng-repeat="data in data.CHILDREN" data-ng-include="tree_item_renderer.html"></ul>
            </li>
        </script>
        ........
            <input data-ng-model="searchVal" placeholder="enter text here" />
        ........
            <ul data-ng-repeat="data in mainData" data-ng-hide="showFilteredData">
                <li>{{data.name}}
                    <div data-ng-if="data.CHILDREN.length > 0">
                        <ul data-ng-repeat="data in data.CHILDREN"
                            data-ng-include="'tree_item_renderer.html'"></ul>
                    </div>
                </li>
            </ul>
            <ul data-ng-repeat="data in filteredData"
                data-ng-show="showFilteredData">
                <li>{{data.name}}
                    <div data-ng-if="data.CHILDREN.length > 0">
                        <ul data-ng-repeat="data in data.CHILDREN"
                            data-ng-include="'tree_item_renderer.html'"></ul>
                    </div>
                </li>
            </ul>
       ........
</html>

AngularJS Code

In this code, you can see sample mainData. Whenever user types some text into the input field, searchVal will be changed. By watching searchVal, we can trigger filtering data. Here $scope.filterResources function is for filtering data
var myApp = angular.module('myApp', []);

function MyCtrl($scope) {
    $scope.mainData = [ {
        "name" : "cse",
        "CHILDREN" : [ {
            "name" : "OS",
            "CHILDREN" : []
        }, {
            "name" : "OOPS",
            "CHILDREN" : []
        } ]
    }, {
        "name" : "mech",
        "CHILDREN" : [ {
            "name" : "Dynamics",
            "CHILDREN" : []
        }, {
            "name" : "Mechines",
            "CHILDREN" : []
        } ]
    }, {
        "name" : "biotech",
        "CHILDREN" : [ {
            "name" : "cardio",
            "CHILDREN" : []
        }, {
            "name" : "biochemicals",
            "CHILDREN" : []
        } ]
    } ];
    $scope.filteredData = [];

    $scope.$watch('searchVal', function() {
        if ($scope.searchVal == null || $scope.searchVal.length == 0) {
            $scope.showFilteredData = false;
        } else {
            $scope.filteredData = [];
            var temp = angular.copy($scope.mainData);
            $scope.lowerCaseSearchKeyword = $scope.searchVal
                    .toLowerCase();
            $scope.filterResources(temp);
            $scope.showFilteredData = true;
            $scope.filteredData = temp;
        }
    });

    $scope.filterResources = function(resourceList) {
        for (var i = 0; i < resourceList.length; i++) {
            if (resourceList[i].CHILDREN != null
                    && resourceList[i].CHILDREN.length > 0) {
                $scope.filterResources(resourceList[i].CHILDREN);
                if (resourceList[i].CHILDREN.length == 0) {
                    var name = resourceList[i].name.toLowerCase();
                    if (!(name.indexOf($scope.lowerCaseSearchKeyword) >= 0)) {
                        resourceList.splice(i, 1);
                        i--;
                    }
                }
            } else {
                var name = resourceList[i].name.toLowerCase();
                if (!(name.indexOf($scope.lowerCaseSearchKeyword) >= 0)) {
                    resourceList.splice(i, 1);
                    i--;
                }
            }
        }
    };

}

1 comment:

Blogroll

Popular Posts