Angular Material Dialog with Google Places Autocomplete dropdown positioning

544 views Asked by At

I have a web page that uses the Angular framework and therefore the Materials UI library. I have a dialog with a form that uses the Google Places Autocomplete functionality, but the positioning of it stays constant when scrolling through the dialog. Without the dialog, the autocomplete positioning works as I would like and stays directly beneath the input. No styling on the .pac-container has been done for the positioning. The dialog and non-dialog have the same code and styling. Thank you in advance! (Mind the ugliness, it is all testing right now)

google.maps.places.Autocomplete position offset inside angular material Dialog is the exact issue I am having (I think), but I do not know what is meant by "My solution was to remove the top style and then restore it."

Initial position of autocomplete in the dialog enter image description here

Autocomplete position when scrolling through the dialog enter image description here

Initial position of autocomplete outside dialog enter image description here

Autocomplete position when scrolling outside dialog enter image description here

Non-Dialog TS:

export class AddressTestComponent implements OnInit, AfterViewInit {

    @ViewChild("addressLine1") addressField1: ElementRef;
    @ViewChild("addressLine2") addressField2: ElementRef;
    @ViewChild(MatAutocompleteTrigger, {static: false}) trigger: MatAutocompleteTrigger;
    addressForm: UntypedFormGroup;

    googleAutocomplete: google.maps.places.Autocomplete;

    constructor(private formBuilder: UntypedFormBuilder) { }

    ngOnInit(): void {
        this.addressForm = this.formBuilder.group(
            {
                addressLine1: ['', Validators.required],
                addressLine2: [''],
                city: ['', Validators.required],
                state: ['', Validators.required],
                zipCode: ['', Validators.required],
                country: ['', Validators.required],
            }
        );
    }

    ngAfterViewInit(): void {
        this.googleAutocomplete = new google.maps.places.Autocomplete(this.addressField1.nativeElement as HTMLInputElement, {
            componentRestrictions: { country: ["us"] },
            fields: ["address_components"],
            types: ["address"]
        });

        this.addressField1.nativeElement.focus();
        this.googleAutocomplete.addListener("place_changed", () => this.autocomplete(this.googleAutocomplete.getPlace()) );
        
    }
}

Non-Dialog HTML:

<div>
    <div class="dialog-header">
        <h2>Add a New Address</h2>
        <h2 class="header-closer" (click)="onClose()" >X</h2>
    </div>
    <form [formGroup]="addressForm" (ngSubmit)="onSubmitNewAddress()" class="address-form">
        <div class="address-wrapper">
            <mat-form-field (keydown.escape)="$event.stopPropagation()"
                appearance="fill">
                <mat-label>Address Line 1</mat-label>
                <input matInput #addressLine1 formControlName="addressLine1" required>
            </mat-form-field>
            <mat-form-field appearance="fill">
                <mat-label>Address Line 2 (Optional)</mat-label>
                <input matInput #addressLine2 formControlName="addressLine2">
            </mat-form-field>
            <mat-form-field appearance="fill">
                <mat-label>City</mat-label>
                <input matInput formControlName="city" required>
            </mat-form-field>
            <mat-form-field appearance="fill">
                <mat-label>State</mat-label>
                <input matInput formControlName="state" required>
            </mat-form-field>
            <mat-form-field appearance="fill" style="margin-bottom: 10px;">
                <mat-label>Zip Code</mat-label>
                <mat-hint align="end">{{ zipcode.value.length }} / 5</mat-hint>
                <input matInput #zipcode type="tel" [maxLength]="5" formControlName="zipCode" required>
            </mat-form-field>
            <mat-form-field appearance="fill">
                <mat-label>Country</mat-label>
                <input matInput formControlName="country" required>
            </mat-form-field>
        </div>
        <div class="form-buttons">
            <button mat-raised-button (click)="onClose()">Cancel</button>
            <button mat-raised-button color="primary" type="submit" [disabled]="this.addressForm.invalid">Use This Address</button>
        </div>
    </form>
</div>

Non-Dialog SCSS:

.dialog-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 5px;
}

#map {
    height: 100%;
}

.address-form {
    padding-bottom: 2000px; // for scrolling test
}

.header-closer {
    cursor: pointer;
    color: red;
    margin-top: 30px;
}

.address-wrapper {
    display: flex;
    flex-wrap: wrap;

    mat-form-field {
        margin: 0 15px;
        flex: 1;
    }
}

.form-buttons {

    button {
        margin: 0 5px;
    }

    button:hover {
        background-color: #771f1f;
    }
}

I have tried the autocomplete without a Material Dialog and it works just as intended and how I would like it to work. I am just trying to replicate that while scrolling through the dialog as well. To fix the issue, I tried to change the position styling of .pac-container but was unsuccessful.

EDIT: I figured out what the other stackoverflow link was talking about. Is there a way the autocomplete styling can be tied to the actual input element rather than the html tag?

0

There are 0 answers