I am using AngularJS, jQuery UI (with a custom directive for resize), and Bootstrap. On my page, a Google Map appears in the top section, and a table will appear in the bottom section. As the user resizes the bottom section, I’d like the Google Map to automatically resize to take up the remaining space.
I’ve tried several different approaches including:
- Setting
html, body { height: 100%; width: 100% }
and#mapCanvas { height: 100% }
. - Using flexbox and flexgrow.
- Calculating the size of the top section after the bottom section is resized, and dynamically changing the height of the
#mapCanvas
element based on that.
But I haven’t had luck with any of these. Any suggestions would be appreciated. Below is an example demonstrating the issue.
JSFiddle (in case the snippet area is obscured by the Google Maps API key warnings): https://jsfiddle.net/jmg157/9odt0hLn/
function initMap() { let mapOptions = { zoom: 8, minZoom: 8, center: new google.maps.LatLng(43, -81), mapTypeId: google.maps.MapTypeId.ROADMAP, }; map = new google.maps.Map(document.getElementById('mapCanvas'), mapOptions); } let app = angular.module("mapApp", ['ui.bootstrap']); app.directive('resizable', function() { return { restrict: 'A', scope: { callback: '&onResize' }, link: function postLink(scope, elem, attrs) { elem.resizable({ "handles": { "n": ".ui-resizable-n" } }); } }; }); app.controller("MapAppController", function($scope) { initMap(); });
html, body { height: 100%; width: 100%; } #mapCanvas { /*height: 100%;*/ height: 60vh; } .ui-resizable-n { border-top: 5px solid grey; } .table { background: #fff; }
<html> <head> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" /> <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script> <script src="https://maps.googleapis.com/maps/api/js?key="></script> </head> <body ng-app="mapApp"> <div ng-controller="MapAppController"> <div class="container-fluid"> <div class="row"> <div class="col-md-12"> <div id="mapCanvas"></div> </div> </div> <div class="row" resizable> <div class="ui-resizable-n ui-resizable-handle"></div> <div class="col-md-12 col-xs-12"> Bottom Content Section </div> </div> </div> </div> </body> </html>
Advertisement
Answer
By setting the upper element to resizable and listening to the resize
event and setting the map container height to be the resized element height.
app.directive('resizable', function() { return { restrict: 'A', scope: { callback: '&onResize' }, link: function postLink(scope, elem, attrs) { elem.resizable(); elem.on('resizestop', function(evt, ui) { if (scope.callback) { scope.callback(); } }); elem.on('resize', function(evt, ui) { // Set map container height based on resizable element height $('#map-canvas').height($('div[resizable]').height()); }); } }; });
Full working fiddle here.