views:

3790

answers:

6

I have a form that looks like this:

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

When I bind to the form's submit ($("vote_form").submit()), I don't seem to have access to which image the user clicked on. So I'm trying to bind to clicking on the image itself ($(".vote_down, .vote_up").click()), which always submits the form, regardless of whether I try

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

because all of those are form events.

  1. Should I attach my $.post() to the form.submit() event, and if so, how do I tell which input the user clicked on, or

  2. Should I attach my $.post() to the image click, and if so, how do I prevent the form from submitting also.

Here is what my jQuery code looks like now:

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

I don't get how return false and preventDefault failed to do their job. Maybe try replacing the image buttons with linked images:

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

You can always ensure that a form does not submit by binding to the submit event, e.g.:

$('#vote_form').submit(function() {
    return false;
});
karim79
Like I said in the question, I have done what you've suggested in the second part, but I do not have access to which input the user clicked on. Further, I do not want to switch to linked images -- while that may work with Ajax, I still want my form to work for users w/o Javascript, as it currently does (and wouldn't with plain images).
worksology
A: 

Try adding onsubmit="return false;" to your form, and then submitting your form with 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>
Emmett
While I'm not convinced this is an elegant solution, it really led me to a workable fix, which is to add:$(".vote_form").submit(function() { return false; });(I certainly don't want to add "onsubmit='return false;'" to the form since I want the form to work w/o Ajax.)
worksology
A: 

You can also try out the jquery From Plugin which as all sorts of nice tools for submitting forms via ajax.

http://malsup.com/jquery/form/

PetersenDidIt
A: 

Without resorting to the Form plugin (which you should use) you should be handling the submit event instead. The code would stay pretty close to the original:

$("form").submit(function()) {
  $.post($(this).attr("action"), $(this).serialize(), function(data) {
    // work with the response
  });
  return false;
});
Andy Gaskell
Like I said in the original question, I can do this, but I still need to know what image-input the user clicked on within this function. event.target == the form, unfortunately.
worksology
+2  A: 

Based on Emmett's answer, my ideal fix for this was just to kill the form's submit with Javascript itself, like this:

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

And that totally worked.

For completeness, some of my JS code in the original post need a little love. For example, the way I was adding to the serialize function didn't seem to work. This did:

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

Here's my entire jQuery code:

$(".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)
    });
});
worksology
A: 

Another solution is to use a hidden field, and have the onclick event update its value. This gives you access from javascript, as well as on the server where the hidden field will get posted.

Jim C