I need to implement 2 different sort operation on two different columns of datagrid, Its becoming tough by using 2 different select boxes. I tried with below code, as I new to this i couldn't solved this...
In HTML:
<select ng-model="reverse">
<option value="false">Top Sr</option>
<option value="true">Bottom Sr</option>
</select>
<select ng-model="reverse">
<option value="false">Top Rank</option>
<option value="true">Bottom Rank</option>
</select>
In datagrid:
<tr ng-repeat="items in empList | orderBy : ['-TR', 'SR']" >
In controller:
In controller : $scope.reverse = false;
I would recommend you following solution:
<select ng-model="sr">
<option value="+sr">Top Sr</option>
<option value="-sr">Bottom Sr</option>
</select>
<select ng-model="tr">
<option value="+tr">Top Rank</option>
<option value="-tr">Bottom Rank</option>
</select>
Then you should apply following ng-repeat statement to table:
<tr ng-repeat="items in empList | orderBy : [tr, sr]" >
And also set default values in controller:
$scope.sr = '+sr';
$scope.tr = '+tr';
You should substitute 'sr' and 'tr' with your objects (single element from empList) properties names that you want to sort by.
When you modify $scope variables via selecting other option in select then it's automatically evaluated into correct orderBy statement, ex:
<tr ng-repeat="items in empList | orderBy : [sr, tr]" >
Here is updated plunker. I've modified property name to 'tr' and now it works, but I'm not sure if that's what you wanted -> currently it'll sort by first column and only if values are equal then it'll compare objects by another property (which is 'tr').
UPDATE:
If you want to always sort by property associated with recently changed dropdown then you need to change a bit (another plunker):
1)add this initialization:
$scope.srRecentlyChanged = true;
2)add event on selects change:
<select ng-model="sr" ng-change="srRecentlyChanged = true;">
<option value="+sr">Top Sr</option>
<option value="-sr">Bottom Sr</option>
</select>
<select ng-model="tr" ng-change="srRecentlyChanged = false;">
<option value="+tr">Top Rank</option>
<option value="-tr">Bottom Rank</option>
</select>
3)modify orderBy expression:
<tr ng-repeat="items in empList | orderBy : (srRecentlyChanged? sr : tr)" >
Related
In the past I was able to pass out the 'object' that was used for the select options. I'd like to capture that information off a regular select, but I cannot remember how.
So When you do an *ngFor in your select option, you specify a N of N's like this
<option *ngFor="let thing of things" value= {{thing.name}}>
{{thing.family}} - {{thing.name}}
</option>
I'm hoping I can get that 'whole' thing that was selected, by calling a function on change.
<select class="form-control input-sm "
(change)="changeThing($event)"
name="thing"
formControlName="thing" >
<option *ngFor="let thing of things" value= {{thing.name}}>
{{thing.family}} - {{thing.name}}
</option>
</select>
because I want to change some form options based on the 'family' of the thing, not the value that gets passed.
my function looks like this.
changeThing (thing) {
console.log('thing:', thing);
selectedFamily = ??;
}
The $event is probably the wrong thing to be looking at - I can get the value selected there, but I cannot find the whole "thing" that was selected.
Thanks for any help.
You can do that with the help of index
Template Side :
<select class="form-control input-sm "
[(ngModel)]="selectedValue"
(change)="changeThing($event.target.value)"
name="thing" >
<option *ngFor="let thing of things; let i = index;" [value]="i">
{{thing.family}} - {{thing.name}}
</option>
</select>
Component Side :
changeThing(index){
alert(this.things[index].family +' '+this.things[index].name );
console.log(this.things[index]);
}
WORKING DEMO
I hope it will help
<option *ngFor="let thing of things" value= {{thing}}>
{{thing.family}} - {{thing.name}}
</option>
You can use ngModel with ngModelChange
<select [(ngModel)] ="selectedType" (ngModelChange)="changeThing(selectedType)">
<option *ngFor="let thing of things" [ngValue]="thing ">
{{type.name}}
</option>
</select>
I have 2 arrays out of which 1 array values are bound to select dropdown values.
On clearing of another array, I want to render only one option.
Following is the code:
Component
#Component({
selector: 'my-app',
templateUrl : 'app/app.html'
})
export class AppComponent {
arrToClear = [1,2,3,4];
arrToBind = ["NONE", "SOME", "OTHER"];
modelToBind = 'NONE';
}
View
MODEL -> {{modelToBind}}
<button type='button'(click)="arrToClear.length = 0; modelToBind = 'NONE'">Clear Array </button>
<select class="form-control"
id="someId"
name="someName"
[ngModel]="modelToBind"
#someName="ngModel"
>
<ng-container *ngIf="arrToClear.length">
<option *ngFor="let data of arrToBind"
[ngValue]="data"> {{data}}
</option>
</ng-container>
<option value="NONE" *ngIf="!arrToClear.length">
Value
</option>
</select>
Problem is, when I clear "arrToClearArr" array, my selected value is empty. It should get bound to "A" because my model contains "A".
Additionally, I want only one-way binding hence I have used [ngModel].
What am I missing here? Any help will be appreciated.
Thanks.
Plunker Link
Expected behavior:
Change dropdown value
Click 'Clear array' button
Dropdown value should be "A", currently, it is ""
This is optional but personally I would not use the [ngModel] and try using Template-driven forms for this issue as I believe it would be clearer to just bind the variable directly.Just as you did with the for loop.
<select class="form-control" id="someId" formControlName="someName" name="someName">
<ng-container *ngIf="arrToClear.length">
<option *ngFor="let data of arrToBind" [value]="data"> {{data}}</option>
</ng-container>
<option [value]="modelToBind" *ngIf="!arrToClear.length">{{modelToBind}</option>
</select>
Alternatively could you not keep everything the same and just edit the last option.
<select class="form-control" id="someId" [ngModel]="modelToBind" #someName="ngModel" name="someName">
<ng-container *ngIf="arrToClear.length">
<option *ngFor="let data of arrToBind" [ngValue]="data"> {{data}}</option>
</ng-container>
<option [value]="modelToBind" *ngIf="!arrToClear.length">{{modelToBind}</option>
</select>
I am creating a template for showing Select fields in my app. However I have 4 different types of select field. value = id, value = name, value = static_id and value = static_name (it's complicated...).
I plan to migrate these to ngOptions if possible in the future, but for now I am attempting to have a single select template, that will handle all 4 types of field.
I currently use an ng-if to show the different 'static' code for a select, but this creates a lot of code that I want to reduce into this single template.
Here's some code:
// shows a basic select field where option value = id
<div ng-if="field.type=='select'" class="form-group">
<select-field></select-field>
</div>
// shows a basic select field where option value = name
<div ng-if="field.type=='select_name'" class="form-group">
<select-field></select-field>
</div>
// shows a basic select field where option value = static_id
<div ng-if="field.type=='select_static_id'" class="form-group">
<select-field></select-field>
</div>
// shows a basic select field where option value = static_name
<div ng-if="field.type=='select_static_name'" class="form-group">
<select-field></select-field>
</div>
Here, all the field attributes are identical, except for the generated options. Hence why I want to template this.
I am attempting to have this single template have another ng-if inside that will detect the field type, from the JSON it reads, and then change the options displayed accordingly, like this (2 of the 4 examples shown):
<select
name={{field.name}}
class="form-control form-field {{relationshipUrl}}"
id={{field.name}}
data-is-autofocus={{field.focus}}
data-selectreq={{field.rules.selectreq}}
data-showhide={{field.rules.showhide}}
>
<option value="" selected>Please select...</option>
<span ng-if="field.type=='select'">
<option
value={{option.id}}
ng-repeat="option in cache[field.relationshipURL] | orderBy:'name || firstName'"
ng-selected="formData[field.name] == option.id">
{{option.name || option.firstName}}
</option>
</span>
<span ng-if="field.type=='select_static_name'">
<option
value={{option.name}}
ng-repeat="option in cache[field.relationshipURL] | orderBy:'name'"
ng-selected="formData[field.name] == option.name">
{{option.name}}
</option>
</span>
</select>
Possibly horrible code to use a span within the select, but that's why I am coming to you good people. Currently this works in that it shows the correct options, however, it shows the options listed out twice, and I assume it will list them 4 times once all the option types are included. I hope that makes sense. Thanks in advance.
Well no sooner had I posted, the answer was blindingly obvious. Instead of the above approach by removing the span and putting the ng-if on the <option> instead fixed the issue and it works perfectly!
<select
name={{field.name}}
class="form-control form-field {{relationshipUrl}}"
id={{field.name}}
data-is-autofocus={{field.focus}}
data-selectreq={{field.rules.selectreq}}
data-showhide={{field.rules.showhide}}
>
<option value="" selected>Please select...</option>
<option ng-if="field.type=='select'"
value={{option.id}}
ng-repeat="option in cache[field.relationshipURL] | orderBy:'name || firstName'"
ng-selected="formData[field.name] == option.id">
{{option.name || option.firstName}}
</option>
<option ng-if="field.type=='select_name'"
value={{option.name}}
ng-repeat="option in cache[field.relationshipURL] | orderBy:'name'"
ng-selected="formData[field.name] == option.name" >
{{option.name}}
</option>
<option ng-if="field.type=='select_static_id'"
value={{option.id}}
ng-repeat="option in cache[field.relationshipURL] | orderBy:'name'"
ng-selected="formData[field.name] == option.id" >
{{option.name}}
</option>
<option ng-if="field.type=='select_static_name'"
value={{option.name}}
ng-repeat="option in cache[field.relationshipURL] | orderBy:'name'"
ng-selected="formData[field.name] == option.name">
{{option.name}}
</option>
</select>
Thank you anyway #charlietfl very quick response.
I'm a bit late for the answer, but I managed to make a working JSFIDDLE of what I hoped you tried to accomplish.
I factorized your code into a single select and added another select to show you how to display either only one, or all of them.
<div>
<select ng-model="selector">
<option value=""></option>
<option value="">Show everything</option>
<option ng-repeat="option in Options" value="{{option.type}}">{{option.type}}</option>
</select>
</div>
<div ng-repeat="option in Options" ng-show="$parent.selector == option.type || $parent.selector == ''">
{{option.type}}
<select>
<option ng-repeat="choice in option.choices" value="{{choice}}">{{choice}}</option>
</select>
</div>
And the data :
$scope.Options = [
{type:"id", choices:["0", "1", "2"]},
{type:"name", choices:["John", "Doe", "Smith"]},
{type:"static_id", choices:["3", "4", "5"]},
{type:"static_name", choices:["Static 1", "Static 2", "Static 3"]},
];
In html
<select class="element-margin-top" ng-model="vm.selectedRole" ng-options="(roleName,enabled) in vm.roleNames">
<option value="">All Roles</option>{{vm.roles[0]}}
</select>
I want to display all the array elements in select options.I dont understand what is going on in this.It is giving me error related to (roleName,enabled) in vm.roleNames
In js:
var vm = this;
vm.roleNames = ['SuperAdmin','Admin','Retailer','Manufacturer'];
vm.selectedRole = vm.roleNames[-1];
I want first element to be selected by default.
ng-options="(roleName,enabled) in vm.roleNames" in this case, vm.roleNames is an array, so, roleName is the index and enabled is the real "roleName"
So your code should looks like this:
<select class="element-margin-top" ng-model="vm.selectedRole" ng-options="(index,roleName) as roleName in vm.roleNames">
<option value="">All Roles</option>
</select>
try this , for first selected by defult you can use $first
<select ng-model="selectedRole">
<option ng-repeat="name in roleNames "
ng-selected="$first" value="{{name}}">{{name}}</option>
</select>
In html:
<select class="element-margin-top" ng-model="vm.selectedOption">
<option value="">All Roles</option>
<option ng-repeat="item in vm.optionNames" value="{{item}}">{{item}}</option>
</select>
in js:-
vm.optionNames = ['User', 'Account', 'Brand'];
vm.selectedOption = vm.optionNames[-1];
try reading http://www.undefinednull.com/2014/08/11/a-brief-walk-through-of-the-ng-options-in-angularjs/
is there in AngularJS a nice way that it is possible to hide the selected value from the first select picker in the second one?
If I select another value in the first one it need's to be visible again in the second one.
I wrote something with pure javascript that works but it's like magic code that you never want to touch.
Thanks for your help.
You just need to add a filter to the second <select>. The negative filter's syntax is as follows:
items | filter: "!somevalue"
or
items | filter: "!" + var
for var variable that contains the filtered out string.
So, the full solution looks like so:
<select ng-model="select1"
ng-options = "item for item in items" ng-change="select2 = undefined">
<option value="">select 1</option>
</select>
<select ng-model="select2"
ng-options = "item for item in items | filter: '!' + select1">
<option value="">select 2</option>
</select>
plunker
EDIT:
If the order of the selection should not matter, then you could filter as follows:
<select ng-model="select1" ng-options="item for item in items | filter: filter1"
ng-change="filter2 = select1 ? '!' + select1 : undefined">
<option value="">select 1</option>
</select>
<select ng-model="select2" ng-options="item for item in items | filter: filter2"
ng-change="filter1 = select2 ? '!' + select2 : undefined">
<option value="">select 2</option>
</select>
(when filter expression is undefined the filter doesn't apply)
plunker 2