Accessing Object properties, from HTML Select. - html

Scenario:
I am trying to access a property (code) of a ng-Model object (myRide).
I've tried doing this by
<select ng-model = "myRide"
ng-change = "getCode(myRide.code)">
...and at getCode,
alert(parameter) //which should be myRide.code.
I've also tried to do this by
<select ng-model = "myRide"
ng-change = getCode(myRide)
(Note: 'myRide' is passed, not 'myRide.code') ...and at getCode,
alert(myRide.code).
myRide does indeed contain a property called 'code', which is not undefined.
Problem: Both tries do not produce the wanted outcome.
How can I make it display the property (code)?
Here is the JSFiddle: http://jsfiddle.net/a2J6z/1/

The better way to do this is to restructure the view. Instead of using ng-repeat on options inside of a select, use the ng-options directive. Then, you can bind the actual object to the model instead of just a JSON string, which is what your current fiddle is doing.
Your new select looks like
<select ng-options="car.Name for car in myGarage" ng-model="myRide" ng-change="getCode(myRide)">
</select>
Then in your controller
$scope.getCode = function(car){
alert(car.code);
}
An updated fiddle:
http://jsfiddle.net/a2J6z/5/

I updated the fiddle:
http://jsfiddle.net/a2J6z/3/
var ngApp = angular.module('ngAppl',[]);
function aControlla($scope){
$scope.myRide = "bus";
$scope.getCode = function(car){
alert(JSON.parse(car).code);
}
$scope.myGarage = [
{Name: "Toyota 86", code:"1"},
{Name: "Hyundai Genesis Coupe", code:"2"},
{Name: "Nissan GTR", code:"3"},
{Name: "Veyron", code:"4"}
];
};
And
<div ng-app="ngAppl">
<div ng-controller="aControlla">
<select ng-model="myRide" ng-change="getCode(myRide)">
<option ng-repeat="car in myGarage">{{car}}</option>
<!--Note: value of myRide MUST be simply 'car' (not say, 'car.Code')-->
</select>
<br/> This shows that 'myRide' contains the property called 'Name', and importantly, 'code':<br/> {{myRide}}
</div>
</div>
Basically I just had it alert what car was with myRide as the parameter, it showed the JSON string so I added the parse to get it to give me the code. There may be a better way I'm an AngularJS noob so to speak.

Related

Can't display options in select list using *ngFor in Angular 9

I'm having trouble displaying the options in a select list. The HTML code is the following:
<select class="selectpicker" (change) = "searchCountry(selectedCountry)" [(ngModel)] = "selectedCountry" data-live-search="true" title = "Selecciona un país">
<option [ngValue]="object" *ngFor = "let object of countryList" >{{object.Country}}</option>
</select>
What I'm trying to do is to display the property "Country" (which is a string) of the objects inside the countryList array.
The problem is that there are no options displaying, the select list is empty.
I'm sure that the problem is not with countryList because if I run the following code outside the select element, the Country property displays correctly.
<h2>{{countryList[0].Country}}</h2>
I've also tried replacing countryList with an array like the following, and it displays correctly, so I'm not sure that the problem is with the select list.
countryList: Country[] = ["Argentina", "Chile", "Ecuador];
Can it be related to the length of the countryList array? It has 186 elements.
Please try this:
<option *ngFor="let country of countryList" value="{{country}}">{{country}}</option>
in case that countryList is
countryList: Country[] = ["Argentina", "Chile", "Ecuador];
As you have shown countryList is array of strings so you can't use it like object.Country simply use object
use like below
<select [(ngModel)]="selectedCountry" (change) = "searchCountry(selectedCountry)">
<option [value]="object" *ngFor="let object of countryList">{{object}}</option>
</select>
Working example
https://stackblitz.com/edit/angular-select-example-v6rndj?embed=1&file=app/app.component.html
Thanks for the answers, I've partially solved the issue.
The code was ok, the problem was the class of the select box in the HTML code. I deleted 'class="selectpicker"' and the select box started showing all the options. This class is from bootstrap-select, maybe it doesn´t support this kind of clauses.
So the code is like this:
<select (change) = "searchCountry(selectedCountry)" [(ngModel)] = "selectedCountry" title = "Selecciona un país">
<option *ngFor = "let countryName of countryList" >{{countryName.Country}}</option>
</select>
I forgot to mention that countryList's elements are delivered by an HTTP GET method, so replacing it with a string array was not an option. The issue could've been generated by the delay in the HTTP response.
Thanks again.

What is the difference between valueChanges and snapshotChanges()

this is my component.html
<div class="form-group">
<label for="category">Category</label>
<select ngModel name="category" id="category" class="form-control">
<option value=""></option>
<option *ngFor="let c of categories$ | async" [value]="c.key$">
{{ c.name }}
</option>
</select>
</div>
This is my Component.ts
categories$: Observable<any[]>;
constructor(categoryService: CategoryService) {
this.categories$ = categoryService.getCategories();
}
save(product){
console.log(product);
}
This is my categoty.service.ts
I used both valueChanges() and snapShotChanges(). In using valueChanges i can access c.name but cannot c.key
And using snapshotChanges() i can access c.key but cannot access c.name
getCategories(){
//return this.db.list('/categories/').valueChanges();
return this.db.list('/categories').snapshotChanges();`
}
I need to access c.name and c.key$ in the same time Need a solution for this
valueChanges():
Use it when you just need the object data. No document metadata is attached which makes it simple to render to a view.
snapshotChanges():
When you need the document data but also want to keep around metadata. This metadata provides you the underyling DocumentReference and document id. Having the document's id around makes it easier to use data manipulation methods. This method gives you more horsepower with other Angular integrations such as ngrx, forms, and animations due to the type property. The type property on each DocumentChangeAction is useful for ngrx reducers, form states, and animation states.
Basically snapshotChanges() will give you access to the document id compared to valueChanges()
https://github.com/angular/angularfire/blob/master/docs/firestore/documents.md
By adding .pipe(tap(categories => console.log(categories)); to .snapshotChanges() you get a good look on what the data you're working with is looking like. It's a collection of objects that look like below
0: {
payload: DataSnapshot,
type: "value",
prevKey: null,
key: "frock"
},
1: {
payload: DataSnapshot,
type: "value",
prevKey: "frock",
key: "saree"
},
As you can see, there's no name property in your data, so you can't use that. You must instead use one of the other values that the data provides, such as key or prevKey.
On another note, I don't think it's a good idea to use snapshotChanges to map data to a select dropdown. I'm sure there are better ways in Firestore to retrieve the values.

Setting selected option of select control in an Angular 2 model-driven form

I have researched many similar existing answers on SO and elsewhere, but just can't find the solution to this.
I'm using the model-driven approach in Angular 2 to build my form, which is both an add and edit form. When in edit mode, the values are populated with data retrieved from a service: this aspect is all fine because the simple text inputs all bind correctly.
One of the properties is 'Country' and this is an object as follows:
export class Country {id: number; name: string;}
I want to bind this to a select control which will have the list of countries available, and the one from the model populated when the form loads. I want the value of the binding to be the country object, not just the id.
Here's the html of the select control:
<select class="form-control" id="country" formControlName="country">
<option value="default">--Select a country--</option>
<option *ngFor="let c of countries" [value]="c">{{c.name}} </option>
</select>
And here is where i try to to populate the value from the component class:
(<FormControl>this.personForm.controls['country'])
.setValue(this.person.country, { onlySelf: true });
But there is no selected option when the page loads, even though the console confirms that this.person.country exists and is populated with the correct object.
I can get it working with ids: changing to [value]="c.id" in the view and appending .id in the class, and then it works in that the right option is selected. The problem is that the select no longer emits an object for the country property, just the id. I tried changing [value] to [ngValue] and get the same result. I even added [ngModel]="country" to the select element and that didn't help either.
I'd be grateful for any help.
The issue is most likely that this.person.country is not the same country as in your countries array.
If we want to make them the same we can either explicitly subscribe to the valueChanges of the select control or bind [(ngModel)] to person.country:
subscribe to changes
code
this.countryForm.controls['country'].valueChanges.subscribe(country =>
this.person.country = country;
);
// initialize by finding the correct country object (this will overwrite the person's country object)
this.countryForm.controls['country'].setValue(countries.filter(c => c.id === person.country.id));
template
ngModel bind
We still have to make the objects match (compare strategy that Angular 2 uses which is really what JS uses)
code
this.person.country = this.countries.filter(c => c.id === this.person.country.id)[0];
template
<select class="form-control" id="country" formControlName="country" [(ngModel)]="person.country">
<option value="default">--Select a country--</option>
<option *ngFor="let c of countries" [ngValue]="c">{{c.name}}</option>
</select>
ngModel Plunker: http://plnkr.co/edit/UIS2V5rKh77n4JsjZtii?p=preview
subscription Plunker: http://plnkr.co/edit/yyZ6ol1NPD77nyuzwS2t?p=info

Dropdownlist binding to an object not returning selected object

I am binding an object to a dropdownlist using Knockout 2.2.1. The binding is working for putting the correct items in the list but when I try to get the OBJECT selected it is not working. I have a JSFiddle showing this problem; http://jsfiddle.net/CTBSTerry/g4Gex/
Html
<div style="margin-bottom: 15px;">
Your Choices:
<select data-bind="options: choicelists[0].options, optionsText: 'otext', optionsValue: 'oprice', value: selOpt1, optionsCaption: 'Choose...'"></select>
</div>
<div data-bind="visible: selOpt1" style="margin-bottom: 15px;"> <!-- Appears when you select something -->
You have chosen<br>
From Object:
<span data-bind="text: selOpt1() ? selOpt1().otext : 'unknown'"></span>
<br>From Value:
<span data-bind="text: selOpt1() ? selOpt1() : 'unknown'"></span>
</div>
JavaScript:
var mychoice = function (txt, price) {
this.otext = txt;
this.oprice = price;
}
var viewModel = {
prodphoto: "",
prodname: "",
prodDesc: "",
baseprice: "",
choicelists: [
{ 'listlabel': 'Size List',
'options': ko.observableArray([
new mychoice('Small', 'Small|$|0.00'),
new mychoice('Medium', 'Medium|$|0.00'),
new mychoice('Large', 'Large|$|0.00'),
new mychoice('X Large + 2.00', 'X Large|$|2.00'),
])
}],
textlists: [],
selOpt1: ko.observable()
}
ko.applyBindings(viewModel);
When you click the dropdown to make a choice I have 2 spans that attempt to show the selected value which I want as the object selected not just the specific value field. The object notation returns nothing but does not error. The second span shows the selected value but since it is not the selected object I would have to iterate through the object to get the related object. The Knockout documentation shows a very similar sample but I need a bit more complex view model. Can someone help me and point out why this is not working?
Thanks,
Terry
If you remove optionsValue from your binding, then Knockout will use the actual object rather than a property on it.
So, you would want to remove optionsValue: 'oprice' from the binding, then selOpt1 will be populated with the actual object.
Sample: http://jsfiddle.net/rniemeyer/g4Gex/1/

MooTools - How to use getSelected()

I'm trying to learn MooTools and am a TOTAL javascript noobie so please be gentle with me.
What I'm tying to do is to change the state of a disabled input field (type is text) when a particular option is selected. The html looks a bit like tis:
<select class="wide" id="selectBox" name="option>
<optgroup label="Common">
<option value="one">One<option>
<option value="two">Two<option>
<option value="three">Three<option>
</optgroup>
<optgroup label="Less Common">
<option value="other">Other<option>
</optgroup>
</select>
<input id="other" type="text" disabled="disabled" />
This is what I was HOPING would give me the value to be checked in an if statement that would then change the input disabled to enabled:
window.addEvent('domready', function(){
$$('#selectBox').addEvent('change',function(){
var selection = $$('#selectBox').getSelected();
alert(selection);
});
});
When the code us run (i.e. I select another value in the option box) all I get is [object HTMLOptionElement].
The documentation on mootools for this method is SPARSE and only says:
Element Method: getSelected
Returns the selected options of a
select element.
Returns:
* (array) An array of the selected elements.
Examples:
HTML
<select id="country-select" name="country">
<option value="US">United States</option
<option value ="IT">Italy</option>
</select>
JavaScript
$('country-select').getSelected(); //Returns whatever the user selected.
Note:
This method returns an array, regardless of the multiple attribute of the select element. If the select is single, it will return an array with only one item.
Totally confusing!
Someone please tell me what I'm missing. I've also tried:
var selection = $$('#selectBox').getSelected().value; //and
var selection = $$('#selectBox').getSelected('value'); //and
//a WHOLE bunch of other wild ideas including
var selection = $$('#selectBox').getSelected();
alert(selection[0]);
Nothing comes out properly. In some cases I get undefined and in other cases I get the same [object HTMLOptionElement].
so many things wrong, not sure where to begin.
$$() is a collection operator (alias for document.getElements() which returns multiples based upon a selector) - not appropriate to use for an id.
you want document.id("idhere") or $("idhere")
for mootools 1.2+
document.id('selectBox').addEvent('change',function() {
alert(this.get("value")); // get value
alert(this.getSelected().get("value")); // gets the option that's selected and then it's value
});
make sure you check your markup - you don't close the options, you have a missing " from name="option> as well.
getSelected is there as a method as some selects use multiple selection so doing selectEl.get("value") will not report anything meaningful. any other case, .get("value") is fine.
check it working:
http://www.jsfiddle.net/dimitar/SmShF/
have fun and read the manual :)
late reply but I was facing the same issue and solved it in this (simple) way in Mootools:
$('selectBox').getSelected().get('text')
So Complex!
You don't need to do such a complex thing, this would suffice:
var selection = document.getElementById("selectBox").value;
alert(selection);
That should get you the selected text.
But if you wanted to use mootools, I guess that this would work (I'm not going to try it)
var selection = $('selectBox').getSelected();
alert(selection[0].value);
Also this has some problems:
<select class="wide" id="selectBox" name="option>
You don't need the name attribute, as it is basically the same as id. Also if you do have both, then they should probably be the same. I.e. id="selectBox" and name="selectBox
Your name tag should be closed.
Also in your sample, you had a lot of <option>...<option> which should be <option>...</option>
All you need to do is:
$('country-select').getSelected().get('value')[0];
Quick, hackish way:
alert($('selectBox').value)
Verbose, recommended way:
var selectBox = document.id('selectBox');
alert(selectBox.get('value'));
.getSelected() returns an array. See the docs: http://mootools.net/docs/core/Element/Element#Element:getSelected .
My Code is :
var $obj=$$('#id').getSelected()[0];
alert( $obj.get('text') );
alert( $obj.get('value') );