views:

1397

answers:

9

What would be the best way to handle the submit event when you have multiple forms dynamicly created with the same form id in jQuery?

So far this line makes that jquery only handles the first form.

$("form#noteform").submit(function(){
  // do stuff
});

Kind of confusing, because I really need to catch the submit of a particular form to get the correct post values, therefore the selector of the form must be unique.

How can you make it listen to all submits? and later identify, if it is the correct form id that launched the submit?

+4  A: 

There is no best way to do this using ID's, because having multiple elements with the same ID is invalid HTML.

I would suggest instead your forms have unique ID's but share a class name. If you then needed to get the first one, you could use the ID directly or the class and the jquery :first selector.

$('form.className:first').submit(function(){
  stuff();
});

-edit- Trying to actually address the issue of identifying which form has been submitted. Again this solution relies on Unique form ID's

$('form.className').submit(function(){
  switch( $(this).attr('id') ){
    case 'form1id':
      submitForm1();
      break;
    case 'form2id':
      submitForm2();
      break;
    default:
      stuff()
      break;
  }      
});
Corey Downie
-1 It seems to me that the OP is listening for any submit event and hopes to process data on whichever one was fired. Although the class recomendation might work, I suspect it would have the same problem. As for the sample, that doesn't provide any additional functionality over what he already has.
bendewey
I agree with @Corey Downie@ using the same ID more than once is *invalid HTML* it is generally a bad idea and it might even lead to unexpected behaviour in jQuery.
brianpeiris
I'm not saying that using the id more then once is recommended, I agree that its bad, but that wasn't the question. I'm assuming that the OP isn't in control of the ids.
bendewey
A: 

I've seen some issues with the submit event. I would recommend attaching your events to the button click events for your forms. I would also have to recommend that you don't use the same ids in html if possible. That's generally bad practice.

For example:

with the following html:

<form id="questionForm" action="question/save/1234" method="post">>
   <input type="text" id="question1" />
   <input type="text" id="answer1" />
   <input type="submit" id="saveQuestion1" class="submit" value="Save" />
</form>
<!-- more forms -->
<form id="questionForm" action="question/save/4321" method="post">
   <input type="text" id="question2" />
   <input type="text" id="answer2" />
   <input type="submit" id="saveQuestion2" class="submit" value="Save" />
</form>

You could use this instead:

$(document).ready(function() {
  $('.submit').click(function(e) {
    // load the form with closest (jQuery v1.3+)
    var form = $(this).closest('form');
    // check form
    if (!isValid(form))
    {
      e.preventDefault();
    }
    // or if you make the buttons of type button and not submit
    if (isValid(form))
    {
      form.submit();
    }
  });
});
bendewey
Added note about using the same ids being a bad practice.
bendewey
A: 

the last option I was actually thinking about it because I already used that code somewhere else

If that is really working, then that would be great

too check if the form is valid I could use instead off

if (!isValid(form))  

if form.id="tbnoteform" then
submit the form

I still trying to get the hang off this

Can you use the keyword this everytime after you used the selector statement too create an object instance?? so form is now an object instance off the form?

Richard

In jQuery the `this` variable is usually used in event callbacks to refer to the element that the event was bound to. In @bendewey's code it refers to the `.submit` button that triggered the event.It is also used in jQuery UI widgets to refer to the element that was used to create the widget.
brianpeiris
Yes, that code will do what you expect. Although, since `form` is a jQuery object, you have to use `form.attr('id')` instead of `form.id`.P.S. Please update your question instead of adding more information in answer.
brianpeiris
thanks Brian, I don't mean to drift off the topic too muchI was actualy reading up on the use off this, but I want too understand the code that's given too me, otherwise I can create multiple posts on every little thing I don't getBut I generarly keep that in check
A: 

I think I ran into some syntax problem

I have my complete code here

the button is of type image

$(document).ready(function(){
    timestamp = 0;
    $('.delete').click(function(e) {   
          // load the form with closest (jQuery v1.3+)    
         var form = $(this).closest('form');    // check form   
         if (!form.attr('id')="noteform")    {     
       e.preventDefault();    
         }    

          // or if you make the buttons of type button and not submit    
         if (form.attr('id')="noteform")   {     
     form.submit(function(){ 

     $(this).parents(".pane").animate({ opacity: 'hide' }, "slow");
     $.post("tbnotes.php",{
          noteid: $("#frmnoteid").val(),
          action: "delete",
          time: timestamp

     }, function(xml) {
         addMessages(xml);
         });
     return false;
              });         

        } // end off IF(form.attr('id')="noteform")

}); //end off $('.delete).click(function(e) {

    //select all the a tag with name equal to modal   
    $('a[name=modal]').click(function(e) {   
        //Cancel the link behavior   
        e.preventDefault(); 
        // make a new note  
        newnote(); 

    });

}); //end off document ready

You're missing a quote on the third line. Should be `$('.submit')` instead of `$('.submit)`Again, please update the current question. It does not make sense to add an extension to the question in an answer.
brianpeiris
I don't know what you want me too changethe mean question is still valid, and other people may have the same issueso, I can't just change the questionI still have problems too make this one work
on your last comment, the quote was caused by my editingthe image type button, that has submit as it's default action has the class="delete" attached too itI wil have to tear the code apart again too see what is failing
A: 

I've complete reworked my answer... It's cleaner, simpler, and it works for dynamically added forms too! ;-P

<script language="javscript">
$(function() {
    $('form').live('specialSubmit',function() {
        // do stuff... the form = $(this)
        alert($(this).serialize()); // to prove it's working...
    });
    bind_same_id_forms('noteform');
});
function bind_same_id_forms(id) {
    $('form').die().live('keypress',function(ev) { 
        if(ev.keyCode == 13 && $(this).attr('id') == id) {
            $(this).trigger('specialSubmit');
            return false;
        }
    }).children(':submit,:image').die().live('click',function(ev) {
        if($(this).attr('id') == id) {
            $(this).trigger('specialSubmit'); 
            return false;
        }
    });
}
</script>

Example HTML:

<form id="noteform" action="question/save/1234" method="post">
   <input type="text" name="question" />
   <input type="text" name="answer" />
   <input type="submit"value="Save" />
</form>
<!-- more forms -->
<form id="noteform" action="question/save/4321" method="post">
   <input type="text" name="question" />
   <input type="text" name="answer" />
   <input type="submit" value="Save" />
</form>
KyleFarris
Kyle, are those static forms on the page or do you also create them on the fly
Static. They are just my versions of an example of a multi-form (with same IDs) HTML structure. You don't have to use that structure though. You can have you HTML any way you want.
KyleFarris
So, for better understanding. I have to put this code in the head section of the page. But then It runs only onceShould I put the bind_same_id_forms function in the callback of the load method in my newnote() function, otherwise I think I run into the same problem that the newly created forms don't attach to the click event
Nope, that's the point of the live() method. It only needs to be ran once and then it will watch for all newly added elements that match the initial selector. The bind method only binds on the initial load.
KyleFarris
I get no results from this, I still get a page refreshYou can see it if you follow the link
Sorry, I didn't consider that you would have 'image' type submit buttons. The modified code should work.
KyleFarris
A: 

I revised my code example of creating a new note

This one attaches the submit event too the newly added form within the callback function off the load event.

It's a step forward because the other examples diddn't do the job, for some reason.

I don't know about any drawbacks off doing it like this, yet!! I am open for any comments on the issue If you want see example

Purpose&Comments: The newnote function takes two arguments

-: index = the number off notes already present on the page

-: tbnoteid = the noteid from the database

The index is supposed too act like a counter of displayed messages.

If the counter exceeds 10 for example, it is supposed to delete the message on the criterium off last one is first one out (message with the oldest timestamp)from the page and the db(logic has too be added later)

The only action the form is permitted todo is delete the message from the database and remove itself(the container div) from the page.For estatic purposes it is first faded out.

The function can take more arguments like the message itself. When user enters the page the newnote function should be called from another function that pulls the messages from the db if there are any.

The link too generate a new note will be replaced by the action off another form like this example

$(document).ready(function(){
 $('a[name=modal]').click(function(e) {  //the selector is for testing purpose 
        //Cancel the link behavior   
        e.preventDefault();   
       var $aantal = $("div.pane").size()
    newnote($number+1,1); // second argument is supposed too come from the database


    }); 

    function newnote(index,tbnoteid) {


    $("div.wrapper:last").after('<div class="wrapper"></div>'); 
    $('.wrapper:last').load('tbnote.html .pane', function() { 
    $(".pane:last").prepend("testmessage");  //testpurpose
    $('.pane:last #frmnoteid').val(tbnoteid);

    $(this,".frm" ).attr('id' , index);
    var $id = $(this).attr('id'); ");  //testpurpose
    $('.frm:last').submit(function(){ 
     $.post("tbnotes.php",{
     noteid: $("#frmnoteid").val(),
     actie: "verwijder",
     tijd: timestamp}, function(xml) {
     addMessages(xml);
     });

     alert("Hello mijn id = " + $id );"); //testpurpose 
    $(this).parents(".pane").animate({ opacity: 'hide' }, "slow");
    $(this).parents(".wrapper").remove();
    return false;

            });
        });

}
You have some very bad code/bad practices on that page you linked to. I don't want to come off as offensive, but, you may want to consider re-doing your logic and HTML on that page. For instance, you are binding a click event to an '<a>' tag based on its 'name' attribute. That's not standard at all. You should probably use an ID or class there. I would prefer a class in this situation since you may have other elements on your page that will trigger the same action.
KyleFarris
not offended, most of it is for testingpurposes onlyIt was actually something I copypasted from some other tutorialIf I am actually going too use it for production so to speakI will go over every detail, especially, naming conventions, but thanks for the heads up
+1  A: 

If you're using dynamically added forms, you should use the live function in jQuery:

  $('.submit').live('click', function(e) {

instead of

  $('.submit').click(function(e) {

This binds the click callback to buttons with the submit class even if new ones are added dynamically.

P.S. Sorry for bugging you about this but the clarifications you are adding in new answers to your own question should be appended to the original question, not added as answers. They are technically not answers.

brianpeiris
Brian, you are assuming the person will be submitting the form with a click. They could just as easily be submitting the form with the 'enter' button. You could intercept the clicking of the submit button as well as the keyPress event for the 'enter' key with the live() method, but you unfortunately can't (yet) use the live() method to submit forms. I do agree with Brian about the submitter's answers though. They should be appended to his original question or added as comments to the appropriate answers.
KyleFarris
@KyleFarris, you're right the live() method currently does not support binding to 'submit' events.
brianpeiris
clarifications, yes I understand. Answers usually lead to new questions. The only thing I try too keep in mind is how too solve the main problem without getting too much offtopicsorry, I am not realy aware that it is confusing it's just my thought process
ok, I will use the comment box, although they are not really suited to place code in
If I cannot use the live method, should I bind the click event thenin the callback of the load method with any additional code for submitting??
A: 

What would be the best way to handle the submit event when you have multiple forms dynamicly created with the same form id in jQuery?

If id is 'noteform', to select all form with that id:

jQuery('form[id="noteform"]')

Caution: It may not be the best idea to have multiple HTML element (including form) to have non-unique id.

How can you make it listen to all submits?

You may bind event on its event:

jQuery('form[id="noteform"]').submit(function(e){});

and later identify, if it is the correct form id that launched the submit?

Although by using the selector, it is guaranteed (in my opinion) to have form with correct id, you can check the id of the form in the submit event, by using this object, eg:

jQuery('form[id="noteform"]').submit(function(e){
  if(this.id=='noteform') {/* do interesting stuffs */}

  // use .index function to determine the form index from the jQuery array.
  alert('index='+jQuery('form[id="noteform"]').index(this));
});

If you are interested in POC code snippet that I use to test them (solution), here it is:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled 1</title>

<script type="text/javascript" src="jquery-1.3.2.js"></script>

</head>

<body>

<form id="noteform"><div>
<input type="submit" value="submit" />
</div></form>

<form id="noteform"><div>
<input type="submit" value="submit" />
</div></form>

<form id="noteform"><div>
<input type="submit" value="submit" />
</div></form>

<script type="text/javascript">
/* <![CDATA[ */

// test for selection
jQuery('form[id="noteform"]').each(function(i){
  alert('noteform #' + i); //
});

// test for submission
jQuery('form[id="noteform"]').submit(function(e){
  if(this.id=='noteform'){
    alert('index='+jQuery('form[id="noteform"]').index(this));
    return false; // cancel submission
  }
});

/* ]]> */
</script>

</body>

</html>

Thanks.

Nordin
are you sure this works, because it looks like it is similar too @bendeway's code. It diddn't seem too attach too the new forms.If you see my example, I put it in the load callback. That seems too work. I also made my id's unique by placing an indexnumber behind the name. You can also see that in the source off the live example. It is a bit cluncky, but it works. It is still in testingfase, so I problably could improve on some stuff. Do you know if there is any disadvantage, by placing the event inthe load callback??
The POC code works, using JQuery 1.3.2, based on my testing on Safari 4b and Chrome 1. I was just trying to answer the question, but perhaps I may misundestood the question though. The question explicitly said same id. However, having non-unique id might not be a wise idea.It will event will not be binded to any new dynamically add form after the event binding was done. I am not sure if this was asked in the question, that's why I left it out.And for load callback, it is definitely good idea to use it. I don't verbosely use it in the POC code just for the sake of POC. ;-)Thanks, Richard.
Nordin
Hi Richard, after reading other answers in this question, that explain why I am not able to understand the whole picture here. Don't take this as an offending you, we are all learning here, I agree with others' suggestion here to update the question than to append in answer section. Anyway, I guess you already had it all working, congrats. ;-)
Nordin
A: 

Hi, does anyone know how i would do this with 3 forms on one page - then when one is submitted it disappears and only leaves 2 left to fill in?

I'd then like to show a different thankyou message after all three have been submitted - just not sure how at the moment!

Thanks in advance, James

James