mercoledì 4 gennaio 2012

Gestire click su riga utilizzando display tag

L'ottima libreria display tag dispone di molte facilitazioni per la visualizzazione, formattazione export ordinamento e paginazione dei dati.
Tipicamente la richiesta negli applicativi gestionali è di avere la possibilità una volta visualizzata la lista di entrare nel dettaglio della stessa.
Ciò è facilmente ottenibile costruendo (ad esempio tramite un decorator) una proprietà ad hoc del bean che sia in realtà del tipo <a href="..." con la lista dei parametri in get espressi nella stringa.
In questo modo quindi è possibile cliccando sulla cella (dove possiamo aggiungere ovviamente anche una immagine) accedere al nostro dettaglio.
Spesso però l'utente chiede qualcosa di diverso ossia poter accedere al dettaglio cliccando su qualsiasi punto della riga e non espressamente sul nostro link.
Anche questa operazione, pur se con qualche artificio, è possibile utilizzando display tag.
Vediamo come con un esempio volutamente banale e che illustra soltanto la funzionalità: si tratta di esporre a video una serie di parametri (Regione,Provincia,Dettaglio testuale) e quindi cliccando su qualsiasi punto della riga accedere ad una pagina di dettaglio, dove verrà vissualizzato semplicemente il dettaglio di quanto cliccato.

Il segreto per poter riuscire nel click di riga è aggiungere l'evento onclick alla riga della tabella generata da displaytag. Il javascript avrà accesso alle celle della riga e in una cella hidden avremo i parametri da passare in get alla nostra funzione (in questo caso sarà una servlet).

Vediamo il codice javascript:

 function addRowHandlers(tableId, rowClassName, url,  columnIndex) {
    var previousClass = null;
    var table = document.getElementById(tableId);
    var rows = table.getElementsByTagName("tr");
    for (i = 1; i < rows.length; i++) {
        rows[i].onmouseover = function () {
            previousClass = this.className;
            this.className = this.className + " " + rowClassName ;
        };
       
        rows[i].onmouseout = function () {
            this.className = previousClass;
        };
       
        rows[i].onclick = function () {
            var cell = this.getElementsByTagName("td")[columnIndex];
            var paramValue = cell.innerHTML;
            location.href= url +"?"+paramValue.replace(/&amp;/g,'&');
        };
    }
}


Questo codice aggiunge alla riga generata prima gli eventi onmouseover e onmouseout (solo per migliorare la visualizzazione della griglia le cui righe cambieranno colore al passare del mouse) e poi l'evento onclick che costruisce il link di chiamata.

Si noti che per evitare problemi con Firefox nel contenuto della cella sono sostituiti tutti i caratteri del tipo &amp; con & questo perchè con Firefox il carattere & se inviato lato server viene subito trasformato in &amp; e quindi effettuando la get i parametri non arrivano correttamente nella request.

Una volta installata display tag copiando i jar dentro la directory lib aggiungiamo anche un css di questo tipo, chiamandolo displaytagex.css:


table.dataTable {
 background-color: white;
 width: 100%;
 height:1%;
 font: 10pt Verdana, Arial, Helvetica, sans-serif;
 border:0px solid gray;

}
table.dataTable tr {
 background-color: #E9E9E9;

}
table.dataTable tr.fixed {
 position:absolute;
 color: #E9E9E9;
}

table.dataTable tr.odd {
 background-color: whitesmoke;

}
table.dataTable tr.even {
 background-color: #C8E6F0;

}
table.dataTable tr.rowMouseOver {
 background-image: url(../images/transparent.png);
 background-repeat: repeat-x;
 background-color: #ffff99;

}
table.dataTable th{
 color:black;
 background-image: url(../images/transparent.png);
 vertical-align:middle;
 text-align: center;
 font: 9pt Verdana, Arial, Helvetica, sans-serif;
 font-weight:bold;
 border-right: 1px solid white;
}

table.dataTable td{
 padding-top: 0px;
 padding-bottom: 0px;
 empty-cells:show;
 vertical-align:middle;
 text-align: center;
 background-image: url(../images/transparent.png);
 color:#333333;
 font: 8pt Verdana, Arial, Helvetica, sans-serif;
 font-weight:normal;
 border-right: 1px solid white;
}

.scrollDiv {
 background-color: white;
 overflow-y: scroll;
 border: 3px solid #E9E9E9;
 vertical-align: middle;
 text-align: left;

}
.scrollDivComportamenti {
 background-color: white;
 overflow-y: scroll;
 border: 3px solid #E9E9E9;
 vertical-align: middle;
 text-align: left;
 height:300px;

}
table.dataTable th.left{
 color: black;
 background-image: url(../images/transparent.png);
 vertical-align: middle;
 text-align: left;
 font: 9pt Verdana, Arial, Helvetica, sans-serif;
 font-weight:bold;
 border-right: 1px solid white;
 padding-left: 5px;
}

table.dataTable td.codice {
 cursor: hand;
 width: 10%;
 text-align: left;
 font: 7pt Verdana, Arial, Helvetica, sans-serif;
 padding-left: 6px;
 height:1px;
}

table.dataTable td.descrizione {
 cursor: hand;
 width: 90%;
 text-align: left;
 font: 7pt Verdana, Arial, Helvetica, sans-serif;
 padding-left: 5px;
 height:1px;
}

table.dataTable th.sortable {
 background-image: url(../images/arrow_off.png);
 background-repeat: no-repeat;
 background-position: left;
 padding-right: 10px;
 padding-left: 5px;
}

table.dataTable th.hidden {
 display: none;
}

table.dataTable td.hidden {
 display: none;
}

Ecco la jsp che visualizza i dati in tabella:

<html>
<head>
 <link href="stili/displaytagex.css" rel="stylesheet" media="screen" type="text/css">
 <script src="js/RowHandlers.js" language="javascript" type="text/javascript" /></script>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test click su riga</title>
</head>
<body onload="addRowHandlers('row', 'rowMouseOver', 'VisualizzaDettaglio',  0)">

<display:table name="${LISTA}" id="row" class="dataTable" >
 <display:column property="queryString" class="hidden" headerClass="hidden"></display:column>
 <display:column property="regione" group="1" title="REGIONE" ></display:column>
 <display:column property="provincia" title="PROVINCIA"></display:column>
 <display:column property="dettaglio" title="DETTAGLIO"></display:column>
 <display:column property="link" title="LINK"></display:column>
</display:table>
</body>
</html>


La proprietà querystring come possiamo vedere è nascosta, e servirà al javascript per leggere i parametri da passare in get.

La classe Regione, il bean della lista dati, è il seguente:

public class Regione {
 private String regione;
 private String provincia;
 private String dettaglio;
 private String link;

 public String getQueryString(){
    
 
   return "regione="+regione+"&provincia="+provincia+"&dettaglio="+dettaglio;
 
 }
 public String getLink() {
 
  return "<a href='VisualizzaDettaglio?regione="+regione+"&provincia="+provincia+"&dettaglio="+dettaglio+"'>Vai<a/>";
 }
 public void setLink(String link) {
  this.link = link;
 }
 public String getRegione() {
  return regione;
 }
 public void setRegione(String regione) {
  this.regione = regione;
 }
 public String getProvincia() {
  return provincia;
 }
 public void setProvincia(String provincia) {
  this.provincia = provincia;
 }
 public String getDettaglio() {
  return dettaglio;
 }
 public void setDettaglio(String dettaglio) {
  this.dettaglio = dettaglio;
 }
 public Regione(){
 
 }
 public Regione(String regione,String provincia,String dettaglio){
  this.regione=regione;
  this.provincia=provincia;
  this.dettaglio=dettaglio;
 }
}


I dati sono recuperati da una servlet e inviati alla jsp nella request, in questo modo:

List<Regione> lista=new ArrayList<Regione>();
  lista.add(new Regione("Lazio", "FR", "txkjfskjdj"));
  lista.add(new Regione("Lazio", "LT", "txkjfskjdj"));
  lista.add(new Regione("Lazio", "VT", "txkjfskjdj"));
  lista.add(new Regione("Lazio", "FR", "txkjfskjdj"));
  lista.add(new Regione("ABRUZZO", "AQ", "txkjfskjdj"));
  lista.add(new Regione("Lombardia", "MI", "txkjfskjdj"));
  lista.add(new Regione("Toscana", "FI", "txkjfskjdj"));
  lista.add(new Regione("Sicilia", "PA", "txkjfskjdj"));
  lista.add(new Regione("Sardegna", "CG", "txkjfskjdj"));
  request.setAttribute("LISTA", lista);
  RequestDispatcher rd=request.getRequestDispatcher("jsp/listaRegioni.jsp");
  rd.forward(request, response);



La servlet di destinazione non fa che esporre i dati selezionati dalla griglia, in questo modo:

PrintWriter pw=response.getWriter();
  String regione=request.getParameter("regione");
  String provincia=request.getParameter("provincia");
  String dettaglio=request.getParameter("dettaglio");
  pw.append("<html>Hai selezionato<br> <b>Regione: </b> "+regione.toUpperCase()+" <br>  <b>Provincia: </b> "+provincia.toUpperCase()+"<br> <b>Dettaglio: </b> "+dettaglio.toUpperCase()+"</html>");
  pw.flush();


Il risultato visuale di quanto descritto è il seguente:



Cliccando sulla riga selezionata si arriva poi qui:

Nessun commento:

Posta un commento