0

I came up with a very strange (for me) error today when it comes to html checkboxes. So, I have a table list with a checkbox in the end and a script to read the whole row for each selected checkbox. It is working fine, but I decided to add a "Select All" feature, and here is where things get weird. When I use the Select all, I receive an error and my object is empty.

Here is the code I am using for the select all:

c.transacoes = function() {


        $('input[type=checkbox]:checked').each(function() {

            var row = $(this).parent().parent();
            var rowcells = row.find('td');
            var chkdTransac = [];
            var obj = (g_form.getValue('u_transactions').length != 0) ? JSON.parse(g_form.getValue('u_transactions')) : [];;
            var i;
            for (i = 0; i < 5; i++) {
                chkdTransac[i] = rowcells[i].innerText;
            }
            
            obj.push({
                descricao_transacao: chkdTransac[1],
                valor_transacao: chkdTransac[2].replace(/-/g, ''),
                data: chkdTransac[3],
                ref_essence: chkdTransac[4],
                narrative: chkdTransac[5]
            });

            g_form.setValue('u_transactions', JSON.stringify(obj));
            c.modalInstance.close();

        });


    };

    toggle = function(source) {
        checkboxes = document.getElementsByName('cb1');
        for (var i = 0, n = checkboxes.length; i < n; i++) {
            checkboxes[i].checked = source.checked;
        }
    };
<div class="panel panel-default">
  <div class="panel-heading">
    <h4 class="panel-title">${Transactions}
     <button type="button" class="close" data-dismiss="modal" aria-label="Close" ng-click="c.closeModal()"> <span aria-hidden="true">&times;</span>
      </button></h4>
  </div>
 
  <div paging page="1" page-size="10" total="1000">
 
  <table id="table1" class="table table-bordered table-striped">
    <thead>
      <tr>
       <th>${Select}<input type="checkbox" onClick="toggle(this)" /></th>
       <th>${description}</th>
       <th>${Amount}</th>
       <th>${date}</th>
       <th>${reference}</th>
       <th>${Narrative}</th>
        <!--<th>${Select All}<input type="checkbox" onClick="toggle(this)" /></th> -->
        
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="transac in c.transactions">
        <td><input type="checkbox" name="cb1"></td>
        <td>{{transac.transaction.description}}</td>
        <td>{{transac.transaction.amount}}</td>
        <td>{{transac.transaction.date}}</td>
        <td>{{transac.transaction.reference}}</td>
        <td>{{transac.transaction.narrative}}</td>
      </tr>
    </tbody>
  </table>
     </div>

 <div class="panel-body">
    <div class="col-sm-4"></div>
    <div class="col-sm-4" style="align-items:center;">
      <div style="margin-bottom: 8px;">
      </div>
      <div>
        <button type="button" class="btn btn-primary btn-block" ng-click="c.transacoes()">${Use selected transactions}</button>
      </div>
    </div>
    <div class="col-sm-4"></div>
  </div>
</div>

The idea here is that a table with a list is generated dynamically with a checkbox that I later verify if it is checked and fill a multirow variable set (in ServiceNow) with the information. If I select manually the boxes, the code works perfectly, but if I use the select all, the following error message is trown:

"TypeError: Cannot read property 'innerText' of undefined"

You guys have any idea why this is happening and how to solve this?

Thanks in advance.

3
  • What is the specific error? What object are you referring to? Please provide a minimal reproducible example that demonstrates the issue Commented Jun 4, 2021 at 12:17
  • The example you gave is missing an element named 'cb1'. So checkboxes is empty Commented Jun 4, 2021 at 12:36
  • you have checkboxes without names, values and form parent ... Commented Jun 4, 2021 at 12:43

2 Answers 2

2

I assume you meant to create multiple checkboxes and add a feature that will select all the checkboxes at once. If my assumption is correct, you will need to create more checkboxes and modify your function as follows:

function toggle(source) {
  // store all the checkboxes that named 'cb1[]' in an array
  var checkboxes = document.getElementsByName('cb1[]');;
  for (var i = 0; i < checkboxes.length; i++) {
    if (checkboxes[i] != source)
      // set true to the checked property of the rest of the checkboxes 
      checkboxes[i].checked = source.checked;
  }
}
<input type="checkbox" on onclick="toggle(this);" />Select all!<br />
<input type="checkbox" name='cb1[]' />checkbox 1<br />
<input type="checkbox" name='cb1[]' />checkbox 2<br />
<input type="checkbox" name='cb1[]' />checkbox 3<br />
<input type="checkbox" name='cb1[]' />checkbox 4<br />

Remember to "attach square brackets to the end of the name in order for server-side code to treat checked checkboxes as an array. Otherwise only the last checked item in the group would be available upon submission" (source: dyn-web.com).

Original code is from the following response where querySelectorAll is used instead of getElementsByName: How to implement “select all” check box in HTML?

Sign up to request clarification or add additional context in comments.

2 Comments

in valid HTML, checkboxes can't have the same name...
Good point, @MisterJojo. Even though w3c states that "Several checkboxes in a form may share the same control name." You would need to "attach square brackets to the end of the name in order for server-side code to treat checked checkboxes as an array" (source: dyn-web.com).
0

Ok, so I figured out that where some "trash" before my rows when I used the "select all" checkbox, so I made a small change in the c.transacoes function to ignore those undefined and it is working.

Here is the final function:

c.transacoes = function() {

        $('input[type=checkbox]:checked').each(function() {

            var row = $(this).parent().parent();
            var rowcells = row.find('td');
            var chkdTransac = [];
            var obj = (g_form.getValue('u_transactions').length != 0) ? JSON.parse(g_form.getValue('u_transactions')) : [];;
            var i;
            for (i = 0; i < 6; i++) {

                if (rowcells[i] == undefined) {
                    return;
                } else {
                    chkdTransac[i] = rowcells[i].innerText;
                }

            }

            var date = chkdTransac[3].split("T");

            obj.push({
                descricao_transacao: chkdTransac[1],
                valor_transacao: chkdTransac[2].replace(/-/g, ''),
                data: date[0],
                ref_essence: chkdTransac[4],
                narrative: chkdTransac[5]
            });

            g_form.setValue('u_transactions', JSON.stringify(obj));
            c.modalInstance.close();

        });

    };

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.