Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display HTML options based on separately selected options with Angular

I have some data that consists of various brands, and each brand has a nested array (of strings) containing range names:

[
    {
        "brandName" : "Brand 1",
        "ranges" : [
            "Range A1",
            "Range A2",
            "Range A3"
        ]
    },
    {
        "brand" : "Brand 2",
        "ranges" : [
            "Range B1",
            "Range B2",
            "Range B3"
        ]
    },
]


What I am trying to do is display a select element with a list of options containing range names as their values and innerHTML, based on the previously selected brand in a separate select element.

I'm not sure how to go about targeting the selected brand object in order to gain access to the nested array, as I'm trying to do it 'the Angular way'.

Currently, I've been trying with ngRepeat, but can't get it to work.

In the controller:

$scope.formData = {
    brandData : [
        {
            "brandName" : "Brand 1",
            "ranges" : [
                "Range A1",
                "Range A2",
                "Range A3"
            ]
        },
        {
            "brandName" : "Brand 2",
            "ranges" : [
                "Range B1",
                "Range B2",
                "Range B3"
            ]
        },
    ],
    currentBrand : undefined,
    currentRange : undefined
};


And the simplified markup:

<select name="currentBrand" ng-model="formData.currentBrand">
    <option value="" disabled>Select a brand</option>
    <option value="none" selected>None</option>
    <option ng-repeat="brand in formData.brandData" value="{{brand.brandName}}">{{brand.brandName}}</option>
</select>

<select name="currentRange" ng-model="formData.currentRange">
    <option value="" disabled>Select a range</option>
    <option value="none" selected>None</option>
    <option ng-repeat="how do I show each range name in the 'ranges' array of the selected brand ????? value="{{rangeName}}">{{rangeName}}</option>
</select>


There are some similar questions floating around, but I couldn't find any specific to the data structure that I have.

Thanks in advance!


UPDATE

Thanks to Rohan, I have now achieved my original goal. However, I also wanted the value of each option element to get set to the same value as its innerHTML. To do this I used the track by... feature of ngOptions:

<select name="currentBrand" ng-model="formData.currentBrand" ng-options="brandOption as brandOption.brandName for brandOption in brandOptions track by brandOption.brandName">
    <option value="" disabled>Select a brand</option>
</select>

<select name="currentRange" ng-model="formData.currentRange" ng-options="rangeOption for rangeOption in formData.currentBrand.ranges track by rangeOption">
    <option value="" disabled>Select a range</option>
</select>


For a working example, I have forked and updated Rohan's jsfiddle: http://jsfiddle.net/munkychop/hgzdannz/1/

like image 617
munkychop Avatar asked Mar 18 '23 07:03

munkychop


1 Answers

Use ng-options for this: https://docs.angularjs.org/api/ng/directive/select

You need to set your selected brand as an object, then use that brand to repeat over your ranges in your next ng-options select.

   <div>
        <select name="currentBrand" ng-model="currentBrand"
                ng-options="brandOption as brandOption.brandName for brandOption in brandOptions">
                <option value="" disabled>Select a brand</option>
            </select>
        </div>

        <span>Selected brand: {{currentBrand}}</span>
        <div>
            <select name="currentRange" ng-model="currentRange"
            ng-options="rangeOption for rangeOption in currentBrand.ranges">
                <option value="" disabled>Select a range</option>
            </select>
        </div>

        <span>Selected Range: {{currentRange}}</span>
    </div>

Here's your working snippet of code:

http://jsfiddle.net/hjq7gbLz/

like image 100
Rohan Avatar answered Apr 25 '23 06:04

Rohan