2009-09-01 8 views
21

J'ai une forme qui ressemble à ceci:Envoi d'un formulaire ajax jQuery avec deux boutons de soumission

<form action="/vote/" method="post" class="vote_form"> 
    <input type="hidden" name="question_id" value="10" /> 
    <input type="image" src="vote_down.png" class="vote_down" name="submit" value="down" /> 
    <input type="image" src="vote_up.png" class="vote_up" name="submit" value="up" /> 
</form> 

Quand je lie à présenter de la forme ($("vote_form").submit()), je ne semble pas avoir accès à quelle image l'utilisateur a cliqué sur. Donc, je suis en train de se lier à cliquer sur l'image elle-même ($(".vote_down, .vote_up").click()), qui soumet toujours la forme, que j'essaie

  • return false;
  • event.stopPropogation(); ou
  • événement.preventDefault();

car tous sont des événements de formulaire.

  1. Dois-je joindre mon .post de $() à l'événement form.submit(), et si oui, comment puis-je dire à quelle entrée l'utilisateur a cliqué sur, ou

  2. Dois-je joindre mon $ .post() au clic sur l'image, et si oui, comment puis-je empêcher le formulaire de soumettre aussi.

Voici ce que mon code jQuery ressemble maintenant:

$(".vote_up, .vote_down").click(function (event) { 
    $form = $(this).parent("form"); 
    $.post($form.attr("action"), $form.find("input").serialize() + { 
     'submit': $(this).attr("value") 
    }, function (data) { 
     // do something with data 
    }); 
    return false; // <--- This doesn't prevent form from submitting; what does!? 
}); 

Répondre

28

Sur la base de la réponse d'Emmett, mon solution idéale pour c'était juste de tuer soumettre de la forme avec Javascript lui-même, comme ceci:

$(".vote_form").submit(function() { return false; }); 

Et totalement travaillé.

Pour être complet, certains de mes codes JS dans le message original ont besoin d'un peu d'amour. Par exemple, la façon dont j'ajoutais à la fonction sérialiser ne semblait pas fonctionner.Cela a fait:

$form.serialize() + "&submit="+ $(this).attr("value") 

Voici mon intégralité du code jQuery:

$(".vote_form").submit(function() { return false; }); 
$(".vote_up, .vote_down").click(function(event) { 
    $form = $(this).parent("form"); 
    $.post($form.attr("action"), $form.serialize() + "&submit="+ $(this).attr("value"), function(data) { 
     // do something with response (data) 
    }); 
}); 
+0

Merci beaucoup pour cela. Réduit ma tentative existante un peu! – mhenrixon

+1

Pourquoi ne pas éviter le codage en dur '" & submit = "' en utilisant '$ this.attr (" name ")'? – Bengt

+0

@bngtlrs Je suppose que c'est une surcharge d'appel de fonction qui est simplement inutile. – PaulSkinner

1

Je ne comprends pas comment return false et preventDefault n'a pas réussi à faire leur travail. Peut-être essayer de remplacer les boutons d'image avec des images liées:

<a href="#" class="vote_down"><img src="vote_down.png"/></a> 

$('#vote_form > a').click(function(e) { 
    e.preventDefault(); 

    //one way to know which image was clicked 
    alert($(this).attr('class')); 

    $.post(... 
}); 

Vous pouvez toujours veiller à ce qu'une forme ne présente pas en se liant à l'événement présenter, par exemple:

$('#vote_form').submit(function() { 
    return false; 
}); 
+0

Comme je l'ai dit dans la question, je l'ai fait ce que vous avez dit dans la deuxième partie, mais je ne veux pas avoir accès à l'entrée qui utilisateur a cliqué sur. En outre, je ne veux pas passer aux images liées - bien que cela puisse fonctionner avec Ajax, je veux toujours que mon formulaire fonctionne pour les utilisateurs sans Javascript, comme c'est le cas actuellement (et pas avec des images simples). – worksology

0

Essayez d'ajouter onsubmit = "return false " à votre formulaire, puis de soumettre votre formulaire javascript:

<form action="/vote/" method="post" name="vote_form" class="vote_form" onsubmit="return false;"> 
    <input type="hidden" name="question_id" value="10" /> 
    <input type="image" src="vote_down.png" class="vote_down" name="submit" value="down" onclick="imageClicked(this)"/> 
    <input type="image" src="vote_up.png" class="vote_up" name="submit" value="up" onclick="imageClicked(this)"/> 
</form> 

<script> 
function imageClicked(img) { 
    alert(img.className); 
    document.forms["vote_form"].submit(); 
} 
</script> 
+0

Bien que je ne sois pas convaincu que c'est une solution élégante, cela m'a vraiment conduit à un correctif réalisable, qui consiste à ajouter: $ (". Vote_form"). Submit (function() {return false;}); (Je ne veux certainement pas ajouter "onsubmit = 'return false;'" à la forme puisque je veux que le formulaire fonctionne sans Ajax.) – worksology

0

Sans avoir recours au plugin formulaire (que vous devez utiliser), vous devriez manutentionneront le soumettre à la place événement. Le code resterait assez proche de l'original:

$("form").submit(function()) { 
    $.post($(this).attr("action"), $(this).serialize(), function(data) { 
    // work with the response 
    }); 
    return false; 
}); 
+0

Comme je l'ai dit dans la question initiale, je peux le faire, mais j'ai encore besoin de savoir quelle image-entrée l'utilisateur a cliqué sur cette fonction. event.target == le formulaire, malheureusement. – worksology

4

Une autre solution consiste à utiliser un champ caché, et que l'événement onclick mettre à jour sa valeur. Cela vous donne accès à partir de javascript, ainsi que sur le serveur où le champ caché sera affiché.

2

Vous pouvez déclencher l'envoi du formulaire en cliquant sur les images. Cela fonctionnera avec preventDefault().

var vote; 
$(".vote_up, .vote_down").click(function(event) { 
    vote = $(this).attr("class"); 
    $(".vote_form").trigger("submit"); 
}); 

$(".vote_form").submit(function(event) { 
    $form = $(this); 
    $.post($form.attr("action"), $form.serialize() + "&submit="+ vote, function(data) { 
     // do something with response (data) 
    });  
    event.preventDefault(); 
}); 
0
var form = jQuery('#myform'); 

var data = form.serialize(); 

// add the button to the form data 
var btn = jQuery('button[name=mybuttonname]').attr('value'); 
data += '&yourpostname=' + btn; 

var ajax = jQuery.ajax({ 
    url: url, 
    type: 'POST', 
    data: data, 
    statusCode: { 
     404: function() { 
      alert("page not found"); 
     } 
    } 
}); 
... rest of your code ...