conditions for select - HTML or Javascript/Jquery - html

I have the following code:
<select class="form-control" required>
<option *ngFor="let car of cars" type="text">{{car.Name}}</option>
</select>
my problem is that i can get just a name, so *ngFor fails.
is there a way in HTML to make a condition like. If not Javascript or Jquery
//There are more than 1 option
if(options.length>1){<option *ngFor="let car of cars" type="text">{{car.Name}}</option>}
//There is only an option
else {<option *ngIf="car" type="text">{{car.Name}}</option>}
Car
export class Car {
id: String;
name: [{
brand: String,
}
}]
}
JSON returns an Array[] when there are more than one element. If not, it returns an Object{} so I can not use *ngFor
Solved
The problem was in the back-end, and not in the front-end

You can use *ngIf directive like:
<select id="oneICO" class="form-control" required *ngIf="cars.length > 1">
<option *ngFor="let car of cars">{{car.Name}}</option>
</select>
<input type="text" *ngIf="cars.length < 2">{{car.Name}}</input>

Checking if a variable is an array in the template is sort of nasty How to check type of variable in ngIf in Angular2
It would be better to check if !(cars instanceof Array) and then turn it into an array in your javascript code.

In html you can use ngif in angular2
<div *ngIf="options.length>1">
<option *ngFor="let car of cars" type="text">{{car.Name}}</option>
</div>
or simple put the next code in html
<option *ngIf="options.length == 1 " type="text">{{car.Name}}</option>

cars is not a collection so you don't need any angular directives:
<select id="oneICO" class="form-control" required>
<option>{{cars.Name}}</option>
</select>
In which case, rename cars to car so that it signifies a single item.
[It is a little pointless, though, have a select with only a single option.]
Note that an option does not have a type attribute.

Your original code is fine. There's nothing wrong with it.
<select id="oneICO" class="form-control" required>
<option *ngFor="let car of cars" type="text">{{car.Name}}</option>
</select>
If you have single car, make an array of single element and it will work just fine.
cars = ['Honda']
If you have multiple cars, you'll have something like this.
cars = ['Honda', 'Toyota', 'Mitsubishi']

Related

how can I know which option is clicked on in a select tag while updating a variable in the ts file?

I have this simple select that is generating the numbers from an array in the component.ts file and I want to make it so that when the user clicks a number on the dropdown list, a variable in that .ts file is updated (inputBoxes) and that many input boxes will be displayed.
in my html file I have
component.html
<p>How many words will you be using?</p>
<select>
<option *ngFor="let num of wordCount" (click)="updateInputBoxes(num)">{{num}}</option>
</select>
component.ts
public wordCount: Array<number> = [1,2,3,4,5];
public inputBoxes: number;
constructor() { }
ngOnInit(): void {
}
updateInputBoxes(num: number) {
this.inputBoxes = num;
}
This is what I was trying so far but the updateInputBoxes function doesn't even execute. How do I know which number is selected while sending that selected number as a parameter to the function updateInputBoxes?
You need to add change method in select tag then pass the event to get current selected option vaule in ts file.
Try this code to get selected option value :
HTML CODE
<select (change)="updateInputBoxes($event)">
<option value="">
Select count
</option>
<option *ngFor="let num of wordCount" value={{num}}>{{num}}</option>
</select>
TS CODE
updateInputBoxes(event) {
this.inputBoxes = event.target.value;
}
If you want to call method after select each options you need to use change event in select tag not option tag.
And to pass selected value to your methods you can use template reference like this:
<select #selectList (change)="updateInputBoxes(selectList.value)">
<option *ngFor="let num of wordCount" [value]="num">{{num}}</option>
</select>
Here is working sample I created: StackBlitzLink
But if you only need selected value of selectbox there is no need to call fanction just use [(ngModel)]="inputBoxes" like this:
<select [(ngModel)]="inputBoxes">
<option *ngFor="let num of wordCount" [value]="num">{{num}}</option>
</select>
Use template driven or reactive forms for this.
The template driven version looks like this:
<select name="countControl" [(ngModel)]="inputBoxes">
<option *ngFor="let wordCount of wordCounts" [ngValue]="wordCount">
{{ wordCount }}
</option>
</select>
Docs: https://angular.io/api/forms/SelectControlValueAccessor#description

Label element inside component

When I run Lighthouse on my local project it returns the following:
Form elements do not have associated labels
For inputs I've used id="<input_id>", adding for="<input_id>"to its label. But now, I have a component for selecting the country, which is responsible for loading the list of countries.
<form name="notificationDetailForm" [formGroup]="form">
<div class="key-input">
<label for="country-label">Country</label>
<country-selector id="country-label" formControlName="country"></country-selector>
</div>
</form>
So, label is separated from the select tag, which is inside the country-selector component:
<select [(ngModel)]="selectedCountry">
<option [ngValue]="null" disabled selected>-- Select country --</option>
<option *ngFor="let country of countries$ | async" [ngValue]="country">
{{ country.name }}
</option>
</select>
I have tried using aria-labelledby in the form component but it is the same.
My question is: How can I make the label reference the select tag inside the component?
Thank you!
You can pass it through via an input property
country-selector.ts
#Input() controlId: string;
country-selector.html (other html
<select [id]="controlId" [(ngModel)]="selectedCountry">
<option [ngValue]="null" disabled selected>-- Select country --</option>
<option *ngFor="let country of countries$ | async" [ngValue]="country">
{{ country.name }}
</option>
</select>
parent.html
<country-selector controlId="country-label" formControlName="country">
</country-selector>
You will probably need to do a similar thing with formControlName - avoid using #Input() property names that clash with the Angular directive names.
The problem with your approach is that you are assigning the id to the parent control itself (inspect the HTML that is generated). So the label never gets associated with the <select>.

Is it possible to display certain number of objects from a list in a dropdown? (but keep rest available for search)

In my dropdown for now all of the products are displayed, and I have like 200 products there, and dropdown is pretty large, I would like to display only 5-10 product for example, so it might look like this:
So basically all of the products would be there available for search, BUT ONLY 5 - 10 of them would be displayed, so dropdown would look more cleaner..
This is pure html of dropdown:
<div class="col-sm-6">
<select class="form-control dash-form-control select2" style="width: 100%;">
<option selected disabled>Search...</option>
<option>258-656 - Product 1 0,5l</option>
<option>358-656 - Product 2 0,75l</option>
<option>428-656 - Product 3 1kg</option>
</select>
</div>
And this is Angular modified:
<div class="col-sm-6">
<select class="form-control dash-form-control select2" style="width: 100%;">
<option selected disabled>Search...</option>
<option *ngFor="let p of products;" [value]="p.id">{{product.title}}</option>
</select>
</div>
And this angular way of course display all the values that are contained in products array.. and that's not it:)
Any kind of help would be awesome
Thanks guys
Cheers
In your component, import FormControl from #angular/forms and create an observable that takes a Product[].
public productCtrl: FormControl = new FormControl();
public products$: Observable<Product[]>;
now introduce a cold-observable that listens to input on the form-control, but until then, display the first 5 items.
this.products$ = this.productCtrl.valueChanges.pipe(
debounceTime(500),
startWith(null)
map(this.filterOrFirstFiveElements)
// implement a function
// that filters and returns your current product array or returns first five elements
// when a filter is provided and you get more that five elements, you can still only return first five elements of that result
);
Now in your template go ahead and adjust it to use the observable and mark the control as form-control.
<div class="col-sm-6">
<select class="form-control dash-form-control select2" style="width: 100%;">
<option selected disabled>Search...</option>
<option *ngFor="let p of products$ | async;" [value]="p.id">{{product.title}}</option>
</select>
</div>
<input type="text" [formControl]="productsCtrl" />
You need to import reactive-forms module into your module in order to be able to use [FormControl] directive.
Not directly related: As a user I would be completely confused when I see only five elements, use the filter and get a completely different result. An autocomplete is maybe a better solution. Show nothing, until user searches for a product.
Use Pipe
filter.pipe.ts
transform(value: any, args?: any): any {
console.log(args)
if(!value){
return null;
}
let arg=args ? args :5;
let limitTo=value.length >5 ? value.slice(0,arg) : value ;
return limitTo;
}
HTML
<div *ngFor="let d of data |filterpipe:5">
{{d.name}}
</div>
Example:https://stackblitz.com/edit/angular-r3kpxc
You could just use an index:
<div class="col-sm-6">
<select class="form-control dash-form-control select2" style="width: 100%;">
<option selected disabled>Search...</option>
<ng-container *ngFor="let p of products; let i = index;" >
<option *ngIf="i < 5" [value]="p.id">{{product.title}}</option>
</ng-container>
</select>
</div>

Not able to receive option value in angular 2 function upon selection

<form>
<div class="form-group">
<label for="sel1 primary"></label>
<select class="form-control" id="sel1">
<option *ngFor="let group of instanceList"(click)="change_group(group.name)" > {{group.name}}
</option>
</select>
</div>
</form>
Sorry for bad indentation.
Instancelist list is the array of object contain, id, name, groupnumber.
I want to get the value of selected option in my calling method and want to display it in console.
function change_group(groupname){
this.change_to=groupname;
console.log(change_to);
}
The problem is, the given function not even call upon selecting value in dropdown.
Why not leave the option tags alone and just subscribe to the selection changed event in the <select> tag
<select class="form-control" id="sel1" (change)="onGroupChange($event)">
(click) on <option> is usually not how to do it.
Use instead ngModel
<select class="form-control" id="sel1" ngModel (ngModelChange)="change_group($event)">
<option *ngFor="let group of instanceList" [ngValue]="group"> {{group.name}}
</option>

HTML Select. Select2 + ng-click = Not working?

I am using AngularJS, and Select2 to create a nice dropdown menu.
I've included an ng-click in the Option tag (of the Select tag). However, the ng-click does not seem to be working when in a Select2.
<select ui-select2 >
<option ng-repeat="car in myGarage" ng-click="ride(car)">
{{car.Name}}
</option>
</select>
It also doesn't seem to work when using a normal Select tag.
How can I get them to work?
JSFiddle:
use ng-change and ng-model instead of ng-click
<select ui-select2 ng-change="ride(car)" ng-model="car">
<option ng-repeat="car in myGarage" value ={{car.Name}}>
{{car.Name}}
</option>
</select>
That is the incorrect way to use a select.
First off, there is ng-options attribute to a select that needs to be used instead of ng-repeat on the options.
Secondly, instead of using ng-click, you can assign a ng-model to the select that updates with the selected car as follows:
In your controller, you need only the following model and you can remove other models
$scope.myGarage = [
{
Name: "Toyota 86"
},
{
Name: "Hyundai Genesis Coupe"
},
{
Name: "Nissan GTR"
},
{
Name: "Veyron"
}
];
In your view, use ng-options and ng-model as follows:
<select ng-model="selectedCarUI" ng-options="car.Name as car.Name
for car in myGarage" ui-select2>
</select>
Using UI-Select2 - Car: {{selectedCarUI}}
<select ng-model="selectedCarNormal" ng-options="car.Name as car.Name
for car in myGarage">
</select>
Using Normal Select - Car: {{selectedCarNormal}}
This should now work. Here is a fiddle for the same
The OP is using angular-ui select2. The following is from the angular-iu/ui-select2 website:
"ui-select2 is incompatible with <select ng-options>. For the best results use <option ng-repeat> instead."
See the "Working with dynamic options" section at https://github.com/angular-ui/ui-select2
So ng-change is probably the best option.
I don't know if is a lit bit late but i just discover how to make it work:
1) I'm using the original Select2
<script src="http://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0-rc.2/js/select2.min.js"></script>
2) the html goes as follows:
<select class="form-control js-example-basic-single"
ng-options="item.label for item in yourVector"
ng-change="yourFunction(item)" ng-model="item">
</select>
3) the script at the end of the template:
<script type="text/javascript">
$(".js-example-basic-single").select2();
</script>
it works for me :)