Navigating Hierarchical Data with Angular Dropdowns

I need help with organizing my folder structure in an html select using angular.

Currently, the select only displays the top level of folders. Is there a way to show all folders with proper indentation to reflect the structure?

I am considering adding a depth property to each folder to assist with the indentation. Since the folders are user-defined, I do not know the exact number of levels without examining the data.

Thank you

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>

Answer №1

Transform your directory structure into a streamlined list of objects, each containing a level attribute. Utilize this attribute to visually align the entries within 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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Sending Data From Ajax to JavaScript

While I know this question has been asked and answered a few times before, the exact context of my query remains unanswered. To ensure full understanding, I would like to pose my specific scenario. I am looking to trigger a server-side call to query infor ...

Improving file reading and parsing efficiency with fast random access using csv-parse in Node.js

I recently encountered a challenge while working with the csv-parser library in node for parsing large CSV files. The files I work with can range from 50,000 to 500,000 lines or even larger. My task involved performing computations on this data and then su ...

Execute supplementary build scripts during the angular build process

I've developed an Angular application that loads an iframe containing a basic html page (iframe.html) and a Vanilla JavaScript file (iframe.js). To facilitate this, I've placed these 2 files in the assets folder so that they are automatically cop ...

When using AngularJS, compatibility issues may arise with loading ASP.Net MVC Partial Views triggered by a @Ajax.ActionLink()

Currently, I am facing an issue while trying to incorporate AngularJS into ASP.Net MVC. The problem arises when AngularJS does not seem to work in the rendered view called from @Ajax.actionLink(). Below is a snippet of the code that I have experimented wit ...

Assigning a value to an input field using jQuery

I'm facing an issue while trying to set the value for an input using jQuery. Essentially, when you click on a link, it redirects you to a different page with a form, and I am attempting to set the value of one of the inputs in that form. Unfortunately ...

The process of accessing files from the filesystem using AngularJS

I have a JSON file that I want to use in my Angular application. I came across a discussion here suggesting the use of $http.get to load JSON from the filesystem. However, I am encountering an issue where I keep getting a "http://localhost:9000/jsonFile.js ...

Generate all conceivable combinations of elements found in the array

Looking to generate all possible combinations of elements (without repetition) from a given array and length. For example, with an array of: arr = ['a','b','c','d'] and a length of 3, the desired output would be a ...

Loading a .css file in advance using NextJS

We have integrated NextJS and Material-UI into our website, but we are facing an issue with FOUC (Flash of Unstyled Content) upon page loading. After some investigation, I discovered that the JS files are loading faster than the CSS file, causing the probl ...

Multiply the values of objects by their respective index position

Can someone help me out? I have two different sets of data Data Set 1 29: {value: 29, price: "145"} 30: {value: 30, price: "160"} Data Set 2 29: {value: 29, count: 2} 30: {value: 30, count: 3} I'm attempting to multiply the price by the count at ...

Invoke the componentDidMount() method in a React Component that is not a subclass of React.Component

I have a react component that I render later in my index.js file index.js import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render( <React.StrictMode> <App /> ...

Methods to fill a data table cell

I have recently created a table and I am facing an issue in populating the tds cells using JavaScript. The data for the table is coming from the server. Here's my table: <table id="report" class="infoRecurso" id='testExportId' style="wid ...

Updating Angular.js scope after a variable has been modified

On my website, I have implemented a search bar that communicates with a controller receiving JSON responses from the server. The response is stored in a global variable called assetResult. It works as expected initially; however, subsequent searches do no ...

Error: You forgot to include a name after the dot operator

I am facing an issue where I am unable to use YUIcompressor to compress a file. The script is running smoothly, but I am encountering the error missing name after . operator on line 3 of this script: Specifically at: "+ source.response.chars[k].name +" I ...

Modifying pagination numbers with Reactjs: A step-by-step guide

I am currently working on Reactjs (nextjs) and I have successfully integrated the "Nextjs" framework. The pagination is working fine, but the buttons are displaying as "1,2,3,20" instead of "1,2...20" (showing all numbers without using "..."). How can I mo ...

How can I combine jQuery "this" along with a CSS selector?

Currently, I am working on a script that will allow me to toggle the visibility of a section within a div. I have three of these divs with hidden sections and I am trying to find a way to control all three using a single function. This is what my code loo ...

Initializing Access Model in Sails.js Service启

The inquiry: In the context of sails.js, it appears that Services are initialized before Models during the initialization process. Is there a way to alter this sequence? Can Models be loaded before Services? If not, then how can one retrieve specific se ...

How to delete a line from a file in Node.js without modifying the buffer variable

Hello everyone, I am just starting to explore the world of Nodejs Recently, I created a function that reads data from a file, saves it in an array variable, and then makes some changes to this variable before writing it back to the file. The code snippet ...

Can anyone provide guidance on displaying a JS alert every time a tab in the slider is opened?

Utilizing the liquidslider script on my website, I have created a slider with the following HTML code: <div class="liquid-slider" id="slider-id"> <div> <h2 class="title">Slide 1</h2> // Content goes here ...

Can you explain the significance of the regular expression in a dojo configuration file named dj

As I was working on developing dojo application modules, I came across a regular expression in tutorials. var pathRegex = new RegExp(/\/[^\/]+$/); var locationPath = location.pathname.replace(pathRegex, ''); var dojoConfig = { asyn ...

Retrieve specifically chosen values from the dropdown menu and eliminate any values that have not been selected

Within my two multiple dropdowns, the first contains all available fields with their corresponding values. The second dropdown displays the selected value along with all other values that were not selected. However, I only want to show the three values tha ...