Search code examples
cssiphonetwitter-bootstrapmodal-dialogpopup

Bootstrap modal bug when open ONLY on iphone/ipad


I observe a very strange bug on iphone (and ipad) when I open a Bootstrap modal. The black (semi opaque) background is well show, but the modal is not display. There is nothing visible and the user is blocked.

I'm using the following lib:

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>

I already understood a possible reason, I include all the content of the modal inside an html table. In the follwing exemple, we can see two working case and the one concerned by the bug:

    <!-- debug popup -->
<!DOCTYPE html>
<html lang="fr" class="no-js">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="keywords" content="test" />
    <meta name="author" content="Kaio Gaming" />
    <link rel="shortcut icon" href="https://www.blabl.fr/favicon.ico" sizes="96x96" type="image/x-icon" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
    <script language="JavaScript" src="/membreDev/js/modernizr.js?version=1.0.3a"></script>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

    <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>


    <link href="https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/js/all.js"
        integrity="sha256-2JRzNxMJiS0aHOJjG+liqsEOuBb6++9cY4dSOyiijX4=" crossorigin="anonymous"></script>

    <title>debug popup</title>
    <meta name="description" content="debug popup de Kaio Gaming" />

</head>

<body>
    <div class="container theme-showcase" role="main">
        <div class="jumbotron">
            <center>
                <h1>debug popup</h1>
            </center>
            <div class="row float-right">
                <a type="button" href="../index.php" class="btn btn-danger">&larr;</a>
            </div>
        </div>
    </div>

    <main role="main">
        <div class="container marketing">
            <h1>Working case #1: button and modal content directly in HTML root code</h1>
            <button type="button" class="btn btn-danger col-12" aria-haspopup="true" aria-expanded="false"
                title="Faire une demande" id="btn-demande-acces" data-toggle="modal" data-target="#popup-demande-acces"
                data-backdrop="static" data-keyboard="false">
                Demander un accès
            </button>
            <div class="modal fade" id="popup-demande-acces" tabindex="-1" role="dialog" aria-labelledby=""
                aria-hidden="true" style="display: none;">
                <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <center>
                                <h4 class="modal-title" id="modTitle">Faire une demande d'accès</h4>
                            </center> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                                    aria-hidden="true">×</span></button>
                        </div>
                        <div class="modal-body">
                            <form method="post" action="javascript:void(0);" id="submitModalDemandeAcces">
                                <div class="form-group hide">
                                    <label for="Demandeur" class="control-label">Demandeur:
                                    </label>
                                    <select required="" value="1" class="custom-select" id="Demandeur"
                                        placeholder="Demandeur à définir" name="Demandeur">
                                        <option value="blablabla">blablabla (Exemple)</option>
                                    </select>
                                </div>
                                <div class="form-group">
                                    <label for="Type" class="control-label">Type:
                                    </label>
                                    <select value="1" class="custom-select" id="Type" required=""
                                        placeholder="Type à définir" name="Type">
                                        <option value="1">Example</option>
                                    </select></div>
                                <div class="form-group">
                                    <label for="Details_de_la_demande" class="control-label">Détails de la demande:
                                    </label>
                                    <input type="text" class="form-control" value="" name="Details_de_la_demande"
                                        id="Details_de_la_demande" required=""
                                        placeholder="Détails de la demande à définir">
                                </div>
                                <div class="modal-footer">
                                    <center> <button type="submit" class="btn btn-primary" title="Ajouter ➕">Ajouter
                                            ➕</button>
                                        <button id="demande_annulation" type="button" class="btn btn-default"
                                            data-dismiss="modal">Annuler ⨯</button> </center>
                                </div>
                            </form>
                        </div>
                    </div>
                </div>
            </div>


            <h1>Working case #2: the button is in the table, but the content is outside the table</h1>
            <div class="table-responsive ">
                <table class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th>
                                <center>Membre</center>
                            </th>
                            <th>
                                <center></center>
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="rows countLineId row_1">
                            <td><span title="membre-97">ssj (ssj)</span></td>
                            <td>
                                <center><button type="button" class="btn btn-secondary" data-toggle="modal"
                                        data-target="#contactModal_97">Contacter</button>
                                </center>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <!-- modal body outside the TABLE -->
            <div class="modal fade" id="contactModal_97" tabindex="-1" role="dialog" aria-labelledby="Contacter membre"
                aria-hidden="true">
                <div class="modal-dialog modal-lg" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title" id="viewMembre" title="Contact">
                                Contacter <a title="Voir le profil membre"
                                    href="https://www.blabla.fr/monCompte/maPage.php?pseudo=ssj">ssj:
                                    ssj</a>
                            </h5>
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">×</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            <ul>
                                <li>Email: <a href="mailto:ss@gmail.com">ss@gmail.com</a>
                                </li>

                                <li>Portable: <a href="tel:97678">97678</a></li>
                                <li>Discord: 0999897</li>
                                <li>Adresse postal: <a target="_blank"
                                        href="https://www.google.com/maps/place/blabla FRANCE"
                                        title="Google Maps">blabla, FRANCE</a> </li>
                            </ul>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Fermer</button>
                        </div>
                    </div>
                </div>
            </div>


            <h1>ERROR case: the open modal button AND the content is inside the table</h1>
            <div class="table-responsive ">
                <table class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th>
                                <center>Membre</center>
                            </th>
                            <th>
                                <center></center>
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr class="rows countLineId row_1">
                            <td><span title="membre-96">ssj (ssj)</span></td>
                            <td>
                                <center><button type="button" class="btn btn-secondary" data-toggle="modal"
                                        data-target="#contactModal_96">Contacter</button>
                                    <div class="modal fade" id="contactModal_96" tabindex="-1" role="dialog"
                                        aria-labelledby="Contacter membre" aria-hidden="true">
                                        <div class="modal-dialog modal-lg" role="document">
                                            <div class="modal-content">
                                                <div class="modal-header">
                                                    <h5 class="modal-title" id="viewMembre" title="Contact">
                                                        Contacter <a title="Voir le profil membre"
                                                            href="https://www.blabla.fr/monCompte/maPage.php?pseudo=ssj">ssj:
                                                            ssj</a>
                                                    </h5>
                                                    <button type="button" class="close" data-dismiss="modal"
                                                        aria-label="Close">
                                                        <span aria-hidden="true">×</span>
                                                    </button>
                                                </div>
                                                <div class="modal-body">
                                                    <ul>
                                                        <li>Email: <a href="mailto:ss@gmail.com">ss@gmail.com</a>
                                                        </li>

                                                        <li>Portable: <a href="tel:97678">97678</a></li>
                                                        <li>Discord: 976575</li>
                                                        <li>Adresse postal: <a target="_blank"
                                                                href="https://www.google.com/maps/place/blabla FRANCE"
                                                                title="Google Maps">blabla, FRANCE</a> </li>
                                                    </ul>
                                                </div>
                                                <div class="modal-footer">
                                                    <button type="button" class="btn btn-secondary"
                                                        data-dismiss="modal">Fermer</button>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </center>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </main>
</body>

</html>

Solution

  • I fixed my bug using a "dirty" code.

    I add in all my modal body elements a specific class (moveModalBody) and I move them in another place (a div in the head, in my case, but maybe in the footer or at the end of the body should be better...)

    <script>
    /* MOVE modal body: 
        All HTML code with the class modalBodyToMove  (modal created in sql2html)
        must mouve in div identifier moveModalHere (div in the generic header)
        to move them out of everything (specially the HTML tables)
    */
    var elements = document.querySelectorAll('.modalBodyToMove');
    var classCount = elements.length;
    console.log("Number of class modalBodyToMove: "+classCount);
    if (classCount > 0){
        for(var i = 0; i < elements.length; i++) {
            document.getElementById('moveModalHere').appendChild(  elements[i] )
        }
    }
    </script>
    

    Of course, this script is added at the end of the page (after all the modal bodies are added)

    NOTE: I added a check on the sum to avoid the js error in case of no modal on the page ^^

    Question: I do believe this solution can impact the speed of my page (depending of the browser and the device...) I already open a bug issue on github twitter/bootstrap but if someone have a better idea, I'm open to test thank you in advance