Tabla de Contenidos

Tabla Seleccionable Mediante Checkbox con Filas no Seleccionables

Vamos a mostrar como hacer una tabla seleccionable en el que hay filas que no pueden ser seleccionables, con paginación y sin el checkbox de Seleccionar Todas.

Código Javascript

Creamos en la carpeta src/main/web-app/resources/js del módulo WEB el fichero tabla_seleccionable.js con el siguiente contenido:

function configuraSeleccionMultiple(tabla) {
    try {
        // Permite ocultar la casilla de selección total de la cabecera
        $("th[id$='"+ tabla + ":seleccionColumn']").children("div.ui-chkbox").hide();
 
        $("input[id$='disableSelect']").each(function() {
            // Permite comprobar si una fila es seleccionable
            if ($(this).val() === "true") {
                // Si no seleccionable, desactivamos el comportamiento por defecto
                var tdPadre = $(this).parent(),
                    checkBox = $(tdPadre).children("div.ui-chkbox"),
                    checkBoxChildren = $(checkBox).children("div.ui-chkbox-box"),
                    trPadre = $(tdPadre).parent("tr.ui-datatable-selectable");
 
                $(trPadre).removeClass("ui-datatable-selectable");
 
                $(checkBox).removeClass("ui-state-active");
                $(checkBox).addClass("ui-state-disabled");
 
                // Remove the event from the link
                checkBox.onclick = null;
 
                // Add a check in for the class disabled
                $(checkBox).click(function(e) { 
                    if ($(checkBox).hasClass('ui-state-disabled')) {
                        e.stopImmediatePropagation();
                        e.preventDefault();
                    }                
                });
 
                $(checkBox).onmouseover = null;
                $(checkBox).mouseover(function(e) {
                    if ($(checkBox).hasClass('ui-state-disabled')) {
                        e.stopImmediatePropagation();
                        e.preventDefault();
                    }
                });
 
                $(checkBoxChildren).addClass("ui-state-hover");
                checkBoxChildren.onmouseover = null;
                $(checkBoxChildren).mouseover(function(e) {                 
                    e.stopImmediatePropagation();
                    e.preventDefault();
                    $(checkBoxChildren).addClass("ui-state-hover");
                });
 
            }
        });
    } catch (e) {}
}

Código JSF

En la página, cargamos el fichero Javascript en la cabecera de la página, de la siguiente manera:

<ui:composition template="/layout/template.xhtml">
 
    <ui:define name="head">
 
	<h:outputScript library="js" name="tabla_seleccionable.js" />
 
	<script type="text/javascript">
	$(document).ready(function() {
	    configuraSeleccionMultiple("listaTable");
	});
	</script>
 
    </ui:define>
 
    ...
</ui:composition>

El Javascript, permite ocultar el checkbox de selección global y desactivar la selección de las filas. Para eso, tenemos que pasarle el id del componente JSF <p:dataTable>, en este ejemplo es listaTable.

Tenemos la siguiente definición del <p:dataTable> de PrimeFaces:

    <p:dataTable id="listaTable" var="lista" tableStyleClass="table" value="#{servicioPendientePagoBean.model}"
        paginator="true" rows="10" paginatorPosition="bottom" lazy="true"
        selection="#{servicioPendientePagoBean.listaServicioPendientePago}" rowKey="#{lista.idServicio}" 		                            
        rowSelectMode="checkbox">
 
        <f:facet name="header">#{messages['label.header.listaServiciosNoPagados']}</f:facet>
        <p:column headerText="#{messages['tabla.gepeto.fechaServicio']}" width="7%" style="align:center">
            <h:outputText value="#{lista.getFechaServicio()}"/>
        </p:column>
        <p:column headerText="#{messages['tabla.gepeto.centroServicio']}" width="25%">
            <h:outputText value="#{lista.getCentro()}"/>
        </p:column>
        <p:column headerText="#{messages['tabla.gepeto.descripcionServicio']}" width="20%">
            <h:outputText value="#{lista.getServicio()}"/>
        </p:column>
        <p:column headerText="#{messages['tabla.gepeto.turnoServicio']}" width="9%">
            <h:outputText value="#{lista.getTurno()}"/>
        </p:column>
        <p:column headerText="#{messages['tabla.gepeto.dni']}" width="7%">
            <h:outputText value="#{lista.getDni()}"/>
        </p:column>
        <p:column headerText="#{messages['tabla.gepeto.nombre']}" width="20%">
            <h:outputText value="#{serviciosBean.nombreAuxiliar(lista.getDni())}"/>
        </p:column>			        
        <p:column headerText="#{messages['tabla.gepeto.alertas']}" width="5%">
		<s:div rendered="#{(serviciosBean.isAlertaHoras(lista.getDni(),lista.getFechaServicio()) ||  serviciosBean.isAlertaTika(lista.getDni(),lista.getFechaServicio()))}" > 
 
<i class="fa fa-exclamation-triangle fa-lg" style="color:red;" title="#{serviciosBean.showAlerta(lista.getDni(), lista.getFechaServicio())}"/> 
		</s:div>
        </p:column>
	<p:column id="seleccionColumn" headerText="#{messages['tabla.gepeto.aPago']}" width="5%" 
		selectionMode="multiple">
 
		<input type="hidden" name="disableSelect" id="disableSelect" value="#{(serviciosBean.isAlertaHoras(lista.getDni(),lista.getFechaServicio()) || serviciosBean.isAlertaTika(lista.getDni(),lista.getFechaServicio()))}" /> 		    
	</p:column>
	<f:facet name="footer">
	    	<div class="clearfix">
		    <div class="pull-right">
		    	<p class="text-right text-muted">En total hay #{servicioPendientePagoBean.model.rowCount} servicios pendientes de envío a Pagos</p>
		    </div>
	    	</div>
	</f:facet>
	<p:ajax event="page" oncomplete="configuraSeleccionMultiple('listaTable');"/>
	<p:ajax event="rowUnselectCheckbox" listener="#{servicioPendientePagoBean.deselecionarFila}" global="false"/>
    </p:dataTable>

En la definición de la tabla tenemos las siguientes propiedades referentes a la selección de filas:

Para determinar la posición de la selección en PrimeFaces, se siguen las siguientes condiciones:

En el ejemplo, la selección esta en la última columna, con la siguiente definición:

<p:column id="seleccionColumn" headerText="#{messages['tabla.gepeto.aPago']}" width="5%" selectionMode="multiple">
    <input type="hidden" name="disableSelect" id="disableSelect" value="#{not servicioPendientePagoBean.activarCombo(lista)}" /> 		    
</p:column>

En la definición de la columna, especificamos las siguientes propiedades:

En el componente <p:dataTable> tenemos definidas dos peticiones Ajax:

	<p:ajax event="page" oncomplete="configuraSeleccionMultiple('listaTable');"/>
	<p:ajax event="rowUnselectCheckbox" listener="#{servicioPendientePagoBean.deselecionarFila}" global="false"/>

donde:

El resto del trabajo lo realiza el Javascript inicial.

Código Java

El código Java tenemos

package es.um.atica.gepeto.backbeans;
 
...
 
@Name( ServicioPendientePagoBean.NAME )
@Scope( ScopeType.CONVERSATION )
public class ServicioPendientePagoBean extends FundeWebManagerBean {
 
    ...
 
    private List<ServicioPendientePago> listaServicioPendientePago = new ArrayList<ServicioPendientePago>();
 
    public List<ServicioPendientePago> getListaServicioPendientePago() {
        return listaServicioPendientePago;
    }
 
    public void setListaServicioPendientePago( List<ServicioPendientePago> listaServicioPendientePago ) {
        for (ServicioPendientePago servicioPendientePago : listaServicioPendientePago) {
            if (! this.listaServicioPendientePago.contains( servicioPendientePago )) {
                this.listaServicioPendientePago.add( servicioPendientePago );
            }
        }
    }
 
    public void deselecionarFila(UnselectEvent event) {
        this.listaServicioPendientePago.remove( event.getObject() );
    }
 
 
    public boolean activarCombo(ServicioPendientePago servicioPendientePago) {
         // Logica para determinar si la fila es seleccionable o no
         ...
    }
 
    ...
 
}

descripción de los métodos:

JUAN MIGUEL BERNAL GONZALEZ 2016/07/15 14:45