0

I'm using HTML, JavaScript, Ajax and PHP in this project. I have a form and an onclick event to get the values of the form. The form is being printed out with Ajax and PHP, since it creates the input fields from values stored in a database. I'm trying to get the value from an input field, but it returns empty. If I manually insert the id, the value returns what I want, but now with a variable. I've done this plenty of times but never had this happen, so I'm a bit lost as of the cause of this. Here we have the form:

<p id="arranjos" style="text-align: center;"></p>
<p id="arranjosIDs" value="0" hidden></p>
<button class="btn btn-outline-primary float-right" onclick="save();" style="font-size: 18px; border-radius: 5px;">Save</button>

And here we have the PHP function that creates the form:

function getArranjos($checkedIDs){

    global $conn;

    $res = "";
    $ids = [];

    for($i = 0; $i < count($checkedIDs); $i+=2){

      $sql = "SELECT * FROM arranjos WHERE idprod = '".$checkedIDs[$i]."' AND estadoArranjo = 'ativo';";
    
      $result = $conn->query($sql);
  
      $res .= "<h2 style='background-color: #007bff; padding: 5px; color: white; border-radius: 5px; margin: 0% 10% 0% 10%;'>".$checkedIDs[$i+1]."</h2><br>";
      $res .= "<table style='margin-left: auto; margin-right: auto;'>
                  <tr>
                  <th></th>
                  <th></th>";
  
      if($result->num_rows > 0){
  
        while($row = $result->fetch_assoc()){

          array_push($ids, $row['idArranjo']);
  
          $res .= "
          <tr>
            <td style='text-align: right;'>
              <label style='font-size: 18px;' for=".$row['idArranjo'].">".$row['descricaoArranjo']."&nbsp;&nbsp;</label>
            </td>
            <td style='text-align: left;'>
              <input style='height: 18;' type='number' value='0' placeholder='0' maxlength='2' size='2' id='".$row['idArranjo']."'>
            </td>
          </tr>
          ";
  
        }

        $res .= "</table><br><br>";
  
      } else {
  
        $res .= "Não existem arranjos registados para esta peça";
        $res .= "</table><br>";
  
      }

    }

    $resposta = array("res" => $res, "ids" => json_encode($ids));
    $resposta = json_encode($resposta);

    return($resposta);

  }

This prints out OK, I have no problem with it. I have tried changing id='".$row['idArranjo']."' to id=".$row['idArranjo']." since I saw someone with that problem, but it didn't solve it. Here we have the function where it all goes wrong.

console.log(resposta); // [6, 14]
var arranjos = JSON.parse(resposta);
for(y = 0; y < arranjos.length; y++){
  
  console.log(arranjos[y]);
  if(arranjos[y] == "none"){

    $.ajax({

      type: 'POST',
      data: {

        peça: peçasi,
        arranjo: arranjos[y],
        op: 10

      },
      async: false,
      url: "paginas/dashboard/model/modelDashboardEntrada.php",
      success: function(resposta){

        console.log(resposta);
        obJSON = JSON.parse(resposta);
        $.ajax({

          type: 'POST',
          data: {
    
            idVenda: obJSON.idVenda,
            op: 12
    
          },
          async: false,
          url: "paginas/dashboard/model/modelDashboardEntrada.php",
          success: function(resposta){
    
            console.log(resposta);
    
          }
        })

      }
    })

  } else {
    var index = String(arranjos[y]); // I have tried this with and without String(), none works
    var input0 = document.getElementById(index).value; // If I write "6", it comes out correct, but as it is, just comes out empty. I printed out typeof() and it comes as string
    console.log(input0);

  }
}
patsilva
  • 3
  • 2
  • 1
    Why are you calling json_encode twice here? `$resposta = array("res" => $res, "ids" => json_encode($ids)); $resposta = json_encode($resposta);return($resposta);` that would just doubly escape the ids so it would contain a string like `"[6, 14]"` instead of an array like `[6, 14]`. What happens if you remove the json_encode on the ids? `$resposta = array("res" => $res, "ids" => $ids); $resposta = json_encode($resposta);return($resposta);` – Kevin Y Jun 20 '22 at 22:24
  • $ids is an array, so it has to be encoded, and then $resposta is another array, so it has to be encoded. It throws an error if I don't encode the arrays inside the arrays – patsilva Jun 21 '22 at 21:33
  • In your 3rd block, the else, what happens if you replace the 3 lines you're showing with: `console.log(['else called', arranjos[y], document.getElementById(arranjos[y])]);` let me know what it shows in the console for each instance (it should be easy to locate in the console from the "else called"), It might show something like `['else called', 6, null]` then `['else called', 14, null]` or it might show the entire html element. Whichever the case, please show the output here. – Kevin Y Jun 21 '22 at 22:05
  • it prints out "['else called', '6', input#6]" – patsilva Jun 21 '22 at 22:23
  • What about `console.log(['else called 2', arranjos[y], document.getElementById(arranjos[y]), document.getElementById(arranjos[y]).outerHTML, document.getElementById(arranjos[y]).value]);` – Kevin Y Jun 21 '22 at 22:41
  • it prints out "['else called 2', '6', input#6, '', '1']" – patsilva Jun 21 '22 at 23:06
  • That looks like the right output to me. Any more issues? – Kevin Y Jun 21 '22 at 23:07
  • How can I store the value in a variable? It wasn't working before, the variable itself will print out empty, although like this or just like document.getElementById("6").value comes out right, but I need it to be document.getElementById(arranjos[y]).value – patsilva Jun 21 '22 at 23:24
  • I don't quite understand the issue. When you say empty, do you mean `null`, `undefined`, the empty string `""`, the integer `0`, or the string containing a zero `"0"`? `document.getElementById(arranjos[y])` should return null if the element is not found. Since you're tossing a `.value` on it and not getting an error, that would mean the element is found. The element has an initial value of "0" that is a string containing the number 0. Thus depending on when the code runs, you're expected to get a string value like `"0"` or whatever you enter into the input such as `"1"`. – Kevin Y Jun 21 '22 at 23:42
  • My input is 1, but when I console.log(document.getElementById(String(arranjos[y])).value), it prints out an empty line on the console – patsilva Jun 22 '22 at 00:03
  • An empty line shouldn't be possible unless it's selecting the wrong element such as your empty element. Change your `.value` to a `.id` just to verify it is selecting the right element. You might also try changing your `for(y = 0; y < arranjos.length; y++){` to `for(let y = 0; y < arranjos.length; y++){` so the variable y isn't over-scoped by adding a `let`. You might also try replacing some of the console.logs with an alert to verify the console.log isn't changing the output after it's already outputted. You might try `alert(arranjos[y])` inside the else to verify it's what you expect. – Kevin Y Jun 22 '22 at 00:14
  • Side note: `async: false,` on the main thread is very bad and will have a negative effect on the user's experience. It will block the user's interaction with the page and make JavaScript hold its breath while it waits on the request so no events can fire nor lines afterwards until the request processes. Please try to avoid Synchronous requests ("sjax") in favor of Asynchronous (ajax). Learning how to chain callbacks such as through promises should help avoid unnecessary nesting. https://stackoverflow.com/questions/16026942/how-do-i-chain-three-asynchronous-calls-using-jquery-promises – Kevin Y Jun 22 '22 at 00:34
  • Oh my God! Thank you! Changing the loop worked!!!!! – patsilva Jun 22 '22 at 10:44
  • I read that async: false is not a good practice, but ajax doesn't let me store the values in global variables unless I do it like this. This code will be for a user only, so it shouldn't be too bad of an user experience, since it won't be overloaded – patsilva Jun 22 '22 at 10:45

0 Answers0