4

I have the following markup:

<div class="modal fade" id="locationSearchModal" tabindex="-1" role="dialog">
    <div class="modal-dialog narrow-modal" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel">Search for Locations</h4>
            </div>
            <div class="modal-body">
                <div class="tree-container">                  
                    <section>
                        <h2>Browse for Locations</h2>
                        <div ui-tree="" data-drag-enabled="false" id="tree-root">
                            <ul ui-tree-nodes="" ng-model="data">
                                <li ng-repeat="item in data" ui-tree-node="" collapsed="!item.ItemsRetrieved" ng-include="item.Place || item.$hashkey == undefined ? 'parent_items_renderer' : 'terminal_item_renderer' " ></li>
                            </ul>
                        </div>
                        <script type="text/ng-template" id="parent_items_renderer">
                            <div ui-tree-handle class="tree-node tree-node-content" ng-class="{'tree-node-open': !collapsed}" ng-click="toggle(item); convertObjs(item)">
                                <i class="fa fa-caret-right" ng-class="{'fa-caret-right': collapsed, 'fa-caret-down': !collapsed}"></i>
                                <i class="fa fa-map-marker" ng-class="{'text-blue': !collapsed}"></i>
                                <span class="" ng-bind-html="item.PlaceName"></span>
                            </div>
                            <ul ng-if="item.Place != null" ui-tree-nodes ng-model="item.Place" ng-class="{hidden: collapsed}">
                                <li ng-repeat="item in item.Place" ui-tree-node collapsed="!item.ItemsRetrieved" ng-include="item.Place ? 'parent_items_renderer' :  'terminal_item_renderer' "  on-finish-render="ngRepeatFinished"> </li>
                            </ul>

                        </script>
                        <script type="text/ng-template" id="terminal_item_renderer">
                            <div ui-tree-handle class="tree-node tree-node-content" ng-class="{'tree-node-open': !collapsed}" ng-click="addLocation(item)">
                                <a href title="Add Location"><span class="" ng-bind-html="item.PlaceName"></span></a>
                            </div>
                        </script>
                    </section>
                </div>
            </div>
        </div>
    </div>
</div>

The JSON data object that contains the location data is an hierarchical collection of Places:

{  
   "PlaceHierarchy":{  
      "Places":{  
         "Place":{  
            "PlaceID":"1000",
            "PlaceTypeID":"5",
            "PlaceName":"Company",
            "AbbrName":"Company",
            "Place":[  
               {  
                  "PlaceID":"2000",
                  "PlaceTypeID":"4",
                  "PlaceName":"Region",
                  "AbbrName":"ThePlace",
                  "Place":[  
                     {  
                        "PlaceID":"3000",
                        "PlaceTypeID":"3",
                        "PlaceName":"SubRegion",
                        "AbbrName":"TheSubPlace",
                        "Place":[  
                           {  
                              "PlaceID":"4000",
                              "PlaceTypeID":"2",
                              "PlaceName":"SubSubRegion",
                              "AbbrName":"TheSubSubPlace",
                              "Place":[  
                                 {  
                                    "PlaceID":"5000",
                                    "PlaceTypeID":"1",
                                    "PlaceName":"Building",
                                    "AbbrName":"Building",
                                    "Place":[  
                                       {  
                                          "PlaceID":"5001",
                                          "PlaceTypeID":"6",
                                          "PlaceName":"Lobby",
                                          "AbbrName":"Lobby"
                                       },
                                       {  
                                          "PlaceID":"5002",
                                          "PlaceTypeID":"6",
                                          "PlaceName":"Lobby 2",
                                          "AbbrName":"Lobby2"
                                       }
                                    ]
                                 }
                              ]
                           }
                        ]
                     }
                  ]
               }
            ]
         }
      }
   }
}

When I get that JSON back from the API, I need to process the data to make sure that all nodes are arrays. I do it like this:

$scope.processLocationNodes = function (nodes) {
        for (var node in nodes) {
            if (angular.isArray(node)) {
                $scope.processLocationNodes(node);
            } else {
                $scope.convertObjs(node);
            };
        }
    };

$scope.convertObjs = function (item) {

        angular.forEach(item.Place, function (items) {
            if (items != undefined && !angular.isString(items)) {
                if (items.Place && !angular.isArray(items.Place)) {
                    var PlaceObj = items.Place;
                    items.Place = [];
                    items.Place.push(PlaceObj);
                }
            }
        });
    };

Now, when the modal is shown, the data properly displays and the tree works as expected. The only problem is, I want to default the tree to expand to the node of the Default Place of the user. I do that by the following logic:

The onFinishRender directive (debugging the code shows that this is hit):

app.directive('onFinishRender', function ($timeout) {
    return {
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit(attr.onFinishRender);
                });
            }
        }
    }
});

The ngRepeatFinished function is as follows:

$scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) {
        var rootScope = $scope.getRootNodesScope();

        if (rootScope != undefined) {
            rootScope.collapseAll();
            $scope.expandNode($scope.defaultPlace);
        }
    });

$scope.getRootNodesScope = function() {
        return angular.element(document.getElementById("tree-root")).scope().$nodesScope.childNodes()[0];
    }

$scope.expandNode = function(nodeId) {

        // We need to get the whole path to the node to open all the nodes on the path
        var parentScopes = $scope.getScopePath(nodeId);

        for (var i = 0; i < parentScopes.length; i++) {
            parentScopes[i].expand();
        }

    };

$scope.getScopePath = function (nodeId) {
    return $scope.getScopePathIter(nodeId, $scope.getRootNodesScope(), []);
};

$scope.getScopePathIter = function(nodeId, scope, parentScopeList) {

        if (!scope) return null;

        var newParentScopeList = parentScopeList.slice();
        newParentScopeList.push(scope);

        if (scope.$modelValue && scope.$modelValue.id === nodeId) return newParentScopeList;

        var foundScopesPath = null;
        var childNodes = scope.childNodes();

        for (var i = 0; foundScopesPath === null && i < childNodes.length; i++) {
            foundScopesPath = $scope.getScopePathIter(nodeId, childNodes[i], newParentScopeList);
        }

        return foundScopesPath;
    };

Now, here's what my problem is:

First of all at the angular.element(document.getElementById("tree-root")).scope().$nodesScope.childNodes()[0] code, "childNodes()" is empty. No childNodes exist at all. Thus, the code has nothing to collapse or expand. I don't know why the childNodes collection is empty.

Second, once I figure that out, I can see what the actual NodeId is for a specific node and then be able to expand the tree to that node using the $scope.defaultPlace object.

Essentially, I just need to know why the childNodes collection is empty.

1
  • 1
    Hi...anyone got answer to this?? Please let me know if you have any.. Commented Apr 12, 2018 at 5:33

0

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.