Topic: leaflet map doesn't render properly in stepper
Smart City Solutions GmbH asked 4 years ago
I've integrated different leaflet-maps from ngx-leaflet successfully in my angular project. Now I've got the following problem with the mdb-stepper. I need to render the leaflet map inside a step of the stepper. But the stepper doesn't load properly in css and functionality.
I think this is because the steps of the stepper change their size when going from one to another step. But I just don't know how to fix this. I tried rendering the map & set the size again, when the related step is active, but this doesn't work. Also a common solution with the function invalidateSize(); from the leaflet map doesn't work for me. I use the horizontal stepper.
Can you please help me?
My HTML:
<mdb-step #standortStep name="Standort">
<ng-container *ngIf="standortStep.isActive">
<div class="col-12 col-md-9">
<div class="row m-0 mt-4">
<mdb-card class="location-title p-2 w-100">
Standort
</mdb-card>
</div>
<div class="row m-0 px-2">
<div class="col-12 col-md-8 pl-0 mt-4">
<div class="create-map-wrapper">
<div leaflet class="create-map" [leafletCenter]="center"
[leafletFitBounds]="fitBounds" [leafletBaseLayers]="baseLayers"
[leafletLayers]="markers" (leafletClick)="mapClicked($event)"
*ngIf="standortStep.isActive">
</div>
</div>
</div>
</div>
</div>
</ng-container>
</mdb-step>
My CSS:
.create-map-wrapper {
width: 100%;
.create-map {
height: 30vh;
}
This is one thing I tried:
onMapReady(map: L.Map) {
this.map = map;
f(this.map !== undefined) {
setTimeout(() => {
this.map.invalidateSize();
}, 10);
}
}
Arkadiusz Idzikowski staff answered 4 years ago
The solution with *ngIf
should resolve the problem. You need to hide the map when switching to another step and show it again to reinvoke the (leafletMapReady)
event. You may also need to wrap the code in the onMapReady
method in setTimeout
.
Here is an example:
HTML:
<mdb-stepper #stepper (stepChange)="onStepChange($event)">
<mdb-step name="Step 1" [stepForm]="firstFormGroup">
<button mdbBtn size="sm" color="primary" (click)="stepper.next()">CONTINUE</button>
</mdb-step>
<mdb-step name="Step 2" [stepForm]="secondFormGroup">
<div *ngIf="showMap" style="height: 300px" leaflet [leafletOptions]="leafletOptions" (leafletMapReady)="onMapReady($event)"></div>
<button mdbBtn size="sm" color="primary" (click)="stepper.next()">CONTINUE</button>
<button mdbBtn size="sm" color="secondary" (click)="stepper.previous()">BACK</button>
</mdb-step>
<mdb-step name="Step 3" label="Step 3 label">
<p class="pl-2">Finish!</p>
<div class="step-actions">
<button mdbBtn size="sm" color="primary" (click)="onSubmit()">SUBMIT</button>
</div>
</mdb-step>
</mdb-stepper>
TS:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { latLng, tileLayer } from 'leaflet';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
firstFormGroup: FormGroup;
secondFormGroup: FormGroup;
showMap = false;
leafletOptions = {
layers: [
tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '...' })
],
zoom: 5,
center: latLng(46.879966, -121.726909)
};
ngOnInit() {
this.firstFormGroup = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email])
});
this.secondFormGroup = new FormGroup({
password: new FormControl('', Validators.required)
});
}
get email() { return this.firstFormGroup.get('email'); }
get password() { return this.secondFormGroup.get('password'); }
onSubmit() {
// do something here
}
onMapReady(map: any) {
setTimeout(() => {
map.invalidateSize();
}, 0);
}
onStepChange(event: any) {
if (event.activeStepIndex === 1) {
this.showMap = true;
}
}
}
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- User: Free
- Premium support: No
- Technology: MDB Angular
- MDB Version: 9.3.1
- Device: PC
- Browser: chrome
- OS: Windows 10
- Provided sample code: No
- Provided link: No
Arkadiusz Idzikowski staff commented 4 years ago
Please provide some more HTML/TS code so we can reproduce this problem on our end. Which version of stepper do you use? Horizontal or vertical?