Creare popup modal Bootstrap nella stessa pagina web con CakePHP 3.x

In questa guida vedremo come risolvere un problema riccorente quando si fa ricorso all’uso di più popup modal Bootstrap nella stessa pagina web. La stessa soluzione verrà integrata in Layout CakePHP per rendere centralizzare il modale, e poterlo utilizzare in qualsiasi template in esecuzione.

bootstrap modal popup

Scenario

Inizialmente lo scenario prevede la presenza di una pagina web standard, configurarata per utilizzare stili e script Bootstrap, per questo motivo proponiamo la pagina di esempio presente sul sito Bootstrap getting-started, come di seguito:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>Bootstrap 101 Template</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <h1>Hello, world!</h1>

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
  </body>
</html>

Predisponiamo la pagina con il blocco in cui mandare in esecuzione il modal, ricorrendo all’esempio previsto sulla guida, nella sezione modal.js, come di seguito:

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-body">
      <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>      
      </div>
    </div>
  </div>
</div>

Infine introduciamo questo script che consente di svuotare il contenuto del modale centralizzato, ogni volta che viene nascosto, consentendo di visualizzare ogni volta il contenuto desiderato:

<script>
    // Remove data on hidden bs modal
    $('#myModal').on('hidden.bs.modal', function (e) {
        $(this).removeData('bs.modal');
    });
</script>

Attenzione! Senza questo script viene visualizzato sempre il primo contenuto fino a nuovo caricamento della pagina web che contiene il blocco del modale.

Ritornanndo a quello che il nostro obiettivo, ovvero l’integrazione di questa soluzione in CakePHP 3.x, vediamo come lo script principale della pagina possa essere trasformato in layout, integreremo il blocco modale e lo script nello stesso file ed infine presenteremo il template, definito esternamente per il lancio di contenuti differenti all’interno dello stesso blocco modale.

Layout

Di seguito viene presentato un esempio di layout per applicazione CakePHP, con la possibilità di disporre su tutte le pagine di un blocco modale in cui mandare in esecuzione di volta in volta il contenuto web desiderato:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
        <title>Bootstrap 101 Template</title>

        <!-- Bootstrap -->
        <link href="css/bootstrap.min.css" rel="stylesheet">

        <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
          <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
          <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->
    </head>
    <body>

        <!-- Blooco dove mandare in visualizzazione il contenuto della pagina -->
        <div id="content">
            <div class="container">
                <?= $this->fetch('content'); ?>
            </div>
        </div>

        <!-- Blocco #myModal centralizzato disponibile su tutte le pagine -->
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
            <div class="modal-dialog" role="document">
                <div class="modal-content" style="padding: 10px"></div>
            </div>
        </div> 

        <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <!-- Include all compiled plugins (below), or include individual files as needed -->
        <script src="js/bootstrap.min.js"></script>

        <!-- Script per blocco #myModal che rimuove il contenuto -->
        <script>
            // Remove data on hidden bs modal
            $('#myModal').on('hidden.bs.modal', function (e) {
                $(this).removeData('bs.modal');
            });
        </script>
    </body>
</html>

Conclusioni – bootstrap modal popup

Questa soluzione è molto pratica, in quanto, consente di definire una pagina web che aggrega più informazioni e nella stessa prevedere una serie di bottoni che consentano mediante il modale di visualizzare i template per la modifica al volo dei contenuti, con la possibilità di ritornare alla vista aggregata dopo avere processato e salvato i dati.

Infine, giusto per completezza, viene presentato lo script HTML di esempio da utilizzare nel template CakePHP, con i bottoni che puntano a diversi link, ma che vanno in esecuzione all’interno dello stesso oggetto grafico centralizzato #myModal:

<!-- Button trigger modal --> 
<a href="http://example.com/pagina-1" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">Pagina 1</a>
<a href="http://example.com/pagina-2" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">Pagina 2</a>
<a href="http://example.com/pagina-3" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">Pagina 3</a>

Personalmente ho trovato questa soluzione molto utile, quello che il browser non svuoti in automatico il contenuto del modale quando lo stesso viene nascosto è un problema ricorrente che è possibile risolvere con lo script presentato.

Il fatto di presentare l’intero scenario è perchè spesso ricorro a tale soluzioni per risolvere il problema di di integrare più modali nella stessa vista, che facciamo di fatto azioni diverse sui dati presentati in vista aggregata.

Lascia un commento