Question

I know a lot of people have created topics for this point : "handling multiple forms on same page". Nevertheless, after having reading most of them, I didn't find a solution.

I have a page which lists some articles. The user is able to give a mark on each post thanks to a slider and then submit it. In order to submit the mark associated to the article, I use the function .each() but I don't have the expected result : it's the last form of my page which is submitted, whatever the form I submit.

HTML :

<form method="post" action="" class="vote-form">
    <input type="hidden" id="amount" name="amount" class="hidden" value="5" />
    <input type="hidden" id="post_id" name="post_id" value="<?php echo get_the_ID(); ?>" />
    <input type="submit" name="post_vote" value="VOTE">
</form>

JS :

$( ".vote-form" ).each(function() {

    $( this ).submit(function() {

        // get all the inputs into an array.
        var $inputs = $('.vote-form :input');

        // get an associative array of just the values.
        var values = {};
        $inputs.each(function() {
            values[this.name] = $(this).val();
            alert(values[this.name]);
        });

        // ************ Save vote in AJAX *************
        // ...

        return false;
    });
});

The alert displays each value of the hidden inputs when I submit one of the forms.

Was it helpful?

Solution

You need to grab the inputs for the determined element. You can use .find() for it.

$( ".vote-form" ).each(function() {
    var $this = $(this);
    $this.submit(function() {
        // get all the inputs into an array.
        var $inputs = $this.find(':input');
        ...

You were grabbing all the existent input elements and I suspect that because of this during the associative array creation the elements with same this.name were being overwritten as you were processing the list of matched elements.

By the way, you can drop the .each() since .submit() works over the set of matched elements.

Note: I cached $(this) here.

OTHER TIPS

Obviously it displays all the data, since you are using an each() loop on all elements with the class vote-form. If you only want the submitted form to show, just drop the each and use a single submit event trigger instead, like:

$('.vote-form').submit(function() {

    // get all the inputs into an array.
    var $inputs = $(this).find(':input'); // Get all input fields of "this" specific form

    // get an associative array of just the values.
    var values = {};
    $inputs.each(function() {
        values[this.name] = $(this).val();
        alert(values[this.name]);
    });

    // ************ Save vote in AJAX *************
    // ...

    return false;
});

Use find() from the main parent element, in your case the form, and you will isolate the search to the particular instance you are working with

 var $inputs = $(this).find(':input');

Your problem is the context. By selecting your inputs with

var $inputs = $('.vote-form :input');

you don't tell jQuery about the specific form so it selects all inputs that has class ".vote-form". I prefer to pass the context within the jQuery-Selector. So it should look like this:

var $inputs = $(':input', $(this));

By using this you can get the form object inside the submit method.

working js-fiddle: http://jsfiddle.net/xuAQv/282/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top