AngularJS : using ng-repeat and ng-model to populate an array - javascript

I'm trying to use ng-repeat and ng-model in order to populate an array. The number of required elements in the array comes from a select element`.
The relevant part of my controller:
app.controller('AddMsgCtrl', function($scope){
$scope.range = function(n){
var array = [];
for(var i = 0 ; i < n ; i++)
array.push(i);
return array;
};
$scope.images = ['1.gif', '2.gif', '3.gif', '4.gif', 'any.gif'];
$scope.msg = { 'images': [] }
And the relevant part of my html:
Number of images:
<select class="browser-default" ng-model="numOfImages" ng-init="numOfImages=0">
<option ng-repeat="number in range(6)" value="{{number}}">{{number}}</option>
</select>
<div>
<div ng-repeat="n in range(numOfImages) track by $index">
<select class="browser-default" ng-model= ???>
<option ng-repeat="image in images" value="{{image}}">{{image}}</option>
</select>
</div>
</div>
Right now the user can select the number of images they wish to input and the same amount of select elements shows up. I'm just not sure how to use ng-model to add the chosen elements to the $scope.msgs.images array.
EDIT: I was closer than I thought. This seems to work correctly:
<select class="browser-default" ng-model="msg.images[$index]">
<option ng-repeat="image in images" value="{{image}}">{{image}}</option>
</select>

use msg.images[$index]
Plnkr Demo
HTML
Number of images:
<select class="browser-default" ng-model="numOfImages" ng-init="numOfImages=0" ng-options="number for number in range(6)" ng-change="updateImages()">
</select>
<div>
<div ng-repeat="n in range(numOfImages) track by $index">
<select class="browser-default" ng-model="msg.images[$index]" ng-options="image for image in images">
</select>
</div>
</div>
Msg : {{msg}}
Controller
$scope.range = function(n){
var array = [];
for(var i = 0 ; i < n ; i++)
array.push(i);
return array;
};
$scope.images = ['1.gif', '2.gif', '3.gif', '4.gif', 'any.gif'];
$scope.msg = { 'images': [] };
$scope.updateImages = function() {
// alert($scope.numOfImages);
$scope.msg.images.splice($scope.numOfImages, $scope.msg.images.length);
}
Extra function is added which will execute on selecting the number of images. Once you select a number and if you want to reduce the number, the array size also should be decreased if you want. For that I added.

Related

ng-model on different condition

I have 2 different array set as :
var oldarr = ['one','two','three'];
var newarr = ['four','five','six'];
var condi = 1 / 0;
I am using array value as ng-model as options value for select dropdown. However I want to use different array on basis of value of cond variable, that means : if condi is 1, I will use ng-model = oldarr and vif confi is 2 , I will use ng-model = newarr.
My drop down is as below. can someone pls suggest me how can I do this ?
<select ng-model="oldarr " ng-selected="{{defaultvalue == selectedslastatus}}">
<option ng-repeat="vals in oldarr ">{{vals }}</option>
</select>
I think the best approach is to use a middle array.
(Actually this can be done by ng-show or ng-if or ng-switch but if you want a clean HTML Template (View) and your arrays' structures are the same you may want to migrate the logic to Controller)
like:
<select ng-model="modelArr" ng-selected="{{defaultvalue == selectedslastatus}}">
<option ng-repeat="vals in modelArr ">{{vals }}</option>
</select>
and do the logic of using which array in your controller.
This is how your controller may look like:
//
$scope.$watch('condi', function (){
if (condi === true)
$scope.modelArr = newArr;
else
$scope.modelArr = oldArr;
})
I would simply swap the views with ng-show or something similar. Assuming that condi is not always a boolean (1 or 0), I suggest ng-switch. Here is an example:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.condi = 1;
$scope.oldarr = ['one', 'two', 'three'];
$scope.newarr = ['four', 'five', 'six'];
$scope.changeCondi = function() {
$scope.condi = ($scope.condi == 1) ? 0 : 1;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="changeCondi()">Change condi</button> : {{condi}}
<div ng-switch="condi">
<div ng-switch-when="1">
<select ng-model="oldar">
<option ng-repeat="vals in oldarr">{{vals}}</option>
</select>
Selected: {{oldar}}
</div>
<div ng-switch-when="0">
<select ng-model="newar">
<option ng-repeat="vals in newarr">{{vals}}</option>
</select>
Selected: {{newar}}
</div>
</div>
</div>

Set Selected Option In Dropdown in AngularJS onload

In Angularjs, I have a DropDown:
<select ng-model="category" ng-change="categoryChanged(category)" class="form-control"
data-ng-options="category as category.name for category in categories">
<option value="">Select Category</option>
</select>
And I have a controller:
app.controller('searchBoxController', ['$scope', '$location', '$routeParams', 'categoryService', function ($scope, $location, $routeParams, categoryService) {
categoryService.getParentCategory().$promise.then(
function (model) {
$scope.categories = model;
$scope.category.id = $routeParams.categoryId;// Which is coming as "1"
},
function (error) {
});
$scope.categoryChanged = function (category) {
alert(category.id);
};
}]);
$routeParams.categoryId is coming as "1" but still it is not setting the selected option in the dropdown.
Your categories variable is an array of objects, while you set the ng-model to an object with only an id. Because it is a whole new object, angular doesn't see it as a match of the category in your array, and won't select the correct one.
The solution is to set the $scope.category to the matching object of the array instead of creating a new one:
var id = $routeParams.categoryId;
// Find the category object with the given id and set it as the selected category
for (var i = 0; i < $scope.categories.length; i++){
if ($scope.categories[i].id == id) {
$scope.category = $scope.categories[i];
}
}
You have to change ng-model directive when promise operation is end.
<select ng-model="category" ng-change="categoryChanged(category)" class="form-control" data-ng-options="category as category.name for category in categories">
<option value="">Select Category</option>
</select>
Suppose you have var id = $routeParams.categoryId and its value is 2 for example. You have to find category from categories where category.id is 2. For this, the simpliest method is to use a filter method.
$scope.category = $scope.categories.filter(function(item){
return item.id==$scope.id;
})[0];
Please take a look to working fiddle

ng-option or ng-repeat cannot updated after change array

i used ng-option or ng-repeat and change value of array but not bind new values
<select multiple="true" ng-model="staticField.text">
<option ng-repeat="t in Activitydata track by $index ">{{t}}</option>
</select>
and i change it to ng-option and does work
that's angular js code
$scope.Activitydata = [];
$scope.ActivityFound = function (from) {
for (var h = 0; h < allRequestDetails.procurationCustomers.length; h++) {
activitynote = allRequestDetails.procurationCustomers[h].notes;
actList = activitynote.split('|');
for (i = 0; i < actList.length; i++) {
//alert(1);
console.log('element : ' + actList[i]);
$scope.Activitydata.push(actList[i]);
}
$scope.Activitydata.removeDuplicates();
$scope.Activitydata.unique();
$scope.Activitydata.remove("");
};
....
....
If you are using ng-repeat the you should provide what value to bind as..
<select multiple="true" ng-model="staticField.text">
<option ng-repeat="t in Activitydata track by $index" value={{t}}>{{t}}</option>
So in this case the value of t gets bind to the ng-model..If you are using ng-options then you should use as..
<select multiple="true" ng-model="staticField.text" ng-options="t.code as t.name for t in Activitydata track by $index ">
<option value="">Select</option>
I am assuming here that ActivityData contains name and code as property....

Adding things to a different route with a POST Angular

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!
}

AngularJS set values of multi-select dropdown

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');

Categories