I have 2 multi select element and both get options from a variable list.
If a variable selected as row variable it will not be shown in column select options. if user unselect option then variable should will shown in both list
$scope.variables = ['a','b','c','d','e','f'];
<select multiple ng-model="selectedAsRows" ng-options="v for v in variables"></select>
<select multiple ng-model="selectedAsCols" ng-options="v for v in variables"></select>
I think that I understood what you want. Here is a fiddle with an example:
http://jsfiddle.net/26fZb/209/
The key is to use a custom filter like this one:
filter: { name: '!' + selectedAsFriend.name }
EDIT:
Here is your case with multiSelect. I have created custom filters.
app.filter('myFilter', function() {
return function(inputList, list) {
return inputList.filter(isAlreadySelected(list));
};
function isAlreadySelected(list){
return function(elem){
if (list.indexOf(elem) == -1)
return true;
else
return false;
}
}
});
Then to use it in the html file:
<select multiple ng-model="selectedAsRows" ng-options="v for v in variables | myFilter: selectedAsCols"></select>
<select multiple ng-model="selectedAsCols" ng-options="v for v in variables | myFilter: selectedAsRows"></select>
Take a look at the full code:
http://plnkr.co/edit/6eWZB75dAdquPD1jMmb7?p=preview
Related
How to make a select option not disappear when selected if filtered out and not be displayed on other select dropdowns.
For example
if i have some array of objects, and i make
<select ng-options = "here we go through each object "></select>
My idea is to make filter function that would not display any item that's in the array i'm filling if I selected this item before. So that would be my array of items that should be unavailable in another dropdowns. Is there some example way how can i accomplish that? I have an idea that my filter would look something like this:
for(var i=0;i<$scope.removedIds.length;i++){
if(tab.tabID===$scope.removedIds[i].tabID)
return false;
}
return tab;
and this would be used in ng-options for ex: ng-options="tab.ID as tab.name for tab in tables | filter: "
and in my function ng-change i would be adding to $scope.removedIds next values that should not be available in next select dropdowns. But I think it would not work because values would be filter out in different select dropdowns.
Example
I guess that you have three dropdowns with same datasource, a simple solution would look like:
<div>
<select ng-model="selectedItem1" ng-options="item1 for item1 in options1"></select>
<select ng-model="selectedItem2" ng-options="item2 for item2 in options2"></select>
<select ng-model="selectedItem3" ng-options="item3 for item3 in options3"></select>
</div>
In the corresponding controller, and using angularjs watchers, add these lines:
$scope.options1 = ["opt1","opt2","opt3"];
$scope.options2 = angular.copy($scope.options1);
$scope.options3 = angular.copy($scope.options1);
$scope.$watch("selectedItem1", function(nv, ov) {
if (nv != ov) {
$scope.options2.splice($scope.options2.indexOf(nv),1);
$scope.options3.splice($scope.options3.indexOf(nv),1);
}
});
$scope.$watch("selectedItem2", function(nv, ov) {
if (nv != ov) {
$scope.options1.splice($scope.options1.indexOf(nv),1);
$scope.options3.splice($scope.options3.indexOf(nv),1);
}
});
$scope.$watch("selectedItem3", function(nv, ov) {
if (nv != ov) {
$scope.options1.splice($scope.options1.indexOf(nv),1);
$scope.options2.splice($scope.options2.indexOf(nv),1);
}
});
Referring to this question
I am able to successfully apply filter for my table. Now I want to change the way this filter is working. Here is the situation:
I am applying Mapped filter. It filtered out all mapped variables for me. Now I will change the value of one of the filtered variables, as soon as I delete the complete value, the variable is moved to Unmapped list and User is not able to change the variable. User now need to change the filter to either All or UnMapped filter to edit that variable.
Same in the case of Unmapped filter. Select Unmapped filter, as soon as I try entering value, the variable disappears and moved to 'Mapped' list.
What I need to do is to apply filter only when I select filter from drop down using ng-change and when I try to edit some variable the filter should not work.
Here is the code:
For Filter :
$scope.filterOpt = 'All';
$scope.emptyOrNull = function (variable) {
if ($scope.filterOpt == "All")
return true;
if ($scope.filterOpt == "Mapped")
return variable.Name && variable.Variable
if ($scope.filterOpt == "UnMapped")
return !(variable.Variable) ;
}
HTML :
<select class="selectpicker form-control" ng-model="filterOpt" ng-change="emptyOrNull()">
<option value="All">All</option>
<option value="Mapped">Mapped</option>
<option value="UnMapped">Un-Mapped</option>
</select>
and Table:
<tr ng-repeat="var in Mappings | filter: searchVariable | filter : emptyOrNull">
<td>{{var.Name}}</td>
<td>
<div><input-dropdown name="fqn" ng-model="var.Variable" list="variables" ng-disabled="var.IsTrue"></input-dropdown></div>
</td>
</tr>
UI :
In above picture when I select Mapped from filter and try to change/delete Value1 it should not disappear.
Please help.
Basically I don't understand why do you want | filter : emptyOrNull, when you want to update UI only if you change the dropdown value.
Why don't you only update array($scope.Mappings). In this array you can only push values you want to display.
Remove filter and update your dropdown ng-change function like this
Here origArray is your original array, I am just changing scope variables
$scope.emptyOrNull = function (variable) {
$scope.Mappings = [];
if ($scope.filterOpt == "All") {
$scope.Mappings = angular.copy(origArray);
} else {
for (var i = 0; i < origArray.length; i++) {
if ($scope.filterOpt == "Mapped") {
if (origArray[i].Name && origArray[i].Variable) {
$scope.Mappings.push(origArray[i]);
}
}
if ($scope.filterOpt == "UnMapped") {
if (!origArray[i].Variable) {
$scope.Mappings.push(origArray[i]);
}
}
}
}
}
Don't use filter for this kind of requirements, it reduces performance.
What you can do is add a conditional filter. That means apply filter only when you want it to be and don't apply when you don't want.
you can check when input is focused with something like and toggle a variable to disable or enable filter
<input-dropdown name="fqn" ng-model="var.Variable" ng-focus="disable=true" list="variables" ng-disabled="var.IsTrue"></input-dropdown>
And to do conditional filtering use
<tr ng-repeat="var in Mappings | filter : (disable ? '' : emptyOrNull)">
And then you can update the disable to true on changing mapped/unmapped dropdown.
Hope this helps
Currently I'm stuck on a select input field. In the project was used this code:
<select ng-init="crtController.order.orders[$index].quantity = 0" ng-model="crtController.order.orders[$index].quantity" ng-options="value for value in crtController.quantity.values track by value" ng-change="crtController.quantity.check()"></select>
It was using this "quantity" variable:
this.quantity = {
values: [0,1,2,3,4,5,6,7,8,9,10],
decrease: function(index) {
if (vm.order.orders[index].quantity > 0) {
vm.order.orders[index].quantity--;
this.check();
}
},
increase: function(index) {
if (vm.order.orders[index].quantity < 10) {
vm.order.orders[index].quantity++;
this.check();
}
},
check: function() {
this.valid = false;
for (var i = 0; i < vm.order.orders.length; i++) {
if (vm.order.orders[i].quantity > 0) {
this.valid = true;
}
vm.order.orders[i].productId = vm.products[i].id;
}
vm.calculatePrice();
}
}
On the top of this select I've got a variable product.stock. Let's say this is 5. In that case I only want it to show 0,1,2,3,4,5 from the quantity array.
I already tried serveral things:
1. Adding a "where" clause. This didn't seem to work or I implemented it the wrong way of course.
2. Added a filter, not quite sure how this works using the value variable and the product.stock variable but I gave it a try.
3. I tried to change it so the repeat is on a option. This gave the possibility to "hide" options that should not be shown.
<select ng-init="crtController.order.orders[$index].quantity = 0" ng-model="crtController.order.orders[$index].quantity" ng-change="crtController.quantity.check()">
<option ng-repeat="value in crtController.quantity.values track by value" value="{{value}}" ng-hide="product.stock < value" ng-bind="value"></option>
</select>
but that didn't seem to work either as the first value of the selectbox is now empty. Beside that the buttons arround the select option:
<div class="input-group-addon hidden-xs"><a class="min" ng-click="crtController.quantity.decrease($index)">-</a></div>
didn't seem to work anymore. I also have visited a lot of similar Stackoverflow questions but still didn't find my solution. Questions such as:
AngularJs conditional display for ng-options: I don't have this in my array, but didn't work just on a check of two variable.
not sure that i understand question but try to change ng-hide by ng-if inside
or
<option ng-repeat="value in crtController.quantity.values|limitTo:product.stock track by $index" value="{{value}}" ng-if="product.stock >= value" ng-bind="value"></option>
You can try filtering the options
<option ng-repeat="value in crtController.quantity.values track by
value | filterQuantity " value="{{value}}" ng-bind="value"></option>
filters.filter('filterQuantity', function () {
return function(tasks, tags) {
return tasks.filter(function(value) {
...
});
};
});
just play around with this, i hope it helps
I Want to archive to have unique options in a select.
For example:
At first there is only one Select. But you can add infinitely Selects. All Selects use the same array to fill in the options.
The Array is for example [1,2].
If you know select "1" in the first Select, the second Select should only have "2" as an option.
Thanks
Example of how a filter could look like:
JavaScript
app.filter('notInArray', function() {
return function(inputArray, filterArray) {
if (inputArray) {
return inputArray.filter(function (item) {
return !filterArray || filterArray.indexOf(item) === -1;
});
}
return [];
}
});
Usage:
<select data-ng-model="mySelect" data-ng-options="item as item.Name for item in items | notInArray:mySelected">
<option value="">-- Choose option --</option>
</select>
And then maybe have a $watch on mySelect that adds it to mySelectedand sets mySelect to null. This way you only need one select. You should probably implement a way to remove options from the mySelected array also.
Example of this:
JavaScript
$scope.$watch("mySelect", function(){
if($scope.mySelect){
$scope.mySelected.push($scope.mySelect);
$scope.mySelect = null;
}
});
$scope.removeOption = function(option){
$scope.mySelected.splice($scope.mySelected.indexOf(option), 1);
}
I'm trying display data from an array in a select using ng-options and I want filter it which is not working. I don't want to show object having billHeadShortForm=FEC & FDG
Here is my HTML
<select class="form-control" ng-init="getBillHeadCurrentProjWise()" ng-model="headID" ng-options="h.billHeadID as h.billHead for h in billHeadsProjWise | filter:h.billHeadShortForm!='FEC' | h.billHeadShortForm!='FDG'">
<option value="">--Select Billing Head--</option>
</select>
I have found solution
$scope.myFunction = function (Billhead) {
if (Billhead.billHeadShortForm == 'FEC' || Billhead.billHeadShortForm == 'FDG' || Billhead.billHeadShortForm == 'GL') {
return false;
} else {
return true;
}
}
ng-options="h.billHeadID as h.billHead for h in billHeadsProjWise | filter:myFunction"
Adjust the filter part of the ng-options to the following:
ng-options="... | filter: {billHeadShortForm: '!FEC'} | filter: {billHeadShortForm: '!FDG'}"
See fiddle
Although, you might want to read filter documentation, and write a function to avoid piping two filters.
Edit:
The function could be something like that:
$scope.filterBillHead = function (billHead) {
// Exclude 'FEC' and 'FDG'
// return true if billHeadShortForm is not in the array, false otherwise
return ['FEC', 'FDG'].indexOf(billHead.billHeadShortForm) < 0;
}
Template:
ng-options="... | filter: filterBillHead"
See updated fiddle