-1

I have a JavaScript function, that uses the id on 3 textboxes to get their numerical values, add all of them together and give me the result on the last textbox. I am also getting a list of people on my DB and I am using Foreach row to get all names and then create the 4 textboxes that the user can input the values and get the result. The problem is that I can only get the first row to show the result, the rest doesn't show.

<tbody>
  <?php
  if ($accao_formandos->num_rows()>0){
    foreach ($accao_formandos->result() as $row){
    ?>
    <tr>
      <td>
        <input type="text" class="form-control" name="formandos" id="formandos" onkeyup="sum();" data-fieldgroup="fg-formandos" data-error-msg="" value="<?php echo $row->nome; ?>" readonly>
      </td>
      <td>
        <input type="text" class="form-control" name="n_faltas" id="n_faltas" onkeyup="sum();" data-fieldgroup="fg-n_faltas" data-error-msg="" value="<?php //echo $n_faltas; ?>">
      </td>
      <td>
        <input type="text" class="form-control" name="assiduidade" id="assiduidade" onkeyup="sum();" data-fieldgroup="fg-assiduidade" data-error-msg="" value="<?php //echo $pauta_assiduidade; ?>">
      </td>
      <td>
        <input type="text" class="form-control" name="participacao_tarefas" id="participacao_tarefas" onkeyup="sum();" data-fieldgroup="fg-participacao_tarefas" data-error-msg="" value="<?php //echo $pauta_participacao_tarefas; ?>">
      </td>
      <td>
        <input type="text" class="form-control" name="elaboracao_trabalho" id="elaboracao_trabalho" onkeyup="sum();" data-fieldgroup="fg-elaboracao_trabalho" data-error-msg="" value="<?php //echo $pauta_elaboracao_trabalho; ?>">
      </td>
      <td>
        <input type="text" class="form-control" name="classificacao_quant" id="classificacao_quant" data-fieldgroup="fg-classificacao_quant" data-error-msg="" value="" readonly>
      </td>

    </tr>
  <?php
      }
    }
  ?>
</tbody>



function sum(result) {
            var assiduidade = document.getElementById('assiduidade').value;
            var participacao_tarefas = document.getElementById('participacao_tarefas').value;
            var elaboracao_trabalho = document.getElementById('elaboracao_trabalho').value;

            var result = (parseInt(assiduidade)*10 + parseInt(participacao_tarefas)*30 + parseInt(elaboracao_trabalho)*60) / 100;

            if (!isNaN(result)) {
                document.getElementById('classificacao_quant').value = result;
            }
        }

JavaScript function is getting called at the end of body maybe that helps.

I read here on another post, that document.querySelector doesn't work because it gets the first element, but I am using getElementByid but its probably that. If someone can help out, I would appreciate it

Thanks for all the help in advance.

  • The JavaScript isn’t in a script element? Is that related to your issue? – evolutionxbox Dec 28 '21 at 04:01
  • IDs must be unique. Please read the [documentation](//developer.mozilla.org/docs/Web/API/Document/getElementById). – Sebastian Simon Dec 28 '21 at 04:02
  • Covered by "[JavaScript and getElementById for multiple elements with the same ID](https://stackoverflow.com/q/3607291/90527)", "[getElementById returns null?](https://stackoverflow.com/a/14950153/90527)", "[Javascript does not recognize HTML arrays](https://stackoverflow.com/q/24230931/90527)" and others. – outis Dec 28 '21 at 11:04

2 Answers2

1

You can almost always dispense with ID attributes, especially when you involve loops and generating content. querySelector and querySelectorAll when used in conjunction with other selector functions (parentNode,nextSibling etc) allow for easy identification of elements so you can also dispense with the old fashioned inline event handlers and assign an external event listener to all elements as per the below code snippet.

The snippet uses dummy data for the name and various fields believed to be numeric in nature

document.querySelectorAll('tr input:not([data-result])').forEach(input => {
  input.addEventListener('keyup', function(e) {
    let tr = this.parentNode.parentNode;
    
    let ass = tr.querySelector('input[name="assiduidade"]');
    let par = tr.querySelector('input[name="participacao_tarefas"]');
    let ela = tr.querySelector('input[name="elaboracao_trabalho"]');
    let res = tr.querySelector('input[data-result]');

    let result = ( (Number(ass.value) * 10) + (Number(par.value) * 30) + (ela.value * 60) ) / 100;
    if (!isNaN(result) ) res.value = result;
  })
})
[type='text']{width:80px;}
<table>
  <tr>
    <td>
      <input type="text" class="form-control" name="formandos" data-fieldgroup="fg-formandos" data-error-msg="" value="Fred" readonly />
    </td>
    <td>
      <input type="text" class="form-control" name="n_faltas" data-fieldgroup="fg-n_faltas" data-error-msg="" value="" />
    </td>
    <td>
      <input type="text" class="form-control" name="assiduidade" data-fieldgroup="fg-assiduidade" data-error-msg="" value="23" />
    </td>
    <td>
      <input type="text" class="form-control" name="participacao_tarefas" data-fieldgroup="fg-participacao_tarefas" data-error-msg="" value="64" />
    </td>
    <td>
      <input type="text" class="form-control" name="elaboracao_trabalho" data-fieldgroup="fg-elaboracao_trabalho" data-error-msg="" value="41" />
    </td>
    <td>
      <input type="text" class="form-control" name="classificacao_quant" data-result=true data-fieldgroup="fg-classificacao_quant" data-error-msg="" value="" readonly />
    </td>
  </tr>
  <tr>
    <td>
      <input type="text" class="form-control" name="formandos" data-fieldgroup="fg-formandos" data-error-msg="" value="Barny" readonly />
    </td>
    <td>
      <input type="text" class="form-control" name="n_faltas" data-fieldgroup="fg-n_faltas" data-error-msg="" value="" />
    </td>
    <td>
      <input type="text" class="form-control" name="assiduidade" data-fieldgroup="fg-assiduidade" data-error-msg="" value="68" />
    </td>
    <td>
      <input type="text" class="form-control" name="participacao_tarefas" data-fieldgroup="fg-participacao_tarefas" data-error-msg="" value="21" />
    </td>
    <td>
      <input type="text" class="form-control" name="elaboracao_trabalho" data-fieldgroup="fg-elaboracao_trabalho" data-error-msg="" value="88" />
    </td>
    <td>
      <input type="text" class="form-control" name="classificacao_quant" data-result=true data-fieldgroup="fg-classificacao_quant" data-error-msg="" value="" readonly />
    </td>
  </tr>
  <tr>
    <td>
      <input type="text" class="form-control" name="formandos" data-fieldgroup="fg-formandos" data-error-msg="" value="Betty" readonly />
    </td>
    <td>
      <input type="text" class="form-control" name="n_faltas" data-fieldgroup="fg-n_faltas" data-error-msg="" value="" />
    </td>
    <td>
      <input type="text" class="form-control" name="assiduidade" data-fieldgroup="fg-assiduidade" data-error-msg="" value="88" />
    </td>
    <td>
      <input type="text" class="form-control" name="participacao_tarefas" data-fieldgroup="fg-participacao_tarefas" data-error-msg="" value="14" />
    </td>
    <td>
      <input type="text" class="form-control" name="elaboracao_trabalho" data-fieldgroup="fg-elaboracao_trabalho" data-error-msg="" value="57" />
    </td>
    <td>
      <input type="text" class="form-control" name="classificacao_quant" data-result=true data-fieldgroup="fg-classificacao_quant" data-error-msg="" value="" readonly />
    </td>
  </tr>
  <tr>
    <td>
      <input type="text" class="form-control" name="formandos" data-fieldgroup="fg-formandos" data-error-msg="" value="Wilma" readonly />
    </td>
    <td>
      <input type="text" class="form-control" name="n_faltas" data-fieldgroup="fg-n_faltas" data-error-msg="" value="" />
    </td>
    <td>
      <input type="text" class="form-control" name="assiduidade" data-fieldgroup="fg-assiduidade" data-error-msg="" value="8" />
    </td>
    <td>
      <input type="text" class="form-control" name="participacao_tarefas" data-fieldgroup="fg-participacao_tarefas" data-error-msg="" value="12" />
    </td>
    <td>
      <input type="text" class="form-control" name="elaboracao_trabalho" data-fieldgroup="fg-elaboracao_trabalho" data-error-msg="" value="88" />
    </td>
    <td>
      <input type="text" class="form-control" name="classificacao_quant" data-result=true data-fieldgroup="fg-classificacao_quant" data-error-msg="" value="" readonly />
    </td>
  </tr>
</table>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
0

Your HTML is technically invalid. An ID is only allowed to be used once. Try something like this:

Change your loop to foreach ($accao_formandos->result() as $key => $row) to get a unique key for each row.

Change your inputs to look like id="assiduidade<?= $key ?>" onkeyup="sum(<?= $key ?>);" so that they all have a unique ID, and pass the key to your function.

Prototype for your function should become function sum(key) (you never previously passed in a parameter to it, so the "result" in there isn't doing anything).

And finally change every element reference to include the key, like getElementById('assiduidade' + key).

Greg Schmidt
  • 5,010
  • 2
  • 14
  • 35
  • Works perfectly, I know that an ID is unique, but I tried with some other stuff and it didn't work aswell, but I loved your simple way of fixing it, thanks a ton – Daniel Santos Dec 28 '21 at 22:05