Home > Software engineering >  applying jquery code inside a foreachloop
applying jquery code inside a foreachloop

Time:06-22

@foreach($fiche as $f)
<tr id="trTab">
    <td>{{ $f->Date }}</td>
    <td>{{ $f->activite1 }}</td>
    <td>{{ $f->heuresEffectu }}</td>
    <td>{{ $f->Poids }}</td>
    <td>{{ $f->ecart }}</td>

    <form method="post" action="" id="form1">
        <td>
            {{ csrf_field() }}
            <input type="hidden" name="id" value="{{$f->id}}">
            <button type="submit"  id="valider" onclick="">V</button>
        </td>
    </form>
    <form method="post" action="">
        <td>
            <button type="submit"  id="refuser">R</button>
        </td>
    </form>
</tr>
@endforeach

and i have this jquery code which disables a button when i click on it :

<script>
    $("#valider").click(function() {
        if ($('#refuser').prop("disabled")) {
            $('#refuser').attr("disabled", false);
        } else {
            $('#refuser').attr("disabled", true);
        }
        $("#form1").toggle();
    });
</script>

the jquery code is working fine but the problem is whenever i click on one of the buttons it only works for the first row , how do i fix this ?

CodePudding user response:

You're re-using the same id value multiple times on the page. So when you query the DOM for an element by id:

$("#valider")

Which one is it going to refer to? I suspect the behavior is undefined because the markup is invalid, but generally browsers will find the first element with that id and then simply stop looking because there shouldn't be more elements with the same id.

First, move all of your id values within that loop into class values. These can be re-used and applied to multiple elements on the page. For example, this:

<tr id="trTab">

Becomes this:

<tr >

Be sure to do this with all of the id values within that loop.

Second, update your click handler to select by class instead of id. So this:

$("#valider").click(function() {
  //...
});

Becomes this:

$(".valider").click(function() {
  //...
});

Note that this will attach a separate click handler to every matched ".valider" element. If there are potentially many of them, you can improve performance by using a single click handler at a higher level, taking advantage of event propagation. In that case you'd use this:

$(document).on("click", ".valider", function() {
  //...
});

This would instead place one click handler at the document level, catching every click anywhere in the document, but only invoke the handler function if the originating element matches the ".valider" selector.

Third, within your click handler you need to determine which elements you want to reference. For example, you can't just do this:

$(".form1").toggle();

Because it will target every matching ".form1" element. You can use DOM traversal in jQuery to navigate to the target elements. Starting from this (which is the element that was clicked) you can traverse up to a common parent element with .closest() and then traverse down to your target element(s) with .find(). So this:

$(".form1").toggle();

Becomes this:

$(this).closest(".trTab").find(".form1").toggle();

Do this for each of your jQuery selectors which formerly relied on id values.

Overall, the goal here is to not always rely on id values for selecting elements. You can select an element in a variety of ways, and from within the event handler you can select or find your other relevant elements in a variety of ways.

CodePudding user response:

PHP CODE:

@foreach($fiche as $f)
<tr id="trTab">        
            <td>{{ $f->Date }}</td>
            <td>{{ $f->activite1 }}</td>
            <td>{{ $f->heuresEffectu }}</td>
            <td>{{ $f->Poids }}</td>
            <td>{{ $f->ecart }}</td>
           
            <form method="post" action="" id="form1">
            <td>
            {{ csrf_field() }}
            <input type="hidden" name="id" value="{{$f->id}}">
            <button type="submit"   data-id="{{$f->id}}" onclick="">V</button>
            </td></form>
            <form method="post" action="">
            <td>
            <button type="submit"   id="refuser_{{$f->id}}" data-id="{{$f->id}}">R</button>
            </td>
            </form>
</tr>
@endforeach
  1. Your code won't work as multiple Same IDs are there and that is the first thumbrule.
  2. If you have multiple elements than try to use class instead of id. I have added instead of id.
  3. To differenciate which class is clicked you can see I have added data attribute data-id="" will give extra attribute which can help you to retrieve which class id clicked.

Your final jquery code can be like this:

<script>
    $(".valider").click(function() {
        //get current id which was clicked
        var current_id = $(this).data("id");
        if ($('#refuser_' current_id).prop("disabled")) {
            $('#refuser_' current_id).attr("disabled", false);
        } else {
            $('#refuser_' current_id).attr("disabled", true);
        }
        $("#form1").toggle();
    });
</script>

CodePudding user response:

Use class attributes instead of id's.

Class attributes can be referenced into multiple elements and you can use the $(this) to make sure you get the exact clicked attribute.

<script>
 $(".valider").click(function () {}
</script>
  • Related