3

I'm facing a problem that is driving me crazy. I'm working on an angular project and I need maps search to be put in a modal window. I used ng bootstrap modals and google maps.

This is my .ts:

    @Component({
  selector: 'app-classroom-detail-dialog',
  templateUrl: './classroom-detail-dialog.component.html',
  styleUrls: ['./classroom-detail-dialog.component.css']
})
export class ClassroomDetailDialogComponent implements OnInit {
  @Input() idClassroom: number;
  classroom: Class;
  edit: boolean = true;

  public latitude: number;
  public longitude: number;

  public searchControl: FormControl;
  @ViewChild("search") public searchElementRef: ElementRef;

  constructor(public activeModal: NgbActiveModal, public classroomService: ClassroomService,
    public mapsAPILoader: MapsAPILoader, public ngZone: NgZone) { }

  ngOnInit() {
    this.classroomService.getClassroomDetail(this.idClassroom).subscribe(classroom=>{
      this.classroom = classroom;
      this.latitude = this.classroom.latitude;
      this.longitude = this.classroom.longitude;
    });
    //create search FormControl
    this.searchControl = new FormControl();

    //load Places Autocomplete
    this.mapsAPILoader.load().then(() => {      
      let autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement, {
        types: ["address"]
      });
      autocomplete.addListener("place_changed", () => {
        this.ngZone.run(() => {
          //get the place result
          let place: google.maps.places.PlaceResult = autocomplete.getPlace();

          //verify result
          if (place.geometry === undefined || place.geometry === null) {
            return;
          }

          //set latitude, longitude and zoom
          this.classroom.latitude = place.geometry.location.lat();
          this.classroom.longitude = place.geometry.location.lng();
        });
      });
      autocomplete.setComponentRestrictions
    });
  }

  closeModal() {
    this.activeModal.close('Modal Closed');
  }

  markerDragEnd($event) {
    console.log($event.coords.lat);
    console.log($event.coords.lng);
    this.classroom.latitude = $event.coords.lat;
    this.classroom.longitude = $event.coords.lng;
  }

  reset() {
    this.classroom.latitude = this.latitude;
    this.classroom.longitude = this.longitude;
  }
}

This is my .html:

<div id="myModal_def" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog">
        <div class="modal-content">

            <div class="modal-header" style="padding:0">                                                        
                <h3 id="titolo_modal" style="text-align: center;">Classroom {{classroom?.name}}</h3>                                                              
                </div>
            <div class="modal-body" style="padding:0">                                    
                <div class="col-lg-12">
                        <div class="form-group">
                                <input placeholder="Search" autocorrect="off" autocapitalize="off" spellcheck="off" type="text" class="pac-container" #search [formControl]="searchControl">
                            </div>
                                    <agm-map [latitude]="classroom?.latitude" [longitude]="classroom?.longitude" [zoom]="18" [mapTypeId]="'hybrid'">

                                <agm-marker [markerDraggable]="true" [latitude]="classroom?.latitude" [longitude]="classroom?.longitude" (dragEnd)="markerDragEnd($event)"></agm-marker>
                                    </agm-map>
                                    <button (click)="reset()">Reset position</button>
                </div>                                                                                                          
            </div>
            <div class="modal-footer" style="margin-right:20%">
                <div id="div_footer" class="col-md-12">                            
                    <button (click)="closeModal()" id="close_modal" class="btn btn-info">Close</button>
                    <button *ngIf="!edit" id="save_modal"  class="btn btn-info">Save</button>                            
                </div>
            </div>
        </div>
    </div>

</div>

And this is my .css:

agm-map {
  height: 300px;
}

  /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
       #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #description {
        font-family: Roboto;
        font-size: 15px;
        font-weight: 300;
      }

      #infowindow-content .title {
        font-weight: bold;
      }

      #infowindow-content {
        display: none;
      }

      #map #infowindow-content {
        display: inline;
      }

      .pac-container {
        background-color: #fff;
        position: absolute!important;
        z-index: 1100;
        border-radius: 2px;
        border-top: 1px solid #d9d9d9;
        font-family: Arial,sans-serif;
        box-shadow: 0 2px 6px rgba(0,0,0,0.3);
        -moz-box-sizing: border-box;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
        overflow: hidden;
    }
      .pac-card {
        margin: 10px 10px 0 0;
        border-radius: 2px 0 0 2px;
        box-sizing: border-box;
        -moz-box-sizing: border-box;
        outline: none;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
        background-color: #fff;
        font-family: Roboto;
      }


      .pac-controls {
        display: inline-block;
        padding: 5px 11px;
      }

      .pac-controls label {
        font-family: Roboto;
        font-size: 13px;
        font-weight: 300;
      }

      #pac-input {
        background-color: #fff;
        font-family: Roboto;
        font-size: 15px;
        font-weight: 300;
        margin-left: 12px;
        padding: 0 11px 0 13px;
        text-overflow: ellipsis;
        width: 400px;
      }

      #pac-input:focus {
        border-color: #4d90fe;
      }

      #title {
        color: #fff;
        background-color: #4d90fe;
        font-size: 25px;
        font-weight: 500;
        padding: 6px 12px;
      }
      #target {
        width: 345px;
      }

So, this is my problem:

Screenshot

Autocomplete is not showing, it is behind the modal! I know it is behind the modal because if I move the search box, I can see it!

Screenshot 2

I have already tried with z-index: every value is useless even if I use !important.

Moreover, I noticed that if I edit the z-index value in Elements tab in Developer option of Chrome, I can see the pac-container. So i think it is something related to css that is not working.

Screenshot 3

Please help!

Crystian182
  • 69
  • 1
  • 4

3 Answers3

5

Please add following style in your scss file with ::ng-deep its working for me.

::ng-deep .pac-container {   
    z-index: 9999;
}
Jay Patidar
  • 51
  • 1
  • 3
2

I got it working using this:

.pac-container {
  background-color: #FFF;
  z-index: 1050;
  position: fixed;
  display: inline-block;
  float: left;
}

Source: Google Maps Autocomplete Result in Bootstrap Modal Dialog

MadMac
  • 4,048
  • 6
  • 32
  • 69
1

I ran into this problem yesterday (and upon this question). I fixed it by injecting the NgbTypeaheadConfig into my class and setting the config.container to 'body'.

This Github issue pointed me in the right direction. (And the subsequent pull request)

Your constructor would become:

constructor(public activeModal: NgbActiveModal, public classroomService: 
    ClassroomService, public mapsAPILoader: MapsAPILoader, public ngZone: NgZone,
    private typeaheadConfig: NgbTypeaheadConfig)  
{
    this.typeaheadConfig.container = 'body';
}
TheLethalCoder
  • 6,668
  • 6
  • 34
  • 69
Michiel R
  • 11
  • 1
  • 2