I recently learned Angular2. Currently, I have got a material modal after some searching. However,I can't find how I return the data that the user can input.
In the modal I currently have, there is one input field and one checkbox. When close the console logs "de dialog closed" and "true".
This is my modal HTML:
<h2 mat-dialog-title>Add Group</h2>
<mat-dialog-content>
<div>
<mat-form-field>
<input matInput placeholder="Groupname">
</mat-form-field>
<mat-form-field>
<mat-checkbox >Private group?</mat-checkbox>
</mat-form-field>
<mat-form-field>
<button mat-raised-button color="primary">img</button>
</mat-form-field>
</div>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button mat-dialog-close>cancel</button>
<!-- The mat-dialog-close directive optionally accepts a value as a result for the dialog. -->
<button mat-button [mat-dialog-close]="true" >save</button>
</mat-dialog-actions>
TS code:
import { Component, OnInit, Inject } from '#angular/core';
import { GroupsService} from '../../../services/Groups.service';
import { Groups } from '../../../models/groupModel'
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '#angular/material';
#Component({
selector: 'app-groups',
templateUrl: './groups.component.html',
styleUrls: ['./groups.component.scss'],
})
export class GroupsComponent implements OnInit {
animal: string;
name: string;
groups: Groups[];
constructor(
private groupsService: GroupsService,
public dialog: MatDialog
){}
ngOnInit() {
this.groupsService.getMyGroups()
.then(group =>{
this.groups = group;
console.log(this.groups)
}).catch(error=>{
console.log(error);
});
}
openDialog(): void {
let dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
height: '300px',
width: '300px',
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
console.log(result);
this.animal = result;
});
}
testgroup(id){
console.log(id)
}
acceptGroup(){
console.log('accept')
}
declineGroup(){
console.log('decline');
}
createGroup(){
console.log("sample");
}
}
#Component({
selector: 'dialog-overview-example-dialog',
templateUrl: './model.html',
})
export class DialogOverviewExampleDialog {
constructor(
public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
#Inject(MAT_DIALOG_DATA) public data: any) { }
onNoClick(): void {
this.dialogRef.close();
}
}
This part of your code inside HTML template is currently responsible for what you're passing back from the model: [mat-dialog-close]="true". As you see you're just passing true and nothing else. Simplest way to achieve what you want is to create form inside the dialog and pass its value.
<h2 mat-dialog-title>Add Group</h2>
<mat-dialog-content>
<form #modalForm="ngForm">
<div>
<mat-form-field>
<input matInput name="groupName" placeholder="Groupname" ngModel>
</mat-form-field>
<mat-form-field>
<mat-checkbox name="privateGroup" ngModel>Private group?</mat-checkbox>
</mat-form-field>
<mat-form-field>
<button mat-raised-button color="primary">img</button>
</mat-form-field>
</div>
</form>
</mat-dialog-content>
<mat-dialog-actions>
<button mat-button mat-dialog-close>cancel</button>
<button mat-button [mat-dialog-close]="modalForm.value">save</button>
</mat-dialog-actions>
You can also pass form value on submit (using (ngSubmit)="mySubmitFunction(modalForm.value)" on form tag ) to the mySubmitFunction defined in DialogOverviewExampleDialog. And then, after some kind of validation for example, pass data by using: this.dialogRef.close(someVariableContainingValues).
use this code i think it will be work:
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
console.log(result);
//this.animal = result;
}).()=>{
this.animal = result;
};
Related
I'm trying to save some data that I display dynamic in the browser.This is my HTML where I iterate trough a list of exam questions dragged from the database and display them dynamic in browser.
<div mat-dialog-content [formGroup]="examform">
<div *ngFor="let exam_question of exam_questions;let i = index">
<mat-label >{{exam_question.questionTitle}}</mat-label><br>
<mat-radio-group aria-label="Image Position">
<mat-radio-button id="{{'examItem1'+i}}" value="1" >{{exam_question.questionItem1}}</mat-radio-button>
<mat-radio-button id="{{'examItem2'+i}}" value="2">{{exam_question.questionItem2}}</mat-radio-button>
<mat-radio-button id="{{'examItem3'+i}}" value="3">{{exam_question.questionItem3}}</mat-radio-button>
<mat-radio-button id="{{'examItem4'+i}}" value="4">{{exam_question.questionItem4}}</mat-radio-button>
</mat-radio-group>
</div>
<div>
<button class="button-course" mat-raised-button color="primary" (click)="submitAnswer()">Submit</button>
How can I use Form from Angular Typescript to save what the user responds to this form? For example what was the answer for the first question, for the second question and so on. I tried to put on every Form Controls and id, but I don t know how to go further.This is the form from Typescript.
import { registerLocaleData } from '#angular/common';
import { Component, OnInit } from '#angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '#angular/forms';
import { ActivatedRoute, Router } from '#angular/router';
import { Questions } from '../models/questions';
import { SharedService } from '../service/shared.service';
#Component({
selector: 'app-quiz-exam-page',
templateUrl: './quiz-exam-page.component.html',
styleUrls: ['./quiz-exam-page.component.css']
})
export class QuizExamPageComponent implements OnInit {
examID:any;
examform!: FormGroup;
examData: any;
userDetails:any;
examFormArray=new FormArray([new FormControl('',Validators.required)]);
constructor(private formBuilder:FormBuilder,private router:Router,private sharedService:SharedService,private route:ActivatedRoute) { }
exam_questions:Questions[]=[];
ngOnInit(): void {
this.route.queryParams
.subscribe(params => {
this.examID = params['examID'];
}
);
this.examform=this.formBuilder.group({
examTitle:this.formBuilder.array([],Validators.required),
examItem1:this.formBuilder.array([],Validators.required),
examItem2:this.formBuilder.array([],Validators.required),
examItem3:this.formBuilder.array([],Validators.required),
examItem4:this.formBuilder.array([],Validators.required)
});
if(localStorage.getItem('token')==null)
this.router.navigate(['login'])
this.sharedService.getUserProfile().subscribe(res=>{
this.userDetails=res;
this.sharedService.getExamQuestionsByID(this.examID).subscribe(data=>{
this.exam_questions=data;
},err=>{
console.log(err)
});
},(err:any)=>{
console.log(err);
},
);
}
submitAnswer(submitData:any)
{
this.examData = submitData;
console.log(this.examData)
}
}
This is the generated form. And as you can see, I need the answer for every question and after that I click submit, it will save the answer for every question, but I need to know to what question it was the answer, that is why I put the Id in the HTML.
This is my question array. It is an interface:
export interface Questions {
questionID:number;
questionCourseID:number;
questionTitle:string;
questionTopic:string;
questionPoints:string;
questionDifficulty:string;
questionItem1:string;
questionItem2:string;
questionItem3:string;
questionItem4:string;
qustionAnswers:string;
}
To your HTML-File I would add an NgSubmit and also add the type submit to your button. In the ngSubmit you give the value of your form (examForm) to the function (saveForm) in the Typescript-File. Instead I would delete the (click) event on your button.
HTML-File
<div mat-dialog-content [formGroup]="examform" (ngSubmit)="saveForm(examform.value)">
<div *ngFor="let exam_question of exam_questions;let i = index">
<mat-label >{{exam_question.questionTitle}}</mat-label><br>
<mat-radio-group aria-label="Image Position">
<mat-radio-button id="{{'examItem1'+i}}" value="1" >{{exam_question.questionItem1}}</mat-radio-button>
<mat-radio-button id="{{'examItem2'+i}}" value="2">{{exam_question.questionItem2}}</mat-radio-button>
<mat-radio-button id="{{'examItem3'+i}}" value="3">{{exam_question.questionItem3}}</mat-radio-button>
<mat-radio-button id="{{'examItem4'+i}}" value="4">{{exam_question.questionItem4}}</mat-radio-button>
</mat-radio-group>
</div>
<div>
<button type="submit" class="button-course" mat-raised-button color="primary">Submit</button>
If you want, that your button only is pressable if the inputs are valid (for example every required fields are filled out). You can add following code to your button:
<button [disabled]="!examForm?.valid" type="submit" class="button-course" mat-raised-button color="primary">Submit</button>
In your Typescript-File, you should write a function with the same name as you specified in (ngSubmit)="functionName". In my example, the function Name is saveData(). Then you write the value from the Form to a variable with the datatype any.
So your TS-File would look something like:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '#angular/forms';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
examForm!: FormGroup;
examData: any;
constructor(
private formBuilder: FormBuilder,
) { }
ngOnInit(): void {
this.examForm=this.formBuilder.group({
examTitle:this.formBuilder.array([],Validators.required),
examItem1:this.formBuilder.array([],Validators.required),
examItem2:this.formBuilder.array([],Validators.required),
examItem3:this.formBuilder.array([],Validators.required),
examItem4:this.formBuilder.array([],Validators.required)
});
}
showPreview(submitData: any) {
this.examData = submitData;
console.log(this.examData)
}
}
I have a form with a text input and then I want to add a select inside that Form:
The select is an array:
typeAlert: TypeAlert[] = [
{ value: 'MEDICAL'},
{ value: 'POLICE'},
{ value: 'FIRE'}
];
I want to bind the value selected on the select. I have a var called select to store which the user has selected. I have to add the selected inside formGroup?
Also I am getting this error:
ngModel cannot be used to register form controls with a parent formGroup directive
component.html
<form class="container" [formGroup]="alertForm">
<div class="actions">
<div class="action" [routerLink]="['/alertes']">
<span>Torna a Alertes</span>
</div>
<div class="space"></div>
<button class="action" (click)="save()" [disabled]="!alertForm.valid">
Guardar
</button>
</div>
<div class="dades">
<div class="card">
<div class="card-title">
<b>Title</b>
</div>
<div class="card-content">
<mat-form-field>
<mat-label>Title</mat-label>
<input formControlName="title" matInput>
</mat-form-field>
</div>
</div>
</div>
<div class="dades">
<div class="card">
<div class="card-title">
<b>Type Alert</b>
</div>
<div class="card-content">
<mat-form-field appearance="fill">
<mat-label>Type Alert</mat-label>
<mat-select [(ngModel)]="selected">
<mat-option *ngFor="let alert of typeAlert" [value]="alert.value">
{{alert.value}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
</form>
component.ts:
import { Component, OnInit, OnDestroy } from '#angular/core';
import { FormGroup, FormControl, FormArray, Validators } from '#angular/forms';
import { ActivatedRoute, Router } from '#angular/router';
import { AlertesService } from 'src/app/core/services/alertes.service';
import { MatDialog } from '#angular/material/dialog';
import { DialogNotificationsComponent } from 'src/app/shared/components/dialog-notifications/dialog-notifications.component';
interface TypeAlert {
value: string;
}
#Component({
selector: 'app-alert',
templateUrl: './alert.component.html',
styleUrls: ['./alert.component.scss']
})
export class AlertComponent implements OnInit, OnDestroy {
typeAlert: TypeAlert[] = [
{ value: 'MEDICAL'},
{ value: 'POLICE'},
{ value: 'FIRE'}
];
selected: string = this.typeAlert[0].value;
alertForm: FormGroup;
alert;
constructor(
private alertesService: AlertesService,
private route: ActivatedRoute,
private router: Router,
public dialog: MatDialog
) { }
ngOnInit() {
this.alert = this.route.snapshot.data.alert;
this.initForm();
}
ngOnDestroy() {
}
initForm() {
this.alertForm = new FormGroup({
title: new FormControl(this.alert ? this.alert.title : '', [Validators.required]),
});
}
save() {
console.log(this.selected);
if(this.alert) {
this.alertesService.update(this.alert._id, this.alertForm.value).subscribe(() => {
this.router.navigate(['/alertes'])
})
}
else {
const dialogRef = this.dialog.open(DialogNotificationsComponent, {
width: '600px',
data: {title: "Nova alerta", msg: this.alertForm.value.title}
});
dialogRef.afterClosed().subscribe(result => {
console.log(result);
if(result != undefined && result != null) {
this.alertesService.create({
notification: result ? result: null,
...this.alertForm.value
}).subscribe(() => {
this.router.navigate(['/alertes'])
})
}
});
}
}
}
You should [formControlName] with form groups, instead of ngmodel.
Please check https://angular.io/api/forms/FormControlName
I have a component in which [(ngModel)]=attrProps._value is getting set on user input and also getting value when already present by default.
Now there is a button which leads to a toggle button for value option when the user wants to have custom value.
But when the user clicks on the refresh button the value in the input field should get clear?
#Component({
selector: 'n-customValue',
template: `
<mat-form-field class="inputfield-attr-view">
<input matInput [(ngModel)]="attrProps._value" placeholder="{{bKeeperService.getAttributeType(attrProps).displayAs}}">
<mat-icon matSuffix (click)="revertIcon()" class="editButton">
<img class="attributeview-button" src="../../assets/icons/refresh.svg">
</mat-icon>
</mat-form-field>
`
})
export class customValueComponent implements OnInit {
#Output() clickEvent: EventEmitter<string> = new EventEmitter<string>();
constructor(public myservice: customService) { }
ngOnInit(): void { }
revertIcon() {
this.clickEvent.emit('REVERT_EVENT');
}
}
I tried using element ref but could not solve it.
#Component({
selector: 'n-customvalue',
template: `
<mat-form-field class="inputfield-attr-view">
<input matInput [(ngModel)]="attrProps._value" #searchInput placeholder="{{bKeeperService.getAttributeType(attrProps).displayAs}}">
<mat-icon matSuffix (click)="revertIcon()" class="editButton">
<img class="attributeview-button" src="../../assets/icons/refresh.svg">
</mat-icon>
</mat-form-field>
`
})
export class customvalueComponent implements OnInit {
#Output() clickEvent: EventEmitter<string> = new EventEmitter<string>();
#Input('nAttrProps') nAttrProps;
#ViewChild('searchInput') searchInput: ElementRef;
attrPropsValue;
constructor(public myservice: customService) { }
ngOnInit(): void { }
revertIcon() {
this.clickEvent.emit('REVERT_EVENT');
this.searchInput.nativeElement.value = '';
}
}
I have been trying to hide my form and making it appear only when user click on the button. but for some reason, the function I have created never work is there something wrong with my code? and I saw quite a few example that uses angular.module and I tried it but I always get an error message.
transfer.component.html
<form [formGroup]="AddRiciverForm" id="AddRiciverForm" (ngSubmit)="addRiciverFunc()" *ngIf="show">
<div class="container">
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<p><input type="email" id="emailTo" formControlName="emailTo" placeholder="Reciver Email" [(ngModel)]="this.AddRiciverForm.value.emailTo" required></p>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<p><button class="btn btn-primary" type="submit" [disabled]="!transferForm.form.valid">Add</button> </p>
</div>
</div>
</div>
</form>
<button ng-click="AddEmailFunc()">add user</button>
transfer.component.ts
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../auth.service';
import { FormBuilder, FormGroup } from '#angular/forms';
import { Router } from '#angular/router';
import { Http } from '#angular/http';
import { PostsService } from '../posts.service';
#Component({
selector: 'app-transfer',
templateUrl: './transfer.component.html',
styleUrls: ['./transfer.component.css']
})
export class TransferComponent implements OnInit {
constructor(private fb: FormBuilder, private http: Http, private router: Router, private auth: AuthService,private postsService: PostsService) { }
transfer = {};
addRiciver = {};
recivers: any;
AddRiciverForm: FormGroup;
transferForm: FormGroup;
public userEmail: string;
show=false;
ngOnInit() {
this.transferForm = this.fb.group({
emailTo: '',
amount: ''
});
this.AddRiciverForm = this.fb.group({
emailTo: ''
});
this.auth.currentEmail.subscribe(email => this.userEmail = email);
this.postsService.getAllReciver().subscribe(reciver => {
this.recivers = reciver;
});
}
transFunds(){
}
addRiciverFunc(){
this.addRiciver={
emailFrom: this.userEmail,
emailTo: this.AddRiciverForm.value.emailTo
}
this.http.post('/transfer', this.addRiciver)
.subscribe(res => {
let id = res['_id'];
}, (err) => {
console.log(err);
}
);
}
AddEmailFunc(){
if(!this.show){
this.show = true;
}
}
}
You must try adding [hidden]="AddEmailFunc()" on your form.
please see my sample code
import { Component } from '#angular/core';
#Component({
selector: 'Sandbox',
template: `<form [hidden]="isDisplayed">
<label>Sample: </label>
<input type="text">
</form>
<button (click)="showMe()">Click</button>`
})
export class SandboxComponent{
isDisplayed = true;
showMe()
{
if(this.isDisplayed)
{
this.isDisplayed = false;
}else{
this.isDisplayed = true;
}
}
}
Hope it helps. :) cheers!
You are mixing angularjs (1.x) and angular (>2)
the ng-click in Angular should be:
<button (click)="AddEmailFunc()">add user</button>
If this does not solve your issue please post the full component.
you can use *ngIf in and (model) binded to event click of button.
<button (click)="changeView()">add user</button>
and clickEvent
changeView(){
this.showForm = !this.showForm;
}
import {Component, Inject} from '#angular/core';
import {MdDialog, MdDialogRef, MD_DIALOG_DATA} from '#angular/material';
/**
* #title Dialog Overview
*/
#Component({
selector: 'dialog-overview-example',
templateUrl: 'dialog-overview-example.html'
})
export class DialogOverviewExample {
animal: string;
name: string;
constructor(public dialog: MdDialog) {}
openDialog(): void {
let dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
width: '250px',
data: { name: this.name, animal: this.animal }
});
dialogRef.afterClosed().subscribe(result => {
console.log('The dialog was closed');
this.animal = result;
});
}
}
#Component({
selector: 'dialog-overview-example-dialog',
templateUrl: 'dialog-overview-example-dialog.html',
})
export class DialogOverviewExampleDialog {
constructor(
public dialogRef: MdDialogRef<DialogOverviewExampleDialog>,
#Inject(MD_DIALOG_DATA) public data: any) { }
onNoClick(): void {
this.dialogRef.close();
}
}
Let's say i have the code as above. And the result shown below:
Based on this picture, how can i determine if the user clicked OK or No thanks. I want to create a function for each event. tried dialogRefAfterClose but it runs no matter what button i click.
In your dialog html, dialog-overview-example-dialog.html, You can just add (click) event in your both button.
<div mat-dialog-actions>
<button mat-button (click)="clickOK()" tabindex="2">Ok</button>
<button mat-button (click)="clickNo()" tabindex="-1">No Thanks</button>
</div>
and you can close the dialog programmaticly:
clickNo() {
console.log('No button clicked');
this.dialogRef.close();
}
clickOk() {
console.log('Ok button clicked');
this.dialogRef.close();
}
Hi I noticed that you are using the exact same example from angular.material.
The option you asked for need to be handled by Yourself according to your purpose. As seen in the example there.
my example
In here the onNoClick() and the onOkClick() does the Job
Add the functions in compontent ts and bind it in the component html
Dialog Component TS
export class DialogOverviewExampleDialog {
constructor(
public dialogRef: MatDialogRef<DialogOverviewExampleDialog>,
#Inject(MAT_DIALOG_DATA) public data: any) { }
onNoClick(): void {
alert("You clicked no.")
this.dialogRef.close();
}
onOkClick():void{
alert("You clicked Ok");
}
}
Dialog Component HTML
<h1 mat-dialog-title>Hi {{data.name}}</h1>
<div mat-dialog-content>
<p>What's your favorite animal?</p>
<mat-form-field>
<input matInput tabindex="1" [(ngModel)]="data.animal">
</mat-form-field>
</div>
<div mat-dialog-actions>
<button mat-button (click)="onOkClick()" [mat-dialog-close]="data.animal" tabindex="2">Ok</button>
<button mat-button (click)="onNoClick()" tabindex="-1">No Thanks</button>
</div>
You can do that with single function, no need to add functions for more buttons
Like this :
<div mat-dialog-actions>
<button mat-button (click)="clickBtn(true)" tabindex="2">Ok</button>
<button mat-button (click)="clickBtn(false)" tabindex="-1">No Thanks</button>
</div>
clickBtn(status) {
if(status)
console.log('Ok button clicked');
else
console.log('No button clicked');
this.dialogRef.close();
}
<button mat-button (click)="onNoClick()" [mat-dialog-close]="data.SelectedBtn">No Thanks</button>
<button mat-button (click)="onOkClick()" [mat-dialog-close]="data.SelectedBtn" cdkFocusInitial>Ok</button>
#Component({
selector: 'dialog-overview-example-dialog',
templateUrl: './dialog.html',
})
export class DialogComponent {
constructor(
public dialogRef: MatDialogRef<DialogComponent>,
#Inject(MAT_DIALOG_DATA) public data: DialogData) { }
onNoClick(): void {
this.data.SelectedBtn = false;
this.dialogRef.close(this.data.SelectedBtn);
}
onOkClick(): void {
this.data.SelectedBtn = true;
this.dialogRef.close(this.data.SelectedBtn);
}
}