angular6 cannot set the value of ngForm from component.ts - angular6

i am developing an basic angular 6 application that fetches the data, display it in the table, each row has delete, edit button this is one component 'detail list', i have another component as 'detail component' that are having controls to add the record in the table, i am fetching the data from the webapi, adding the record and deleting the record using the same webapi, they all are working fine, now i want to edit the record from the table, i am using the same webapi to fetch the data, webapi returning the record, i want to display this record's data in the 'detail component', the same component that is used to add the record, so at the component i am calling ngAfterViewInit()
>
ngAfterViewInit() {
this.service.change.subscribe((data: Patient) => {
alert('in the detail component of ngAfterViewInit');
console.log(data);
this.ModelChange(data);
}) ;
}
and the code for the ModelChange is as follows
ModelChange(data: Patient) {
this.form.controls['PatientCode'].setValue(data.PatientCode);
}
and my html is like
<form #form="ngForm" autocomplete="on" (submit)="OnSubmit(form)">
<div class="row">
<div class="form-group">
<input name="PatientCode" [(ngModel)]="PatientCode"class="form-control" placeholder ="Patient Code" (ngModelChange)="ModelChange(event)" required>
</div>
<div class="col-md -3 form-group">
<input name="FirstName" [(ngModel)] ="FirstName" class="form-control" placeholder="First Name" required>
</div>
<div class=" col-md-5 form-group">
<input name="LastName" [(ngModel)]="LastName" class="form-control" placeholder="Last Name" required>
</div>
</div>
<div class="row">
<div class="form-group">
<input name="MRN" class="form-control" [(ngModel)]="MRN" placeholder="MRN" required>
</div>
<div class="col-md-3 form-group">
<!--<input name="DateOfBirth" class="form-control" placeholder="Date of Birth">-->
<ejs-datepicker name="DateOfBirth" [(ngModel)]="DateOfBirth" id='datepicker' placeholder='Enter Date Of Birth' [value]='value' [min]='minDate' [max]='maxDate'></ejs-datepicker>
</div>
</div>
<div class="row">
<div class="col-md-12 text-center">
<button type="submit" (click)="AddPatient(p)" class="btn btn-success center-block "> Add Patient</button>
</div>
<div class="col-md-13">
<button type="submit" (click)="EditPatient(p)" class="btn btn-success center-block "> Edit Patient</button>
</div>
</div>
</form>
at the console i am getting error that cannot Cannot read property 'controls' of undefined
Please help me out what is the correct way of setting the control property with the fetched data

Related

Jquery validation collide with HTML validation

I want to use jquery validation for simple form using built-in validation method like required and email.
Here is my form
<form id="setup-company" class="form-horizontal form-rest validator" action="{{$updatePath}}">
<div class="form-group">
<label for="name" class="col-sm-6 control-label" style="font-size: 12px;text-transform:uppercase">Nama Institusi *</label>
<div class="col-sm-12">
<input type="text" class="form-control" name="name" value="{{$company->name}}" style="width: 100%;" required>
</div>
</div>
<div class="form-group">
<label for="abbreviation" class="col-sm-6 control-label" style="font-size: 12px;text-transform:uppercase">Singkatan</label>
<div class="col-sm-12">
<input type="text" class="form-control" name="abbreviation" value="{{$company->abbreviation}}" style="width: 100%;">
</div>
</div>
<div class="form-group">
<label for="phone" class="col-sm-6 control-label" style="font-size: 12px;text-transform:uppercase">No. Telp</label>
<div class="col-sm-12">
<input type="number" class="form-control" minlength="10" maxlength="12" name="phone" value="{{$company->phone}}">
</div>
</div>
<div class="form-group">
<label for="email" class="col-sm-6 control-label" style="font-size: 12px;text-transform:uppercase">Email</label>
<div class="col-sm-12">
<input type="email" class="form-control" name="email" value="{{$company->email}}">
</div>
</div>
<button style="float:right;" type="submit" class="btn btn-sm btn-success btn-raised rippler rippler-inverse edit-row">
SIMPAN
</button>
</form>
In the javascript, I initiate jquery validation like this.
$('.form-rest').unbind().submit(function(e) {
e.preventDefault();
var $form = $(this);
// check if the input is valid
if (!$form.valid())
return false;
});
But when I try it, it shows HTML validation like this
When I fill invalid input for phone (which is third input), it seems jquery validation working properly. And when I try to fill blank input for first input, the error message came from jquery validation like this.
Whats the cause of this?
It's totally fine to have the required attribute. You just have to tell the browser that you want to skip the default validation by adding the novalidate attribute to the form element.
The novalidate attribute is a boolean attribute.
When present, it specifies that the form-data (input) should not be validated when submitted.

Angular Material 8 formControlName error - getting conflicting messages

I am attempting to work with Angular Material (8) Reactive Forms. I am working on a Registration Form. I am getting errors that seem to contradict each other.
**
When I do it this way (file: register.component.html):
**
<!-- Form -->
<form [formGroup]="registerForm" class="text-center" style="color: #757575;">
<div class="form-col">
<div class="col">
<!-- First name -->
<div class="md-form">
<input required type="text" id="materialRegisterFormFirstName" class="form-control"
mdbInput [(ngModel)]="user.firstname"/>
<label for="materialRegisterFormFirstName">First name</label>
</div>
</div>
[... snip ...]
**
I get this error:
**
ERROR Error:
ngModel cannot be used to register form controls with a parent formGroup directive. Try using
formGroup's partner directive "formControlName" instead.
So, I follow the instructions. When I use this approach (adding in formControlName="firstname"),
<div class="form-col">
<div class="col">
<!-- First name -->
<div class="md-form">
<input required type="text" id="materialRegisterFormFirstName" class="form-control"
mdbInput formControlName="firstname" [(ngModel)]="user.firstname"/>
<label for="materialRegisterFormFirstName">First name</label>
</div>
</div>
[... snip ...]
**
I get the following error:
**
forms.js:2312
It looks like you're using ngModel on the same form field as formControlName.
Support for using the ngModel input property and ngModelChange event with
reactive form directives has been deprecated in Angular v6 and will be removed
in Angular v7.
For more information on this, see our API docs here:
https://angular.io/api/forms/FormControlName#use-with-ngmodel
When looking up the problem, I come across this in an old thread:
REFERENCE: ngModel on the same form field as formControlName
From Angular 7 and onward you can't use both formControlName and ngModel together. If you want to use template-driven forms you can go with ngModel and if you want to use reactive forms you can't go with ngModel. (Simple)
**
It sounds like it is saying to remove the formControlName reference. How can this problem be resolved?
**
TIA
That is because you are using template-driven and reactive form at the same time. You need to use it one of them, you cant use both at same time.
Syntax of template driven form is as below.
.html file
<div class="row">
<div class="col-xs-12">
<form (ngSubmit)="onSubmit()">
<div class="row">
<div class="col-sm-5 form-group">
<label for="courseName">Course Name</label>
<input
type="text"
id="courseName"
class="form-control"
name="courseName"
ngModel>
</div>
<div class="col-sm-2 form-group">
<label for="courseDesc">Course Description</label>
<input
type="text"
id="courseDesc"
class="form-control"
name="courseDesc"
ngModel>
</div>
<div class="col-sm-2 form-group">
<label for="courseAmount">Course Amount</label>
<input
type="number"
id="courseAmount"
class="form-control"
name="courseAmount"
ngModel>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button
class="btn btn-success"
type="submit">Add</button>
<button
class="btn btn-danger"
type="button">Delete</button>
<button class="btn btn-primary" type="button">Clear</button>
</div>
</div>
</form>
</div>
</div>
.ts file
onSubmit(form: NgForm) {
console.log("Course Name is : " + form.value.courseName);
console.log("Course Desc is : " + form.value.courseDesc);
console.log("Course Amount is : " + form.value.courseAmount);
}
Syntax for Reactive Form as below
.html file.
<div class="row">
<div class="col-xs-12">
<form [formGroup]="courseForm" (ngSubmit)="onSubmit()">
<div class="row">
<div class="col-sm-5 form-group">
<label for="courseName">Course Name</label>
<input
type="text"
id="courseName"
class="form-control"
formControlName="courseName">
</div>
<div class="col-sm-2 form-group">
<label for="courseDesc">Course Description</label>
<input
type="text"
id="courseDesc"
class="form-control"
formControlName="courseDesc">
</div>
<div class="col-sm-2 form-group">
<label for="courseAmount">Course Amount</label>
<input
type="number"
id="courseAmount"
class="form-control"
formControlName="courseAmount">
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button
class="btn btn-success"
type="submit">Add</button>
<button
class="btn btn-danger"
type="button">Delete</button>
<button class="btn btn-primary" type="button">Clear</button>
</div>
</div>
</form>
</div>
</div>
.ts file
this.courseForm = new FormGroup({
'courseName': new FormControl(null, Validators.required),
'courseDesc': new FormControl([Validators.required, Validators.minLength(100)]),
'courseAmount': new FormControl(null)
});
for more reference visit
You Cannot use both ngModel and FormControlName or ngModel and formGroup together. Because ngModel is a template forms driven whereas FormControlName and FormGroup are reactive forms driven.
If you want to use both together you are increasing the complexity of the application. If you want to access the value through formControlName then use it like
<form [formGroup]="registerForm" class="text-center" style="color: #757575;">
<div class="form-col">
<div class="col">
<div class="md-form">
<input formControlName="firstName" type="text" id="materialRegisterFormFirstName" class="form-control" mdbInput/>
<label for="materialRegisterFormFirstName">First name</label>
</div>
</div>
</div>
</form>
In component.ts file write like
registerForm = new FormGroup({
firstName: new FormControl([Validator.required]),
});
or else you can build formgroup using formbuilder, fb is an instance of formBuilder
this.registerForm = fb.group({
'fullname': ['', Validators.required],
});
and you can read value like this
this.user.firstName = this.registerForm.get('firstName').value;
Use [ngModelOptions]="{ standalone: true }" on the input element
since you are using reactive forms , no need to use ngModelin your input fields use formControlName insted. ngModel is used in template driven froms
<div class="md-form">
<input required type="text" id="materialRegisterFormFirstName" class="form-control"
mdbInput formControlName="firstname"/>
<label for="materialRegisterFormFirstName">First name</label>
</div>
here you can find better examples https://v8.angular.io/guide/reactive-forms

Why the form disappear using ngFor directive

When I am using ngFor directive in the form tag, the entire form will disappear. Can anyone guide me on how I can fix this issue?
<form #myforms="ngForm" *ngFor="let i of editaddress">
<div class="p-3 p-lg-5 border">
<div class="form-group row">
<div class="col-md-12">
<label for="c_fname" class="text-black">Save this address as<span class="text-danger">*</span></label>
<input type="text" class="form-control c_fname" value="{{i.title}}" name="title" [(ngModel)]="location.title" #title=ngModel>
</div>
<div class="col-md-6">
<label for="c_fname" class="text-black">First Name<span class="text-danger">*</span></label>
<input type="text" class="form-control c_fname" value="{{i.first_name}}" name="fname" [(ngModel)]="location.first_name" #fname=ngModel>
</div>
<div class="col-md-6">
<label for="c_lname" class="text-black">Last Name<span class="text-danger">*</span></label>
<input type="text" class="form-control c_lname" value="{{i.last_name}}" name="lname" [(ngModel)]="location.last_name" #lname=ngModel>
</div>
</div>
</div>
<div class="col-lg-12">
<input type="submit" class="btn btn-primary btn-lg btn-block" value="Save" (click)="saveAddress(location)">
</div>
</div>
</div>
Since you did not show any part of the underlying controller, the only thing I can do is inform you that the property editaddress would be an empty array. Therefore it would not render anything.
If it flashes and disappears, it means that through your life cycle the array may have content, but at some point the array is set to [] which updates the the markup accordingly.

Cannot read property 'form' of undefined angular 5

I have the following html form in angular
<form (ngSubmit)="signin()" #signinform="ngForm">
<div class="form-group row">
<label for="signinemail" class="col-sm-2 col-form-label">Email:</label>
<div class="col-sm-10">
<input type="email"
class="form-control"
id="signinemail"
name="signinemail"
ngModel
placeholder="Email">
</div>
</div>
<div class="form-group row">
<label for="signinpassword" class="col-sm-2 col-form-label">Password:</label>
<div class="col-sm-10">
<input type="password"
class="form-control"
id="signinpassword"
name="signinpassword"
ngModel
placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input ml-0"
type="checkbox"
id="gridCheck"
name="remembercheckbox"
ngModel>
<label class="form-check-label" for="gridCheck">
Remember Me
</label>
</div>
<small class="form-text text-muted">Forget Password?</small>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Sign In</button>
<button type="button" class="btn btn-outline-dark" (click)="c('Close click')">Close</button>
</div>
</form>
and the following typescript for the form:
import {NgForm} from "#angular/forms";
#ViewChild('signinform') signinform: NgForm;
signin() {
let payload = {
email: this.signinform.form.value.signinemail,
password: this.signinform.form.value.signinpassword,
localstorage: this.signinform.form.value.remembercheckbox
};
this.userservice.gettoken(payload);
this.signedin = true;
}
I have compared this to other forms I have built and yet there is no difference. What could be causing this?
the form element is on the dom when I call. The submit button is within the form. The #ViewChild element syntax is correct and properly imported. I truly don't understand and I am ready to punch a baby.
The code looks fine...You could just try not using view child, and instead do:
<form (ngSubmit)="signin(signinform)" #signinform="ngForm">
signin(form: NgForm) {
console.log(form);
}
I'd definitely try that console though, to make sure the form is being submitted properly.

HTML Form Post handling

I have a form as detailed below. It uses a post method to send data to getUsername.php. This file echoes some JSON results from mysql db.
Am wondering how do I grab this data? When I hit submit it navigates to the file and displays the JSON. I want to grab the JSON and stay on the same page or move to a different one!
I have kept the php file simple because the data is also used for returning data to my android app.
<div class="well bs-component">
<form id ='formLogin' action="http://localhost/getUsername.php" method="post" class="form-horizontal">
<fieldset>
<legend>Sign In</legend>
<div class="form-group">
<label for="inputEmail" class="col-lg-2 control-label">Email</label>
<div class="col-lg-10">
<input name='email' type="text" class="form-control" id="inputEmail" placeholder="Email">
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-lg-2 control-label">Password</label>
<div class="col-lg-10">
<input name='password' type="password" class="form-control" id="inputPassword" placeholder="Password">
<div class="checkbox">
<label>
<input type="checkbox"> Checkbox
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</fieldset>
</form>
I believe this cannot be done from a form. I instead used jquery post function to return data