Select all items in Multiple SelectManyCheckBox with dynamic ids
Asked Answered
N

1

2

I want to select all check box in some groups of checkboxes using PrimeFaces component on top of JSF.

My code is like this:

<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
    <p:outputLabel value="Confere:" style="font-weight:bold!important" />
    <p:selectManyCheckbox
        value="#{funcionarioBean.funcionario.permissaoConfere.stringArray}">
        <f:selectItem itemLabel="Consulta" itemValue="C" />
        <f:selectItem itemLabel="Edição" itemValue="E" />
        <f:selectItem itemLabel="Deleção" itemValue="D" />
        <f:selectItem itemLabel="Inclusão" itemValue="I" />
        <f:selectItem itemLabel="Relatório" itemValue="R" />
        <f:selectItem itemLabel="Check All"/>
    </p:selectManyCheckbox>
</h:panelGrid>
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
    <p:outputLabel value="Visitante:" style="font-weight:bold!important" />
    <p:selectManyCheckbox
        value="#{funcionarioBean.funcionario.permissaoVisitante.stringArray}">
        <f:selectItem itemLabel="Consulta" itemValue="C" />
        <f:selectItem itemLabel="Edição" itemValue="E" />
        <f:selectItem itemLabel="Deleção" itemValue="D" />
        <f:selectItem itemLabel="Inclusão" itemValue="I" />
        <f:selectItem itemLabel="Relatório" itemValue="R" />
        <f:selectItem itemLabel="Check All"/>
    </p:selectManyCheckbox>
</h:panelGrid>
<h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
    <p:outputLabel value="Ocorrências:" style="font-weight:bold!important" />
    <p:selectManyCheckbox
        value="#{funcionarioBean.funcionario.permissaoOcorrencia.stringArray}">
        <f:selectItem itemLabel="Consulta" itemValue="C" />
        <f:selectItem itemLabel="Edição" itemValue="E" />
        <f:selectItem itemLabel="Deleção" itemValue="D" />
        <f:selectItem itemLabel="Inclusão" itemValue="I" />
        <f:selectItem itemLabel="Relatório" itemValue="R" />
        <f:selectItem itemLabel="Check All"/>
    </p:selectManyCheckbox>
</h:panelGrid>

I tried with the code posted here but it only works, if you have only one group of checkboxes on the page.

Nicolnicola answered 14/5, 2015 at 5:34 Comment(0)
W
6

Wrap it in a reusable composite component like below:

/resources/composites/selectManyCheckboxAll.xhtml

<ui:component
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:cc="http://xmlns.jcp.org/jsf/composite"
    xmlns:p="http://primefaces.org/ui"
>
    <cc:interface>
        <cc:attribute name="value" />
        <cc:editableValueHolder name="input" targets="checkboxes" />
    </cc:interface>
    <cc:implementation>
        <h:outputStylesheet library="composites" name="selectManyCheckboxAll.css" target="head" />
        <h:outputScript library="composites" name="selectManyCheckboxAll.js" target="head" />
        <div id="#{cc.clientId}" class="checkboxes-all" 
            data-widget-checkboxes="#{p:widgetVarFromContext('checkboxes', cc).split('\'')[1]}" 
            data-widget-all="#{p:widgetVarFromContext('all', cc).split('\'')[1]}">
            <p:selectManyCheckbox id="checkboxes" value="#{cc.attrs.value}">
                <cc:insertChildren />
            </p:selectManyCheckbox>
            <div class="all">
                <p:selectBooleanCheckbox id="all" />
                <p:outputLabel for="all" value="Check all" />
            </div>
        </div>
    </cc:implementation>          
</ui:component>

/resources/composites/selectManyCheckboxAll.css

.checkboxes-all {
    white-space:  nowrap;
}

.checkboxes-all .ui-selectmanycheckbox,
.checkboxes-all .all {
    display: inline-block;
    vertical-align: middle;
}

.checkboxes-all .all .ui-chkbox {
    margin: 1px 4px 0 0;
    vertical-align: top;
}

.checkboxes-all .all label {
    display: inline-block;
    margin-top: 4px;
}

/resources/composites/selectManyCheckboxAll.js

$(document).on("click", ".checkboxes-all .all .ui-chkbox-box, .checkboxes-all .all input", function() {
    var $composite = $(this).closest(".checkboxes-all");
    var widgetAll = PrimeFaces.widgets[$composite.data("widget-all")];
    var widgetCheckboxes = PrimeFaces.widgets[$composite.data("widget-checkboxes")];

    widgetCheckboxes.inputs.prop("checked", !widgetAll.isChecked()).click();
});

$(document).on("click", ".checkboxes-all .ui-selectmanycheckbox input", function() {
    var $composite = $(this).closest(".checkboxes-all");
    var widgetAll = PrimeFaces.widgets[$composite.data("widget-all")];

    if (!$(this).is(":checked") && widgetAll.isChecked()) {
        widgetAll.uncheck();
    }
});

Usage:

<html xmlns:my="http://xmlns.jcp.org/jsf/composite/composites">
...
<my:selectManyCheckboxAll value="#{bean.selectedItems}">
    <f:selectItem itemLabel="Consulta" itemValue="C" />
    <f:selectItem itemLabel="Edição" itemValue="E" />
    <f:selectItem itemLabel="Deleção" itemValue="D" />
    <f:selectItem itemLabel="Inclusão" itemValue="I" />
    <f:selectItem itemLabel="Relatório" itemValue="R" />
</my:selectManyCheckboxAll>
Wynd answered 16/5, 2015 at 10:0 Comment(5)
Any idea why this works locally (running Wildfly) but not on our DEV server running JBoss 7? I'm using other composite components successfully. Your implementation is pretty slick, btwMiseno
@jeff: Provided that PrimeFaces version is exactly the same, it's perhaps some bug in JSF implementation being used in server? WF uses 2.2.x and AS7 uses 2.1.x. Any clues/differences in JS console or HTTP traffic?Wynd
hmm, yeah, "dev-server.com/AppName/javax.faces.resource/theme.css.xhtml" HTTP 404 not found" locally I don't get this errorMiseno
if they all selected in value all button isnt selected so a solution for it is add this to js file -next comment-Bumbailiff
$(document).ready(function () {var $composite = $(".checkboxes-all > .ui-selectmanycheckbox").closest(".checkboxes-all"); var widgetAll = PrimeFaces.widgets[$composite.data("widget-all")]; var widgetCheckboxes =PrimeFaces.widgets[$composite.data("widget-checkboxes")]; let arr = widgetCheckboxes.inputs; for (var e in arr) { console.log(arr[e]); if (arr[e].tagName === "INPUT") { if (!arr[e].checked) {return; } }}widgetAll.check(); });Bumbailiff

© 2022 - 2024 — McMap. All rights reserved.