*ngIf with button, disabled or not disabled Angular 9 - html

I have two drop downs that are parameters for a function that is called on the Retrieve button click. What I want to happen is when both drop downs do not have data selected, the Retrieve button is disabled. If both drop downs have data then I want the button to act normally.
Here is my current html:
<div class="dropdown">
<div class="input-group">
<h4 class="sessionText">Session: </h4>
<select [(ngModel)]='sessionReportFilter.sessionName'
class="custom-select form-control-sm"
(change)='sessionDataChange($event)'
id="inputGroupSelect01">
<option [value]="null">Select session...</option>
<option *ngFor="let session of sessionData" [value]='session.sessionName'>
{{session.sessionName}}
</option>
</select>
</div>
<div class="input-group">
<h4 class="reportText">Report Date: </h4>
<select [(ngModel)]='sessionReportFilter.fileName' *ngIf='currentSession' class="custom-select form-control-sm" id="inputGroupSelect01">
<option [value]="null">Select report...</option>
<option *ngFor="let report of currentSession.reportFiles"
[value]="report">
{{report}}
</option>
</select>
<select *ngIf="currentSession === null" class="custom-select form-control-sm" id="inputGroupSelect01"></select>
</div>
<div>
<button type="button" class="btn btn-primary" disabled="disabled">Retrieve</button>
<button type="button" class="btn btn-primary" (click)="orderExceptionReportData()">Retrieve</button>
</div>
</div>
How can I achieve the desired results?

[disabled]="!sessionReportFilter.fileName && !sessionReportFilter.sessionName"
Replace that where you want the disabled button when at least one dropdown don't have a value,
so
<button type="button" class="btn btn-primary" disabled="disabled">Retrieve</button>
would be
<button type="button" class="btn btn-primary" [disabled]="!sessionReportFilter.fileName && !sessionReportFilter.sessionName">Retrieve</button>

You can use angular reactive forms validations to solve this problem easily, all you need to do is to put your HTML script and link it to formControlName, the typescript will handle it all:
Suppose we have two select lists, one is for foods and the other for the cars, we need to enable the submit button only if both of the lists are selected (hold values that has been entered by the user), that means that these two fields must be required, we can mark them as required by using angular built-in validation called required, angular will mark the whole form as invalid if one validation is not validated to true, in the HTML script we can make use of the form's status to enable or disable the submit button:
typescript code:
export class SelectOverviewExample {
foods: Food[] = [
{value: 'steak-0', viewValue: 'Steak'},
{value: 'pizza-1', viewValue: 'Pizza'},
{value: 'tacos-2', viewValue: 'Tacos'}
];
form : FormGroup;
constructor(private fb: FormBuilder){
this.createForm();
}
createForm(){
this.form = this.fb.group({
foods: [{value: '', disabled: false}, [Validators.required]],
cars: [{value: '', disabled: false}, [Validators.required]],
});
}
onSubmit(){
// get the values of the form that has been enterd by the user
console.log(this.form.value);
}
}
HTML script:
<h4>Basic mat-select</h4>
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<mat-form-field>
<mat-label>Favorite food</mat-label>
<mat-select formControlName="foods">
<mat-option *ngFor="let food of foods" [value]="food.value">
{{food.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
<br>
<mat-form-field>
<mat-label>Cars</mat-label>
<select matNativeControl formControlName="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
<br>
<button mat-raised-button color="primary" cdkFocusInitial class="col-md-3" type="submit"
[disabled]="!form.valid">Submit</button>
</form>
Live demo (stackblitz reproduction):
https://stackblitz.com/edit/angular-x9nuhj?file=src%2Fapp%2Fselect-overview-example.html

HTML:
<button [disabled]="yourFunctionError" nz-button nzType="primary">Submit</button>
TS:
export class yourComponent implements OnInit {
yourFunctionError: string;
constructor() { }
ngOnInit(): void {
});
this.yourFunctionError= true; //Use your logic
}

Related

Angular form validation with select and textarea doesn't work

I'm trying creating form validation based on built-in validators, it doesn't work correctly. Form is created with select and textarea controls. The form tag include ngNativeValidate, to disable default novalidate attribute. State is change correctly, so validators works, but I do not have information under controls and form can be subbmitted. It is possible to make validation by disable submit button, but I want to avoid this solution.
HTML:
<form [formGroup]="form" ngNativeValidate (ngSubmit)="addNewJoke()">
<div>
<div>
<select formControlName="category" class="customSelect">
<option value="" disabled hidden>Wybierz kategorię</option>
<option
*ngFor="let category of jokesFacadeService.categories$ | async"
[value]="category.id"
>
{{ category.name }}
</option>
</select>
</div>
<div class="textarea-wrapper">
<textarea
type="text"
class="textarea"
formControlName="content"
placeholder="Wprowadź tekst żartu"
></textarea>
</div>
</div>
<mat-dialog-actions class="modalButton">
<button mat-button mat-dialog-close class="btn-secondary">Anuluj</button>
<button
type="submit"
mat-button
[mat-dialog-close]="true"
class="btn-primary"
>
Dodaj
</button>
</mat-dialog-actions>
</form>
TS:
ngOnInit(): void {
this.form = this.fb.group({
category: new FormControl('', Validators.required,),
content: new FormControl('', [Validators.required,Validators.minLength(3)]),
});
}
I try to change controls to input mark, but this not change anything, the behavior is the same.

I want to create dropdown in place of buttons for graphs change but my function is not working on <select> but with button it's working fine

Here is my html and ts code, I want to create dropdown for changing graph
through chartType function but error occurs that chartType
is not a function but that function works fine with buttons but not dropdown.
<div>
<button mat-raised-button color="warn" (click)="chartType('bar')">Bar Chart</button>
<button mat-raised-button color="primary" (click)="chartType('line')">Line Chart</button>
<button mat-raised-button color="accent" (click)="chartType('radar')">Radar Chart</button>
<button mat-raised-button color="primary" (click)="chartType('polarArea')">Polar Chart</button>
<select name="chartType" id="chartType" onchange="chartType(this)">
<option selected>Select Chart Type</option>
<option value="bar">Bar</option>
<option value="line">Line</option>
</select>
<div class = "chart" >
<canvas id="canvas"> {{charts}} </canvas>
</div>
</div>
chartType(type: any)
{
this.charts.destroy()
this.charts = new Chart('canvas', {
type: type,
data: {
labels: this.arr,
datasets: [{
label: 'IR',
data: this.a1,
borderWidth: 3,
fill: false,
backgroundColor: 'red',
borderColor: 'red'
}
]
}
})
}
Your problem should get solved, if you define a change event handler on your select element as follows.
<select (change)="chartType($any($event.target).value)">
Please take a look at this StackBlitz and see how it works.

for loop in form and input type all the same angular

I for loop in my form and when I type it type in every input. (Look at the photo I attached)
Here's my app.components.html:
<ul class="border">
<li *ngFor="let cake of cakes; let idx = index">
<img class="d-inline-block" (click)="getCake(idx)" src="{{cake.url}}" alt="{{cake.id}}" width="250"
height="250">
<form class="d-inline-block form-rate">
<div class="form-group">
<select name="rating" [(ngModel)]="newRating.rating" class="custom-select">
<option selected value="1">1 stars</option>
<option value="2">2 stars</option>
<option value="3">3 stars</option>
<option value="4">4 stars</option>
<option value="5">5 stars</option>
</select>
</div>
<div class="form-group">
<textarea name="comment" [(ngModel)]="newRating.comment" class="form-control" id="rate-comment" rows="4"
placeholder="Type your comment here"></textarea>
</div>
<div class="form-group clearfix">
<button class="btn btn-primary float-right btn-sm" (click)="ratingSubmit(cake._id)">Rate!</button>
</div>
</form>
</li>
</ul>
And this is my app.components.ts:
import { Component } from "#angular/core";
import { HttpService } from "./http.service";
#Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
title = "cake";
cakes = [];
newCake: any;
newRating = { rating: "", comment: "" };
selectedCake;
avg;
constructor(private _httpService: HttpService) {}
ngOnInit() {
this.getCakesFromService();
this.newCake = { name: "", url: "" };
}
getCakesFromService() {
let observable = this._httpService.getCakes();
observable.subscribe((data) => {
this.cakes = data["data"];
});
}
onSubmit() {
let observable = this._httpService.addCake(this.newCake);
observable.subscribe((data) => {
this.newCake = { name: "", url: "" };
this.getCakesFromService();
});
}
ratingSubmit(cakeId) {
let observable = this._httpService.addRating(this.newRating, cakeId);
observable.subscribe((data) => {});
this.newRating = { rating: "", comment: "" };
this.getCakesFromService();
}
getCake(idx) {
this.selectedCake = this.cakes[idx];
var sum = 0;
for (var i = 0; i < this.selectedCake.ratings.length; i++) {
sum += this.selectedCake.ratings[i].rating;
}
this.avg = sum / this.selectedCake.ratings.length;
}
}
Just updated my code and add some more codes into it.
I tried to console.log(this.newRating) but it came out an object with empty string
{rating: "", comment: ""}
What can I do to fix this issue?
You can bind comment and rating to cake object itself. You need to use cake.newRating instead of newRating.rating and cake.newComment instead of newRating.comment.
app.components.html
<ul class="border">
<li *ngFor="let cake of cakes; let idx = index">
<img class="d-inline-block" (click)="getCake(idx)" src="{{cake.url}}" alt="{{cake.id}}" width="250"
height="250">
<form class="d-inline-block form-rate">
<div class="form-group">
<select name="rating" [(ngModel)]="cake.newRating" class="custom-select">
<option selected value="1">1 stars</option>
<option value="2">2 stars</option>
<option value="3">3 stars</option>
<option value="4">4 stars</option>
<option value="5">5 stars</option>
</select>
</div>
<div class="form-group">
<textarea name="comment" [(ngModel)]="cake.newComment" class="form-control" id="rate-comment" rows="4"
placeholder="Type your comment here"></textarea>
</div>
<div class="form-group clearfix">
<button class="btn btn-primary float-right btn-sm" (click)="ratingSubmit(cake)">Rate!</button>
</div>
</form>
</li>
</ul>
You need to do some changes into ratingSubmit() method as well.
app.components.ts
ratingSubmit(cake) {
let observable = this._httpService.addRating({'rating' : cake.newRating, 'comment': cake.newComment}, cake._id);
observable.subscribe((data) => {
// after successful submission of ratings do following.
cake.newRating = '';
cake.newComment: '';
this.getCakesFromService();
});
}
You are looping correctly, but it is binding each input to the same variable: newRating.rating. That is why each input is showing up the same.
Fixing this is a little bit more complicated, and I don't know enough about what you are trying to do to tell you exactly how to do it.
One guess I have is binding it to the exact cake:
<select name="rating" [(ngModel)]="cakes[idx].rating" class="custom-select">
But again, that might not be what you're trying to accomplish. You may have to create an array of newRating that you can then bind to based on the index of the for loop.
Anyways, I hope that helps. Best of luck!

How to generate JSON of a HTML form on submit in Angular 7

I want to generate JSON from a HTML form to store that form template in ms sql database. Please help.
<div class="container">
<mat-card>
<mat-toolbar color="accent">
<div align="center" style="color:white;text-align: right;">
Create Survey/Template
</div>
</mat-toolbar>
<br><br>
<mat-card-content>
<form [formGroup]="employeeForm"(ngSubmit)="onFormSubmit(employeeForm.value)">
<table>
<tr>
<td class="tbl1">
<mat-form-field class="demo-full-width">
<input formControlName="TemplateName" matTooltip="Enter Template Name" matInput placeholder="Template Name">
</mat-form-field>
</td>
</tr>
<tr>
<td class="tbl1">
<mat-form-field class="demo-full-width">
<input formControlName="Label" matTooltip="Label" matInput placeholder="Label">
</mat-form-field>
<mat-form-field>
<mat-label>Input Type</mat-label>
<select matNativeControl required>
<option value="text">Text</option>
<option value="number">Number</option>
<option value="email">Email</option>
</select>
</mat-form-field>
<button type="button" mat-raised-button color="accent" class="btn btn-danger" matTooltip="Add Input Box" >Add Input Box</button>
</td>
</tr>
<tr>
<td class="tbl1">
<mat-form-field class="demo-full-width">
<input formControlName="Radio Field Question" matTooltip="Radio Field Question" matInput placeholder="Radio Field Question">
</mat-form-field>
<mat-form-field>
<mat-label>Options</mat-label>
<select matNativeControl name="radioOptions" (change)="RadioSelectChangeHandler($event)" required>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</mat-form-field>
<ng-container *ngFor="let field of fieldsArray">
<br>
<input formControlName="RadioFieldOptions" [name]="field+1" matInput placeholder="Radio Option">
<br>
</ng-container>
<button type="button" mat-raised-button color="accent" class="btn btn-danger" matTooltip="Add Radio Button" >Add Radio Button</button>
</td>
</tr>
<button type="button" mat-raised-button color="accent" class="btn btn-danger" matTooltip="Create Template" >Create Template</button>
</table>
</form>
</mat-card-content>
</mat-card>
</div>
I want to save above form template in database and later want to render that template from database. Is this possible? Or what approach I can try to achieve that goal?
Try to follow below steps.
add the code in app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
#NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
in your app.component.html
<h1> Template-Based Contact Form Example </h1>
<form #myform = "ngForm" (ngSubmit) = "onSubmit(myform)" >
<input type = "text" name = "fullName" placeholder = "Your full name" ngModel>
<br/>
<input type = "email" name = "email" placeholder = "Your email" ngModel>
<br/>
<textarea name = "message" placeholder = "Your message" ngModel></textarea>
<br/>
<input type = "submit" value = "Send">
</form>
in your app.component.ts
import { Component } from '#angular/core';
import {NgForm} from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
onSubmit(form: NgForm) {
console.log('Your form data : ', form.value);
}
}
We passed in the reference to the NgForm object that represents our form to the onSubmit() method and we can use it to access various properties like value which provides a plain JS object that contains the attributes of the form and their values. In this example, we simply print the form value in the console but in a real world situation, we can use it to send the data to a server via a POST request.
You can see all the available methods of NgForm from the docs.
You can see the data in your browser console. Please try this. hope this will help you.

how to set form validation for select form with option as placeholder in angular 2

category.component.ts
export class CategoryComponent{
public categories : any = [
{ name: 'Hotel', type: 'Company'},
{ name: 'School', type: 'Company'}
];
}
category.html
<form name="addCategoryForm" class="addCategoryForm" #addCategoryForm="ngForm" novalidate>
<div class="form-group">
<label class="control-label">Category Type</label>
<select class="form-control" name="SelectCategory" [(ngModel)]="selectcategory" #SelectCategory="ngModel" required>
<option>Category Type</option>
<option *ngFor="let category of categories">{{category.name}} </option>
</select>
<button [disabled]="!addCategoryForm.form.valid">Save</button>
</div>
</form>
how can i set the placeholder in select form along with form validation