Conditionally showing options in a select with Angular - javascript

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"]},
];

Related

drop-down selected option old value editing is in not working in laravel

I am trying to show the selected option value of drop-down and just used blew code and that's now working even I used the same trick for another table data and that is working fine. But I don't know why it's not working?
public function userEdit($id) {
$user = User::find($id);
$userType = User::first()->userType;
$isActive = User::first()->isActive;
$allRoles=Role::all();
$role_user = $user->roles()->pluck('user_id','role_id')->toArray();
return view('admin\userEdit',compact('user','allRoles','userType','isActive','role_user','selectedRole'));
}
<div class="form-group">
<label class="control-label col-md-3">User Type
<span class="required" aria-required="true"> * </span>
</label>
<div class="col-md-6">
<div class="input-icon right">
<i class="fa"></i>
<select class="form-control"
name="userType">
<option #if(old('userType',$userType) == 'host') selected #endif>
host
</option>
<option #if(old('userType',$userType) == 'visitor') selected #endif>
visitor
</option>
<option #if(old('userType',$userType) == 'admin') selected #endif>
admin
</option>
<option #if(old('userType',$userType) == 'operator') selected #endif>
operator
</option>
</select>
</div>
</div>
Can anyone help me to fix this that will show my old value when user will edit the data?
i used to have the same question and i had to do it the unprofessional way, we all know select is not restricted for repeating options in it so i used that hack. For your case i would do something like :
<select class="form-control"
name="userType">
<option value"{{ $userType }}"> {{ $userType }} </option>
<option value"host"> host </option>
<option value"admin"> admin </option>
<option value"visitor"> visitor </option>
<option value"operator"> operator </option>
</select>
For your variables you are sending to the blade file can you try this code to make sure you dont get the same userType, isActive and all
$user = User::find($id);
$userType = $user->userType;
$isActive = $user->isActive;
$allRoles=Role::all();
$role_user = $user->roles()->pluck('user_id','role_id')->toArray();
I am so confident this is not the best way to go about it but it solves your problem currently.
Even if $userType be host, it will give you host when posting the form

angular2 getting the whole object selected in a select box

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>

Setting 'selected' option for select element in Vue.js

I have an array- selected_players, which I am looping through in Vue.js, but am not able to set the selected attribute of an option.
What I am trying: :selected="player.round.best_player == 1"
Here is the section of the related template:
<div v-if="selected_players.length && ! loading">
<h4>Select Best Player</h4>
<div class="form-group">
<select name="best-player" id="best-player" v-model="best_player" class="form-control">
<option v-for="player in selected_players" :value="player.id" :selected="player.round.best_player == 1">{{ player.name }}</option>
</select>
</div>
<br />
When loaded, this is the related HTML:
<select name="best-player" id="best-player" class="form-control">
<option value="1">Ashley</option>
</select>
How can I achieve this?
To have a selected option, you can just set the best_player as the one you want to have by default selected.
With below code I am iterating over your player array and finding the player which has round.best_player === 1. The idea is to set the best_player with the selected option.
best_player = player.filter(p => p.round.best_player === 1).id

AngularJS 1.4.8 creates an empty option in select when my model is updated

I have a service where you can select different types of agreement documents. When I load the page for the first time, the agreement drop down is always populated correctly and the correct value is displayed in the browser. The agreement is fetched from the vm.getAgreement() function. Like this:
However it is also possible to update the AgreementDocumentType. This is done by calling the vm.save() function which in turn calls vm.getAgreement() again. I debugged the code to see when the error happens and it is when vm.agreement = data; is set for the second time. The object data is however exactly the same as the first time, vm.agreement.AgreementDocumentType is 3. Every other field is updated correctly but the select list looks like this after save:
Looking at the generated HTML the weird thing is that the option with value 3 is marked as selected, as it should be, but still no value is displayed in the drop down list: value="3" selected="selected">. If I then select Agreement3 or any other value the empty value (<option value="? number:3 ?"></option>) directly disappears from the list. I'm using AngularJS version 1.4.8 if it can be of any help. My best guess is that when vm.agreement.AgreementDocumentType is re-populated the binding is lost for a split second and therefore an empty value is created and for some reason not removed until the drop down is interacted with. Has anyone experienced this and solved it?
Generated HTML:
<select name="Agreement" class="form-control ng-valid ng-valid-required ng-dirty ng-touched" ng-model="vm.agreement.AgreementDocumentType" required="">
<option value="? number:3 ?"></option>
<!-- ngRepeat: option in vm.agreementTypes -->
<option ng-selected="vm.agreement.AgreementDocumentType == option.id" ng-repeat="option in vm.agreementTypes" ng-value="option.id" class="ng-binding ng-scope" value="1">
Agreement1
</option>
<!-- end ngRepeat: option in vm.agreementTypes -->
<option ng-selected="vm.agreement.AgreementDocumentType == option.id" ng-repeat="option in vm.agreementTypes" ng-value="option.id" class="ng-binding ng-scope" value="2">
Agreement2
</option>
<!-- end ngRepeat: option in vm.agreementTypes -->
<option ng-selected="vm.agreement.AgreementDocumentType == option.id" ng-repeat="option in vm.agreementTypes" ng-value="option.id" class="ng-binding ng-scope" value="3" selected="selected">
Agreement3
</option>
<!-- end ngRepeat: option in vm.agreementTypes -->
</select>
Html:
<select name="Agreement" class="form-control" ng-model="vm.agreement.AgreementDocumentType" required>
<option ng-selected="vm.agreement.AgreementDocumentType == option.id"
ng-repeat="option in vm.agreementTypes"
ng-value="option.id">
{{option.label}}
</option>
</select>
Controller:
vm.agreementTypes = [
{ id: 1, label: 'Agreement1' },
{ id: 2, label: 'Agreement2' },
{ id: 3, label: 'Agreement3' }
];
vm.save = function () {
agreementResource.update({ agreementId: vm.agreementId }, vm.agreement).$promise.then(function () {
toastr.success('Agreement saved');
vm.getAgreement();
});
};
vm.getAgreement = function () {
agreementResource.get({ agreementId: vm.agreementId }).$promise.then(function (data) {
vm.agreement = data;
});
}
vm.getAgreement();
I think because you are building the options manually, angularjs internals are not binding your model properly when it gets changed from scope side, there is more than selected="selected" to do, this internal are made by the ngOptions directive, consider using it instead of building your options list manually.
<select
name="Agreement"
class="form-control"
ng-model="vm.agreement.AgreementDocumentType"
ng-options="option.id as option.label for option in vm.agreementTypes"
required>
</select>

Detect changing of the select list value with AngularJS

I tried using ng-change on select but the problem is, I need to send ticket.id to the method but, ticket.name to model.
<select name="ticketAttendeeMapping"
ng-model="attendee.ticketTypeName"
class="form-control">
<option ng-repeat="ticket in inTransitionTickets | filter: greaterThan('countRemaining', 0)"
ng-value="ticket.name"
ng-click="onAttendeeTicketmapping(ticket.id, $parent.$index)">
{{ticket.name}}
</option>
</select>
I also tried doing this:
<select name="ticketAttendeeMapping"
ng-model="attendee.ticketTypeName" class="form-control"
ng-options="ticket.name as ticket.name for ticket in inTransitionTickets | filter: greaterThan('countRemaining', 0)"
ng-change="onAttendeeTicketmapping(ticket.id, $index)">
<option value="" disabled>Choose Your Ticket</option>
</select>
The easiest way is to just use the object in the model:
<select name="ticketAttendeeMapping" ng-model="attendee.ticket" class="form-control" ng-options="ticket.name for ticket in inTransitionTickets" ng-change="change(attendee.ticket.id)">
</select>
Then you can access the name by using $scope.attendee.ticket.name and you can access the id by using $scope.attendee.ticket.id
Plunkr
try to do this:
<select name="ticketAttendeeMapping" ng-model="attendee.ticketTypeName" class="form-control" ng-options="ticket.name as ticket for ticket in inTransitionTickets | filter: greaterThan('countRemaining', 0)" ng-change="onAttendeeTicketmapping(attendee.ticketTypeName, $index)">
<option value="" disabled>Choose Your Ticket</option>
</select>
now you will get ticket i.e."attendee.ticketTypeName" object in ur ng-change method. where u can get its "id"
I am not sure, If what I have done here is what was originally asked by OP.
We can't use ng-options here simply!!
because while we use "ng-options" it restricts our access to current selected Json element to the properties explicitly mentioned in ng-options, on the contrary ng-repeat gives you complete access to current Object.
<select name="ticketAttendeeMapping"
ng-model="SelectedTicketNameFromngModel"
class="form-control">
<option ng-repeat="ticket in ticketJson "
ng-value="ticket.name"
ng-click="alertMe(ticket.id)">
{{ticket.name}}
</option>
</select>
$scope.SelectedTicketNameFromngModel = '';
$scope.selectTicketIdFromMethod = '';
$scope.ticketJson = [{'name':'tick1','id':'t1'},{'name':'tick2','id':'t2'},{'name':'tick3','id':'t3'}];
$scope.alertMe = function(tId){
$scope.selectTicketIdFromMethod = tId;
}
http://jsfiddle.net/HB7LU/16124/

Categories

Resources