Assign value to inputs using .each ()

0

I have an error when I want to set the data to the IDs of the inputs, only set one and not the N that I get.

It should be noted that the input IDs are placed with PHP, that is, dynamically, as well as the amount of input's they will show.

This is my code that I am applying.

A quick example of my project:

In my view there is a form of attendance record, which a teacher does, the form is dynamic. That is to say, if the teacher has a classroom, one of them comes out, but if he has two, two fields appear where he fills the number of students.

What I want to do is that those fields are filled in with jquery and continue with the process that follows.

JQUERY:

$(".letras").each(function () {
    codigo_modular = this.id;
    var res = codigo_modular.substr(-7);
    $.ajax({
        url: baseurl + 'asistencia/traer_alumnos',
        type: 'POST',
        data: {res: res},
        dataType: 'JSON',
        success: function (data) {
            if (data != null) {
                $('#' + codigo_modular).val(data[0]['cant_estudiantes']);
            } else {
                $('#' + codigo_modular).prop('disabled', false);
            }
        }
    });
});

HMTL + PHP

<?php foreach ($niveles as $obj) { ?>
   td>
       <div class="form-group">
       <div class="col-md-12">
       <input class="form-control letras" type="text" id="3_<?php echo str_replace(' ', '_', $obj->nivel) . '_' . $obj->codigoModular; ?>"  name="3_<?php echo str_replace(' ', '_', $obj->nivel) . '_' . $obj->codigoModular; ?>">
       </div>
       </div>
       </td><?php } ?>

As you see in .each send a post, for example if there are shifts I send 2 times, I bring both but when I set it in my html with the val only set the last one as it is in the image.

    
asked by Ivan More Flores 08.05.2017 в 18:57
source

2 answers

0

Try this:

$(".letras").each(function () {
    codigo_modular = this.id;
    var res = codigo_modular.substr(-7);
    (function (codigo_modular) {
        $.ajax({
            url: baseurl + 'asistencia/traer_alumnos',
            type: 'POST',
            data: {res: res},
            dataType: 'JSON',
            async: false, 
            success: function (data) {
                if (data != null) {
                    $('#' + codigo_modular).val(data[0]['cant_estudiantes']);
                } else {
                    $('#' + codigo_modular).prop('disabled', false);
                }
            }
        });
    }(codigo_modular));
});

Understanding that the variables are overlapping, we will simply wait for the answer before continuing (Synchronous Process). What should stop the javascript until it ends, and therefore in the success now you can give the value to your first input .

I hope it helps you!

NOTE:

If you are in the same PHP, it is better that you do the query from there and draw the html with the information, avoiding that you have to make another request through jquery to the server.

Knowing how to use your resources is something that helps you to have a better user experience.

Answer based on the specific question, but as for your business logic, it is better that you bring this data from php.

    
answered by 08.05.2017 / 20:41
source
0

You are misusing a variable and its scope (global or local). Unfortunately you are changing the value of codigo_modular in a loop .each and, since javascript is not multithreaded, all iterations will be executed one after the other without processing the requests $.ajax , so when you return calls from each one, variable codigo_modular will contain the last assigned value.

In JavaScript, unlike other languages such as Java, C, Perl, PHP, etc., the scope of a variable is defined by its closure in a function ( closure ) .

If we use IIFE (Immediately Invoked Function Expressions) with a parameter, the execution will be done with the parameter codigo_modular local, with a different scope, for each execution, so it will not be affected by the consequent changes of the local value of the parent function.

Try this way of doing it:

/* Podría tener ámbito global */
var codigo_modular;
$(".letras").each(function () {
    /* O local */
    var codigo_modular;
    codigo_modular = this.id;
    var res = codigo_modular.substr(-7);
    (function (codigo_modular) {
        /* Pero al llegar aquí codigo_modular ya no es el mismo que ninguno de los anteriores */
        $.ajax({
            url: baseurl + 'asistencia/traer_alumnos',
            type: 'POST',
            data: {res: res},
            dataType: 'JSON',
            success: function (data) {
                if (data != null) {
                    $('#' + codigo_modular).val(data[0]['cant_estudiantes']);
                } else {
                    $('#' + codigo_modular).prop('disabled', false);
                }
            }
        });
    }(codigo_modular));
});

A cleaner way could be:

$(".letras").each(function () {
    (function (elemento) {
        $.ajax({
            url: baseurl + 'asistencia/traer_alumnos',
            type: 'POST',
            data: {
                res: elemento.id.substr(-7)
            },
            dataType: 'JSON',
            success: function (data) {
                if (data != null) {
                    elemento.val(data[0]['cant_estudiantes']);
                } else {
                    elemento.prop('disabled', false);
                }
            }
        });
    }(this));
});

We take advantage that in each iteration of each() the variable this points to the class jQuery that is being analyzed, so if we pass it as parameter elemento the IIFE we can use it directly without needing to re-enter to her by $('#' + ...) .

Avoiding the (over) load of requests

If the variable $niveles contains the information necessary to fill in the information of the form, or can be obtained by improving the SQL query, the HTML document could be generated from PHP with the filled data, without having to request them using XHR , reducing the latency in the generation of the page and improving the user experience:

<?php
foreach ($niveles as $obj) {
  $id = htmlspecialchars(
    '3_' .
    str_replace(' ', '_', $obj->nivel) .
    '_' .
    $obj->codigoModular
  );
?>
  <td>
    <div class="form-group">
      <div class="col-md-12">
        <input class="form-control letras"
          type="text" id="<?= $id ?>" name="<?= $id ?>"
          value="<?= htmlspecialchars($obj->valor) ?>"
        />
      </div>
    </div>
  </td>
<?php
}
?>

Assuming that $obj->valor contains that value.

    
answered by 08.05.2017 в 20:37