Milos
Milos

Reputation: 2946

How to get a string value on select option instead of object:1 etc

How can I make angular populate value with actual string. I want to get this

<option label="New York City" value="New York City">New York City</option>

Instead of this

<option label="New York City" value="object:3">New York City</option>

My code:

<div ng-controller="CountryCntrl">
    <div>
        City: <br>
        <select id="country" ng-model="states" ng-options="country for (country, states) in countries" required>
        <option value=''>Select</option>
        </select>
    </div>
    <br>

    <div>
        SubArea:<br>
        <select id="state" ng-disabled="!states" ng-model="cities" ng-options="state for (state,city) in states" required>
        <option value=''>Select</option></select>
    </div>
    <br>

    <div>
        SpecLoc:<br>
        <select id="city" ng-disabled="!cities || !states" ng-model="city">
        <option value=''>Select</option>
        <option ng-repeat="city in cities" value='{{city}}'>{{city}}</option></select>        
    </div>
</div>  

And here is the scope array. Please ignore the wrong naming(countries/cities). Its an example

    $scope.countries = {
                    'New York City': {
                        'manhattan': ['Battery Park','Chelsea','Chinatown / Lit Italy','Downtown','East Harlem','East Village','Financial District','Flatiron','Gramercy','Greenwich Village','Harlem / Morningside','Inwood / Wash Hts','Lower East Side','Midtown','Midtown East','Midtown West','Murray Hill','Nolita / Bowery','SoHo','TriBeCa','Union Square','Upper East Side','Upper West Side','West Village'],
                        'brooklyn': [],
                        'queens': [],
                        'bronx': [],
                        'staten island': [],
                        'new jersey': [],
                        'long island': [],
                        'westchester': [],
                        'fairfield co': [],
                        'fairfield co, CT': []
                    },
                    'Chicago': {
                        'city of chicago': [],
                        'north chicagoland': [],
                        'west chicagoland': [],
                        'south chicagoland': [],
                        'northwest indiana': [],
                        'northwest suburbs': []
                    },
                    'Washington': {
                        'district of columbia': [],
                        'northern virginia': [],
                        'maryland': []

                    }
                };
  }
]);

Upvotes: 1

Views: 903

Answers (3)

Naren Murali
Naren Murali

Reputation: 56600

The code you have provided works perfectly fine. You had raised an issue for the value of the option tag in select being value="object:3", but it is a sort of internal indexing for the select, that is why the other selects work fine.

Working Code (without changing the object):

https://jsfiddle.net/Kai_Draord/98dfLp4p/5/

This method is really cool, and is a quick way to create sequential selects. Anyway coming back to your issue. Since you wanted the input to look like value="New York", I tried to do this. But from what I can see, this messes up the internal indexing of the object, the first select alone works fine, but the other selects just split a string into individual characters.

For ng-options (value="object:3"):

<select id="country" ng-model="states" ng-options="country for (country, states) in countries" required> 

For ng-options(value="New York"):

<select id="country" ng-model="states" ng-options="country as country for (country, states) in countries" required> 

In the above example country as country will set the values and the label as country value. seen in the example below.

So it is:

ng-options="value as label for (key, value) in object"

Atempt to set value (without changing the object):

https://jsfiddle.net/Kai_Draord/98dfLp4p/6/

Final Solution: The reason you want the select to show that value must be that you want the actual values for country(i.e. "New York" instead of "Object:3" So what I suggest is you need to change the structure of the main object as shown below.

$scope.countries = [{
                    'state': 'New York City',
                    'cities': [{'city': 'manhattan', 'districts': ['Battery Park','Chelsea','Chinatown / Lit Italy','Downtown','East Harlem','East Village','Financial District','Flatiron','Gramercy','Greenwich Village','Harlem / Morningside','Inwood / Wash Hts','Lower East Side','Midtown','Midtown East','Midtown West','Murray Hill','Nolita / Bowery','SoHo','TriBeCa','Union Square','Upper East Side','Upper West Side','West Village']}
                    ,{'city': 'brooklyn', 'districts': []}
                    ,{'city': 'queens', 'districts': []}
                    ,{'city': 'bronx', 'districts': []}
                    ,{'city': 'staten island', 'districts': []}
                    ,{'city': 'new jersey', 'districts': []}
                    ,{'city': 'long island', 'districts': []}
                    ,{'city': 'westchester', 'districts': []}
                    ,{'city': 'fairfield co', 'districts': []}
                    ,{'city': 'fairfield co, CT', 'districts': []}]
                    },{
                    'state': 'Chicago',
                    'cities': [{'city': 'city of chicago', 'districts': []}
                    ,{'city': 'north chicagoland', 'districts': []}
                    ,{'city': 'west chicagoland', 'districts': []}
                    ,{'city': 'south chicagoland', 'districts': []}
                    ,{'city': 'northwest indiana', 'districts': []}
                    ,{'city': 'northwest suburbs', 'districts': []}]
                    },{
                    'state': 'Washington',
                    'cities': [{'city': 'district of columbia', 'districts': []}
                    ,{'city': 'northern virginia', 'districts': []}
                    ,{'city': 'maryland', 'districts': []}]
                    }
                ];

Then we can access the individual state city and country easily by accessing ($scope.state, $scope.city, $scope.district)

angular.module('myApp', []);
angular.module('myApp').controller('testCtrl', function($scope) {
	$scope.countries = [{
                    'state': 'New York City',
                    'cities': [{'city': 'manhattan', 'districts': ['Battery Park','Chelsea','Chinatown / Lit Italy','Downtown','East Harlem','East Village','Financial District','Flatiron','Gramercy','Greenwich Village','Harlem / Morningside','Inwood / Wash Hts','Lower East Side','Midtown','Midtown East','Midtown West','Murray Hill','Nolita / Bowery','SoHo','TriBeCa','Union Square','Upper East Side','Upper West Side','West Village']}
                    ,{'city': 'brooklyn', 'districts': []}
                    ,{'city': 'queens', 'districts': []}
                    ,{'city': 'bronx', 'districts': []}
                    ,{'city': 'staten island', 'districts': []}
                    ,{'city': 'new jersey', 'districts': []}
                    ,{'city': 'long island', 'districts': []}
                    ,{'city': 'westchester', 'districts': []}
                    ,{'city': 'fairfield co', 'districts': []}
                    ,{'city': 'fairfield co, CT', 'districts': []}]
                    },{
                    'state': 'Chicago',
                    'cities': [{'city': 'city of chicago', 'districts': []}
                    ,{'city': 'north chicagoland', 'districts': []}
                    ,{'city': 'west chicagoland', 'districts': []}
                    ,{'city': 'south chicagoland', 'districts': []}
                    ,{'city': 'northwest indiana', 'districts': []}
                    ,{'city': 'northwest suburbs', 'districts': []}]
                    },{
                    'state': 'Washington',
                    'cities': [{'city': 'district of columbia', 'districts': []}
                    ,{'city': 'northern virginia', 'districts': []}
                    ,{'city': 'maryland', 'districts': []}]
                    }
                ];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="testCtrl">
  <div>
        City: <br>
        <select id="country" ng-model="states" ng-options="o.state for o in countries" required>
        <option value=''>Select</option>
        </select>
    </div>
    <br>

    <div>
        SubArea:<br>
        <select id="state" ng-disabled="!states" ng-model="cities" ng-options="o.city for o in states.cities" required>
        <option value=''>Select</option></select>
    </div>
    <br>

    <div>
        SpecLoc:<br>
        <select id="city" ng-disabled="!cities || !states" ng-model="district">
        <option value=''>Select</option>
        <option ng-repeat="city in cities.districts" value='{{city}}'>{{city}}</option></select>        
    </div>

{{states.state}}

{{cities.city}}

{{district}}
</div>

I hope this fixes your issue.

Upvotes: 1

Milos
Milos

Reputation: 2946

After I did a lot of reading, I found a solution. Its pretty simple, if you want your option value to reflect the value and not the object you just add track by.

<select id="country" ng-model="states" ng-options="country for (country, states) in countries track by country" required>
<option value=''>Select</option>
</select>

And you will get this

<option label="New York City" value="New York City">New York City</option>

Instead of this

<option label="New York City" value="object:3">New York City</option>

Upvotes: 0

Freddy Mart&#237;nez
Freddy Mart&#237;nez

Reputation: 83

I'll asume that your countries object is a Json and it has a value field where you save the name of the citie. Said that, you can set the value of your options with this <option value="{{country.value}}"></option>

<div>
    City: <br>
    <select id="country" ng-model="states" ng-options="country for (country, states) in countries" required>
        <option value='{{country.value}}'>Select</option>
    </select>
</div>

Upvotes: 0

Related Questions