Passing data from parent to child (Nested Form) - javascript

I'm creating a nested form in which I have the parent component that holds the form(s) and has the submit button. And there's the child component which is the form itself.
When I submit the form the property submitted became true, I need to inform my child component that submitted is now true when submitted.
This is the code from submit button in parent component:
enviarDados(model: dadosAcordo, isValid: boolean, isJuridica:boolean) {
this.servError = "";
this.submitted = true;
//more code
}
And this is how the child component look like so far:
export class TitularComponent implements OnChanges {
#Input('group') // this is the input for the form
#Input('submitted') // input for the status of submit
public titularForm: FormGroup;
#Output() modelChanged = new EventEmitter();
constructor(private _fb: FormBuilder, private finalizaAcordo:FinalizaNegociacaoService) {}
ngOnChanges(){
}
// more code
This is the html on the parent component:
<div class="wrap-acordo">
<form [formGroup]="formDadosBancarios" novalidate class="" (ngSubmit)="enviarDados(formDadosBancarios.value)">
<div formArrayName="dados_titular">
<div *ngFor="let dados_titular of formDadosBancarios.controls.dados_titular.controls; let i=index">
<div [formGroupName]="i">
<div class="col s12" *ngIf="formDadosBancarios.controls.dados_titular.length > 1">
<span class="span-removeTitular right-align" (click)="removeTitular(i)"> Remover {{i+1}}ยบ Titular </span>
</div>
<titular (modelChanged)="recebeValidators($event)" [group]="formDadosBancarios.controls.dados_titular.controls[i]"></titular>
</div>
</div>
</div>
<div class="col s12 m6">
<input type="submit" class="botao-medio btn-aceita" value="Aceitar">
</div>
<div class="col s12 m6">
<input type="button" class="botao-medio btn-recusa" value="Recusar">
</div>
</div>
</form>
</div>
Can someone help me? Thanks :)

In your parent component, when the button is clicked, set this.formsubmitted = true . And in child cmponent set this form submitted as input using #Input. If you need to dp something once the formsubmitted becomes true, use ngonchanges for the input formsubmitted.
Ngonchanges(change: Simplechange) {
if(changes['submitted']&& changes['submitted'].currentvalue){
Do your stuff here
}
}
You can refer https://angular.io/docs/ts/latest/api/core/index/OnChanges-class.html

Related

TypeError: Cannot read property '_rawValidators' of null after Ng build

I am new to angular. I am dynamically rendering some fields into my reactive form. Everything works great when I am using ng serve with a mock request (i.e. rendering happens properly, no error in the console.log). As soon as I build the project with ng build and use a proper backend, I get the error for each field I am rendering dynamically:
main.js:1 ERROR TypeError: Cannot read property '_rawValidators' of null
I couldn't find any background on this error. I would love to hear your thoughts.
more background
// these fields change with selection
this.datafields = [{
dfId: 48,
dfName: "Phone",
dfType: "text",
dfOptions: null,
dfValue: ""
},
{
dfId: 49,
dfName: "Eval",
dfType: "select",
dfOptions: ["","Remote","Live"],
df_value: "",
}]
typescript rendering in ngOnInit (tried ngAfterViewInit with no improvement)
dfGroup = new FormGroup({})
...
...
this.eyeForm = this.formBuilder.group({
focus: ['', Validators.required],
datafields: this.formBuilder.array([])
})
...
...
if (this.datafields != null || this.datafields != undefined) {
this.datafields.forEach((x:any) => {
this.dfGroup.setControl(x.dfName, new FormControl(x.dfValue));
});
this.getDataFields.push(this.dfGroup);
}
and HTML looks like the following:
<div [formGroup]="dfGroup">
<div class="row pt-2" *ngFor="let field of datafields; let i=index">
<div class="col-4 d-flex align-items-center 13required">
{{field.dfName}}
</div>
<div class="col-6">
<mat-form-field *ngIf="field.dfType == 'text'" appearance="outline">
<input
matInput
[type]="field.dfType"
[formControlName]="field.dfName"
required
/>
</mat-form-field>
<mat-form-field
*ngIf="field.dfType == 'select'"
appearance="outline"
>
<mat-select [formControlName]="field.dfName" placeholder="">
<mat-option
[value]="option"
*ngFor="let option of field.dfOptions"
>
{{ option }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
I ran in to this situation when I was mocking out my template and typo'd my formControlName attribute.
<mycomponent formControlName="bogusfieldSpelledWrong" ...>
Why Angular showed it as this error likely has something to do with how the component was initializing/changing the form.
it must be about formControlName. check out your form control names in ts file and html file.
for nested groups you can use formGroupName, then use formControlName.
this.yourForm = this.fb.group({
name: [''],
contact: this.fb.group({
address: ['']
})
})
<form [formGroup]="yourForm">
<input type="text" formControlName="name" />
<div formGroupName="contact">
<input type="text" formControlName="address" />
</div>
</form>
This is caused by malforming the form in the view.
It was caused by misordering formArrayName, the loop and formGroupName
The form (controller)
form = <FormGroup>this.fb.group({
hops: this.fb.array([
this.fb.group({...}),
...
])
});
The view (mistake)
<li class="asset" *ngFor="let control of hops.controls; let i = index;">
<div formArrayName="hops">
<div [formGroupName]="i">
The view (corrected)
<div formArrayName="hops">
<li class="asset" *ngFor="let control of hops.controls; let i = index;">
<div [formGroupName]="i">
In our application, we had a minifier that renamed class variable names (in this case, the name of form controls) as an optimisation. This made the issue only appear in our production environments (optimisations weren't performed during local development).
The solution was to directly reference the control instance instead of using a string, so that the variable referenced in the angular template was renamed consistently with the class local variable.
Before:
<div formGroupName="myInputGroup">
<div formControlName="myInput">...</div>
</div>
After:
<div [formGroup]="myInputGroup">
<div [formControl]="myInputGroup.controls.myInput">...</div>
</div>
another reason for this issue is when you forget to assign formGroup
wrong:
export class MyComponent{
formGroup: FormGroup;
...
}
correct:
export class MyComponent{
formGroup = new FormGroup({...});
...
}
I had a similar issue, you need to add an extra div with property [formGroupName]="i",
The final code would be,
<div [formGroup]="dfGroup">
<div class="row pt-2" *ngFor="let field of datafields; let i=index">
<div [formGroupName]="i">
<div class="col-4 d-flex align-items-center 13required">
{{field.dfName}}
</div>
<div class="col-6">
<mat-form-field *ngIf="field.dfType == 'text'" appearance="outline">
<input matInput [type]="field.dfType" [formControlName]="field.dfName" required />
</mat-form-field>
<mat-form-field *ngIf="field.dfType == 'select'" appearance="outline">
<mat-select [formControlName]="field.dfName" placeholder="">
<mat-option [value]="option" *ngFor="let option of field.dfOptions">
{{ option }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
</div>
This is resolved by adding formcontrolname value.
Type error gives you null because it didn't find value from your Component.
In your Html file formcontrolname must be the same as FormGroup value.
For example:
<formControlName = 'username'>
this.formGroupName = this.formBuilder.group({
username: ["", [Validators.required]],
})
})
//html page properties
formControlName="drugReproductive"
//ts file attributes
this.drugTypeTwo = new FormControl(0);
this.drugTypeThree = new FormControl(0);
this.drugTypeFour = new FormControl(0);
this.drugTypeFive = new FormControl(0);
this.drugWithCanisterForm = this.fb.group({
drugAntineoplastic:this.drugAntineoplastic,
drugNonAntineoplastic:this.drugNonAntineoplastic,
drugReproductive:this.drugReproductive,
drugTypeOne:this.drugTypeOne,
drugTypeTwo:this.drugTypeTwo,
drugTypeThree:this.drugTypeThree,
drugTypeFour:this.drugTypeFour,
drugTypeFive:this.drugTypeFive,
configuration: this.configuration,
deviceId:this.deviceId,
deviceTypeId: this.deviceTypeId,
isOtcExcluded: this.isOtcExcluded,
isScheduleExcluded: this.isScheduleExcluded,
isUnitOfUsageExcluded: this.isUnitOfUsageExcluded,
unitOfUsageValue: this.unitOfUsageValue,
canisterQuantity: this.canisterQuantity,
canisterSize: this.canisterSize,
searchText: this.searchText,
scheduleExcludedValue: this.scheduleExcludedValue,
nioshValue:this.nioshValue,
superCellNo:this.superCellNo,
lockingCellNo:this.lockingCellNo,
superLockingCellNo:this.superLockingCellNo,
isNioshExcluded:this.isNioshExcluded
});
In my case this problem arised, because i didn't bind the formControllName attributes in my form object

How to set select value using Reactive form and looping through array

I am trying to set select value dynamically but the changes are not reflected even with using detect changes.
Component:
export class AppComponent implements OnInit {
constructor(private cd: ChangeDetectorRef) {
}
genders=['male','female'];
SignupForm:FormGroup;
ngOnInit(){
this.SignupForm = new FormGroup({
'gender':new FormControl(),
});
}
onSubmit(){
console.log(this.SignupForm);
}
setGender() {
this.SignupForm.controls.gender.setValue(this.genders[1]);
console.log(this.SignupForm.controls.gender.value);
this.cd.detectChanges();
}
}
Template:
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-8 col-md-offset-2 col-sm-offset-1">
<form [formGroup]="SignupForm" (ngSubmit)="onSubmit()">
<select fromControlName="gender">
<option *ngFor="let g of genders">{{g}}</option>
</select>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
</div>
</div>
</div>
<button class="btn btn-primary" (click)="setGender()">Set Female</button>
Stackblitz
You have a very little error, see:
<select fromControlName="gender">
Change by:
<select formControlName="gender">
I think you can try something looking like the following, this would be selecting a default option for the select / option by getting it to read the value of the form control which would be set early into the lifecycle of the component.
Solution
Add this to your options to set the default the the form value.
<option *ngFor="let g of genders" [selected]="gender.value">{{g}}</option>
Then within your component.
public ngOnInit(): void {
this.SignupForm = new FormGroup({
'gender':new FormControl(),
});
}
public setGender(): void
{
this.gender.setValue(this.genders[1]);
this.cd.detectChanges();
console.log(this.gender) // just check here the value is set correct.
}
public get gender(): AbstractControl
{
return this.SignupForm.controls['gender']
}
This should give the the required functionality. Looking a little neater.
Here is an article
someone wrote on the subject. All the best.

Angular 5 Passing form data to another component's dropdown in sync

I have a form (a material dialog modal) which lets the user to create an account, once the user clicks on Register button then the user stays on the same page with the username of that account that he created. The issue I am having is its getting created but its not getting updated in sync with the closing of dialog modal. Means the user should be registered and in parallel that created user value should be populated in the dropdown for better user expereince. I dont want the user to distract from the current page because if the user have entered the details and if that page is reloaded then all the data whatever he entered will be lost. So i dont want that to happen. So for that i created this below code.
<section class="container-fluid with-maxwidth chapter">
<article class="article">
<div class="box box-default">
<div class="box-body">
<mat-horizontal-stepper [linear]="true" #stepper>
<mat-step [stepControl]="firstFormGroup">
<form [formGroup]="firstFormGroup">
<ng-template matStepLabel>Project Registration</ng-template>
<div class="form-group row"></div>
<div class="form-group row">
<label for="name" class="col-md-0 control-label"></label>
<div class="col-md-5">
<mat-input-container class="full-width">
<input required [(ngModel)]="project.name" formControlName="nameCtrl" id="name"
matInput placeholder="Project name">
</mat-input-container>
</div>
</div>
<!-- Repository details -->
<div class="form-group row">
<label for="name" class="col-md-0 control-label"></label>
<div class="col-md-5">
<mat-input-container class="full-width">
<input required [(ngModel)]="project.url" formControlName="urlCtrl" id="repo"
matInput placeholder="Repository URL">
</mat-input-container>
</div>
<div class="col-md-7">
<div class="callout1 text-muted callout-info1">
<p>e.g. https://github.com/username/MyApp.git or
git#github.com:username/MyApp.git.
</p>
</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-0 control-label">
</label>
<div class="col-md-5">
<mat-form-field>
<mat-select placeholder="Repository Credentials" required
[(ngModel)]="project.account.id" formControlName="typeCtrl">
<mat-option *ngFor="let account of accounts" [value]="account.id">
{{account.name}} ({{account.accountType}})
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-7">
<div class="callout1 text-muted callout-info1">
<p>
Add credentials
<br/>
Credentials are required for automatic test creation and check-in.
</p>
</div>
</div>
</div>
<div>
<mat-card-actions>
<button mat-raised-button color="primary"
class="nav-btn"
[disabled]="firstFormGroup.invalid"
(click)="save(stepper);">Save & Next
</button>
</mat-card-actions>
</div>
<div class="form-group row">
<div class="col-md-0"></div>
<div class="col-md-8">
<button [disabled]="!heroForm.valid" mat-raised-button color="primary" (click)="create();"
class="btn-w-md no-margin-left">Register
</button>
<button mat-button type="button" color="primary" class="btn-w-md" (click)="onClose();">Cancel
</button>
</div>
</div>
</form>
</mat-step>
</mat-horizontal-stepper>
</div>
</div>
</article>
</section>
From the template's below code, here if go to other page and then come to here then the username is adding to the drop down properly. But i dont want the user to go back and forth to see whether his credentials are registered or not but instead i want to show the credentials created on the fly so that he can further move.
<mat-form-field>
<mat-select placeholder="Repository Credentials" required
[(ngModel)]="project.account.id" formControlName="typeCtrl">
<mat-option *ngFor="let account of accounts" [value]="account.id">
{{account.name}} ({{account.accountType}})
</mat-option>
</mat-select>
</mat-form-field>
The code for register dialog box component
export class RegisterComponent implements OnInit{
#Input() entry: Account = new Account();
create(entry: Account) {
this.handler.activateLoader();
this.snackbarService.openSnackBar(this.entry.name + " registering...", "");
this.accountService.create(entry).subscribe(results => {
this.entry = entry;
this.handler.hideLoader();
if (this.handler.handle(results)) {
return;
}
this.snackbarService.openSnackBar(this.entry.name + " registered successfully", "");
this.onClose();
// this.router.navigateByUrl('/app/projects', {skipLocationChange: true}).then(()=>
// this.router.navigate(['/app/projects/new']));
this.router.navigate(['/app/projects/new']);
}, error => {
this.handler.hideLoader();
this.handler.error(error);
});
}
onClose(){
this.dialogRef.close();
}
}
This is where i have written the service:
import { Account } from './../models/project.model';
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '#angular/common/http';
import { Headers } from '#angular/http';
import { Observable, Subject } from 'rxjs';
import 'rxjs/add/observable/timer';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class AccountService {
private serviceUrl = '/api/v1/accounts';
private entry = new Subject<Object>();
entry$ = this.entry.asObservable();
constructor(private http: HttpClient) {
}
create(entry: Account): Observable<any> {
return this.http.post(this.serviceUrl, entry);
}
emitAccount(entry){
this.entry.next();
}
}
I want the user to be on the same page and should update the dropdown with latest results. How is that possible? Could you please suggest me? What i have done wrong with my code.
Thanks.
create Service:
let newEntry = this.http.post(this.serviceUrl, entry);
emitAccount(newEntry);
return newEntry;
Register Component:
entry$.subscribe(updateAccount => {
accounts.push(updateAccount)
}
So to check .. it's about this section?
<mat-option *ngFor="let account of accounts" [value]="account.id">
{{account.name}} ({{account.accountType}})
</mat-option>
BEcause I don't see anything in your code repopulating accounts array after registering.
I can't see where you bind the accounts array.

Angular 2: How to prevent a form from submitting on keypress enter?

I have a form with one field that acts as autocomplete. If the user enters a word and presses enter, the content of the field should be added to a list below the field.
The problem: When the user hits enter, naturally the whole form is being submitted.
I already return false on the function that handles the keypress. But the form seems to be submitted even before this function is called.
How do I prevent this from happening?
The basic form:
<div id="profileForm">
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()" method="post" *ngIf="!showSuccessMessage">
<div class="row">
<div class="form-group col-xs-12 col-sm-6">
<label for="first_name">My Skills</label>
<div class="autocomplete">
<input formControlName="skill_string" [(ngModel)]="skillString" name="skill_string"
type="text" class="form-control" id="skill_string" placeholder="Comma separated" (keyup.enter)="skillsHandleEnter(skillString)">
<ul class="autocomplete-list" *ngIf="skillHints.length > 0">
<li class="list-item" *ngFor="let skill of skillHints" (click)="addSkillFromAutocomplete(skill)">{{skill}}</li>
</ul>
</div>
<div id="skill-cloud" class="tag-cloud">
<span class="skill-tag tag label label-success" *ngFor="let skill of selectedSkills" (click)="removeSkill(skill)">{{skill}} x</span>
</div>
</div>
</div>
<div class="row">
<hr>
<div class="form-group submit-group">
<div class="col-sm-12">
<button type="submit" class="btn btn-primary pull-right" [disabled]="!profileForm.valid">Save</button>
</div>
</div>
</div>
</form>
</div>
The basic component (I stripped a lot of the logic for posting it here):
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormBuilder } from '#angular/forms';
import { ActivatedRoute, Router } from '#angular/router';
import { Subscription } from 'rxjs/Rx';
import 'rxjs/add/operator/debounceTime';
import * as _ from 'lodash';
import { MemberService } from '../shared/index';
#Component({
moduleId: module.id,
selector: 'signup',
templateUrl: 'signup.component.html',
styleUrls: ['signup.component.css']
})
export class SignupComponent implements OnInit {
private profileForm:FormGroup;
private validation_errors:Array<any>;
private selectedSkills:Array<string>;
private skillHints:Array<string>;
private skillString:string;
constructor(private route: ActivatedRoute,
private formBuilder: FormBuilder,
private memberService: MemberService,
private router: Router ) {
this.selectedSkills = [];
this.skillHints = [];
this.skillString = '';
// Set up form
this.profileForm = this.formBuilder.group({
skill_string: ['']
});
}
ngOnInit(): any {
// Do something
}
updateSelectedSkills(skillString:string):void {
if(skillString) ) {
let cleanString = skillString.trim().replace(/[ ]{2,}/g, ' ');
this.selectedSkills = _.compact(this.selectedSkills.concat(cleanString.split(',')));
this.skillString = '';
this.skillHints = [];
}
}
skillsHandleEnter(skillString:string):void {
console.log("ENTER");
this.updateSelectedSkills(skillString);
return false;
}
autocompleteSkills(term:string):void {
this.memberService.autocompleteSkills(term).subscribe(
res => {
this.skillHints = [];
for(let i = 0; i < res.data.length; i++) {
this.skillHints.push(res.data[i].name);
}
}
);
}
addSkillFromAutocomplete(skillString:string):void {
this.selectedSkills.push(skillString);
this.memberProfile.skill_string = '';
this.skillHints = [];
this.skillString = '';
}
onSubmit():void {
this.memberService.saveProfile(this.memberProfile, this.selectedSkills).subscribe(
res => {
console.log(res);
}
);
}
}
Try
<form (keydown.enter)="$event.target.tagName == 'TEXTAREA'" [formGroup]="profileForm" (ngSubmit)="onSubmit($event)">
It will also allow enter in Textareas.
So the answer was actually quite simple... It wasn't Event.preventDefault() since I was listening for Enter on the input field and not the button. Removing type="submit" from the button wasn't enough since all buttons are type submit by default. The only change necessary was on the button element, adding type="button" explicitly and adding a (click) listener:
<button type="button" (click)="onSubmit()" class="btn btn-primary pull-right" [disabled]="!profileForm.valid">Save</button>
The only kind-of problem: Now submitting the form with enter never works. Would be a tiny bit more elegant to only prevent enter from submitting the form when the focus is in the autocomplete input field.
Edit:
To only prevent enter from submitting the form when the cursor is in the autocomplete field can be achieved by using Ankit Singh's solution and modifying it a bit:
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()" method="post" (keydown.enter)="$event.target.id != 'skill_string'" *ngIf="!showSuccessMessage">
(Note: The condition has to return false to prevent the default action to be triggered)
Of course we then need our regular submit button again (without the click event attached, or the form will submit twice):
<button type="submit" class="btn btn-primary pull-right" [disabled]="!profileForm.valid">Save</button>
You could also check the event.target.classList if you want to use a .autocomplete class. Or move the checking logic to a function into which you pass the $event.
Events in Angular 2 behave like normal DOM events. To capture the event object, pass $event as a parameter in the event callback from the template:
Html:
<button (keyup.enter)="skillsHandleEnter($event, skillString)"></button>
JavaScript using Event.preventDefault():
#Component(...)
class MyComponent {
skillsHandleEnter(event, skillString) {
event.preventDefault();
// ... your logic
}
}
Prevent a form from submittion on enter or by clicking a button
<textarea (keydown.enter)="provoked($event)"></textarea>
<button (keydown.enter)="provoked($event)" (click)="provoked($event)"></button>
provoked($event) {
$event.preventDefault()
}
in case if you need to pass data to the method, then try
<textarea (keydown.enter)="provoked($event, data)"></textarea>
<button (keydown.enter)="provoked($event, data)" (click)="provoked($event, data)"></button>
provoked($event, data) {
$event.preventDefault()
// process the data here
}

Ember app not posting to server with Ember Data

I am trying to connect my ember app to a node server on the backend. Right now, I have a sign up and login form and when the user submits either form it will go through an authentication process setup in node using Passport. However when the submit button is pressed it just reloads the current page and doesn't even send a HTTP post request. Any ideas on why this is happening/ how to fix it?
Here is my adapter:
import DS from "ember-data";
var ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:8080'
});
export default ApplicationAdapter;
Here is my sign up controller:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
new: function() {
console.log('creating new user...');
var model = this.get('user');
user = this.get('store').createRecord('user', {
title: model.get('title'),
password: model.get('password')
});
user.save().then(function(data) {
// Clear the form.
Ember.$(':input').val('');
});
},
}
});
Here is my model:
import DS from 'ember-data';
export default DS.Model.extend({
username: DS.attr('string'),
password: DS.attr('string')
});
Here is the form:
<div class="row text-center">
<h1>Signup</h1>
</div>
<form>
<div class="row">
<div class="medium-6 medium-centered columns">
{{input value=username type="text" placeholder="Username"}}
</div>
</div>
<div class="row">
<div class="medium-6 medium-centered columns">
{{input value=password type="password" placeholder="Password"}}
</div>
</div>
<div class="row">
<div class="medium-6 medium-centered columns">
{{input class="button" type="submit" value="Signup"}}
</div>
</div>
</form>
Alright, so there seems to be a few issues here.
First, looking at the controller that you posted, there are a few things that don't look right:
The user variable is never declared
You try to get the user property from the controller, but it is never defined
You try to clear the form using Ember.$(':input').val(''); which doesn't really make any sense, if the inputs are bound to the template.
We'll start by cleaning up the template, which will drive the improvements to the controller:
<div class="row text-center">
<h1>Signup</h1>
</div>
<form>
<div class="row">
<div class="medium-6 medium-centered columns">
{{input value=username type="text" placeholder="Username"}}
</div>
</div>
<div class="row">
<div class="medium-6 medium-centered columns">
{{input value=password type="password" placeholder="Password"}}
</div>
</div>
<div class="row">
<div class="medium-6 medium-centered columns">
<button class="button" type="submit" {{action 'createUser'}}>Signup</button>
</div>
</div>
</form>
The major issues seems to be that you're using an {{input}} helper for the button, which doesn't really make any sense. The {{input}} helper if for inputting text. We've also moved the action to be bound to the button being clicked instead, which is the behavior that you want.
Now, the controller:
import Ember from 'ember';
export default Ember.Controller.extend({
// Username for the new user
username: '',
// Password for the new user
password: '',
actions: {
// Create a new user
createUser() {
const username = this.get('username');
const password = this.get('password');
this.get('store').createRecord('user', {
username,
password
}).save()
.then(() => {
this.send('clearForm'); // Invokes the `clearForm` action on the controller
})
.catch(() => {
// Do some kind of error handling if the creation fails
});
},
// Clear the form
clearForm() {
this.set('username', '');
this.set('password', '');
}
}
});
Now we have a controller with two properties defined, to hold the username and password for the new user. They are bound to the input fields in the template, and we manipulate them both get the values out of the template and also to clear them again.
You have a submit button that does a post request by default. You can do the following.
<form {{action 'new' on='submit'}}>
<div class="row">
<div class="medium-6 medium-centered columns">
{{input value=user.username type="text" placeholder="Username"}}
</div>
</div>
<div class="row">
<div class="medium-6 medium-centered columns">
{{input value=user.password type="password" placeholder="Password"}}
</div>
</div>
<div class="row">
<div class="medium-6 medium-centered columns">
<button class="button" type="submit">Signup</button>
</div>
</div>
</form>
This basically says intercept the submit event and call the action instead.
Note that I also added user. to your input values, otherwise you'd get them from your controller as this.get('username'), etc.

Categories