javascript – Select all checkbox by clicking on another PrimeFaces checkbox

Question:

I have a question, how to select all the checkbox that is inside a panelgrid? I saw that it is possible to do this via javaScript.

But I was in doubt about how to run the method because to select all. At first I wanted to see if it really caught on. Then I made the method to select from the panelgrid id.

But I don't know how to run the method in primefaces.

I'm using p:selectManyCheckbox component.

<p:panelGrid styleClass="panelGridCenter" style="width:70%">
    <p:row>
        <p:column >
            <p:panelGrid id="panelEstados" styleClass="panelGridCenter">
                <p:row>
                    <p:column styleClass="columnCenter">
                        <p:selectManyCheckbox value="#{lojaBean.pojo.ufsInss}" layout="grid" columns="4" >
                            <f:selectItems value="#{lojaBean.helper.estados}"/>
                            <f:selectItem id="checkBoxTodas" itemLabel="Todas" itemValue="false"/>
                        </p:selectManyCheckbox>
                    </p:column>
                </p:row>
            </p:panelGrid>
        </p:column>
    </p:row>
</p:panelGrid>

So how to accomplish such a feat?

Answer:

The big difficulty when customizing with Javascript in JSF pages is that we don't have control over the HTML generated for the browser. Both the structure and component IDs are not under our control, so it is difficult to reference them in a script.

What I usually do is look for some patterns in the generated HTML, and build the script based on those patterns. In this case I would make a solution like the following:

Get the elements whose ID contains "checkBoxTodas" . JSF generates its own IDs for them, but they all contain the ID you specified.
For each of these elements, add the following click procedure:
(1) Get the table cell where it is contained. That is, search on parent elements until you find a "td" that has class=columnCenter
(2) Get all checkboxes contained in this TD.
(3) Mark these checkboxes with the same value that is in the clicked checkbox (checkBoxTodas).

It sounds like a lot of work, but jQuery makes life a lot easier, it's actually quite simple. Here's an example simulating this case:

<html>
  <head>
    <!--
    Na página feita com PrimeFaces nao é preciso o trecho abaixo para 
    importar o JQuery, ele vem de brinde.
    -->
    <script language="javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

    <script language="javascript">

      /**
      * Funcao a ser disparada quando o checkbox checkBoxTodas for clicado.
      */
      function checkBoxTodas_onClick() {
        // Localiza a celula de class "columnCenter" que esta imediatamente superior
        var parentTd = $(this).parents(".columnCenter").first();

        // Pega referência a todos os filhos que são checkboxes
        var checkboxes = parentTd.find("input[type=checkbox]");

        // Estado do checkbox TODAS
        var check = $(this).is(":checked");

        // Atribui esse mesmo estado aos demais checkboxes
        checkboxes.prop("checked", check);
      }

      /**
      * Adiciona a funcao acima como event handler para todos os checkboxes cujo ID
      * contem "checkBoxTodas".
      * O JSF gerara ids diferentes para cada ocorrencia, mas todos contem a 
      * tal String.
      */
      $(document).ready(function(){
        $('input[id*="checkBoxTodas"]').click(checkBoxTodas_onClick);
      });
    </script>
  </head>

  <body>

    <!--
      O trecho abaixo simula aproximadamente o HTML gerado pelo codigo JSF.
      O checkbox com id="checkBoxTodas" acaba recebendo no HTML um ID bem mais complicado,
      que geralmente não está sob nosso controle.
    -->
    <table border="1">
      <tr>
        <td class="columnCenter">
          A <input type="checkbox" />
          B <input type="checkbox" />
          C <input type="checkbox" />
          D <input type="checkbox" />
          E <input type="checkbox" />
          <br />

          <input type="checkbox" id="form1:panelEstados:checkBoxTodas:blablabla"></input>
          <label for="form1:panelEstados:checkBoxTodas:blablabla">Todas</label>

        </td>
      </tr>
    </table>
  </body>
</html>
Scroll to Top