Angular using ng-bind-html and ng-model together in select dropdown? - angularjs

Is it possible to use ng-bind-html and ng-model together on the same select dropdown? In my application I have a select dropdown that gets populated with ng-bind-html (which is working fine) but when I try to bind the value of the dropdown to the $scope with ng-model, it isn't updating the scope with the value of the dropdown, it just stays the same as the original declaration in my controller. Here is what it looks like:
<select id="newNumOfPlayers" ng-bind-html="compiledSelect" ng-model="newNumOfPlayers"></select>
I declare my variable at the start of my controller
$scope.newNumOfPlayers = 0;
And here is where I populate my select string
$scope.compiledSelect = "";
var contentSelectString = "";
for (i = 1; i <= data[0].noOfPlayersNeeded; i++) {
contentSelectString += "<option value="+i+">"+i+"</option>";
}
$scope.compiledSelect = $sce.trustAsHtml(contentSelectString);
but this always logs as 0
console.log("new number "+$scope.newNumOfPlayers);
Anyone have any ideas? Thanks

Is there any reason why you are using ng-bind-html instead of ng-options?
Here is a reasonably clean way to do this with just a number input:
First we create a filter that creates an array with numbers equal leading up to your threshold (number of players needed)
app.filter('range', function() {
return function(input, min, max) {
min = parseInt(min); //Make string input int
max = parseInt(max);
for (var i=min; i<=max; i++)
input.push(i);
return input;
};
});
Next up we use ng-options combined with our filter to populate the select
<select ng-model="newNumOfPlayers" ng-options="n for n in [] | range:1:noOfPlayersNeeded"></select>
Now newNumberOfPlayers should be updated correctly and the range filter doesn't pollute your controller and can be used whereever you need it. Please note that noOfPlayersNeeded should be in your scope.

Related

What is the criteria for md-select to check duplicate options in md-options

I have been using Angular Material for a while in my project. While using md-select, I am stuck to a problem wherein I am getting Duplicate md-option values error.
I am aware that md-options takes unique values and I am assigning an array to md-options. This is however, an array of objects. So I would like to know what is the criteria that is used to differentiate objects. The API do not say much about it.
My use case demands to change md-options of an md-select, based on selection from another md-select. So I am watching the selection of first md-select and firing a watch on its change and updating md-options of second md-select.
Below is the approach I am using to assign array to md-options:
$scope.$watch('search.selectedTrades', function(newTrades, oldTrades) {
if ((newTrades.length === 0)) {
$rootScope.search.selectedTrades = oldTrades;
return;
}
if ($rootScope.search.selectedTrades && $rootScope.search.selectedTrades.length > 0) {
if (!$rootScope.identity.isClusterManager) {
$rootScope.search.selectedTrades = newTrades;
SearchFilterData.setSelectedTrades(newTrades);
$rootScope.search.selectedClusters = [];
$scope.clusters = [];
$scope.subareas = [];
var clusterKeys = [];
$rootScope.search.selectedTrades.forEach(function(t) {
t.lstClusters.forEach(function(c) {
if (clusterKeys.indexOf(c.ClusterKey) == -1) {
clusterKeys.push(c.ClusterKey);
$scope.clusters.push(c);
}
})
})
}
} else {
$scope.clusters = [];
$scope.subareas = [];
$rootScope.search.selectedClusters = [];
$rootScope.search.selectedSubAreas = [];
SearchFilterData.setSelectedTrades($rootScope.search.selectedTrades);
}
});
In above code, clusterKey is a unique entity for each object. So I am using it to push unique values into array.
This however happens on few random scenarios, after I have selected and de-selected various options. Please advise what I am doing wrong and what is the criteria for marking two objects duplicate
You did not provide your markup, so I cannot be sure, but in my case the problem was caused by omitting the double curleys on the 'value' attribute in the md-option tag.
This is bad: Notice the missing curly braces
<md-option ng-repeat="item in vm.list" value="item.id">{{item.text}}</md-option>
This is not:
<md-option ng-repeat="item in vm.itemlist" value="{{item.id}}">{{item.text}}</md-option>
I believe the reason that this fails is that each item will be placed into the option list will be given a value of 'item.id' (literally). It will fail on the second iteration of the repeat.
Using the curly braces causes the value in 'item.id' to be used.
Hope this helps.
Try using ng-value instead of just value attribute.
<md-option ng-repeat="item in vm.list" ng-value="item.id">{{item.text}}</md-option>

AngularJS ng-options to get selected option from an array that matches another scope var

I have an array and a var
$scope.fcFeedTypes = [{"name":"Plain Text","value":"Plain Text"},{"name":"MQ Message","value":"MQ Message"}];
}
$scope.feedEditor.ft = "MQ Message"; // this is dynamically obtained from some other source
I want a dropdown select with default selection based on the value of $scope.feedEditor.ft
HTML:
<select ng-model="fcFeedTypes"
ng-options="ft.name for ft in fcFeedTypes"
ng-init="ft=feedEditor.ft">
I am new to AngularJS and need some help...
If you just want the string "MQ Message" (or the value of whatever a user selects) as your ng-model value, then it's quite simple:
<select ng-model="someModelName"
ng-options="ft.value as ft.name for ft in fcFeedTypes"
ng-init="someModelName=feedEditor.ft">
If you want the full object as the ng-model value, then you've got to find the right one in JS. It must be referentially/strictly equal to the one in the options.
<select ng-model="someModelName"
ng-options="ft.name for ft in fcFeedTypes">
-
$scope.fcFeedTypes = [{"name":"Plain Text","value":"Plain Text"},{"name":"MQ Message","value":"MQ Message"}];
$scope.feedEditor.ft = "MQ Message"; // this is dynamically obtained from some other source
angular.forEach($scope.fcFeedTypes, function(feedType){
if(feedType.value === $scope.feedEditor.ft){
$scope.someModelName = feedType;
}
});

Angular Js dropdownlist Ng init not working along with Orderby

I was trying to bind an initial value to the dropdownlist. Here is my code sample
$scope.sessionid = $scope.sessions[0];
also i want to sort the drop down list which i managed by
<select ng-options="session.SessionStartTime for session in sessions | orderBy:'-SessionStartTime' track by session.TrackerSessionId " ng-model="sessionid" >
But the initial value is binding before the sorting take place.I need it to take place after sorting...could someone help me sort out this
Do a native javascript sort of your array of objects. You can change the sort direction by swapping the > and < operators. You can then remove the orderBy filter.
$scope.sessions.sort(function(a,b){
if (a.SessionStartTime < b.SessionStartTime) return -1;
if (a.SessionStartTime > b.SessionStartTime) return 1;
return 0;
});
$scope.sessionid = $scope.sessions[0];

How can I fire a custom Angular filter from ng-change from the html?

Lets say I have two dropdowns that are populated with numbers using a min value and a max value for example 0 and 9.
I populate them using a filter
export class NumberRangeFilter {
public static Factory() {
return function(input: number[], min: number, max: number) {
for (var i = min; i <= max; i++) {
input.push(i);
}
return input;
}
}
}
which is invoked in the html
ng-repeat="n for n in [] | numberrange:vm.minAllowedAdults:vm.maxAllowedAdults"
This works great. However the numbers in both combos can only ever add up to a max value for example 9. If 5 is selected in combo 1 then combo 2 should update to only show options 0 - 4.
Can this be achieved by invoking the filter that already exists from the html using an ng-change whilst keeping as much of the logic out of the controller as possible?
You can calculate the max depending on each other.
var total = 9;
dropDown1Max = total - dropDown2Value;
dropDown2Max = total - dropDown1Value;
Something like this
Cant you just use the limitTo filter provided by angular [] | limitTo:numLimit. Where numLimit points to the value chosen in the first dropdown.

AngularJS issue showing dynamic phrases according to a scope value.

I have an issue. When people click on a link, this variable add 5 to the original value:
$scope.sumareco = function(cantidad) { $scope.contadoreco += cantidad};
If i print the value {{sumareco}} you can see how the value changes.
The problem starts when I create a conditional on the controller.
if ($scope.contadoreco < 30 && $scope.contadoreco > 10) {
$scope.resultadoeco = "Opción uno";
} else {
$scope.resultadoeco = "";
}
If I print {{resultadoeco}} I expect that the phrase changes dinamically depending of the numeric value of $contadoreco. But it remains static and only shows the phrase assigned to the original value. ¿What can I do?
Thanks
I'm guessing your if statement is just sitting in your controller and not inside any method or statement that would run during a digest cycle.
The easiest way to update resultadoeco is to watch contadoreco. For example
$scope.$watch('contadoreco', function(val) {
$scope.resultadoeco = val > 10 && val < 30 ?
'Opción uno' : '';
});
See https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

Resources