I am trying to create a select component. In which I need to select an option based on the value in object.
Found something similar here
Implemented same:
<select>
<option value="" selected disabled >Select </option>
{{#each sourceTypes as |sourceType|}}
<option value={{sourceType.id}} selected={{if (eq sourceType.id selectedOption) 'true'}}>{{sourceType.type}}</option>
{{/each}}
</select>
Here sourceType.id is id for current option and selectedOption is sourceType reference in source object. Type is number in REST service response for both of them.
When I tried to print value of eq sourceType.id selectedOption in option it is giving me false. Then I checked for eq documentation, it is a === b
Why is it giving false even if value and type both are same.
Is there any way to just check for value like a == b.
Is there any way to just check for value like a == b.
You can implement a custom helper that does this (see https://guides.emberjs.com/v2.17.0/templates/writing-helpers/)
import { helper } from "#ember/component/helper"
export default helper(function([a, b]) {
return a == b;
});
Related
Let suppose that we have the following datalist, and a js variable var carID = '':
<input list="options" #change='${carID = e.target.value}'>
<datalist id="options">
<option value="ID_1">Ferrari</option>
<option value="ID_2">Lamborghini</option>
<option value="ID_3">Jeep</option>
</datalist>
I'd like to show ONLY the car names in my options, and NOT the option values (that are the IDs of the cars), and have the ID of the selected car (the value of the selected option) stored in the variable, not the car name.
I tried different solutions, I post 2 of them (one totally wrong and one right but not complete, I 've found this one in other stack overflow questions):
wrong: it simply doesn't work, e.target.carID is ''.
<input list="options" #change="${carID = e.target.carID}">
<datalist id="options">
<option carID="ID_1" value="Ferrari"></option>
<option carID="ID_2" value="Lamborghini"></option>
<option carID="ID_3" value="Jeep"></option>
</datalist>
Ok it's working, but what if I have 2 cars with the same name and different id? Yes, the second car is ignored and if I select the 2nd car I store the 1st car's ID.
<input id='inputID' list="options" #change='${this.getValue}'>
<datalist id="options">
<option data-value="ID_1" value="Ferrari"></option>
<option data-value="ID_2" value="Lamborghini"></option>
<option data-value="ID_3" value="Jeep"></option>
<option data-value="ID_4" value="Jeep"></option>
</datalist>
js:
getValue(){
let shownValue = this.shadowRoot.getElementById('inputID').value;
let rightValue =
this.shadowRoot.querySelector("#options[value='"+shownValue+"']").dataset.value;
carID = rightValue;
}
I cannot use JQuery. Do you have any solutions? Thanks!
Your code #change='${carID = e.target.carID}' cannot work, as the right hand side of the event handler binding is not callable. You need to wrap it inside an anonymous function, e.g. like so: #change=${(e) => { this.carID = e.target.value }}
That being said, this is what I understood you want to do:
Have a list, where the user can choose from.
In the list, only display the name of the car, not the ID.
Store the selected car's ID in carID, not the name.
I see two ways to do that.
Option 1: Use <select>
If the list of cars is fixed, I think you will be best served using a <select height="1"> element, resulting in a drop down box. Including the little event handler, it looks something like this:
<select #change=${(e) => { this.carID = e.target.value }}>
<option value="ID_1">Ferrari</option>
<option value="ID_2">Lamborghini</option>
<option value="ID_3">Jeep</option>
<option value="ID_4">Jeep</option>
</select>
This will display the text from the text content of the <option> elements, but set the value of the <select> from the <option>'s value attribute, and by the virtue of the onchange event handler will set the carID field on the element.
You can even have two cars with different IDs, but the same name. Note however, that your users would not know, if the display text is the same, which of the two "Jeep" entries to choose. So that might not be a good idea (but I don't know your full use case).
Option 2: Use <input> with <datalist>
Now, if the list of cars is not fixed, i.e. the users are allowed to enter arbitrary data and the selection list is not for limiting their choices, but to help them (prevent typos, speed-up entry) you can use an <input> with an associated <datalist>. But the popup will display both, the <option>'s value and text content (if they are both defined and different). If you insist on only showing the name of the car, not the ID, then the name has to go in the value attribute of the <option> (or the text content). While you could put the ID in the dataset, you really don't need to.
In any case you'll need to map the value string back to the ID through your own code. This will only work if "cars and names" is a one-to-one (aka bijective) mapping, so no two cars with the exact same name would be allowed. (Otherwise your code cannot know which one has been selected just by looking at the name.)
const CARS_BY_ID = {
ID_1: 'Ferrari',
ID_2: 'Lamborghini',
ID_3: 'Jeep',
}
class MyElem extends LitElement {
constructor() {
super();
this.carID = null;
}
render() {
return html`
<input list="myopts" #change=${this.carChanged}>
<datalist id="myopts">
${Object.values(CARS_BY_ID).map((name) => html`<option>${name}</option>`)}
</datalist>`;
}
carChanged(e) {
const name = e.target.value;
this.carID = null;
for (const [key, value] of Object.entries(CARS_BY_ID)) {
if (value === name) {
this.carID = key;
}
}
console.log(`this.carID = ${this.carID}`);
}
}
Note, that in this example the user can e.g. enter "Bugatti" and this.carID will be null.
Also note, that this.carID has not been registered as a lit-element property (it's not listed in static get properties), so there will be no update lifecycle triggered, and no re-rendering happens upon that change.
I want to display a select with all the option of my enum and change the value to update my database.
To do so:
I have an enum:
export enum SubscriptionEnum {
DAILY= 'DAILY',
ANNUAL= 'ANNUAL',
HALF-YEARLY = 'HALF-YEARLY ',
QUARTERLY = 'QUARTERLY ',
MONTHLY = 'MONTHLY ',
}
In my .ts file i create my enum var:
SubscriptionEnum = SubscriptionEnum ;
And then i display the option in my .html:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select #subscriptionid="subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
This example give me the select with all option and the value change in the view page when i clicked on a new option.
Then, i add the (change) in the select to call a method that change the content of the client subscription in the db. I did it like that:
.html:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select (change)="changeInfo(subscription )" #subscription id="subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
In my changeInfo i send the event and take the event.id and the event.value to update my db and it works because the select option change when i click on it and the <p>{{client.subscription}}</p> that is a value of my db take the good value.
Then i wanted to add a selector so my option value take directly the good value and this is not working ...
I add it like that:
<p>{{client.subscription}}</p> // here it display what is registered in my db, in this case "ANNUAL"
<label for="subscription">Subscription:</label>
<select (change)="changeInfo(subscription )" #subscription id="subscription">
<option value="{{option.key}}"
selected="{{option.key == client.subscription}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}}
</option>
</select>
This give highlight me my sentence and tell me "Wrong attribute method" and when i reload my page my div contains the good value which is "ANNUAL" but my option is equal to QUARTERLY. If i click to change the option, the good value will be saved in my db but the display of my select selector will be wrong.
What do i not understand ? Thank you for your help
There is a subtle difference between two similar Angular syntaxes:
selected="{{option.key == client.subscription}}"
and
[selected]="option.key == client.subscription"
There are both property bindings but the former assigns interpolated value to property.
It means that even in case of falsy values selected property will get true;
el.selected = 'false'
because string is a truthy value in js.
So you can consider the following options:
Use correct property binding:
[selected]="option.key == client.subscription"
Use value binding on <select> tag instead:
<select #subscription id="subscription" [value]="client.subscription">
<option value="{{option.key}}"
*ngFor="let option of SubscriptionEnum | keyvalue">
{{option.value}} {{option.key == client.subscription}}
</option>
</select>
I'm developing an Angular 2 app with ASP.NET Core 2.0 using the Visual Studio 2017 ASP.NET Angular Web application template.
I have a controller whose method get returns all the legislations that I'm using in my app (they come from an Enum):
[Route("api/[controller]")]
public class LawController : Controller
{
[HttpGet]
public IEnumerable<Models.LawPresentation> Get()
{
List<LawPresentation> laws = new List<LawPresentation>();
// Arrange
byte[] values = (byte[])Enum.GetValues(typeof(LawTypes));
foreach (byte value in values)
{
string enumName = Enum.GetName(typeof(LawTypes), value);
LawPresentation law = new LawPresentation()
{
Value = value,
Name = enumName
};
laws.Add(law);
}
return laws;
}
}
I this is the component that shows all these values in a select:
<p *ngIf="!laws"><em>Loading...</em></p>
Legislaciones:
<select>
<option *ngFor="let l of laws" [ngValue]="l">{{l.name}}</option>
</select>
I don't think that return the default value (a blank option) from the controller is a good idea, so I wondering if I can add something to the html component to add the default option.
Is there any way to add the default option to the select into the html component?
I would do something like this:
<p *ngIf="!laws"><em>Loading...</em></p>
Legislaciones:
<select>
<option></option>
<option *ngFor="let l of laws" [ngValue]="l">{{l.name}}</option>
</select>
You can add a default option as below.
selected property will make option selected at initial.
disable property will restrict option to be selected by user.
You can remove them as per requirement
<p *ngIf="!laws"><em>Loading...</em></p>
Legislaciones:
<select>
<option value="" selected disabled>SELECT</option>
<option *ngFor="let l of laws" [ngValue]="l">{{l.name}}</option>
</select>
I have dynamically generated multiple select elements in a page. And I have used
v-model = "selected_option"
for getting the value of the option selected . But all the select elements in the page have different option values and none of the select elements have any common default option value. All the select elements need to have the first option element as the default selected value. But if I write
selected_option = ''
then all the select elements are showing blank by default.
I can get the first option value as the default selected value if I remove
v-model = "selected_option"
and
selected_option = ''
but then I am not being able to get the selected value in the #change method . Here is my code
<div v-if="row.answer_input_type === 'Dropdown'">
<template v-for="answer in answers">
<template v-if="answer.AnswerTypeID === row.answer_type_id">
<select class="dropdown_cl" v-bind:disabled="row.is_enabled == 1 ? false : true" #change="selectChange(row.question_id)" v-model="selected_option">
<option v-for="option in answer.AnswerDescription" v-bind:value="option.AnswerMasterID" >{{option.AnswerDescription}}</option>
</select>
<p v-for="option in answer.AnswerDescription">{{option.AnswerMasterID}}</p>
</template>
</template>
</div>
the default value has been assigned as follows -
el : '...'
data : {
...
selected_option: '';
},
methods: {
selectChange: function(question_id) {
var self=this;
alert(question_id + " " + self.selected_option);
},
...
},
....
I need each select to have the first option as the default selected value. How can I do this? thanks
Here is a quick example of what I was explaining in comments.
<select v-for="answer in answers"
v-model="answer.selectedOption">
<option v-for="option in answer.options"
:value="option">
{{option}}
</option>
</select>
Example.
If you take this approach, you can manage the default option for each individual select. You also will know what was selected for each answer automatically.
Basically i have a select dropdown
<select class="form-control" id="ursel"
ng-change="changeVal()"
ng-options="a for a in RatedVoltage" data-ng-model="TechCharacters.selectedUr">
<option value="" selected="selected">{{globalLangResource.SelectAny}}</option>
</select>
So on change of this select, have results reflecting to another select
viewModel.changeVal = function(){
var val = viewModel.TechCharacters.selectedUr;
if (val != undefined && val === "7.2kV") {
$rootScope.ud = viewModel.InsulationVoltage["7.2kV"]; // 20,30,40
}
}
The 2nd dropdown looks like this
<select class="form-control" id="udsel"
ng-change="setUd();"
ng-options="a for a in ud" data-ng-model="TechCharacters.InsulVolt">
<option value="" ng-if="false"></option>
</select>
Now i have a submit button, on submit,i am getting the main object.
console.log(TechCharacters);
Here i am not getting TechCharacters.InsulVolt value. it is showing empty.
If i have made change is the 2nd dropdown, the model is updated. until then i am not getting the changed model from 1st dropdown
Basically i want all the ng-model values inside form even it is changed or not.
if you want the first object of second dropdown on change of first one. change code to .
viewModel.changeVal = function(){
var val = viewModel.TechCharacters.selectedUr;
if (val != undefined && val === "7.2kV") {
$rootScope.ud = viewModel.InsulationVoltage["7.2kV"]; // 20,30,40
viewModel.TechCharacters.InsulVolt=$rootScope.ud[0]
}
}
hope it will help you
You can actually do this. This will work.
<select data-ng-model="TechCharacters.selectedUr"
<option ng-selected="{{obj == TechCharacters.selectedUr}}" value="{{obj}}" ng-repeat="(key,value) in RatedVoltage">
</select>
Basically you are doing ng-selected and comparing the ng-model value with that of the ng repeat value, and the selected value will be shown.