2009-09-01 3 views
21

Ho una forma che assomiglia a questo:Invio di un modulo ajax jQuery con due bottoni di invio

<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> 

Quando mi legano a quello del modulo di presentare ($("vote_form").submit()), non mi sembra di avere accesso a quale immagine l'utente ha fatto clic. Così sto cercando di legarsi a fare clic sull'immagine stessa ($(".vote_down, .vote_up").click()), che presenta sempre la forma, indipendentemente dal fatto che provo

  • return false;
  • event.stopPropogation(); oppure
  • event.preventDefault();

perché tutti questi sono eventi di tipo.

  1. Devo collegare il mio $ .post() per l'evento form.submit(), e se sì, come faccio a sapere quale ingresso l'utente fa clic su, o

  2. Devo collegare il mio $ .post() al clic dell'immagine e, in tal caso, come impedire che anche il modulo venga inviato.

Ecco ciò che il mio codice jQuery sembra ora:

$(".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!? 
}); 

risposta

28

in base alla risposta di Emmett, il mio fix ideale per questo era solo per uccidere del form presentare con JavaScript in sé, in questo modo:

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

E questo totalmente funzionante

Per completezza, alcuni dei miei codici JS nel post originale hanno bisogno di un po 'di amore. Ad esempio, il modo in cui aggiungevo la funzione serialize non sembrava funzionare.Questo ha fatto:

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

Ecco il mio intero codice 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

Grazie mille per questo. Abbreviato il mio tentativo esistente un po '! – mhenrixon

+1

Perché non evitare hardcoding '" & submit = "' usando '$ this.attr (" nome ")'? – Bengt

+0

@bngtlrs Immagino perché è una funzione chiamata overhead che è semplicemente inutile. – PaulSkinner

1

Non capisco come return false e preventDefault non è riuscito a fare il loro lavoro. Forse provare a sostituire i pulsanti di immagine con immagini collegate:

<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(... 
}); 

È sempre possibile garantire che una forma non presenta legandosi alla manifestazione inviare, ad esempio:

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

Come ho detto nella questione, ho fatto quello che hai suggerito nella seconda parte, ma non hanno accesso a quale ingresso l'utente fa clic su. Inoltre, non voglio passare alle immagini collegate - mentre ciò potrebbe funzionare con Ajax, voglio comunque che il mio modulo funzioni per gli utenti senza Javascript, come al momento (e non con le immagini semplici). – worksology

0

Prova ad aggiungere onsubmit = "return false ;" al modulo, e poi presentando il modulo con 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

Anche se non sono convinto che questa sia una soluzione elegante, mi ha portato a una soluzione praticabile, che è stata aggiunta: $ (". Vote_form"). Submit (function() {return false;}); (Certamente non voglio aggiungere "onsubmit = 'return false;'" al form poiché voglio che il modulo funzioni senza Ajax.) – worksology

0

Senza ricorrere al plugin modulo (che si dovrebbe usare) si dovrebbe essere la gestione dell'evento submit, invece. Il codice dovrebbe rimanere abbastanza vicino a quello originale:

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

Come ho detto nella domanda originale, posso farlo, ma ho ancora bisogno di sapere quale immagine-input l'utente ha cliccato su questa funzione. event.target == il modulo, sfortunatamente. – worksology

4

Un'altra soluzione è quella di utilizzare un campo nascosto, e hanno l'evento onclick aggiornare il suo valore. Questo ti dà accesso da javascript, così come sul server in cui verrà pubblicato il campo nascosto .

2

È possibile attivare il modulo di invio sul clic delle immagini. Funzionerà con 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 ...