Chrome Autofill triggering separately for billing and contact information - html

Autofill is triggering separately for billing and for contact information.
For example, when I click on any of the following 4 input fills it offers autofill for them => first name, last name, phone number and email. When I click on any of the following 4 it triggers autofill for them together => billing address, billing postal-code, billing country, billing city.
Autofill works well for each of the two groups, but I want it to be one group that will autofill by selecting any of the 8 input fields.
Code example (I'm using Angular 8 with Material design components but I think this shouldn't pose as a distraction since I see this as a HTML issue):
<form method="post" id="paymentForm" [formGroup]="formGroup" (ngSubmit)="onSubmit(formGroup.value)" class="form" >
<div class="customer-info">
<div class="customer-info-personal">
<div>
<mat-form-field class="form-element">
<input name="fname" matInput placeholder="Ime" formControlName="firstName" autocomplete="given-name" form="paymentForm">
<mat-error
*ngIf="!formGroup.controls['firstName'].valid && formGroup.controls['firstName'].touched">
</mat-error>
</mat-form-field>
<mat-form-field class="form-element">
<input name="lname" matInput placeholder="Prezime" formControlName="lastName" autocomplete="family-name" form="paymentForm">
<mat-error *ngIf="!formGroup.controls['lastName'].valid && formGroup.controls['lastName'].touched">
</mat-error>
</mat-form-field>
<mat-form-field class="form-element">
<input name="bill-address" matInput placeholder="Adresa" formControlName="billingAddress" autocomplete="billing street-address" form="paymentForm">
<mat-error *ngIf="!formGroup.controls['billingAddress'].valid && formGroup.controls['billingAddress'].touched">
</mat-error>
</mat-form-field>
<mat-form-field class="form-element">
<input name="bill-city" matInput placeholder="Grad" formControlName="billingCity" autocomplete="billing address-level2" form="paymentForm">
<mat-error *ngIf="!formGroup.controls['billingCity'].valid && formGroup.controls['billingCity'].touched">
</mat-error>
</mat-form-field>
</div>
<div>
<mat-form-field class="form-element">
<input name="bill-zip" matInput placeholder="Poštanski broj" formControlName="billingPostalNumber" autocomplete="billing postal-code" form="paymentForm">
<mat-error
*ngIf="!formGroup.controls['billingPostalNumber'].valid && formGroup.controls['billingPostalNumber'].touched">
</mat-error>
</mat-form-field>
<mat-form-field class="form-element">
<input name="bill-country" matInput placeholder="Država" formControlName="billingCountry" autocomplete="billing country" form="paymentForm">
<mat-error *ngIf="!formGroup.controls['billingCountry'].valid && formGroup.controls['billingCountry'].touched">
</mat-error>
</mat-form-field>
<mat-form-field class="form-element">
<input name="email" matInput placeholder="e-mail" formControlName="email" autocomplete="email" type="email" form="paymentForm">
<mat-error *ngIf="!formGroup.controls['email'].valid && formGroup.controls['email'].touched">
</mat-error>
</mat-form-field>
<mat-form-field class="form-element">
<input name="phone" matInput placeholder="Broj telefona" formControlName="phoneNumber" autocomplete="tel" type="tel" form="paymentForm">
<mat-error
*ngIf="!formGroup.controls['phoneNumber'].valid && formGroup.controls['phoneNumber'].touched">
</mat-error>
</mat-form-field>
</div>
</div>
<div class="buttons-element">
<div class="pay-button-element">
<button mat-raised-button color="primary" type="submit" class="button"
[disabled]="!formGroup.valid">Plati</button>
</div>
<div class="cancel-button-element">
<button mat-button color="secondary" type="submit" class="button">Odustani</button>
</div>
</div>
</div>
</form> ```

Fixed it by removing the word billing from autocomplete values and bill- from name values.
E.g.
Before autocomplete="billing postal-code" name="zip"
Before autocomplete="postal-code" name="zip"
Changing the autocomplete field alone proved to be enough.

Related

Error: Uncaught (in promise): TypeError: Cannot read properties of null (reading 'includes')

I am new to angular and was learning how to create custom directives. I was handling some email validations in email-validation.directive.ts and found that i am geting this error
email-validation.directive.ts
import { Directive } from '#angular/core';
import {
AbstractControl,
NG_VALIDATORS,
ValidationErrors,
Validator,
} from '#angular/forms';
#Directive({
selector: '[appEmailValidation]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: EmailValidationDirective,
multi: true,
},
],
})
export class EmailValidationDirective implements Validator {
count = 0;
validate(control: AbstractControl<any, any>): ValidationErrors | null {
const value = control.value as string;
if (!value.includes('#') && !value.includes('.com')) {
return {
invalidEmail: true,
};
}
return null;
}
constructor() {}
}
Here is my code and condition of my directive. I want to check if the email contains # and .com keywords and if id doesn't I want to set invalidEmail as true
Main Component Code
register.component.html
<form #registerForm="ngForm" class="form-container" (ngSubmit)="postData(registerForm)">
<mat-grid-list cols="1" rowHeight="100vh">
<mat-grid-tile>
<div class="example-container">
<mat-form-field hintLabel="Max 20 characters" appearance="fill" class="width-50">
<mat-label>First Name</mat-label>
<input #fname minlength="3" maxlength="20" required [(ngModel)]="ad.firstName" type="text" name="firstName"
matInput placeholder="Enter Your Firstname">
<mat-hint align="end">{{fname.value.length}}/20</mat-hint>
</mat-form-field>
<mat-form-field hintLabel="Max 20 characters" appearance="fill" class="width-50 ml-2">
<mat-label>Last name</mat-label>
<input #lname minlength="3" maxlength="20" required [(ngModel)]="ad.lastName" name="lastName" type="text"
matInput placeholder="Enter your Lastname">
<mat-hint align="end">{{lname.value.length}}/20</mat-hint>
</mat-form-field>
<br>
<mat-form-field appearance="fill" class="width-100">
<mat-label>City</mat-label>
<input minlength="3" maxlength="20" required [(ngModel)]="ad.city" name="city" type="text" matInput
placeholder="Enter your City">
</mat-form-field>
<br>
<mat-form-field appearance="fill" class="width-100">
<mat-label>Age</mat-label>
<input min="1" max="100" required [(ngModel)]="ad.age" name="age" type="number" matInput placeholder="Age">
</mat-form-field>
<br>
<mat-form-field appearance="fill" class="width-100">
<mat-label>Username</mat-label>
<input appEmailValidation #user="ngModel" required [(ngModel)]="ad.username" name="username" matInput
placeholder="Enter your username">
<mat-hint color="warn"></mat-hint>
</mat-form-field>
<br>
<mat-form-field appearance="fill" class="width-100">
<mat-label>Enter password</mat-label>
<input required [(ngModel)]="ad.password" name="password" matInput [type]=" hide ? 'password' : 'text'">
<button mat-icon-button matSuffix (click)=" hide=!hide" [attr.aria-label]="'Hide password'"
[attr.aria-pressed]="hide">
<mat-icon>{{hide ? 'visibility_off' : 'visibility'}}</mat-icon>
</button>
</mat-form-field>
<button [disabled]="registerForm.invalid" mat-raised-button color="primary">Submit</button>
</div>
</mat-grid-tile>
</mat-grid-list>
</form>
{{user.errors | json}}
When I am running the code i am getting this error
Cannot read properties of null
simply edit this condition:
if (!value || ( !value.includes('#') && !value.includes('.com'))) {
return {
invalidEmail: true,
};
}
Because in your case value is null and I believe that null is also an invalid value for email.

Angular Forms change Tab order

For simplicity when building a two column form I built it in two separated divs using flex box. The form however reads from left to right i.e First Name at the top of div one and Surname at the top of div two. If the user uses the tab key to move between inputs the tab key moves down the form rather than across. This was an oversight by me but I was wondering if the tabbing between inputs could be set different from the default. Maybe a picture would help.
So I would like to change it to tab across. How would I do that? Also the actual form is more complicated than shown below so I don't want to rebuild the html.
My HTML
<div fxLayout="row" fxLayout.lt-sm="column" fxLayoutAlign="space-between center">
<div fxFlex="40">
<mat-form-field class="formFieldLeft">
<div class="is-size-7 has-text-grey-light mbxs">First Name</div>
<input matInput formControlName="firstName">
</mat-form-field>
<mat-form-field class="formFieldLeft">
<div class="is-size-7 has-text-grey-light mbxs">Email Address</div>
<input matInput formControlName="email">
</mat-form-field>
<mat-form-field class="formFieldLeft mblg">
<div class="is-size-7 has-text-grey-light mbxs">Company Phone Number</div>
<input matInput formControlName="companyPhoneNumber">
</mat-form-field>
<div fxFlex="60">
<mat-form-field class="formFieldRight">
<div class="is-size-7 has-text-grey-light mbxs">Surname</div>
<input matInput formControlName="lastName">
</mat-form-field>
<mat-form-field class="formFieldRight">
<div class="is-size-7 has-text-grey-light mbxs">Job Title</div>
<input matInput formControlName="jobTitle">
</mat-form-field>
<mat-form-field class="formFieldRight mblg">
<div class="is-size-7 has-text-grey-light mbxs">Mobile Number</div>
<input matInput formControlName="mobilePhoneNumber">
</mat-form-field>
</div>
Add tabIndex like
<input tabindex="3">
<input tabindex="0">
<input tabindex="-1">
<input>
<input tabindex="2">
<input tabindex="1">
see this for more details
You can save active tab index and create separate function on
(keyup)="onKeypressEvent($event)" {
// check does it `tab`
}
chech the key code and depending of where you current tab active change next active tab

Angular autocomplete returns an empty field when clicked searched option

The problem is that when i search a list of users by typing characters into the input field and mat-autocomplete finds the searched user, after i click on it to select that user the input field becomes empty instead of showing the selected user.
Here is my HTML code:
<div class="material-input">
<mat-form-field class="form-group">
<input id="userNameInput" matInput placeholder="Search user name" formControlName="userName" for="search-box"
#searchBox id="search-box" (input)="search(searchBox.value)" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let username of mockLdap | async" [value]="username">
{{username.userName}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
You have to set the [value]="username.userName" of your option accordingly.
<div class="material-input">
<mat-form-field class="form-group">
<input id="userNameInput" matInput placeholder="Search user name" formControlName="userName" for="search-box"
#searchBox id="search-box" (input)="search(searchBox.value)" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let username of mockLdap | async" [value]="username.userName"> <!--- Here you have to set username.UserName -->
{{username.userName}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>

form submit not working on mobile device (match the requested format)

I have a small angular app I have made that works fine on my computer, but does not work properly on any mobile device. The problem is the form submit button. The button will not submit form and hitting the return key on my ipad on the last form field directs back to the card number form field and says "Match the requested format" ... I am using Stripe by the way.
I have tried ngSubmit on the form and changed the button around to input type and type button and etc. I have also got rid of ngSubmit and used (click)="buy()" which also works on a desktop, but not on a mobile device. I have even added (tap) from hammerjs just in case it was a touch issue. I tried using a label outside of the form linked to the submit button. None of which work. I added an alert to just see if the button was even being clicked, and it is, the mobile device will show the alert, but wont submit the form. So, please ignore the the code at the bottom where I have multiple buttons a labels, it was for testing purposes (it all works on desktop though as is, just not on any mobile device).
Here are two pics of the problem:
https://drive.google.com/file/d/18grWfXyQN9gvcuJRuUqIoS_yjMsU1vii/view?usp=sharing)
https://drive.google.com/file/d/1ezhyAtTg1Z1OomLd9pv47Bif-0ILOR5b/view?usp=sharing
<app-navbar></app-navbar>
<div class="container">
<form class="example-form" action="#" [formGroup]="stripeTest">
<table class="example-full-width" cellspacing="0">
<tr>
<td>
<mat-form-field class="example-full-width media-width">
<input matInput type="text" placeholder="Full Name"
formControlName="name" id="firstName">
<mat-error *ngIf="hasError('name', 'required')">First Name is
required
</mat-error>
</mat-form-field>
</td>
</table>
<table class="example-full-width" cellspacing="0">
<td>
<mat-form-field class="example-full-width">
<input matInput type="text" placeholder="Phone "
formControlName="phone" id="phone">
<mat-error *ngIf="hasError('phone', 'required')">Zip is
required
</mat-error>
</mat-form-field>
</td>
<td>
<mat-form-field class="example-full-width">
<input matInput type="text" placeholder="Email"
formControlName="email" id="email">
<mat-error *ngIf="hasError('email', 'required')">Zip is
required
</mat-error>
</mat-form-field>
</td>
</table>
<p>
<mat-form-field class="example-full-width addr-media-width">
<textarea matInput type="text" placeholder="Address"
formControlName="address_line1" id="address"></textarea>
<mat-error *ngIf="hasError('address_line1', 'required')">Address
is required
</mat-error>
</mat-form-field>
</p>
<table class="example-full-width" cellspacing="0">
<tr>
<td>
<mat-form-field class="example-full-width">
<input matInput type="text" placeholder="City"
formControlName="address_city" id="city">
<mat-error *ngIf="hasError('address_city', 'required')">City is
required
</mat-error>
</mat-form-field>
</td>
<td>
<mat-form-field class="example-full-width state-width">
<input matInput type="text" placeholder="State"
formControlName="address_state" id="state">
<mat-error *ngIf="hasError('address_state', 'required')">State is
required
</mat-error>
</mat-form-field>
</td>
<td>
<mat-form-field class="half-width">
<input matInput type="text" placeholder="Zip"
formControlName="address_zip" id="zip">
<mat-error *ngIf="hasError('address_zip', 'required')">Zip is
required
</mat-error>
</mat-form-field>
</td>
</tr>
</table>
<div class="col-lg-12">
<div id="card-element" class="field"></div>
</div>
<div class="col-lg-12">
<input type="submit" id="submit-form" [disabled]="!stripeTest.valid"
class="btn btn-danger" style="visibility: hidden" (click)="buy()">
<button type="button" (tap)="buy()">Buy</button>
<button class="btn btn-danger" (click)="cancel()">Cancel</button>
</div>
</form>
<label for="submit-form" tabindex="0">Submit</label>
buy function
buy(){
const name = this.stripeTest.get('name').value;
const phone = this.stripeTest.get('phone').value;
const email = this.stripeTest.get('email').value;
const address_state = this.stripeTest.get('address_state').value;
const address_city = this.stripeTest.get('address_city').value;
const address_line1 = this.stripeTest.get('address_line1').value;
const address_zip = this.stripeTest.get('address_zip').value;
let newCustomer: Customer = {
name: name,
phone: phone,
email: email
};
this.dataService.addCustomer(newCustomer)
.subscribe(() => {
console.log('Added');
})
this.stripeService
.createToken(this.card, {
name, address_state, address_city, address_line1,
address_zip
})
.subscribe(obj => {
if (obj) {
console.log('Token is --> ', obj.token.id);
// tslint:disable-next-line: no-unused-expression
this.http.post('http://localhost:3000/payme', {
token: obj.token.id,
receipt_email: email
}).subscribe(
(res) => {
console.log('The response from server is ', res);
console.log('Payment Done');
this.router.navigateByUrl('/thank-you');
alert(obj.token.id + obj + Customer + name + res);
},
(err) => {
console.log('The error is ', err);
alert(err);
})
} else {
// Error creating the token
console.log('Error comes ');
}
});
}
Oh wow, I feel like a moron. Jeez, shoot me haha. So, the this.http.post('http://localhost:3000/payme') needed to be just this.http.post(/payme) and needed to make changes in the data service as well, getting rid of the localhost:3000 part and just leaving the /add-customer. Wow, I can not believe I did not even see that! Wow. But it still worked on my computer even when deploying to Heroku. I guess because it was on my computer?

Default type=email validation being ignored

I'm building an Angular Material registration form. One of the input elements is type=email.
The expected behavior is, on submit, if the email is not in proper email format the form will not be valid and I will get a default browser error, seen here:
Code pen to test desired behavior
However, that's not what's happening at all. I'm using Material components to build out the form:
<form class="form" [formGroup]="registerForm" (ngSubmit)="onSubmit()">
<mat-form-field class="form-full">
<input matInput placeholder="First Name" style="width:350px" formControlName="firstName" required />
</mat-form-field>
<mat-form-field class="form-full">
<input matInput placeholder="Last Name" style="width:350px" formControlName="lastName" required />
</mat-form-field>
<mat-form-field class="form-full">
<input matInput placeholder="Email" style="width:350px" type="email" formControlName="email" required />
</mat-form-field>
<mat-form-field class="form-full">
<input matInput placeholder="Password" style="width:350px" type="password" formControlName="password" required />
</mat-form-field>
<mat-form-field class="form-full">
<input matInput placeholder="Confirm Password" style="width:350px" type="password" formControlName="confirmPassword" required />
</mat-form-field>
<mat-card-actions>
<button mat-raised-button mat-button color="primary" type="submit">Register</button>
</mat-card-actions>
</form>
My register.component.ts is very basic right now, as I just started building out the component. I bind a form group to my registration form and console out some values in the onSubmit.
export class RegisterComponent {
registerForm;
constructor(private fb: FormBuilder) {
this.registerForm = fb.group({
firstName: '',
lastName: '',
email: '',
password: '',
confirmPassword: '',
})
}
onSubmit() {
console.log(this.registerForm.value);
console.log(this.registerForm.valid);
}
}
I expect registrationForm.valid to be false and a browser error to display when the submit button is pressed, however that is not happening. Of course, I can validate this myself - but not getting desired behavior is driving me nuts.
Here are the results:
Any thoughts?
You should be able to use the EmailValidator Directive, just add email attribute to your input syntax.
<input matInput placeholder="Email" style="width:350px" type="email" formControlName="email" email required />
https://angular.io/api/forms/EmailValidator