Angular FormGroup custom validator not triggered on button click - forms

I am using reactive forms Angular 4 and added a custom validator addressValidation to the form group - addressGroup.
I am updating all fields to mark as touched on submit click. Looks like the custom validator addressValidation doesn't trigger eventhough I marked all fields as touched. I tried marking the formgroup (addressGroup) as touched and dirty on submit but no help.
In general what I am trying to achieve is - By default I want to make street number and Street name required. If po box is entered then street number and Name is not required. Apt # is only required only if street number and name is entered. I am trying to achieve this on the custom validator in the formGroup.
Any idea on what I am doing wrong. Any other alternate way to achieve the above requirement. I am new to Angular and slowly learning the concepts. Any suggestion on How to trigger the custom validator on submit.
buildForm(): void {
this.contactForm = this.fb.group({
emailAddressControl: ['', [Validators.required, Validators.email, Validators.maxLength(100)]],
phoneControl: ['', [Validators.required, Validators.minLength(10), Validators.maxLength(10)]],
addressGroup: this.fb.group({
streetNumber: ['', [Validators.maxLength(10)]],
pOBox: ['', [Validators.maxLength(8)]],
aptNumber: ['', [Validators.maxLength(8)]],
streetName: ['', [Validators.maxLength(60)]],
cityControl: ['', [Validators.required, Validators.maxLength(50)]],
stateControl: ['', [Validators.required, Validators.maxLength(2)]],
zipControl: ['', [Validators.required, Validators.maxLength(14)]],
countryControl: ['UNITED STATES OF AMERICA', [Validators.required]],
}, { validator: addressValidation })
})
this.contactForm.valueChanges
.debounceTime(800)
.subscribe(data => this.onValueChanged(data));
this.onValueChanged();
}
onSubmit(): void {
this.markAllFormFieldsAsTouched(this.contactForm);
this.onValueChanged();
}
private markAllFormFieldsAsTouched(formGroup: FormGroup) {
Object.keys(formGroup.controls).forEach(field => {
console.log(field);
const control = formGroup.get(field);
if (control instanceof FormControl) {
control.markAsTouched({ onlySelf: true });
}
else if (control instanceof FormGroup) {
this.markAllFormFieldsAsTouched(control);
control.markAsTouched({ onlySelf: true });
}
else if (control instanceof FormArray) {
for (let formgroupKey in control.controls) {
let formgroup = control.controls[formgroupKey];
if (formgroup instanceof FormGroup) {
this.markAllFormFieldsAsTouched(formgroup);
}
}
}
});
}
function addressValidation(c: AbstractControl): { [key: string]: boolean } | null {
if (c.pristine) {
return null;
}
const pOBoxControl = c.get('pOBox');
const streetNameControl = c.get('streetName');
const streetNumberControl = c.get('streetNumber');
const aptNumberControl = c.get('aptNumber');
if (pOBoxControl.value === null || pOBoxControl.value === "") {
if (streetNumberControl.value === null || streetNumberControl.value === "") {
return { ['streetNumberRequired']: true, ['streetNameRequired']: true };
}
if (streetNameControl.value === null || streetNameControl.value === "") {
return { 'streetNameRequired': true };
}
}
else {
if ((streetNameControl.value === null || streetNameControl.value === "")
&& (streetNameControl.value === null || streetNumberControl.value === "") && aptNumberControl.value !== "") {
return { 'apartmentNumberInvalid': true };
}
}
}
Template
<div class="card">
<div class="card-header bg-info text-white">
<h2>Mailing Address:</h2>
</div>
<div formGroupName="addressGroup" class="card-body">
<div class="row">
<div class="col-lg-4">
<div class="form-group">
<label class="form-control-label">PO Box:</label>
<input class="form-control"
[ngClass]="displayFieldCss('pOBox')"
type="text"
formControlName="pOBox"
placeholder=""
maxlength="8" />
<span class="invalid-feedback" *ngIf="isValidToDisplayErrors('pOBox')">
{{validationMessage.pOBox}}
</span>
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label class="form-control-label">Street Number:</label>
<input class="form-control"
[ngClass]="displayFieldCss('streetNumber')"
type="text"
formControlName="streetNumber"
placeholder=""
maxlength="10" />
<span class="invalid-feedback" *ngIf="isValidToDisplayErrors('streetNumber')">
{{validationMessage.streetNumber}}
</span>
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label class="form-control-label">Apt Number:</label>
<input class="form-control"
[ngClass]="displayFieldCss('aptNumber')"
type="text"
formControlName="aptNumber"
placeholder=""
maxlength="8" />
<span class="invalid-feedback" *ngIf="isValidToDisplayErrors('aptNumber')">
{{validationMessage.aptNumber}}
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<label class="form-control-label">Street Name:</label>
<input class="form-control"
[ngClass]="displayFieldCss('streetName')"
type="text"
formControlName="streetName"
placeholder=""
maxlength="60" />
<span class="invalid-feedback" *ngIf="isValidToDisplayErrors('streetName')">
{{validationMessage.streetName}}
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-5">
<div class="form-group">
<label class="form-control-label">City:</label>
<input class="form-control"
[ngClass]="displayFieldCss('cityControl')"
type="text"
formControlName="cityControl"
placeholder="(required)"
maxlength="50" />
<span class="invalid-feedback" *ngIf="isValidToDisplayErrors('cityControl')">
{{validationMessage.cityControl}}
</span>
</div>
</div>
<div class="col-lg-4">
<div class="form-group">
<label class="form-control-label">State/Province (Code):</label>
<input class="form-control"
[ngClass]="displayFieldCss('stateControl')"
type="text"
formControlName="stateControl"
placeholder="(required)"
maxlength="3" />
<span class="invalid-feedback" *ngIf="isValidToDisplayErrors('stateControl')">
{{validationMessage.stateControl}}
</span>
</div>
</div>
<div class="col-lg-3">
<div class="form-group">
<label class="form-control-label">Zip:</label>
<input class="form-control"
[ngClass]="displayFieldCss('zipControl')"
type="text"
formControlName="zipControl"
placeholder="(required)"
maxlength="14" />
<span class="invalid-feedback" *ngIf="isValidToDisplayErrors('zipControl')">
{{validationMessage.zipControl}}
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<label class="form-control-label">Country:</label>
<input class="form-control"
[ngClass]="displayFieldCss('countryControl')"
type="text"
formControlName="countryControl"
placeholder="(required)"
maxlength="50" />
<span class="invalid-feedback" *ngIf="isValidToDisplayErrors('countryControl')">
{{validationMessage.countryControl}}
</span>
</div>
</div>
</div>
</div>
</div>

You must use control.updateValueAndValidity() like this
onSubmit(): void {
if (this.form.valid) {
} else {
this.validateAllFormFields(this.committeForm);
this.logValidationErrors(this.committeForm);
this.scrollToError();
}
}
validateAllFormFields(formGroup: FormGroup) {
Object.keys(formGroup.controls).forEach(field => {
const control = formGroup.get(field);
if (control instanceof FormControl) {
control.updateValueAndValidity()
} else if (control instanceof FormGroup) {
this.validateAllFormFields(control);
}
});
}

Related

Add class if field is already filled VueJS

I am new in Vue and I need to add a new class to div.input-box where inside is label and input.
I can try more options after google but nothing to help me.
html:
<form id="form" class="container">
<div class="row justify-content-center mt-5">
<div class="input-box col-lg-6" #click="isActive = 1" :class="{'focus': isActive === 1}">
<label class="input-label">
{{ $t("system.first_name") }}
</label>
<input type="text" class="input-1" v-model="first_name" #focus="isActive = true" #blur="isActive = false">
</div>
<div class="input-box col-lg-6" #click="isActive = 2" :class="{'focus': isActive === 2}">
<label class="input-label">
{{ $t("system.last_name") }}
</label>
<input type="text" class="input-1" v-model="last_name" #focus="isActive = true" #blur="isActive = false">
</div>
</div>
<div class="row justify-content-center">
<div class="input-box col-lg-12" #click="isActive = 3" :class="{'focus': isActive === 3}">
<label class="input-label">
E-mail
</label>
<input type="text" class="input-1" v-model="email" #focus="isActive = true" #blur="isActive = false">
</div>
</div>
</form>
script:
export default {
name: "RegistrationSecondVersion",
data(){
return {
isActive: false,
first_name: null,
last_name: null,
email: null
}
},
methods: {
checkForInput: function (e) {
let input = e.target;
if (input.value != '') {
input.classList.add('focus');
} else {
input.classList.remove('focus');
}
}
}
}
I had added the function in input but I need after filled to get 'focus' class to div.input-box.
Thank you so much!
You need to call checkForInput function whenever an input occurs. On the other hand, I see no need to use #blur and #focus in your case.
Try this:
<form id="form" class="container">
<div class="row justify-content-center mt-5">
<div class="input-box col-lg-6" #click="isActive = 1" :class="{'focus': isActive === 1}">
<label class="input-label">
{{ $t("system.first_name") }}
</label>
<input type="text" class="input-1" v-model="first_name" #input="checkForInput">
</div>
<div class="input-box col-lg-6" #click="isActive = 2" :class="{'focus': isActive === 2}">
<label class="input-label">
{{ $t("system.last_name") }}
</label>
<input type="text" class="input-1" v-model="last_name" #input="checkForInput">
</div>
</div>
<div class="row justify-content-center">
<div class="input-box col-lg-12" #click="isActive = 3" :class="{'focus': isActive === 3}">
<label class="input-label">
E-mail
</label>
<input type="text" class="input-1" v-model="email" #input="checkForInput">
</div>
</div>
</form>

Property or method "urlImg" is not defined on the instance but referenced during render

I'm trying to create a submit form, but all my v-model are giving me this error.
Here is one example of how I'm creating the form inputs:
<template>
<div class="card mx-xl-5">
<!-- Card body -->
<div class="card-body">
<div>
<form v-on:submit.prevent="pushLocation">
<div class="form-row">
<div class="col-md-6">
<label>Name:</label>
<input
type="text"
class="form-control"
v-model="txtLocationName"
/>
</div>
<div class="col-md-6"> <div class="card mx-xl-5">
<label>Description</label>
<input
type="text"
class="form-control"
v-model="txtLocDescription"
placeholder="Description"
/>
</div>
</div>
<div class="form-group">
<label for="type">Tipo de localização</label>
<select class="form-control" id="type" v-model="typeLoc">
<option value="museum">Museum</option>
<option value="restaurant">Restaurant</option>
<option value="tourist_attraction">Monument</option>
<option value="art_gallery">Galery</option>
</select>
</div>
<div class="col-md-6">
<label>Imagem</label>
<input type="url" class="form-control" v-model="urlImg" placeholder="Link" />
</div>
<div class="form-group row">
<div class="col-auto">
<button type="submit" class="btn btn-primary">Add</button>
</div>
</div>
</form>
</div>
</div>
And here is how I'm setting the properties on my script:
name: "LocationList",
data: function() {
return {
id: 0,
txtLocationName: "",
txtLocDescription: "",
typeLoc: "",
urlImg: "",
listLocation: [],
locationChecked: false
};},
methods: {
getLastLocationId() {
if (this.listLocation.length) {
return this.listLocation[this.listLocation.length - 1].id;
} else {
return 0;
}
},
checkLocationName() {
if (this.listLocation.length) {
for (const location of this.listLocation) {
if (location.Name == this.txtLocName) {
(this.locationChecked = false),
alert("nome de localização indisponivel");
} else {
this.userChecked = true;
}
}
}
},
pushLocation() {
this.checkLocationName();
this.getCoordenates();
if (this.locationChecked == true) {
this.$store.commit("ADD_USER", {
id: this.getLastLocationId() + 1,
Name: this.txtLocationName,
Description: this.txtLocDescription,
Type: this.typeLoc,
imgLink: this.urlImg
});
this.$router.push({ name: "adminLocations" });
} else {
alert("erro no registo");
}
}
}
I've done this type of forms multiple times, yet I can figure out why i'm having this error.I added the rest of my vue component. I get the error on all the property and methods, not only on "urlImg".Meaning all the properties that exist in the data and are in the form are giving me this error.
One last point, the final function, pushLocation() is also giving the error, saying that it is not a real function.

Validations not being reset after submit

After i submit the form and re-initialize the form it still doesn't reset the validations. I have tried multiple solution but it still does not work
this.form.markAsPristine();
this.form.markAsUntouched();
this.form.updateValueAndValidity();
this.form.clearValidators();
this.form.clearAsyncValidators();
None of this actually do the job.
This is my html code:
<form [formGroup]="form">
<div class="row">
<mat-form-field style="margin-top: 20px; margin-left: 20px">
<input [errorStateMatcher]="matcher" formControlName="name" matInput placeholder="Prescurtare">
<mat-error *ngIf="form.controls['name'].hasError('required')">
Introduceti o valoare
</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field style="margin-top: 20px; margin-left: 20px">
<input formControlName="fullName" matInput placeholder="Nume complet">
<mat-error *ngIf="form.controls['name'].hasError('required')">
Introduceti o valoare
</mat-error>
</mat-form-field>
</div>
<div class="col-xs-12" formArrayName="groups">
<label for="imagePath">Grupe</label>
<button mat-icon-button color="primary" (click)="addNewDepartment()">
<mat-icon aria-label="Example icon-button with a heart icon">add</mat-icon>
</button>
<div class="row" *ngFor="let ingredientCtrl of form.get('groups').controls; let i = index" [formGroupName]="i" style="margin-top: 10px;">
<mat-form-field style="margin-left: 50px">
<input formControlName="name" matInput placeholder="Nume">
<mat-error *ngIf="form.get('groups').controls[i].hasError('required')">
Introduceti o valoare
</mat-error>
</mat-form-field>
<mat-form-field style="margin-left: 50px">
<input formControlName="year" matInput placeholder="Anul" [matAutocomplete]="auto">
<mat-error *ngIf="form.get('groups').controls[i].hasError('required')">
Introduceti o valoare
</mat-error>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of options" [value]="option">{{option}}</mat-option>
</mat-autocomplete>
<div class="col-xs-2">
<button mat-icon-button color="accent" (click)="onDeleteDepartment(i)">
<mat-icon aria-label="Delete">delete</mat-icon>
</button>
</div>
</div>
</div>
<button type="submit" [disabled]="!form.valid" (click)="onSubmit()" class="btn btn-success" style="margin-top: 20px">Salveaza</button>
</form>
My typescript code:
form: FormGroup;
private initForm() {
let name = '';
let fullName = '';
const groups = new FormArray([], [Validators.required]);
this.form = new FormGroup(
{
'name': new FormControl(name, [Validators.required]),
'fullName': new FormControl(fullName, [Validators.required]),
'groups': groups
});
this.matcher = new DepartmentStateMatcher();
}
onSubmit() {
this.dataService.addDepartment(this.form.value);
this.resetForm();
setTimeout(() => { this.exampleDatabase.departmentsChange.value.push(this.dataService.getDialogData()); this.refreshTable(); }, 100);
}
private resetForm() {
this.form.markAsPristine();
this.form.markAsUntouched();
this.form.updateValueAndValidity();
this.form.clearValidators();
this.form.clearAsyncValidators();
let name = '';
let fullName = '';
const groups = new FormArray([], [Validators.required]);
this.form = new FormGroup(
{
'name': new FormControl(name, [Validators.required]),
'fullName': new FormControl(fullName, [Validators.required]),
'groups': groups
});
this.matcher = new DepartmentStateMatcher();
}
export class DepartmentStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const isSubmitted = form && form.submitted;
return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
}
}
I would expect that validations would be reset but they are not.

I have a nested group Angular form. I want to take the group's controls values and match the name of the controls to my JSON object

I have a small contact form that I have built using Angular. I want to validate the form and change the form data to JSON object.
Here's my Form:
<form [formGroup]="addContactForm" (ngSubmit)="onSubmit()" novalidate >
<div [hidden]="addcontactForm.submitted">
<div class="modal-body" style="overflow: auto">
<!-- create contact -->
<div style="padding: 0 0px 0px 25px;margin-top:30px;">
<div class="form-horizontal">
<span *ngIf="ACname.invalid && (ACname.dirty || ACname.touched)" class="has-error">
<span *ngIf="ACname.errors.required">
Last Name is required.
</span>
</span>
<!-- name -->
<div FormGroupName="ACname">
<div class="form-group" style="text-align:right" [ngClass]="{ 'has-error': ACname.addContactFirstName.invalid && (ACname.addContactFirstName.dirty || ACname.addContactFirstName.touched) }">
<label class="col-sm-3" for="addContactFirstName">First Name</label>
<div class="col-sm-7">
<input id="addFirstName"
formControlName="addContactFirstName"
class="form-control"
placeholder="Enter First Name" />
</div>
</div>
<div class="form-group" style="text-align:right" [ngClass]="{ 'has-error': ACname.addContactLastName.invalid && (ACname.addContactLastName.dirty || ACname.addContactLastName.touched) }">
<label class="col-sm-3" for="addContactLastName">Last Name</label>
<div class="col-sm-7">
<input id="addLastName"
class="form-control"
formControlName="addContactLastName"
placeholder="Enter Last Name" />
</div>
</div>
</div>
<div FormGroupName="ACcontactMethod">
<!-- office phone -->
<div class="form-group" style="text-align:right" [ngClass]="{ 'has-error': ACcontactMethod.addcontactForm.submitted && !ACcontactMethod.addContactOfficePhone.valid }">
<label class="col-sm-3" for="addContactOfficePhone">Office Phone</label>
<div class="col-sm-7">
<input id="addofcPhone"
type="text"
class="form-control"
formControlName="addContactOfficePhone"
placeholder="Enter Office Number" />
<span *ngIf="addContactOfficePhone.invalid && (addContactOfficePhone.dirty || addContactOfficePhone.touched)" class="has-error">
<span *ngIf="addContactLastName.errors.required">
Name is required.
</span>
</span>
</div>
</div>
<!-- mobile phone -->
<div class="form-group" style="text-align:right" [ngClass]="{ 'has-error': addcontactForm.submitted && !addContactMobilePhone.valid }">
<label class="col-sm-3" for="addContactMobilePhone">Mobile Phone</label>
<div class="col-sm-7">
<input id="addmobPhone"
type="text"
class="form-control"
formControlName="addContactMobilePhone"
placeholder="Enter Mobile Number" />
<span *ngIf="addContactMobilePhone.invalid && (addContactMobilePhone.dirty || addContactMobilePhone.touched)" class="has-error">
<span *ngIf="addContactMobilePhone.errors.required">
Name is required.
</span>
</span>
</div>
</div>
<!-- home phone -->
<div class="form-group" style="text-align:right" [ngClass]="{ 'has-error': addcontactForm.submitted && !addContactHomePhone.valid }">
<label class="col-sm-3" for="addContactHomePhone">Home Phone</label>
<div class="col-sm-7">
<input id="addhomPhone"
type="text"
class="form-control"
formControlName="addContactHomePhone"
placeholder="Enter Home Number" />
<span *ngIf="addContactHomePhone.invalid && (addContactHomePhone.dirty || addContactHomePhone.touched)" class="has-error">
<span *ngIf="addContactHomePhone.errors.required">
Name is required.
</span>
</span>
</div>
</div>
<!-- email -->
<div class="form-group" style="text-align:right" [ngClass]="{ 'has-error': addcontactForm.submitted && !addContactEmail.valid }">
<label class="col-sm-3" for="addContactEmail">Email</label>
<div class="col-sm-7">
<input id="addEmail"
type="email"
class="form-control"
formControlName="addContactEmail"
placeholder="Enter Email" />
<span *ngIf="addContactEmail.invalid && (addContactEmail.dirty || addContactEmail.touched)" class="has-error">
<span *ngIf="addContactEmail.errors.required">
Name is required.
</span>
</span>
</div>
</div>
<!-- chat id -->
<div class="form-group" style="text-align:right" [ngClass]="{ 'has-error': addcontactForm.submitted && !addContactChatId.valid }">
<label class="col-sm-3" for="addContactChatId">Chat ID</label>
<div class="col-sm-7">
<input id="addChatID"
type="text"
class="form-control"
formControlName="addContactChatId"
placeholder="Enter Chat ID" />
<span *ngIf="addContactChatId.invalid && (addContactChatId.dirty || addContactChatId.touched)" class="has-error">
<span *ngIf="addContactChatId.errors.required">
Name is required.
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left" (click)="addcontactForm.reset()" data-dismiss="modal">Close</button>
<button type="submit"
class="btn btn-primary"
[disabled]="!addcontactForm.valid"
(click)="addContact(model);">
Add Contact
</button>
</div>
</div>
<div class="submitted-message" *ngIf="addcontactForm.submitted">
<p>You've submitted your contact, {{ addcontactForm.value.addContactFirstName }} {{ addcontactForm.value.addContactLastName }}!</p>
<button type="button" class="btn btn-default pull-left" (click)="addcontactForm.reset()" data-dismiss="modal">Close</button>
<button (click)="addcontactForm.resetForm({})">Add new Contact </button>
</div>
</form>
Here's my ts:
import { Component} from '#angular/core';
import { AppComponent } from '../app.component';
import { FormBuilder, Validators, FormGroup, FormControl } from '#angular/forms';
#Component({
selector: 'addcontactmodal',
templateUrl: 'addcontact.component.html'
})
export class AddContactModalComponent {
id: any;
addContactForm: FormGroup;
constructor(private _appComponent: AppComponent, private fb: FormBuilder) {
this.id = localStorage.getItem('Id');
this.addContactForm = this.fb.group({
ACname: new FormGroup({
addContactFirstName: new FormControl('', Validators.minLength(40)),
addContactLastName: new FormControl('', Validators.minLength(40)),
}),
ACcontactMethod: new FormGroup({
addContactOfficePhone: new FormControl('', Validators.minLength(20)),
addContactMobilePhone: new FormControl('', Validators.minLength(20)),
addContactHomePhone: new FormControl('', Validators.minLength(20)),
addContactEmail: new FormControl('', Validators.minLength(127)),
addContactChatId: new FormControl('', Validators.minLength(127))
})
});
}
// private method(s)
private addContact() {
let data = {
ChatId: this.fb.group('addContactChatId').value,
Email: addContactEmail,
FirstName: addContactFirstName,
HomePhone: addContactHomePhone,
MobilePhone: addContactMobilePhone,
LastName: addContactLastName,
OfficePhone: this.model.addContactOfficePhone
}
this._appComponent.signalRService.setAgentContact(this.id, data);
}
}
I want to:
Validate the form
Have the data output to JSON
I do not get any of the validation the form promises. It doesn't submit.
Errors:
nhandled Promise rejection: Cannot read property 'invalid' of undefined ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read property 'invalid' of undefined
at Object.View_AddContactModalComponent_0.co [as updateDirectives]
You are not using complete property paths for your validation messages. Here's a simplified template of yours:
<form [formGroup]="addContactForm" (ngSubmit)="onSubmit()" novalidate >
<!-- formGroupName - mark all form controls belonging to this group inside tag -->
<div formGroupName="ACname">
<input formControlName="addContactFirstName" />
<!-- use complete property path or do like follows! -->
<span *ngIf="addContactForm.hasError('minlength', 'ACname.addContactFirstName')">
Minlength 40
</span>
</div>
</form>
StackBlitz

React form not clearing inputs after submit POST

Not sure why the setState function in the addUser() not doing it's job. The POST request works fine, but the inputs don't clear and that is an issue for the users. Perhaps a second pair of eyes, can spot the flaw.
import React, { Component, PropTypes } from 'react';
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
import { Link } from 'react-router';
// Import Style
import styles from './UserRegistrationForm.css';
export class UserRegistrationForm extends Component {
constructor(props) {
super(props);
this.state = { nickname: '', studentId: '', email: '', password: '' };
this.handleInputChange = this.handleInputChange.bind(this);
this.addUser = this.addUser.bind(this);
}
handleInputChange(event) {
this.setState({
[event.target.name]: event.target.value,
});
}
addUser = () => {
if (this.state.nickname && this.state.studentId && this.state.email && this.state.password) {
this.props.addUser(this.state.nickname, this.state.studentId, this.state.email, this.state.password);
this.setState({ nickname: '', studentId: '', email: '', password: '' });
}
};
render() {
return (
<div className={`${styles.formContainer} ${styles.center}`}>
<i className={`${styles.cap} fa fa-graduation-cap`} />
<h1 className={styles.title}><FormattedMessage id="siteTitle" /></h1>
<div className="row">
<form method="POST" className="col-lg-4 push-lg-4 col-md-6 push-md-3 col-xs-8 push-xs-2">
<div className="form-group row">
<label className="input-labels">Full Name</label>
<input type="text" className="form-control" name="nickname" placeholder="Full Name" onChange={this.handleInputChange} />
</div>
<div className="form-group row">
<label className="input-labels">Student ID</label>
<input type="text" className="form-control" name="studentId" placeholder="Student ID" onChange={this.handleInputChange} />
</div>
<div className="form-group row">
<label className="input-labels">Email</label>
<input type="email" className="form-control" name="email" placeholder="Email" onChange={this.handleInputChange} />
</div>
<div className="form-group row">
<label className="input-labels">Password</label>
<input type="password" className="form-control" name="password" placeholder="Password" onChange={this.handleInputChange} />
</div>
<div className={styles.center}>
<button
className={`${styles.btnOutlineSecondary} btn btn-outline-secondary ${styles.signInButton}`}
type="button" onClick={this.addUser}
>
Register and Start Studying!
</button><br /><br />
<Link to="/profile"><button className="btn btn-info" type="button">Temp Button to Profile Page</button></Link><br /><br />
<Link to="/">Already have an account? Sign in Here</Link>
</div>
</form>
</div>
</div>
);
}
}
UserRegistrationForm.propTypes = {
addUser: PropTypes.func.isRequired,
intl: intlShape.isRequired,
};
export default injectIntl(UserRegistrationForm);
There is no two-way data-binding in react, so you have to be careful when implementing controlled components https://facebook.github.io/react/docs/forms.html#controlled-components
for every one of your inputs, to make them controlled inputs, that will clear on submit, you must set their values to the corresponding state value, e.g.
<input value={this.state.nickname} type="text" className="form-control" name="nickname" placeholder="Full Name" onChange={this.handleInputChange} />
and
<input value={this.state.nickname} type="text" className="form-control" name="studentId" placeholder="Student ID" onChange={this.handleInputChange} />
... for every one of your inputs, adding the value attribute will make sure they stay in sync with, this.setState calls