Combining Select Options with AngularJS

I am completely new to AngularJS framework and just experimenting with it. Therefore, I'm not entirely sure if my current approach is the best or right way to achieve my goal.

My aim is to create a 3-level chained ajax-filled select boxes, and while it seems to be partly working, there are a couple of issues that I've encountered.

While my actual code utilizes ajax within a factory, for the purpose of this demo on fiddle, I have used a controller to return results from an array instead.

Demo (using arrays, not ajax): http://jsfiddle.net/xxwe1zu8/1/

Challenges:

  1. The second and third level selects do not have a "selected" attribute, meaning the selected option does not get highlighted.
  2. Ideally, I would like the top-level categories to be dynamically populated on page load via ajax (or in this case, using an array) by utilizing the same angular function (e.g., getSubcategories = function(0, 0)) rather than hardcoding them. Top level categories have a parent of 0.
  3. Bonus: Is it possible to show/only make the third select box visible if there is a sub-sub-category returned after selecting the sub-category? In most cases, sub-categories won't have further sub-categories.

    var myAppModule = angular.module('myApp',[]);
    myAppModule.controller('SearchCtrl', function($scope) {
    var self = this;
    
    self.subCategories = [];
    self.getSubcategories = function(parent, level) {
    
        theCategories = [];
    
            angular.forEach(sub_category[parent], function(idx, val) {
                 theCategories.push({id: val, name: idx});
            });
    
    
        self.subCategories[level] = theCategories;
    }       
    });
    

Thank you

Answer №1

One approach could be to organize the data into an array of objects and remove unnecessary indices.

var transport = [
    {
        name: "Cars",
        models: [
            {
                name: "Hatchback",
                variations: ["4 door", "5 door"]
            },
            {
                name: "Sedan",
                variations: ["4 door", "5 door"]
            },
            {
                name: "SUV",
                variations: ["Medium", "Large"]
            }
        ]
    },
 ...

This restructuring can lead to cleaner code in the template. I am not using ControllerAs syntax here because $scope is already injected. This approach is beneficial for beginners in AngularJS.

    <select 
         ng-model="selectedType" 
         ng-options="t.name for t in transport"
         ng-change = "selectedModel=null;selectedVariation=null">
         <option value="">Select type</option>
    </select>

    <select 
         ng-model="selectedModel" 
         ng-options="model.name for model in selectedType.models"
         ng-change="selectedVariation=null" 
         ng-show="selectedType.models">
        <option value="">Select model</option>
    </select>

    <span ng-show="loading">Loading...</span>
    <select 
         ng-model="selectedVariation" 
         ng-options="variation for variation in variations"
         ng-show="variations && !loading">
        <option value="">Select variation</option>
    </select> 

selectedType, selectedModel, and selectedVariation are automatically defined in $scope by ng-model of each select element. Despite not being mentioned in the controller, these properties are used in ng-show to show or hide select tags based on current selection.
The last select (sub-subcategory) demonstrates how to fetch data asynchronously. For instance, if you need to retrieve variations from the server when a model is selected. You would add a watch in the controller for selectedModel and upon selection, initiate a request for data and update the variations upon receiving a response.

$scope.$watch('selectedModel', function(model){
    if(model){
        $scope.loading = true;
        //setTimeout simulates an AJAX request
        setTimeout(function(){
            $scope.variations = model.variations;
            $scope.loading = false;
            $scope.$apply();
        }, 1000);
    }
})

View updated fiddle

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

Utilize Ajax.ActionLink on a DIV by incorporating data from the Model

Although there are similar questions on this topic already, they do not address the specific issue of using values from the model as arguments for the controller. Make DIV containing AJAX ActionLink clickable Div as Ajax.ActionLink Take a look at the fo ...

What is the method to assign a value to ng-class in Angularjs?

I need to categorize items in a list by assigning them classes such as items-count-1, items-count-2, items-count-3, items-count-4, based on the total number of items present. This is how I would like it to appear: li(ng-repeat="area in areas", ng-class=" ...

Using the Tailwind CSS framework in combination with Vue's v-html

My vue component is designed to accept a prop of raw HTML, which originates from a wysiwyg editor utilizing tailwind classes for styling - similar to our vue app. The issue arises when using v-html="responseFromAPI" in my component, as the raw H ...

Ensure the browser stays anchored at the bottom of the page while employing jQuery to reveal a div

This piece of code allows me to toggle the visibility of a div: <a href="#" class="show_hide">Show/hide</a> <div class="slidingDiv"> My content...... <a href="#" class="show_hide">hide</a></div> <script src="http:// ...

One required positional argument is needed in `update_one()`: 'update' is missing

I've exhausted all possible options, but I can't seem to make it work. Any suggestions on how I can get this code to function properly? I attempted using ajax_data to update the values, but it was unsuccessful. The main goal of this code is to al ...

Google Bar Graphs Cannot Display Decimal Values

Having an issue with my bar chart from Google Chart not displaying float numbers. Other types of bar charts provided by Google Chart work fine, but this specific type doesn't show the float numbers. Here is the code I have written: http://jsfiddle.ne ...

Enhance your JQuery skills by implementing variables within the .css() function

Attempting to randomly assign values to an image's left and right properties using JQuery. Here is the code snippet: var sides = ["left", "right"] var currentSide = sides[Math.floor(Math.random() * sides.length)]; $("#"+currentImage).css({currentSide ...

When deciding between utilizing a Javascript animation library and generating dynamically injected <style> tags in the header, consider the pros and cons of each

We are currently in the process of developing a sophisticated single-page application that allows users to create animations on various widgets. For example, a widget button can be animated from left to right with changes in opacity over a set duration. Ad ...

Is there a way to position one DIV behind another?

Hey, I'm working on my first project and running into some trouble with divs. I'm trying to position the firework behind the central text but can't figure it out. Can anyone lend a hand? I need to add more details in order to submit the que ...

Removing elements from an array of objects using specific values stored in another array - JavaScript

I'm currently working on implementing a reducer in redux that can delete multiple items from the state based on an array of values. Let's say I have the following array: const idArray = ["935", "933", "930"]; My goal is to remove objects that ...

What is the best way to incorporate real-time push notifications on my website?

My website consists of two main parts. One part is utilized by individuals labeled as X, while the other is reserved for those identified as Y. When a person from group X requests assistance, members of group Y promptly respond with an estimated time of ...

Error in syntax: The tailwind import statement contains an unrecognized word and will not function correctly

After configuring Tailwind CSS with Next.js, I made changes to the tailwind.config.js file. However, after making these changes, the compilation process failed and resulted in the following error: Error - ./src/assets/styles/global.css:3:1 Syntax error: Un ...

The data received from the frontend is being replicated in the backend, causing duplication issues in a React

Whenever I click the button labeled onClick, it triggers the transmission of data (both time and ID) to the backend. The issue at hand is that the backend seems to be receiving the data twice instead of just once. On inspecting req.body, it becomes eviden ...

Trigger functions by clicking or bind click events by calling a function?

I need help comparing two similar code snippets: myFunc(); function myFunc() { var e = document.getElementByClassName("link"), i = e.length; while (i--) { e[i].addEventListener("click", function() { //do stuff for each ...

Employing aspect.around while actively monitoring for methods invoking one another

Seeking a solution to run specific code around the put() and add() functions for Dojo stores, I encountered an issue with JSON REST stores where add() simply calls put(): add: function(object, options){ options = options || {}; options.overwrite = fal ...

Press the button to activate the function

<table class="calc" cellpadding=2> <td><input type="button" class="calc" id="screen" value="0" ></td> <td><input type="button" class="calc" id="screen" value="0" ></td> <tr> </ ...

When Vue.js Vuex state changes, the template with v-if does not automatically refresh

I have tried setting the v-if value in computed, data, passing it as props, and directly referencing state, but it never seems to re-render despite the fact that the state I am checking for is changed to true. Currently, I am directly referencing the stor ...

What are the steps to resolving an Unhandled promise rejection error in a Node.js application?

I encountered an error message that I need help resolving: I am faced with an unhandled promise rejection. This issue likely occurred due to throwing inside an async function without a catch block, or rejecting a promise without handling it using .catch( ...

When I try to access localhost, it directs me to http://localhost:3000/myprofile%20 instead of localhost:/3000/myprofile

Every time I try to log into my profile page with the correct login credentials, I get redirected to http://localhost:3000/myprofile%20, but then receive a 404 error. This is what my code looks like: // Login Route router.post('/login', functi ...

Find the Nearest Value with Jquery and Swap Out the Div

When users complete a form and click "continue," they move on to the next section. At the top of the page, a heading indicates that the previous form is finished. If users click on the heading, it expands the completed form so they can edit it. For instan ...