Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Maps InfoWindow width is overwritten even when set correctly

I'm using Google Maps API and I have some troubles about InfoWindow.

Here is a summary :

  • I'm loading the InfoWindow's content when user clicks on a marker
  • The content is a partial view, loaded thanks to an Ajax call
  • In the .done callback, I call an asynchronous method which will insert data into the InfoWindow content. I need to do this because I want the InfoWindow main content to be displayed immediately, whereas this "bonus" information could be displayed after some tenths of seconds.

This perfectly works ; but I have a white strip on the right of my InfoWindow I can't remove (see the picture below)

However, the content I load is included in a <div> with a fixed width :

<div id="div-main-infoWindow">
    <!-- All my content -->
</div>

And in my CSS, I wrote :

#div-main-infoWindow {
    width:342px !important;
}


The loading of the InfoWindow, with more details, looks like this :

$.ajax({  
            url         :    "/my-url",
            async       :    false,
            contentType :    "application/json; charset=utf-8",
            dataType    :    "json",
            type        :    "POST",
            data        :    JSON.stringify(myModel)
        }).done(function(response) {

             MarkerContent = response.Content; //The HTML content to display

             MyAsyncMethod().then(function(response) {
                 //do some formatting with response
                 return result;  //result is just a small HTML string 
             }).done(function(result1, result2) {
                 //do some formatting with result1 and result2
                 $("#myNode").html(/*formatted result*/);
             })

            //info is a global variable defined as new google.maps.InfoWindow()
            info.setOptions({
                content: MarkerContent,
                maxWidth: 342 //To be sure 
            });

            info.open(map, marker);
        });
});

The content is perfectly OK, the problem is all about this white strip.

Looking at my browser console (I reproduced it in ALL browsers), I can see this :

IW

As you can see there, my <div> containing all my data loaded from my ajax call is OK with the good size (green rectangle, corresponding to the greyed zone in the screenshot), BUT the above divs (from Google API itself, into the red rectangles) have a bigger size, from which the problem is.

The only way I found is running this jQuery script modifying the InfoWindow internal structure :

$(".gm-style-iw").next().remove();
$(".gm-style-iw").prev().children().last().width(342);
$(".gm-style-iw").prev().children(":nth-child(2)").width(342);

$(".gm-style-iw").width(342);
$(".gm-style-iw").children().first().css("overflow", "hidden");
$(".gm-style-iw").children().first().children().first().css("overflow", "hidden");
$(".gm-style-iw").parent().width(342);

Note : gm-style-iw is the class name given by Google of the div containing all the content of the InfoWindow, the one hovered on the above screenshot. I also add this rule in my CSS :

.gm-style-iw {
    width: 342px !important; //also tried with 100% !important, not better
} 

It works in the console, however, it has no effect when written in the code itself, in the .done callback, or in the domready Google Maps' event...
However, in this late case, if I encapsulate the above jQuery script in a setTimeout(), it works !! I commented the asynchronous method, so it's not this one which is guilty, but it seems domready is executed whereas 100% of the InfoWindow is not still displayed - which is contrary to the doc.

I also tried to move my info.setOptions outside the .done callback and put it at after it, no effect.

So, how can I display a "normal" InfoWindow without this white strip on the right ?
I don't want to implement InfoBubble or other custom InfoWindow library. It's a personal project and I want to understand why and where the problem is. And of course, find a solution.

Thank you for your help !

like image 641
AlexB Avatar asked Feb 18 '15 17:02

AlexB


People also ask

How do I change the width of infowindow on Google Maps?

maps. InfoWindow({ content: some_text, maxWidth: 200 }); The documentation notes that the "value is only considered if it is set before a call to open. To change the maximum width when changing content, call close, setOptions, and then open."

How do you change the infowindow position on Google Maps?

An InfoWindow can be placed on a map at a particular position or above a marker, depending on what is specified in the options. Unless auto-pan is disabled, an InfoWindow will pan the map to make itself visible when it is opened. After constructing an InfoWindow, you must call open to display it on the map.

How do I change the background color of infowindow in Google Maps?

Customize infowindow in Google mapStep 1 Go to Manage Map -> Edit Page. Step 2 Scroll down to 'Infowindow Customization Settings' section and enable 'Turn On Infowindow Customization' checkbox. Step 3 Configure the infowindow height, Border Color , Border Radius , Background Color. Step 4 Then click Save Map.

How do I close all infowindow in Google Maps?

maps. event. addListener(marker, 'click', function() { if (infowindow) { infowindow. close(); } infowindow = new google.


1 Answers

It's a little bit more complex than you think.

Just some things:

  • did you notice that there is a close-button? Even when you remove the button the space will be there, because the API calculates the size of the other nodes based on this space
  • the tip must be in the center
  • there are additional containers for rounded borders and shadows
  • the size of the infoWindow will be calculated so that it fits into the viewport
  • the content must be scrollable when needed
  • the position of the infowindow must be set(therefore it's required to calculate the exact height of the infowindow)

Basically: all these things require to calculate exact sizes and positions, most of the nodes in the infowindow are absolute positioned, it's rather a technique like it will be used in DTP than you would use it in a HTML-document.

Additionally: the InfoWindows will be modified very often to fix bugs, a solution which works today may be broken tomorrow.

However, an approach which currently works for me:

  1. set the maxWidth of the infowindow to the desired width - 51 (would be 291 in this case)
  2. It's not possible to apply !important-rules via $.css , so it must be done via a stylesheet directly. To be able to access all the elements set a new class for the root-node of the infowindow(note that there may be infoWindows which you can't control, e.g. for POI's):

    google.maps.event.addListener(infowindow,'domready',function(){ 
      $('#div-main-infoWindow')//the root of the content
       .closest('.gm-style-iw')
        .parent().addClass('custom-iw');
    });
    
  3. the CSS:

  .custom-iw .gm-style-iw {
      top:15px !important;
      left:0 !important;
      border-radius:2px;
  }
  .custom-iw>div:first-child>div:nth-child(2) {
      display:none;
  }
  /** the shadow **/
  .custom-iw>div:first-child>div:last-child {
      left:0 !important;
      top:0px;
      box-shadow: rgba(0, 0, 0, 0.6) 0px 1px 6px;
      z-index:-1 !important;
  }

  .custom-iw .gm-style-iw, 
  .custom-iw .gm-style-iw>div, 
  .custom-iw .gm-style-iw>div>div {
      width:100% !important;
      max-width:100% !important;
  }
  /** set here the width **/
  .custom-iw, 
  .custom-iw>div:first-child>div:last-child {
      width:342px !important;
  }


  /** set here the desired background-color **/
  #div-main-infoWindow, 
  .custom-iw>div:first-child>div:nth-child(n-1)>div>div, 
  .custom-iw>div>div:last-child, 
  .custom-iw .gm-style-iw, 
  .custom-iw .gm-style-iw>div, 
  .custom-iw .gm-style-iw>div>div {
      background-color:orange !important;
  }

  /** close-button(note that there may be a scrollbar) **/
  .custom-iw>div:last-child {
      top:1px !important;
      right:0 !important;
  }

  /** padding of the content **/
  #div-main-infoWindow {
      padding:6px;
  }

Demo(as I said, may be broken tomorrow): http://jsfiddle.net/doktormolle/k57qojq7/

like image 133
Dr.Molle Avatar answered Nov 07 '22 15:11

Dr.Molle