How to use this Modal bootstrap more elegantly?

Asked

Viewed 518 times

1

I don’t know if the title is appropriate, but I’ll explain:

In the example below I have a confirmation modal that can be called by several buttons and depending on the button clicked I take an attitude.

I’m using a global variable to know which button was clicked, but I’m thinking that this is not a safe way because if this code grows I may have problems.

I don’t know much about jQuery enough to make Callbacks and also don’t know if that would be the case, I’m wondering if it would be possible to transfer the button clicked to the Onclick event from the button object in a more elegant way (or appropriate).

Maybe my idea is totally outside of what would be recommended, but searching the web I did not find or I did not understand how could do it... I found several plugins that could facilitate this, including using Bootstrap.Dialog, but when it gets obsolete I have problems updating, so I would like to work more with something native bootstrap same.

<!DOCTYPE html>
<html>
    <head>
        <title>TESTE MODAL</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
        
        <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    </head>
    <body>

        <div id="confirma" class="modal fade" tabindex="-1" role="dialog">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header bootstrap-dialog-draggable" style="background: #f0ad4e; border-radius: 6px 6px 0 0;">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                        <h4 class="modal-title">Confirma a gravação dos dados?</h4>
                    </div>
                    <div class="modal-body">
                        <p>Texto</p>
                    </div>
                    <div class="modal-footer">
                        <button type="button" id="btn-nao" class="btn btn-default" data-dismiss="modal">
                            <!--span class="bootstrap-dialog-button-icon glyphicon glyphicon-remove"></span-->
                            Não
                        </button>
                        <button type="button" id="btn-sim" class="btn btn-primary">
                            <!--span class="bootstrap-dialog-button-icon glyphicon glyphicon-ok"></span-->
                            Sim
                        </button>
                    </div>
                </div><!-- /.modal-content -->
            </div><!-- /.modal-dialog -->
        </div><!-- /.modal -->

        <script>

            $(document).ready(function () {

                $(".btn-confirma").on("click", function () {

                    botao = $(this).prop("class").split(" ");

                    if (botao[1] === "btn1") {

                        $(".modal-body").html("Botão 1 clicado");
                    } else {

                        $(".modal-body").html("Botão 2 clicado");
                    }

                    $("#confirma").modal();
                });

                $("#btn-sim").on("click", function (e) {
                    alert("Quem clicou? \nBotão: " + botao[1]);
                    $("#btn-nao").click();
                });

            });

        </script>

        <div style="padding: 30px; margin: 0 auto;">
            <button class="btn-confirma btn1">Confirma 1</button>
        </div>

        <div style="padding: 30px; margin: 0 auto;">
            <button class="btn-confirma btn2">Confirma 2</button>
        </div>

        <script src="../../../bootstrap/js/bootstrap.min.js"></script>
        <script src="../../../bootstrap/js/bootstrap-dialog.min.js"></script>
    </body>
</html>

1 answer

1


You really should do everything using Bootstrap methods. For example, to open the modal, you use the attributes data-toggle="modal" data-target="#confirma" on the buttons, and not capturing a click to run $("#confirma").modal(); and open the modal.

There is no need even classes in buttons, much less to do .split() to catch the second class. That’s gambiarra bad and makes your code heavier and may give problem if you do not want to add a class in the buttons other than the one you expected in the split.

A simple way to identify the button that will open the modal is to use an attribute data-*, which may be data-id, with a value for each button:

<button data-id="1" data-toggle="modal" data-target="#confirma">Confirma 1</button>

<button data-id="2" data-toggle="modal" data-target="#confirma">Confirma 2</button>

Each button has its own data-id with its value (note that you do not need class, other than styling buttons via CSS or with native Bootstrap classes).

The improved Javascript code using Bootstrap’s own methods is below with explanations, and still avoiding global variables or broad scope:

$(document).ready(function () {

   $('#confirma').on('show.bs.modal', function (e) { // executa quando a modal abrir
      var botao = $(e.relatedTarget).data("id"); // pega o data-id do botão clicado
      var body_html; // declara variável para criar o html
      if (botao === 1) {
         body_html = "Botão 1 clicado"; // cria o html para o botão 1
      } else if (botao === 2) {
         body_html = "Botão 2 clicado"; // cria o html para o botão 2
      }

      $(".modal-body").html(body_html); // insere o html no body da modal

      $("#btn-sim").one("click", function () { // cria uma evento de clique no botão "sim" que só funciona 1 vez
         alert("Quem clicou? \nBotão: " + botao);
         $("#confirma").modal("hide"); // esconde a modal
      });

   }).on('hide.bs.modal', function (e) { // quando a modal fechar
      $("#btn-sim").off(); // cancela o evento clique no botão "sim"
   });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>

<div id="confirma" class="modal fade" tabindex="-1" role="dialog">
   <div class="modal-dialog" role="document">
       <div class="modal-content">
           <div class="modal-header bootstrap-dialog-draggable" style="background: #f0ad4e; border-radius: 6px 6px 0 0;">
               <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
               <h4 class="modal-title">Confirma a gravação dos dados?</h4>
           </div>
           <div class="modal-body">
               <p>Texto</p>
           </div>
           <div class="modal-footer">
               <button type="button" id="btn-nao" class="btn btn-default" data-dismiss="modal">
                   <!--span class="bootstrap-dialog-button-icon glyphicon glyphicon-remove"></span-->
                   Não
               </button>
               <button type="button" id="btn-sim" class="btn btn-primary">
                   <!--span class="bootstrap-dialog-button-icon glyphicon glyphicon-ok"></span-->
                   Sim
               </button>
           </div>
       </div><!-- /.modal-content -->
   </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

<div style="padding: 30px; margin: 0 auto;">
   <button data-id="1" data-toggle="modal" data-target="#confirma">Confirma 1</button>
</div>

<div style="padding: 30px; margin: 0 auto;">
   <button data-id="2" data-toggle="modal" data-target="#confirma">Confirma 2</button>
</div>

  • Perfect, let me abuse your kindness... is there a link that I can see as "nesting" modals? Like this, let’s assume that the guy clicked on YES so I would open another modal (without closing the current one) with a progress bar (even a simple text, "wait") and when the process is finished I would close the modals. My idea would be to open in this first modal a form and as soon as the guy confirms I open another to wait for the process to finish. If I have to.

  • Opening two modals at the same time I do not know if it works, I think not. Now you could try using a sweetalert (plugin) or even changing the body of the open modal by placing the message "Wait"..

Browser other questions tagged

You are not signed in. Login or sign up in order to post.