Search code examples
jquerycsstwitter-bootstrapleafletbootstrap-4

Show/Hide div in Bootstrap 4 while resizing height of leaflet map


I'm building a web app that has 3 components on the screen.
  Navbar (sticky top)
  Main Container
     map container(75% of main)
     chat window (25% of main)

What I want to be able to do is hide the chat footer then have the map container take up all of the main container, but if user wants to see the chat window, he clicks a button and the map shrinks back to 75% of the main and the chat window is visible again. I want this functionality to work across all the bootstrap breakpoints so from what I've read the responsive visibility classes are not what I want.

The javascript I'm using is

  $('#chatToggle').click(function(e) {
    console.log('in chatToggle');
    var cf = document.getElementById('chatFooter');
    var mc = document.getElementById('leafletMap');
    if (cf.style.display === 'none') {
        console.log('showing chat window');
        cf.className = 'row h-15 ';
        mc.className = "row h-85 map-container";
        $('#chatToggle').text('Hide Chat')
      } else {
        console.log('hiding chat window');
        cf.className = 'row h-15 d-none';
        mc.className = "row h-85 map-container";
        $('#chatToggle').text('Show Chat')
      }
    map.invalidateSize();
  });

When the page first loads, it appears as I want it and the navbar responds to the breakpoints and acts like a nice responsive navbar. However, as soon as I turn off the chat footer with code above, the navbar disappears, the map takes up the whole viewport and map attribution morphs into some big mess on the top of the screen. Here are two screenshots: Here is the page when it first loads

And here is after I execute the js to hide the window

Relevant HTML is:

<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-primary navbar-fixed-top">
            <a class="navbar-brand" href="#">
                    <span class=lg-view>TRACKING SYSTEM</span>
            </a>

            <div class="navbar-toggler">
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarContent" aria-controls="navbarContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
            </div>
            <div class="collapse navbar-collapse justify-content-end" id="navbarContent">
            <ul class="navbar-nav " >
                <li class="nav-item dropdown text-center" >
                    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                                Menu
                    </a>
                    <div class="dropdown-menu" >
                        <a class="dropdown-item" data-toggle="modal" href="#realTimeModal">Real-Time Tracking</a>
                        <a class="dropdown-item" data-toggle="modal" href="#historicalModal">Historical Tracking</a>
                        <a class="dropdown-item" data-toggle="modal" href="#gridsModal">Display Grids</a>
                        <div class="dropdown-divider"></div>
                        <a id="stop_tracking" class="dropdown-item" href="#">Stop Tracking</a>
                        <a id="clear_grids" class="dropdown-item" href="#">Clear Grids</a>
                    </div>
                </li>
                <a class="flex-fill text-center text-light nav-link" href="#chatToggle" id="chatToggle" >Hide Chat</a>
                <a class="flex-fill text-center text-light nav-link" href="#contact">Settings</a>
            </ul>
        </div>
    </nav>
    <div class="container-fluid h-100">
        <div class="row h-75 map-container" id="leafletMap">

        </div>
        <div class="row h-25" id="chatFooter">
                <div class="col-sm-2 border">
                        <h4 class="chatLabel">Chat History</h4>
                </div>

                <div class="col-sm-10 border">
                    <textarea readonly class="chatMsgTxt w-100 border" id="chatMsgTxt" style="border: 1px black;">test data</textarea>
                </div>
        </div>
    </div>
</body>

And in my css I have:

html, 
 body {
     height: 100%;
 }

Is it possible to accomplish what I'm trying to do with Bootstrap 4?


Solution

  • Instead of all the extra JS to handle the button click, use the Bootstrap collapse component. Add handlers for the hide/show events to resize the map, and toggle the button text:

    $('.chat').on('hide.bs.collapse',function(){
        mymap.invalidateSize();
        $('#chatToggle').text("Show Chat");
    }).on('show.bs.collapse',function(){
        mymap.invalidateSize();
        $('#chatToggle').text("Hide Chat");
    });
    

    The problem you're having with resizing heights is easier solved with flexbox. Just add a class to the .map-container so that it grows automatically in height when the chat is collapsed.

    .map-container {
        flex: 1 1 auto;
    }
    

    Working demo: https://www.codeply.com/go/jCa2CsQFYY