1

I want a drop down select and option list which displays a tree, in that sub items are indented so its obvious to the user they are child items. When I run this, literally nothing shows in the select. Ideally Id like it to display like this

My second problem is that using padding within the options wont work I have to use  , but how can I pass nesting information down the template to output the required number of spaces?

<script type="text/ng-template" id="tree_option_renderer.html">
    <option>{{data.Name}}</option>

    <!-- Would want 1 &nbsp; per level to indent properly, how? -->
    &nbsp;<option ng-repeat="data in data.Children" ng-include="'tree_option_renderer.html'">
</script>

<select id="folderList" ng-show="operatesOnSelector == 0">
    <option ng-repeat="group in addressbook" ng-include="tree_option_renderer.html"></option>
</select>

My data looks a little like this:

{
    Id: 0,
    Name: "Level 1",
    Children: [
        {
            Id: 1,
            Name: "level 2",
            Children: []
        }
    ]
}
6
  • <select> doesn't support nested optgroups Commented Dec 4, 2014 at 9:50
  • No but you can use &nbsp; to indent Commented Dec 4, 2014 at 9:53
  • Right... so, why do you have <div> there? Commented Dec 4, 2014 at 9:55
  • If you read my comment, I dont know how to do the &nbsp; stuff in Angular, the div was my initial attempt, the jsFiddle I provided shows it with &nbsp; - Ill update my question to be clearer Commented Dec 4, 2014 at 9:56
  • Ah, didn't notice the edit Commented Dec 4, 2014 at 9:57

2 Answers 2

1

Use NgHierarchicalSelector will resolve your problem. Hope it helps.

Sign up to request clarification or add additional context in comments.

Comments

0

This is an interesting question, but the quick answer is to use a custom directive that does some rudimentary pre-order tree traversal to flatten the structure while keeping the nesting level, and then render <options> elements.

The reason I find this question interesting is because you can take the solution "almost" all way without a custom directive, so long as you don't use an <option>.

Challenge 1: ng-repeat over a nested structure:

<div ng-repeat="l in data" ng-include="'itemTemplate'"></div>

<script type="text/ng-template" id="itemTemplate">
  {{l.Name}}
  <div ng-repeat="lNext in l.Children"
       ng-init="l = lNext"
       ng-include="'itemTemplate'"></div>
</script>

this could actually work with CSS:

<style>
  div > div {
    padding-left: 10px;
  }
</style>

Challenge 2: track nesting levels - can be accomplished with ng-inits:

<div ng-repeat="l in data" ng-include="'itemTemplate'" ng-init="level = 1"></div>

<script type="text/ng-template" id="itemTemplate">
  {{l.Name}}
  <div ng-repeat="lNext in l.Children"
       ng-init="level = level + 1; l = lNext"
       ng-include="'itemTemplate'"></div>
</script>

Challenge 3: generate N &nbsp; based on the nesting level:

This requires a function to be defined on the $scope (that's already kinda funky)

$scope.repeat = function(str, n){
  return Array(n).join(str);
};

and add a <span> before {{l.Name}}:

<span ng-init="arr = repeat('&nbsp;', level)" ng-bind-html="arr"></span>

plunker

... And this is where the requirement to have this done with <option>s unravels this entire solution, and that is because <option>s cannot be nested, while the solution above requires nesting (otherwise, the nested structure cannot be traversed).

So, this answer is a really a non-answer, because the actual answer is kinda boring.

Comments

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.