skip to Main Content

I have a wishlist page which contains items each having a remove button which is created in a loop using form and each button has item id as value. I want to make a post request whenever a remove button is clicked in order to remove that item from the database.

But the problem is that there are many buttons created in the loop with the same id, so how do I access them individually?

<!DOCTYPE html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
    <h1>::WISHLIST::</h1>

    {% for wish in wishes %}
        <img src={{wish.image_path}} width="150" height="200">
        </br>
        {{wish.material}}
        {{wish.productType}}
        </br>
        {{wish.price}}
        </br>
        <form method="POST" target="_self">
            <button id="remove_wish" name="remove_wish" type="submit" value={{wish.id}}>Remove</button>
        </form>
        </br>
    {% endfor %}

    <script>
        $(document).ready(function() {
            $('#remove_wish').click(function (event) {
                event.preventDefault();
                alert($('#remove_wish').val())
           $.ajax({
            data : {
                    delete_wish : $('#remove_wish').val()
                    },
                type : 'POST',
                url : '/wishlist/',
                success: function (data) {
                    location.reload();
                },
                error: function (e) {
                    alert('something went wrong')
                }
            });
        });
        })
    </script>


</body>
</html>

Here I tried using the same id, but this only works for the top most item on the wishlist and for others it gives the error: NoResultFound: No row was found for one()

2

Answers


  1. You shouldn’t have more than one element in the DOM with the same id.

    Change in your button the next things:

    • Add a class to the buttons. Let’s say remove_wish.
    • Change the id value of the buttons to wish-{{wish.id}} (for example).

    <button class="remove_wish" id="wish-{{wish.id}}" name="remove_wish" type="submit" value={{wish.id}}>Remove</button>

    In your AJAX call, change the selector of the event for listening to the class selector instead of the id selector:

    $('.remove_wish')
    

    Get the id of your element using the substring function:

    var id = $(this).attr('id');
    var id_value = id.substring(5); //five because "wish-" has five characters.
    

    I think this should do the work.

    Login or Signup to reply.
  2. I have a couple of alternatives of how could you solve your issue and a tip.

    TIP:
    Remove the <form> tag from your foreach, otherwise you’ll be creating one form per button. The ideal scenario would be having only one form and several buttons. Like this:

    <form method="POST" target="_self">
        {% for wish in wishes %}
            <img src={{wish.image_path}} width="150" height="200">
            </br>
            {{wish.material}}
            {{wish.productType}}
            </br>
            {{wish.price}}
            </br>
            <button id="remove_wish" name="remove_wish" type="submit" value={{wish.id}}>Remove</button>
            </br>
        {% endfor %}
    </form>
    

    ALTERNARTIVE #1 :
    As @cooper and @Shree already told you, you should get rid of the id and use a class instead. Now, wrap your button inside a container, a div (it could be with an id or with a class) for example (please notice that this container must be outside of your foreach as well). And change the type of your button from submit to button. Like this:

    <form method="POST" target="_self">
        <div id="divContainer">
            {% for wish in wishes %}
                <img src={{wish.image_path}} width="150" height="200">
                </br>
                {{wish.material}}
                {{wish.productType}}
                </br>
                {{wish.price}}
                </br>
                <button class="remove_wish" type="button" data-wishid={{wish.id}} >Remove</button>
                </br>
            {% endfor %}
        </div>
    </form>
    
    //and then you can manage all your buttons click events like this
    $("#divContainer").on("click", "remove_wish", function() {
        var id = $(this).data('wishid');
        //the rest of your code
    });
    

    ALTERNARTIVE #2 :
    Or even easier, you can use the onclick event and pass your id to a function. Like this:

    <form method="POST" target="_self">
        {% for wish in wishes %}
            <img src={{wish.image_path}} width="150" height="200">
            </br>
            {{wish.material}}
            {{wish.productType}}
            </br>
            {{wish.price}}
            </br>
            <button type="button" onclick="removeWish(" + {{wish.id}} +")" >Remove</button>
            </br>
        {% endfor %}
    </form>
    
    //and outside your $(document).ready(function()
    function removeWish(id) {
        //the rest of your code
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search