3

I have a folder structure I'd like put into an html select using angular.

I've created an example below showing the structure and outputting it into a nested list structure. I've also put it into the select, but that only shows the top level of folders. Is there a way to have select show all the folders with indentation so you can visually see the structure in a select?

I can possibly add another property to the folders with the depth of the folder to help with the indentation. The folders are user defined in the system so I do not know how many levels it'll have without looking at the data.

Thanks

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

app.controller("selectFolderController", ['$http', '$scope',
  function($http, $scope) {

    var ctrl = this;

    ctrl.folders = [{
      "name": "Housing",
      "id": "1",
      "children": [{
        "name": "Datasheets",
        "id": "2",
        "children": [{
          "name": "Folder 1",
          "id": "3",
          "children": []
        }, {
          "name": "Folder 2",
          "id": "4",
          "children": []
        }]
      }, {
        "name": "Charts",
        "id": "5",
        "children": [{
          "name": "Folder A",
          "id": "6",
          "children": []
        }, {
          "name": "Folder B",
          "id": "7",
          "children": []
        }, {
          "name": "Folder C",
          "id": "8",
          "children": [{
              "name": "Sub Folder 1",
              "id": "9",
              "children": []
            }, {
              "name": "Sub Folder 2",
              "id": "10",
              "children": []
            }

          ]
        }, {
          "name": "Folder D",
          "id": "11",
          "children": []
        }, {
          "name": "Folder E",
          "id": "12",
          "children": []
        }]
      }]
    }, {
      "name": "Road Works",
      "id": "13",
      "children": [{
        "name": "Datasheets",
        "id": "14",
        "children": [{
          "name": "Folder 1",
          "id": "15",
          "children": [{
            "name": "Sub Folder 1",
            "id": "16",
            "children": []
          }]
        }, {
          "name": "Folder 2",
          "id": "17",
          "children": []
        }, {
          "name": "Folder 3",
          "id": "18",
          "children": []
        }, {
          "name": "Folder 4",
          "id": "19",
          "children": []
        }]
      }, {
        "name": "Charts",
        "id": "20",
        "children": [{
          "name": "Folder A",
          "id": "21",
          "children": []
        }, {
          "name": "Folder B",
          "id": "22",
          "children": []
        }, {
          "name": "Folder C",
          "id": "23",
          "children": []
        }]
      }]
    }];

  }
]);
<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="style.css" />
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script src="script.js"></script>
</head>

<body ng-app="selectFolderApp">

  <div ng-controller="selectFolderController as ctrl">

    <br>{{ ctrl.folderId }}
    <br>

    <br>

    <select class="form-control" ng-model="ctrl.folderId" ng-options="item.id as item.name for item in ctrl.folders">
      <option></option>
    </select>

    <br>

    <script type="text/ng-template" id="folderTree">
      {{item.name}}
      <ul>
        <li ng-repeat="item in item.children" ng-include="'folderTree'"></li>
      </ul>
    </script>

    <ul>
      <li ng-repeat="item in ctrl.folders" ng-include="'folderTree'"></li>
    </ul>

  </div>
</body>

</html>

1

1 Answer 1

6

Convert your folder structure into a flat list of objects, each of which would have a level property. You can then use this property to visually indent the values in the select element.

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

app.controller("selectFolderController", ['$http', '$scope',
  function($http, $scope) {

    var ctrl = this;

    ctrl.folders = [{
      "name": "Housing",
      "id": "1",
      "children": [{
        "name": "Datasheets",
        "id": "2",
        "children": [{
          "name": "Folder 1",
          "id": "3",
          "children": []
        }, {
          "name": "Folder 2",
          "id": "4",
          "children": []
        }]
      }, {
        "name": "Charts",
        "id": "5",
        "children": [{
          "name": "Folder A",
          "id": "6",
          "children": []
        }, {
          "name": "Folder B",
          "id": "7",
          "children": []
        }, {
          "name": "Folder C",
          "id": "8",
          "children": [{
              "name": "Sub Folder 1",
              "id": "9",
              "children": []
            }, {
              "name": "Sub Folder 2",
              "id": "10",
              "children": []
            }

          ]
        }, {
          "name": "Folder D",
          "id": "11",
          "children": []
        }, {
          "name": "Folder E",
          "id": "12",
          "children": []
        }]
      }]
    }, {
      "name": "Road Works",
      "id": "13",
      "children": [{
        "name": "Datasheets",
        "id": "14",
        "children": [{
          "name": "Folder 1",
          "id": "15",
          "children": [{
            "name": "Sub Folder 1",
            "id": "16",
            "children": []
          }]
        }, {
          "name": "Folder 2",
          "id": "17",
          "children": []
        }, {
          "name": "Folder 3",
          "id": "18",
          "children": []
        }, {
          "name": "Folder 4",
          "id": "19",
          "children": []
        }]
      }, {
        "name": "Charts",
        "id": "20",
        "children": [{
          "name": "Folder A",
          "id": "21",
          "children": []
        }, {
          "name": "Folder B",
          "id": "22",
          "children": []
        }, {
          "name": "Folder C",
          "id": "23",
          "children": []
        }]
      }]
    }];

    var times = function (n, str) {
        var result = '';
        for (var i = 0; i < n; i++) {
            result += str;
        }
        return result;
    };

    var recur = function (item, level, arr) {
        arr.push({
            name: item.name,
            id: item.id,
            level: level,
            indent: times(level, '–')
        });

        if (item.children) {
            item.children.forEach(function (item) {
                recur(item, level + 1, arr);
            });
        }
    };

    ctrl.flatFolders = [];
    ctrl.folders.forEach(function (item) {
        recur(item, 0, ctrl.flatFolders);
    });
  }
]);
<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="style.css" />

  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script src="script.js"></script>
</head>

<body ng-app="selectFolderApp">

  <div ng-controller="selectFolderController as ctrl">

    <select class="form-control" ng-model="ctrl.folderId">
      <option ng-repeat="item in ctrl.flatFolders" ng-value="{{ item.id }}">
          {{ item.indent }} {{ item.name }}
      </option>
    </select>

  </div>
</body>

</html>

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

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.