I have a multi select dropdown that functions as appropriate when setting values, but once set, I need to display what has been selected in an update form. My values are stored in a DB (SharePoint) accessible over REST. Here is an example REST output with multiple IDs of my array:
"CatId": [
18,
80,
84
],
Here is my select function, including retrieving the variable from REST:
var currentCatValue = results.CatId;
$scope.categoryValues = [];
appCatList.query(function (categorydata) {
var categoryValues = categorydata.value; // Data is within an object of "value", so this pushes the server side array into the $scope array
// Foreach type, push values into types array
angular.forEach(categoryValues, function (categoryvalue, categorykey) {
$scope.categoryValues.push({
label: categoryvalue.Title,
value: categoryvalue.ID,
});
})
var currentDetailIndex = $scope.categoryValues.map(function (e) { return e.value; }).indexOf(currentCatValue);
$scope.vm.selectedCategory = $scope.categoryValues[currentDetailIndex];
});
Here is my HTML:
<select class="form-control" id="Event_Cat" data-ng-model="vm.selectedCategory"
data-ng-options="opt as opt.label for opt in categoryValues | orderBy:'label'" required>
<option style="display:none" value="">Select a Category</option>
</select>
EDIT: Using id (inspired by yvesmancera) in ng-model would greatly reduce the complexity - You don't need to pre-process your options and input array anymore, just plug it in and done!
<select multiple ng-model="currentCatValue" ng-options="opt.ID as opt.Title for opt in categoryValues">
$scope.currentCatValue = currentCatValue;
$scope.categoryValues = categoryValues;
Note: normally we would pre-populate ng-options into an array to preserve the order of the options, if the original data is an object. But since you use orderBy, you can use the object directly as ng-options.
fiddle
Outdated:
You need to point to the same object in ng-options for them to get selected on load.
$scope.categoryValues = [];
$scope.vm.selectedCategory = [];
angular.forEach(categoryValues, function (categoryvalue, categorykey) {
var category = {
label: categoryvalue.Title,
value: categoryvalue.ID,
}
$scope.categoryValues.push(category);
if (currentCatValue.indexOf(parseInt(category.value)) != -1) {
$scope.vm.selectedCategory.push(category);
}
});
Try changing your ng-options to something like:
<select class="form-control" id="Event_Cat" data-ng-model="vm.selectedCategory" data-ng-options="opt.id as opt.label for opt in categoryValues | orderBy:'label'" required>
<option style="display:none" value="">Select a Category</option>
</select>
And make this line change in your controller:
$scope.vm.selectedCategory = $scope.categoryValues[currentDetailIndex].id;
Edit for multiple selection:
<select class="form-control" id="Event_Cat" data-ng-model="selectedCategoriesIds" data-ng-options="opt.id as opt.label for opt in categoryValues | orderBy:'label'" required multiple>
<option style="display:none" value="">Select a Category</option>
</select>
In your controller, add the items you want selected to $scope.selectedCategoriesIds e.g.:
$scope.selectedCategoriesIds = [];
$scope.selectedCategoriesIds.push('18');
$scope.selectedCategoriesIds.push('80');
Related
I've created an angularJS select box which will filter the results in a table based on the selected value in the select box.
Now, the select box is created using an object 'user['location']' which has locations as keys.
Also, I'm grabbing the default user location '${city}' as soon as the page is loaded, passing it on to my select box, and filter the results accordingly in the table.
If the user's current location doesn't match any of the options in my select box, then no filter should be applied!
For e.g., if the user location is 'London', since there's nothing like in 'London' in my object, it should select the first option - 'Select City'.
But currently it is creating an empty string like <option value= "? string:London ?"></option> above that and is selecting it!
How, do fix it?
Here's my code:
HTML:
<select class="form-control" ng-model="user.loc" ng-init="user.loc = '${city}'">
<option value="" ng-selected="!checkKey(user.loc)">Select City</option>
<option value="{{key}}" ng-selected="key == user.loc" ng-repeat="(key, value) in user['location']">{{key}}</option>
</select>
JS:
$scope.user['location'] = {Sydney: 5, Hong Kong : 7, NYC : 3, Toronto: 1};
$scope.checkKey = function(loc) {
if(loc in $scope.user['location']){
return true;
} else {
return false;
}
};
I think I understand what you are trying to do here. But instead of checking the values using checkKey, you can do it once when your controller is loaded.
Also, you can leverage ngOptions to render available options in the select box.
angular.module('myapp', [])
.controller('myctrl', function($scope) {
$scope.user = {};
$scope.user['location'] = {
'Sydney': 5,
'Hong Kong': 7,
'NYC': 3,
'Toronto': 1
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp" ng-controller="myctrl">
<select class="form-control" ng-model="user.loc" ng-init="user.loc = user.location['London']" ng-options="value as key for (key, value) in user.location">
<option value="">Select City</option>
</select>
</div>
You can change ng-init with your own value, as you were doing, and it should work fine with it.
Ok, I tried this and it worked!
<select class="form-control" ng-model="user.loc">
<option value="" ng-selected="!checkKey(user.loc)">Select City</option>
<option value="{{key}}" ng-selected="key == '${city}'" ng-repeat="(key, value) in user['location']">{{key}}</option>
</select>
In Angular.JS, is there a way to bind two different ng-models when a select drop down option is selected?
Angular code:
<select ng-model="vm.data.styleId" ng-options="item.id as item.name for item in vm.getStylesData.styles">
<option value="">Select a Style</option>
</select>
Results in:
<option value="{{item.id}}">{{item.name}}</option>
With the Angular code I have so far, when an option is selected, it will save the option's value to the ng-model. In this case item.id is bound to vm.data.styleId.
However in addition to this, I also need to bind the 'item.name' of the selected option. Basically, when an option is selected, I need to bind both the item.id to vm.data.styleId, and the item.name to vm.data.name.
Is there an easy way to do this using Angular.JS?
Solution (using the answer from lisa p.):
In the View:
<select ng-model="vm.styleItem" ng-change="vm.getDetails()" ng-options="item as item.name for item in vm.getStylesData.styles">
<option value="">Select a Style</option>
</select>
Inside the controller:
vm.getDetails = function () {
// set the values of the select drop down
vm.data.styleId = vm.styleItem.id;
vm.data.style = vm.styleItem.name;
}
You can bind to an object containing both values like
item = { styleId: 23, name: "the name" }
vm.data = {{ styleId: ..., name: ... }}
then you bind to vm.data with
<option value="{{item}}">{{item.name}}</option>
Controller
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.vm.data.styleId = "";
$scope.item = {id : '1', name : 'name'};
});
html
<div ng-controller="myCtrl">
<select ng-model="vm.data.styleId" ng-options="item.id as item.name for item in vm.getStylesData.styles">
<option value="{{item}}">{{item.name}}</option>
</select>
</div>
Make an object which holds both id and name and pass that object as value to option
How can I set the selected value of a dropdown when I edit an item ?
<div class="form-group">
<label for="category" class="col-sm-2 control-label">Category</label>
<div class="col-sm-10">
<select ng-model="quiz.category" ng-options="category as category.name for category in categories" required>
<option></option>
</select>
</div>
</div>
And when I click on edit
$scope.editQuiz = function(quiz)
{
$scope.quiz = {};
$scope.quiz.name = quiz.name // this works fine
$scope.quiz.category = quiz.category[0]; // ?????
console.log($scope.quiz.category);
//$scope.quiz = quiz;
}
Method to get categories:
$scope.getCategories = function() {
$http.get('http://localhost/myappi/API/index.php/Api/categories').
success(function(data) {
$scope.categories = data;
})
.error(function(err) {
console.log('error',err);
})
};
Ok if you really want to keep quiz.category as an array.
At first when you get the quiz assign quiz.category to an new object.
e.g:
$scope.tmp = { category: quiz.category[0] };
We have to do that since quiz.category is an array but the value of the ng-options is an object.
now we can bind that var to the options like this:
<select ng-model="tmp.category" ng-options="category as category.name for category in categories" required>
<option></option>
</select>
and finally in your function you replace the old value with the new:
$scope.quiz.category[0] = tmp.category;
Hope it makes sense
Changing the select's ngModel is definitely the way to go. You can check out this solution, since I believe it deals with the same problem.
$scope.options = [{ name: "a", id: 1 }, { name: "b", id: 2 }];
$scope.selectedOption = $scope.options[1];
<select data-ng-options="o.name for o in options" data-ng-model="selectedOption"></select>
Can you send us your data structure sample?
Use "track by" inside the ng-options
category as category.name for category in categories track by category.id
working example
I am new to Angular and am trying to use $rootScope to save values that have been selected from a dynamically generated options element, so that I can render them at a different route. The selection options are referred to by 'ng-model' in the html, and there are four distinct ng-models that I want to grab. the models are key value pairs and I want want only the keys.
I am also including my HTML as it seems like I might need to access the ng-model inside the controller?
angular.module('FFTrades.tradeanalyzer', [])
.controller('TradesController', function($scope, $rootScope, TradesDataFactory) {
$scope.data = {};
$scope.selectedItem1 = 0;
$scope.selectedItem2 = 0;
//I want to push the selected items here.
$rootScope.data = {};
$scope.getPlayerData = function() {
// getting this from the services.
TradesDataFactory.getPlayerInfo().then(function(playerInfo) {
$scope.data.playerInfo = playerInfo;
}).catch(function(error) {
//console.error(error)
})
}
$scope.calc = function() {
//selectedItem1 is a number. I want its key!
$scope.calculatedValue1 = Number($scope.selectedItem1);
if($scope.selectedItem2){
$scope.calculatedValue1 = Number($scope.selectedItem1) + Number($scope.selectedItem2);
}
}
$scope.calc2 = function() {
$scope.calculatedValue2 = Number($scope.selectedItem3);
if ($scope.selectedItem4) {
$scope.calculatedValue2 = Number($scope.selectedItem3) + Number($scope.selectedItem4);
};
}
for (var key in $scope.data.playerInfo) {
//this is all the players. I just want the ones that have been selected. the problem is $scope.selectedItem4
//for example, is a number, not a key
};
var selectedItems = []
$scope.getPlayerData();
});
<div>Your Team Receives:</div>
<br> Player 1:
<select class="form-control" ng-model="selectedItem1" ng-change="calc()">
<option ng-repeat="(k,v) in data.playerInfo" ng-value="v" >{{k}}
****//{{k}} displays the name of the player only, which is what I want to push to rootScope ****
</option>
</select>
Player 2:
<select class="form-control" ng-model="selectedItem2" ng-change="calc()">
<option ng-repeat="(k,v) in data.playerInfo" ng-value="v">{{k}}</option>
</select>
<!-- show value here -->
<p> Total Value: {{calculatedValue1}} </p>
<br>
<br>
<br>
<div>Their Team Gets:</div>
<br> Player 1:
<select class="form-control" ng-model="selectedItem3" ng-change="calc2()">
<option ng-repeat="(k,v) in data.playerInfo" ng-value="v" >{{k}}</option>
</select>Player 2:
<select class="form-control" ng-model="selectedItem4" ng-change="calc2()">
<option ng-repeat="(k,v) in data.playerInfo" ng-value="v">{{k}}</option>
</select>
<!-- show value here -->
<p> Total Value: {{calculatedValue2}} </p>
<br>
You can use like:
<select class="form-control" ng-model="selectedItem1" ng-change="calc(selectedItem1)">
$scope.calc = function(model) {
//selectedItem1 is a number. I want its key!
}
I'm trying to select multiple values on page load, but it only selects the last value on the array. Take a look at the code
jQuery("#language").chosen();
var str = '12,24,36';
var languageArray = str.split(',');
for (var i = 0; i < languageArray.length; i++) {
jQuery("#language").val(languageArray[i]);
jQuery("#language").trigger("liszt:updated");
}
I get only 36 selected on page load, is there anything wrong with the js ?
Here is the HTML for the select
<select name="language[]" id="language" data-placeholder="Choose Language..." multiple="multiple">
I appreciate your help.
Thanks
You can select multiple options in a multi-value select box by passing an array to the val() method.
Example
Markup
<select name="language" id="language" data-placeholder="Choose Language..." multiple="multiple">
<option value="en">English</option>
<option value="fr">French</option>
<option value="de">German</option>
</select>
JavaScript
var str = 'en,de';
jQuery("#language").val(str.split(','));
And here's a jsFiddle for funsies.
you could set the selected property of matched option element. hope it would help.
var values = ['1', '2', '4'];
$('#languages').find('option').filter(function (idx, option) {
if($.inArray(option.value, values) !== -1) {
return option;
}
}).prop('selected', 'true');