Pre populating the dropdown value inside ng-repeat in Angular JS - javascript

I have an array of objects. I have three properties attorneyId, attorneyName and attorneyList. The attorneyList array should be a drop down. If attorneyId = attorneyName = null then
dropdown will only show Choose attorney. If attorneyId != null and attorneyName != null, the dropdown should display what ever the value is present in attorneyId and attorneyName.
For this i am preparing an object selectedAttorney = {id:list.attorneyId, name:list.attorneyName} and passing this to ng-model of select. When i change the value in dropdown, i am getting the correct values into the selectedAttorney. But if there some value present for attorneyId and attorneyName, the dropdown is not pre populating the value.
HTML :
<div ng-repeat = 'list in List'>
<div class="width-200" ng-init="selectedAttorney = {id:list.attorneyId, name:list.attorneyName}">
{{selectedAttorney}}
<select ng-model="selectedAttorney" ng-options="attorney.name for attorney in list.attorneyList">
<option value="">-- choose attorney --</option>
</select>
</div>
</div>
JS
$scope.List = [ {
"attorneyId": "3",
"attorneyName": "Robert",
"attorneyList": [
{ "id": 1, "name": "sue" },
{ "id": 2, "name": "anthony" },
{ "id": 3, "name": "Robert" },
{ "id": 4, "name": "George" },
{ "id": 5, "name": "Bruce" }
]
},
{
"attorneyId": null,
"attorneyName": null,
"attorneyList": [
{ "id": 1, "name": "sue" },
{ "id": 2, "name": "anthony" },
{ "id": 3, "name": "Robert" },
{ "id": 4, "name": "George" },
{ "id": 5, "name": "Bruce" }
]
}
];
Here is the plunker link.
http://plnkr.co/edit/eqBkX0DNleiFmlO5sm7J?p=preview
Thanks in advance.

Though your approach is right, I prefer writing my select boxes in this manner.
<select ng-model="selectedAttorney">
<option
ng-repeat="attorney in list.attorneyList"
title="{{attorney.name}}"
ng-selected="{{attorney.id == selectedAttorney.id}}"
value="{{attorney}}">{{attorney.name}}
</option>
</select>
and here is the updated working demo : http://plnkr.co/edit/vCNOAPWlR6Mj1kFOgCKT?p=preview

Related

Analysis Paralysis in looping over JSON data to populate select box with optgroup sections

I have Analysis Paralysis and need some input. I can modify the SQL query, the JavaScript, AND/or the CFML controller (all code has been posted below).
All I'm looking to do is to populate a select box with options and optgroups. The optgroup is what is tripping me up here.
The sql is pretty basic and looks like this:
SELECT
g.groupID,
g.groupLabel,
u.unitLabel,
u.unitID
FROM
group g
LEFT JOIN unit u ON g.groupID = u.groupID
And the CFML loop(s) is as follows (this is also where I believe the adjustment should be made with some logic such as if thisGroupLabel matches the preGroupLabel, stay within loop and keep adding unitLabel and unitIDs) but is there a more efficient way?:
local.data.unitLabels = [];
for(local.row in local.__unitLabels){
local.unit = {};
local.unit.groupLabel = local.row.groupLabel;
local.unit.unitLabel = local.row.unitLabel;
local.unit.unitID = local.row.unitID;
// loop over the array so that we can identify which one needs to be preselected
for(local.dataValue in local.data.unitDetails){
if (local.unit.unitID eq local.dataValue.unitID) {
local.unit.selected = 'selected';
} else {
local.unit.selected = '';
}
}
arrayAppend(local.data.unitLabels, local.unit);
}
The JSON data looks like this but I have access to the query so I can reformat it if needed:
{
"data": {
"selectDataOptions": [{
"groupLabel": "COMPLETION",
"selected": "",
"unitID": 1,
"unitLabel": "Completion"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 2,
"unitLabel": "Meters"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 3,
"unitLabel": "Miles"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 4,
"unitLabel": "Yards"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "Hours"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "minutes"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "Seconds"
}]
}
}
As it stands, my select box looks like this (roughly):
<select>
<optgroup>COMPLETION</optgroup>
<option>Complettion</option>
<optgroup>DISTANCE</OPTGROUP>
<option>Meters</option>
<optgroup>DISTANCE</optgroup>
<option>Miles</option>
<optgtroup>DISTANCE</optgroup>
<option>Yards</option>
<optgtroup>TIME</optgroup>
<option>Hours</option>
<optgtroup>TIME</optgroup>
<option>Minutes</option>
</select>
Notice that the optgroup Distance and TIME are repeated. The desired output would look like this:
<select>
<optgroup>COMPLETION</optgroup>
<option>Complettion</option>
<optgroup>DISTANCE</OPTGROUP>
<option>Meters</option>
<option>Miles</option>
<option>Yards</option>
<optgroup>TIME</optgroup>
<option>Hours</option>
<option>Mintues</option>
</select>
Is the issue how to construct a JSON string that Select2 can understand? I'd suggest creating a nested array of children for each GroupLabel, as described in the documentation under Grouped Data.
CF11+ and Lucee 4.5+ support cfloop "group", which would make things a lot easier. Just cfloop through the query and group by "groupLabel". (NB: Don't forget to modify the SQL query and ORDER BY g.groupLabel so the grouping works as expected.)
TryCF.com Example
Code:
data= [];
cfloop(query="qDemo", group="groupLabel") {
children = [];
cfloop() {
arrayAppend(children, {"id": qDemo.unitID, "text": qDemo.unitLabel});
}
arrayAppend(data, {"text" : qDemo.GroupLabel, "children" : children });
}
writeDump(serializeJSON(data));
Result:
[
{
"text": "COMPLETION",
"children": [
{
"text": "Completion",
"id": 1
}
]
},
{
"text": "DISTANCE",
"children": [
{
"text": "Meters",
"id": 2
},
{
"text": "Miles",
"id": 3
},
{
"text": "Yards",
"id": 4
}
]
},
{
"text": "TIME",
"children": [
{
"text": "Hours",
"id": 5
},
{
"text": "minutes",
"id": 5
},
{
"text": "Seconds",
"id": 5
}
]
}
]

Populate and filter a dropdown with an array of objects using AngularJS

I have the following data structure thats coming from an API.
$scope.cityList = [{
"_id": {
"$oid": "584ebd7f734d1d55b6dd4e5e"
},
"cityName": "New York",
"region": "north",
"people": [
{ "id": 1, "name": "x" },
{ "id": 2, "name": "y" },
{ "id": 3, "name": "z" },
{ "id": 4, "name": "a" },
{ "id": 5, "name": "b" },
{ "id": 6, "name": "c" }
]
},
{
"_id": {
"$oid": "584ebd7f734d1d55b6dd4e5e"
},
"cityName": "New Jersey",
"region": "South",
"people": [
{ "id": 1, "name": "x" },
{ "id": 2, "name": "y" },
{ "id": 3, "name": "z" },
{ "id": 4, "name": "a" },
{ "id": 5, "name": "b" },
{ "id": 6, "name": "c" }
]
}]
I'm trying to setup two dropdowns:
the first one displays a list of the cityNames
the second displays the list of all people names from the selected city.
I also want to save the id of the selected user name into a variable.
I've tried this so far:
<select ng-model="city">
<option ng-repeat="city in cityList" value="{{city.cityName}}">{{city.cityName}}</option>
</select>
<select ng-model="selectedItem">
<optgroup ng-repeat="option in cityList | filter: city">
<option ng-repeat="x in option.people">{{x}}</option>
</select>
You should use ng-options:
<select ng-model="selectedCity"
ng-options="c as c.cityName for c in cityList">
</select>
<select ng-model="selectedPerson"
ng-options="p as p.name for p in selectedCity.people">
</select>
Demo on JSFiddle.

How to populate selectbox in angularJS?

This my json data how to set a selected option of a dropdown list control using angular JS
$scope.alltoys=[
{
"dId": "570b886545034f0001718247",
"dName": "Toys",
"dSubName": "Comics",
"users": [
{
"name": "Superman",
"id": "570b9e3a45034f000171827b"
},
{
"name": "Batman",
"id": "570ba00045034f000171828a"
}]
},
{
"dId": "5767c68c52faff0001fb8555",
"dName": "Toys",
"dSubName": "General",
"users": [
{
"name": "Jack",
"id": "570b9e3a45034f000171827b"
},
{
"name": "Sparrow",
"id": "570ba00045034f000171828a"
}]
}
]
How to populate this select box using angular js
I want to populate like this
Toys-Comics
Batman
Superman
Toys-General
Jack
Sparrow
In here Toys-Comics & Toys-General are only title of that selected content
I want to sort users array when populate.
<div class="controls">
<select class="form-control" ng-model="toy"
ng-options="eachtoy as eachtoy.dName+' - '+eachtoy.dSubName group by eachtoy for eachtoy in alltoys">
<option value="">---------------Select---------------</option>
</select>
</div>
I tried this but its not working.
Couple of changes. First, make sure $scope.alltoys is a collection (array), like this:
$scope.alltoys = [{
"dId": "570b886545034f0001718247",
"dName": "Toys",
"dSubName": "Comics",
"users": [{
"name": "Superman",
"id": "570b9e3a45034f000171827b"
}, {
"name": "Batman",
"id": "570ba00045034f000171828a"
}]
}, {
"dId": "5767c68c52faff0001fb8555",
"dName": "Toys",
"dSubName": "General",
"users": [{
"name": "Jack",
"id": "570b9e3a45034f000171827b"
}, {
"name": "Sparrow",
"id": "570ba00045034f000171828a"
}]
}];
Then change your html to handle groups with optgroup, like this:
<select class="form-control" ng-model="toy">
<option value="">---------------Select---------------</option>
<optgroup ng-repeat="eachtoy in alltoys | orderBy: 'dName + dSubName" label="{{eachtoy.dName+' - '+eachtoy.dSubName}}">
<option ng-repeat="user in eachtoy.users | orderBy: 'name'">{{user.name}}</option>
</optgroup>
</select>
Here's a working plunk

Applying filter on parent if it has been applied on children AngularJS

I have a list with items and have applied filter on those items by value from text box. I want to get new filtered list with parent and its children if parent has at least one filtered item.If doesn't, that parent should not be displayed.
For an example: If I enter "3D" in the text box I don't want to get "Day parts" and "Week parts" listed below as they don't have children anymore after filtering.
<div ng-controller="Ctrl">
<input type="text" data-ng-model="inputValue.name"/>
<ul data-ng-repeat="condition in conditions">
<div data-ng-click="setHeadingStatus(condition)">
<div>
{{condition.name}}
</div>
<li ng-repeat="item in condition.items | filter:inputValue">
<div class="custom-typeahead-list-title">{{item.name}}</div>
<div class="custom-typeahead-list-desc">{{item.description}}</div>
</li>
</div>
</ul>
function Ctrl($scope , $filter){
$scope.countryCode = 1;
$scope.conditions = [
{
"id": 1,
"name": "Experiences",
"expanded": false,
"items": [
{
"id": 1,
"name": "3D"
},
{
"id": 2,
"name": "Imax"
},
{
"id": 3,
"name": "D-Box"
},
{
"id": 4,
"name": "THX"
}
]
},
{
"id": 2,
"name": "Day parts",
"expanded": false,
"items": [
{
"id": 1,
"name": "Early Bird"
},
{
"id": 2,
"name": "Matinee"
},
{
"id": 3,
"name": "Last Night"
}
]
},
{
"id": 3,
"name": "Week parts",
"expanded": false,
"items": [
{
"id": 1,
"name": "Monday"
},
{
"id": 2,
"name": "Wednesday"
},
{
"id": 3,
"name": "Weekend"
}
]
}
]
}
Here is the example of it
http://jsfiddle.net/KJ3Nx/48/
You can put an ng-show on the div that displays each block, and set the expression to the filtered length;
<div data-ng-show="(condition.items | filter:inputValue).length > 0" data-ng-click="setHeadingStatus(condition)">
Updated fiddle

Angularjs trigger country state dependency

Can someone please help me make my example of Country/State drop down dependency work?
I intentionally created JSON in this way because I want the dependency to be generic, so I would be able to apply it on any drop down while using only Meta Data and not HTML.
Here's a link to see an example of the code in JSFidlle
HTML
Country:<select data-ng-model="Countries" data-ng-options="country.id as country.name for country in Countries.items">
<option value="">Please select a country</option>
</select>
State: <select data-ng-model="currentItem" data-ng-options="item.id as item.name for item in currentStates.items">
<option value="">Please select a state</option>
</select>
JavaScript Code:
function Controller($scope) {
var Countries = {
"id": "field10",
"items": [{
"id": "10",
"StateGroupID":"0",
"name": "United State"
},
{
"id": "2",
"StateGroupID":"1",
"name": "Canada"
}]
};
var States =
{ "id": "field20",
"StateGroups": [{
"items": [{ "id": "1",
"name": "Alabama"
},
{
"id": "2",
"name": "Alaska"
},
{ "id": "3",
"name": "Arizona"
},
{ "id": "4",
"name": "California"
}]},
[{ "id": "201",
"name": "Alberta"
},
{
"id": "202",
"name": "British Columbia"
},
{
"id": "303",
"name": "Manitoba"
},
{
"id": "304",
"name": "Ontario"
}]]
};
$scope.Countries = Countries;
$scope.currentStates = States.StateGroups[0];
$scope.$watch('currentStates', function(value, oldValue){
//alert(value);
//alert(JSON.stringify(value));
//$scope.currentStates = (value == "10") ? States.StateGroups[0] : States.StateGroups[1];
});
}
first, I think there is a little mistake in your JSON, you should have one "items" before the Canadian states
{"items": [{ "id": "201",
"name": "Alberta"
}, .....
After doing this, I would modify your HTML in order to have 2 different model names (the way you did, at the first click you overwrite the list of countries). Then I'll use a different syntax for the ng-repeat, in order to force the value to the StateGroupId
<select data-ng-model="selectedCountry">
<option ng-repeat='country in Countries.items' value='{{country.StateGroupID}}'>{{country.name}}</option>
</select>
Doing this allows you to create a function to get the states of the selected group ID :
$scope.getStates=function(){
console.log($scope.selectedCountry)
return $scope.backupStates.StateGroups[$scope.selectedCountry].items;
}
Then you can use this function to display them using ng-repeat
<select data-ng-model="selectedState" >
<option value="">Please select a state</option>
<option ng-repeat='state in getStates()'>{{state.name}}</option>
</select>
I modified your fiddle here : http://jsfiddle.net/DotDotDot/TsxTU/14/ , I hope this is the kind of behavior you wanted :)
I suggest you a bit of refactoring to your data model - it seems tangled. Let's store counties and states in two arrays:
$scope.countries = [{
"name": "USA",
"id": 1
},{
"name": "Canada",
"id": 2
}];
$scope.states = [{
"name": "Alabama",
"id": 1,
"countryId": 1
}, {
"name": "Alaska",
"id": 2,
"countryId": 1
}, {
"name": "Arizona",
"id": 3,
"countryId": 1
}, {
"name": "Alberta",
"id": 4,
"countryId": 2
}, {
"name": "British columbia",
"id": 5,
"countryId": 2
}];
Having this, we can write selects for data:
<select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="updateCountry()">
<option value="">Select country</option>
</select>
<select data-ng-model="state" data-ng-options="state.name for state in availableStates">
<option value="">Select state</option>
</select>
It's a pity we cannot use if expressions in selectors - if we can, we do not need a single line of JS! But we need:
$scope.updateCountry = function(){
$scope.availableStates = [];
angular.forEach($scope.states, function(value){
if(value.countryId == $scope.country.id){
$scope.availableStates.push(value);
}
});
}
And that's all. Here is a working plunk for you.
The easiest way to fix is to refer the currentCountry in the 2nd select and no need to use the $watch to achieve your requirement.
<select data-ng-model="currentCountry" data-ng-options="country.name for country in Countries.items">
<select data-ng-model="currentItem" data-ng-options="item.id as item.name for item in States.StateGroups[currentCountry.StateGroupID].items">
Demo
angular-country-picker
bower install angular-country-picker (or)
npm install angular-country-picker
<script src="bower_components/angular-country-picker/country-picker.js"></script>
<script src="node_modules/angular-country-picker/country-picker.js"></script>
angular.module('webApp', ['puigcerber.countryPicker']);
<select ng-model="selectedCountry" pvp-country-picker="name"></select>
angular.module('myApp', ['puigcerber.countryPicker'])
.config(function(pvpCountriesProvider) {
pvpCountriesProvider.setCountries([
{ name: 'Abkhazia', alpha2: 'AB'},
{ name: 'Kosovo', alpha2: 'XK'},
{ name: 'Nagorno-Karabakh', alpha2: 'NK'},
{ name: 'Northern Cyprus', alpha2: 'KK'},
{ name: 'Somaliland', alpha2: 'JS'},
{ name: 'South Ossetia', alpha2: 'XI'},
{ name: 'Transnistria', alpha2: 'PF'}
]);
});

Categories

Resources