【问题标题】:Bind dynamically added form to submit event with jQuery使用 jQuery 绑定动态添加的表单以提交事件
【发布时间】:2009-05-07 14:32:43
【问题描述】:

当您在 jQuery 中使用相同的表单 ID 动态创建多个表单时,处理提交事件的最佳方法是什么?

到目前为止,这行代码让 jQuery 只处理第一个表单。

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

有点混乱,因为我确实需要捕获特定表单的提交才能获得正确的帖子值,因此表单的选择器必须是唯一的。

如何让它监听所有提交,然后确定它是否是启动提交的正确表单 ID?

【问题讨论】:

    标签: jquery binding form-submit


    【解决方案1】:

    没有使用 ID 的最佳方法,因为具有相同 ID 的多个元素是无效的 HTML。

    我建议您的表单具有唯一 ID,但共享一个类名。如果您随后需要获取第一个,则可以直接使用 ID 或使用类和 jquery :first 选择器。

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

    -edit- 试图真正解决识别已提交表单的问题。同样,此解决方案依赖于唯一表单 ID

    $('form.className').submit(function(){
      switch( $(this).attr('id') ){
        case 'form1id':
          submitForm1();
          break;
        case 'form2id':
          submitForm2();
          break;
        default:
          stuff()
          break;
      }      
    });
    

    【讨论】:

    • -1 在我看来,OP 正在侦听任何提交事件,并希望处理任何被解雇的事件的数据。虽然班级推荐可能会奏效,但我怀疑它也会有同样的问题。至于示例,它并没有提供比他已经拥有的任何额外的功能。
    • 我同意@Corey Downie@ 多次使用相同的 ID 是 invalid HTML 这通常是个坏主意,甚至可能导致 jQuery 中出现意外行为。
    • 我并不是说建议多次使用 id,我同意它不好,但这不是问题所在。我假设 OP 无法控制 ID。
    【解决方案2】:

    如果你使用动态添加的表单,你应该使用 jQuery 中的live 函数:

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

    而不是

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

    这会将点击回调绑定到具有submit 类的按钮,即使是动态添加新按钮。

    附:很抱歉打扰您,但您在自己问题的新答案中添加的说明应该附加到原始问题中,而不是作为答案添加。从技术上讲,它们不是答案。

    【讨论】:

    • Brian,您假设此人将通过单击提交表单。他们可以很容易地使用“输入”按钮提交表单。您可以使用 live() 方法拦截单击提交按钮以及“enter”键的 keyPress 事件,但不幸的是,您(还)不能使用 live() 方法提交表单。不过,我确实同意 Brian 关于提交者的回答。它们应该附加到他的原始问题中,或者作为 cmets 添加到适当的答案中。
    • @KyleFarris,你说得对,live() 方法目前不支持绑定到“提交”事件。
    • 澄清,是的,我明白了。答案通常会引出新的问题。我唯一要记住的是如何解决主要问题而不会引起太多离题抱歉,我真的不知道这很令人困惑,这只是我的思考过程
    • 好的,我会使用注释框,虽然它们不太适合在其中放置代码
    • 如果我不能使用live方法,我是否应该在load方法的回调中绑定click事件并添加任何额外的提交代码??
    【解决方案3】:

    我实际上正在考虑的最后一个选项 因为我已经在其他地方使用过该代码

    如果这真的有效,那就太好了

    检查表格是否有效,我可以使用 而是关闭

    if (!isValid(form))  
    
    if form.id="tbnoteform" then
    submit the form  
    

    我还在努力解决这个问题

    在你使用选择器语句后,你能不能每次都使用关键字 this 来创建 一个对象实例??那么表单现在是表单之外的对象实例了吗?

    理查德

    【讨论】:

    • 在 jQuery 中,this 变量通常用于事件回调中,以引用事件绑定到的元素。在@bendewey 的代码中,它指的是触发事件的.submit 按钮。它还用于 jQuery UI 小部件中,指代用于创建小部件的元素。
    • 是的,该代码将按照您的预期进行。虽然,由于form 是一个jQuery 对象,你必须使用form.attr('id') 而不是form.id。附言请更新您的问题,而不是在答案中添加更多信息。
    • 谢谢布赖恩,我并不想过多地偏离主题,我实际上是在阅读有关此功能的使用,但我也想了解给我的代码,否则我可以创建关于我没有得到的每一件小事的多个帖子但我通常会控制它
    【解决方案4】:

    我发现submit 事件存在一些问题。我建议将您的事件附加到表单的按钮单击事件中。如果可能,我还必须建议您不要在 html 中使用相同的 id。这通常是不好的做法。

    例如:

    使用以下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>
    

    你可以改用这个:

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

    【讨论】:

    • 添加了关于使用相同 ID 是一种不好的做法的说明。
    【解决方案5】:

    我想我遇到了一些语法问题

    我有完整的代码

    按钮是图像类型

    $(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")
    

    }); //结束 $('.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(); 
    
        }); 
    

    }); //结束文档准备好

    【讨论】:

    • 您在第三行缺少报价。应该是$('.submit') 而不是$('.submit) 同样,请更新当前问题。在答案中添加问题的扩展是没有意义的。
    • 我不知道你想让我改变什么意思的问题仍然有效,其他人可能有同样的问题,所以我不能只改变问题我也有问题这一项工作
    • 在您的最后一条评论中,引用是由我编辑图像类型按钮引起的,该按钮已提交,因为它的默认操作也附加了 class="delete" 我将不得不将代码分开再次查看失败的原因
    【解决方案6】:

    我修改了创建新笔记的代码示例

    这个也附加了提交事件回调函数中新添加的表单 关闭加载事件。

    这是一个进步 因为出于某种原因,其他示例没有完成这项工作。

    我不知道这样做有什么缺点,但是! 我愿意接受任何关于这个问题的 cmets 如果你想要see example

    目的&评论: newnote 函数有两个参数

    -: index = 页面上已经存在的音符数

    -: tbnoteid = 数据库中的noteid

    索引也应该像显示消息的计数器一样。

    例如,如果计数器超过 10,则应该从页面和数据库中删除标准上的消息,因为最后一个是第一个输出(具有最旧时间戳的消息)(逻辑也已稍后添加)

    允许表单执行的唯一操作是从数据库中删除消息并从页面中删除自身(容器 div)。出于静态目的,它首先淡出。

    该函数可以接受更多参数,例如消息本身。 当用户进入页面时,应该从另一个函数调用 newnote 函数,该函数从数据库中提取消息(如果有的话)。

    该链接也会生成一个新注释,该链接将被其他形式的操作所取代,例如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;
    
                });
            });
    
    }   
    

    【讨论】:

    【解决方案7】:

    什么是最好的处理方式 当你有提交事件 使用动态创建的多个表单 jQuery中相同的表单ID?

    如果 id 是 'noteform',则选择具有该 id 的所有表单:

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

    警告:让多个 HTML 元素(包括表单)具有非唯一 id 可能不是最好的主意。

    你怎样才能让它倾听所有人的声音 提交?

    您可以在其事件上绑定事件:

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

    然后识别,如果它是 启动的正确表单 ID 提交?

    虽然通过使用选择器,可以保证(在我看来)具有正确 id 的表单,您可以使用 this 对象在提交事件中检查表单的 id,例如:

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

    如果您对我用来测试它们的 POC 代码 sn-p 感兴趣(解决方案),这里是:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    
    <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>
    

    谢谢。

    【讨论】:

    • 你确定这行得通吗,因为它看起来也很相似@bendeway 的代码。它似乎并没有太附加新表格。如果你看到我的例子,我把它放在加载回调中。这似乎太奏效了。我还通过在名称后面放置一个索引号来使我的 id 独一无二。您还可以在实时示例的源代码中看到这一点。这有点笨拙,但它确实有效。它仍在测试阶段,所以我可能可以改进一些东西。通过将事件放在加载回调中,您知道是否有任何缺点??
    • 根据我在 Safari 4b 和 Chrome 1 上的测试,POC 代码使用 JQuery 1.3.2 工作。我只是想回答这个问题,但也许我可能误解了这个问题。该问题明确表示相同的ID。但是,拥有非唯一 id 可能不是一个明智的主意。事件绑定完成后,它将不会绑定到任何新的动态添加表单。我不确定这个问题是否被问到,这就是我忽略它的原因。而对于加载回调,使用它绝对是个好主意。为了 POC,我不会在 POC 代码中详细使用它。 ;-) 谢谢,理查德。
    • 嗨,理查德,在阅读了这个问题的其他答案后,这解释了为什么我在这里无法理解整个画面。不要将此视为冒犯您,我们都在这里学习,我同意其他人在这里更新问题而不是附加在答案部分的建议。无论如何,我猜你已经完成了所有工作,恭喜。 ;-)
    【解决方案8】:

    我已经完全修改了我的答案...它更干净、更简单,并且也适用于动态添加的表单! ;-P

    <script language="javascript">
    $(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>
    

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

    【讨论】:

    • Kyle,是页面上的那些静态表单还是你也动态创建它们
    • 静态。它们只是我的多表单(具有相同 ID)HTML 结构示例的版本。不过,您不必使用该结构。你可以以任何你想要的方式拥有你的 HTML。
    • 所以,为了更好地理解。我必须将此代码放在页面的头部。但是它只运行一次我应该将 bind_same_id_forms 函数放在我的 newnote() 函数中的 load 方法的回调中,否则我认为我遇到了新创建的表单不附加到单击事件的相同问题跨度>
    • 不,这就是 live() 方法的重点。它只需要运行一次,然后它将监视与初始选择器匹配的所有新添加的元素。 bind 方法只在初始加载时绑定。
    • 我没有得到任何结果,我仍然刷新页面你可以通过链接看到它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多