Ruby On Rails 3, form_tag remote on responding to Ajax request

前端 未结 6 1311
清歌不尽
清歌不尽 2021-02-02 01:37

thanks for reading this post. I\'ve been stuck on an issue with RoR for the past few days. I have a form under index.html.erb as:


    A         
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="ca-pub-5408099190056760"
     data-ad-slot="7305827575"
     data-ad-format="auto"
     data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>        </div>
                      <div class="relativetags">
              相关标签:
       </div>
      </div>
      
      <div class="fly-panel detail-box" id="flyReply">
        <fieldset class="layui-elem-field layui-field-title" style="text-align: center;">
          <legend>6条回答</legend>        </fieldset>

        <ul class="jieda" id="jieda">
                         				            <li data-id="111">
            <a name="item-1111111111"></a>
           
            <div class="detail-about detail-about-reply">
                              <a class="fly-avatar" href="https://www.e-learn.cn/qa/u-64.html">
                <img src="https://www.e-learn.cn/qa/data/avatar/000/00/00/small_000000064.jpg" alt=" ">
              </a>
              <div class="fly-detail-user">
                <a href="https://www.e-learn.cn/qa/u-64.html" class="fly-link">
                  <cite>梦如初夏 </cite>       
                </a>
              </div>
                            <div class="detail-hits">
                <span>2021-02-02 02:15</span>
              </div>
            </div>
            <div class="detail-body jieda-body photos">
                                                                       
<p>If you look at the rendered source of your page, you should notice an error in the fields attributes.  </p>

<p>The correct way to do it is as follows:</p>

<pre><code><%= form_tag({:action => 'list'}, :remote => true %>
</code></pre>

<p>Notice the curly brackets, very important!  Alternatively you could have done:</p>

<pre><code><%= form_tag('list', :remote => true %>
</code></pre>
                                                                        <div class="appendcontent">
                                                        </div>
            </div>
            <div class="jieda-reply">
              <span class="jieda-zan button_agree" type="zan" data-id='2014033'>
                <i class="iconfont icon-zan"></i>
                <em>0</em>
              </span>
                 <span type="reply" class="showpinglun" data-id="2014033">
                <i class="iconfont icon-svgmoban53"></i>
               讨论(0)
              </span>
              
                                                   
              <div class="jieda-admin">
                                                            </div>
            </div>
                      <div class="comments-mod "  style="display: none; float:none;padding-top:10px;" id="comment_2014033">
                    <div class="areabox clearfix">

<form class="layui-form" action="">
               
            <div class="layui-form-item">
    <label class="layui-form-label" style="padding-left:0px;width:60px;">发布评论:</label>
    <div class="layui-input-block" style="margin-left:90px;">
         <input type="text" placeholder="不少于5个字" AUTOCOMPLETE="off" class="comment-input layui-input" name="content" />
                        <input type='hidden' value='0' name='replyauthor' />
    </div>
    <div class="mar-t10"><span class="fr layui-btn layui-btn-sm addhuidapinglun" data-id="2014033">提交评论 </span></div>
  </div>
  
</form>
                    </div>
                    <hr>
                    <ul class="my-comments-list nav">
                        <li class="loading">
                        <img src='https://www.e-learn.cn/qa/static/css/default/loading.gif' align='absmiddle' />
                         加载中...
                        </li>
                    </ul>
                </div>
          </li>
          	          <li data-id="111">
            <a name="item-1111111111"></a>
           
            <div class="detail-about detail-about-reply">
                              <a class="fly-avatar" href="https://www.e-learn.cn/qa/u-90.html">
                <img src="https://www.e-learn.cn/qa/data/avatar/000/00/00/small_000000090.jpg" alt=" ">
              </a>
              <div class="fly-detail-user">
                <a href="https://www.e-learn.cn/qa/u-90.html" class="fly-link">
                  <cite>感情败类 </cite>       
                </a>
              </div>
                            <div class="detail-hits">
                <span>2021-02-02 02:16</span>
              </div>
            </div>
            <div class="detail-body jieda-body photos">
                                                                       
<p>I posted this answer on Hacker News, but figured the Stack Overflow community might benefit as well :-)</p>

<p>In Rails 3, the javascript drivers are very hands-off (i.e. unobtrusive). The problem you're having is that your app is returning to the browser a string of javascript, but there is nothing in the page that is then executing that javascript in the context of the page.</p>

<p>The rails.js ujs driver binds to forms and links with <code>data-remote=true</code>, which is what the <code>:remote => true</code> is doing, to make them submit their requests remotely, but that is where the Rails magic stops. </p>

<p>The good news is that the remote requests fires off some events you can bind to, which give you access to the data returned by the server (which fire off in the following order):</p>

<pre><code>  ajax:before
  ajax:loading
  ajax:success
  ajax:complete
  ajax:failure
  ajax:after
</code></pre>

<p>You need to bind an event to the <code>ajax:success</code> event of your form. So, if your form had the id "myform", you'd want something like this on your page:</p>

<pre><code>  $('#myform').bind('ajax:success', function(evt, data, status, xhr){
    eval(xhr.responseText);
  });
</code></pre>

<p><code>xhr.responseText</code> is what your server returns, so this simply executes it as javascript.</p>

<p>Of course, it's proper to also bind to the failure event with some error handling as well.</p>

<p>I usually don't even use the action.js.erb method of returning javascript, I just have my controller render the HTML partial, and then I have a binding like this in the page:</p>

<pre><code>  $('#myform').bind('ajax:success', function(evt, data, status, xhr){
    $('#target-div').html(xhr.responseText);
  });
</code></pre>

<p>I'm actually in the middle of writing a full article on this, but hopefully this is enough to get you going.</p>

<p>EDIT: I finished that article, fully explaining remote links and forms in Rails 3. Maybe it will help: </p>

<p>Rails 3 Remote Links and Forms: 
A Definitive Guide</p>
                                                                        <div class="appendcontent">
                                                        </div>
            </div>
            <div class="jieda-reply">
              <span class="jieda-zan button_agree" type="zan" data-id='2014032'>
                <i class="iconfont icon-zan"></i>
                <em>0</em>
              </span>
                 <span type="reply" class="showpinglun" data-id="2014032">
                <i class="iconfont icon-svgmoban53"></i>
               讨论(0)
              </span>
              
                                                   
              <div class="jieda-admin">
                                                            </div>
            </div>
                      <div class="comments-mod "  style="display: none; float:none;padding-top:10px;" id="comment_2014032">
                    <div class="areabox clearfix">

<form class="layui-form" action="">
               
            <div class="layui-form-item">
    <label class="layui-form-label" style="padding-left:0px;width:60px;">发布评论:</label>
    <div class="layui-input-block" style="margin-left:90px;">
         <input type="text" placeholder="不少于5个字" AUTOCOMPLETE="off" class="comment-input layui-input" name="content" />
                        <input type='hidden' value='0' name='replyauthor' />
    </div>
    <div class="mar-t10"><span class="fr layui-btn layui-btn-sm addhuidapinglun" data-id="2014032">提交评论 </span></div>
  </div>
  
</form>
                    </div>
                    <hr>
                    <ul class="my-comments-list nav">
                        <li class="loading">
                        <img src='https://www.e-learn.cn/qa/static/css/default/loading.gif' align='absmiddle' />
                         加载中...
                        </li>
                    </ul>
                </div>
          </li>
          	          <li data-id="111">
            <a name="item-1111111111"></a>
           
            <div class="detail-about detail-about-reply">
                              <a class="fly-avatar" href="https://www.e-learn.cn/qa/u-129.html">
                <img src="https://www.e-learn.cn/qa/data/avatar/000/00/01/small_000000129.jpg" alt=" ">
              </a>
              <div class="fly-detail-user">
                <a href="https://www.e-learn.cn/qa/u-129.html" class="fly-link">
                  <cite>忘了有多久 </cite>       
                </a>
              </div>
                            <div class="detail-hits">
                <span>2021-02-02 02:25</span>
              </div>
            </div>
            <div class="detail-body jieda-body photos">
                                                                       
<p>I know this is an old question but someone can benefit from it.</p>
<p>I think the error is related to this:</p>
<blockquote>
<p>JS _doit.js.erb $("#my_list").html("<%= escape_javascript(render(:partial => "doit"))%>");</p>
<p>And finally a partial:</p>
<p>_doit.html.erb.</p>
</blockquote>
<p>You are creating a <code>_doit.js.erb</code> partial to respond to the action <code>doit</code> in the controller but what you need is a <strong>view</strong> called <code>doit.js.erb</code> (without the underscore). Conceptually, the <code>format.js</code> in your action will respond to a view with the same name of it with extension <code>js.erb</code>.</p>
                                                                        <div class="appendcontent">
                                                        </div>
            </div>
            <div class="jieda-reply">
              <span class="jieda-zan button_agree" type="zan" data-id='2014037'>
                <i class="iconfont icon-zan"></i>
                <em>0</em>
              </span>
                 <span type="reply" class="showpinglun" data-id="2014037">
                <i class="iconfont icon-svgmoban53"></i>
               讨论(0)
              </span>
              
                                                   
              <div class="jieda-admin">
                                                            </div>
            </div>
                      <div class="comments-mod "  style="display: none; float:none;padding-top:10px;" id="comment_2014037">
                    <div class="areabox clearfix">

<form class="layui-form" action="">
               
            <div class="layui-form-item">
    <label class="layui-form-label" style="padding-left:0px;width:60px;">发布评论:</label>
    <div class="layui-input-block" style="margin-left:90px;">
         <input type="text" placeholder="不少于5个字" AUTOCOMPLETE="off" class="comment-input layui-input" name="content" />
                        <input type='hidden' value='0' name='replyauthor' />
    </div>
    <div class="mar-t10"><span class="fr layui-btn layui-btn-sm addhuidapinglun" data-id="2014037">提交评论 </span></div>
  </div>
  
</form>
                    </div>
                    <hr>
                    <ul class="my-comments-list nav">
                        <li class="loading">
                        <img src='https://www.e-learn.cn/qa/static/css/default/loading.gif' align='absmiddle' />
                         加载中...
                        </li>
                    </ul>
                </div>
          </li>
          	          <li data-id="111">
            <a name="item-1111111111"></a>
           
            <div class="detail-about detail-about-reply">
                              <a class="fly-avatar" href="https://www.e-learn.cn/qa/u-41.html">
                <img src="https://www.e-learn.cn/qa/data/avatar/000/00/00/small_000000041.jpg" alt=" ">
              </a>
              <div class="fly-detail-user">
                <a href="https://www.e-learn.cn/qa/u-41.html" class="fly-link">
                  <cite>滥情空心 </cite>       
                </a>
              </div>
                            <div class="detail-hits">
                <span>2021-02-02 02:33</span>
              </div>
            </div>
            <div class="detail-body jieda-body photos">
                                                                       
<p>Using <code>list</code> as your function name in the controller may be the problem. That name is used internally by Rails.</p>
                                                                        <div class="appendcontent">
                                                        </div>
            </div>
            <div class="jieda-reply">
              <span class="jieda-zan button_agree" type="zan" data-id='2014035'>
                <i class="iconfont icon-zan"></i>
                <em>0</em>
              </span>
                 <span type="reply" class="showpinglun" data-id="2014035">
                <i class="iconfont icon-svgmoban53"></i>
               讨论(0)
              </span>
              
                                                   
              <div class="jieda-admin">
                                                            </div>
            </div>
                      <div class="comments-mod "  style="display: none; float:none;padding-top:10px;" id="comment_2014035">
                    <div class="areabox clearfix">

<form class="layui-form" action="">
               
            <div class="layui-form-item">
    <label class="layui-form-label" style="padding-left:0px;width:60px;">发布评论:</label>
    <div class="layui-input-block" style="margin-left:90px;">
         <input type="text" placeholder="不少于5个字" AUTOCOMPLETE="off" class="comment-input layui-input" name="content" />
                        <input type='hidden' value='0' name='replyauthor' />
    </div>
    <div class="mar-t10"><span class="fr layui-btn layui-btn-sm addhuidapinglun" data-id="2014035">提交评论 </span></div>
  </div>
  
</form>
                    </div>
                    <hr>
                    <ul class="my-comments-list nav">
                        <li class="loading">
                        <img src='https://www.e-learn.cn/qa/static/css/default/loading.gif' align='absmiddle' />
                         加载中...
                        </li>
                    </ul>
                </div>
          </li>
          	          <li data-id="111">
            <a name="item-1111111111"></a>
           
            <div class="detail-about detail-about-reply">
                              <a class="fly-avatar" href="https://www.e-learn.cn/qa/u-120.html">
                <img src="https://www.e-learn.cn/qa/data/avatar/000/00/01/small_000000120.jpg" alt=" ">
              </a>
              <div class="fly-detail-user">
                <a href="https://www.e-learn.cn/qa/u-120.html" class="fly-link">
                  <cite>刺人心 </cite>       
                </a>
              </div>
                            <div class="detail-hits">
                <span>2021-02-02 02:36</span>
              </div>
            </div>
            <div class="detail-body jieda-body photos">
                                                                       
<p>Rails 5.1 introduced rails-ujs, which changes the parameters of these event handlers. The following should work:</p>

<pre><code>$('#myform').bind('ajax:success', function(event) {
        const [_data, _status, xhr] = event.detail;

});
</code></pre>

<p>Source:https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers</p>
                                                                        <div class="appendcontent">
                                                        </div>
            </div>
            <div class="jieda-reply">
              <span class="jieda-zan button_agree" type="zan" data-id='2014036'>
                <i class="iconfont icon-zan"></i>
                <em>0</em>
              </span>
                 <span type="reply" class="showpinglun" data-id="2014036">
                <i class="iconfont icon-svgmoban53"></i>
               讨论(0)
              </span>
              
                                                   
              <div class="jieda-admin">
                                                            </div>
            </div>
                      <div class="comments-mod "  style="display: none; float:none;padding-top:10px;" id="comment_2014036">
                    <div class="areabox clearfix">

<form class="layui-form" action="">
               
            <div class="layui-form-item">
    <label class="layui-form-label" style="padding-left:0px;width:60px;">发布评论:</label>
    <div class="layui-input-block" style="margin-left:90px;">
         <input type="text" placeholder="不少于5个字" AUTOCOMPLETE="off" class="comment-input layui-input" name="content" />
                        <input type='hidden' value='0' name='replyauthor' />
    </div>
    <div class="mar-t10"><span class="fr layui-btn layui-btn-sm addhuidapinglun" data-id="2014036">提交评论 </span></div>
  </div>
  
</form>
                    </div>
                    <hr>
                    <ul class="my-comments-list nav">
                        <li class="loading">
                        <img src='https://www.e-learn.cn/qa/static/css/default/loading.gif' align='absmiddle' />
                         加载中...
                        </li>
                    </ul>
                </div>
          </li>
          	          <li data-id="111">
            <a name="item-1111111111"></a>
           
            <div class="detail-about detail-about-reply">
                              <a class="fly-avatar" href="https://www.e-learn.cn/qa/u-134.html">
                <img src="https://www.e-learn.cn/qa/data/avatar/000/00/01/small_000000134.jpg" alt=" ">
              </a>
              <div class="fly-detail-user">
                <a href="https://www.e-learn.cn/qa/u-134.html" class="fly-link">
                  <cite>青春惊慌失措 </cite>       
                </a>
              </div>
                            <div class="detail-hits">
                <span>2021-02-02 02:38</span>
              </div>
            </div>
            <div class="detail-body jieda-body photos">
                                                                       
<p>Do you have 2 partials named '_list'? Maybe that's causing problems and you should just a little more specific:</p>

<pre><code>$("#my_list").html("<%= escape_javascript(render(:partial => "list.html.erb"))%>");
</code></pre>

<p><br/>
I'm not sure if this helps, but are if you using in IE be aware that IE sends some headers that screw with how your controller responds. So you may be sending an Ajax request with IE, but your Rails app thinks its just a plain html request.</p>

<p>I've had to setup jQuery to first erase the current headers and then add just the javascript header:</p>

<pre><code>$.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept",'');xhr.setRequestHeader("Accept", "text/javascript")}
</code></pre>

<p>})</p>
                                                                        <div class="appendcontent">
                                                        </div>
            </div>
            <div class="jieda-reply">
              <span class="jieda-zan button_agree" type="zan" data-id='2014034'>
                <i class="iconfont icon-zan"></i>
                <em>0</em>
              </span>
                 <span type="reply" class="showpinglun" data-id="2014034">
                <i class="iconfont icon-svgmoban53"></i>
               讨论(0)
              </span>
              
                                                   
              <div class="jieda-admin">
                                                            </div>
            </div>
                      <div class="comments-mod "  style="display: none; float:none;padding-top:10px;" id="comment_2014034">
                    <div class="areabox clearfix">

<form class="layui-form" action="">
               
            <div class="layui-form-item">
    <label class="layui-form-label" style="padding-left:0px;width:60px;">发布评论:</label>
    <div class="layui-input-block" style="margin-left:90px;">
         <input type="text" placeholder="不少于5个字" AUTOCOMPLETE="off" class="comment-input layui-input" name="content" />
                        <input type='hidden' value='0' name='replyauthor' />
    </div>
    <div class="mar-t10"><span class="fr layui-btn layui-btn-sm addhuidapinglun" data-id="2014034">提交评论 </span></div>
  </div>
  
</form>
                    </div>
                    <hr>
                    <ul class="my-comments-list nav">
                        <li class="loading">
                        <img src='https://www.e-learn.cn/qa/static/css/default/loading.gif' align='absmiddle' />
                         加载中...
                        </li>
                    </ul>
                </div>
          </li>
          	          
           <style>
   
.laypage-main a, .laypage-main span {
    display: inline-block;
}
        </style>                  </ul>
        
        <div class="layui-form layui-form-pane">
          <form id="huidaform"  name="answerForm"  method="post">
            
            <div class="layui-form-item layui-form-text">
              <a name="comment"></a>
              <div class="layui-input-block">
            
    
<script type="text/javascript" src="https://www.e-learn.cn/qa/static/js/neweditor/ueditor.config.js"></script>
<script type="text/javascript" src="https://www.e-learn.cn/qa/static/js/neweditor/ueditor.all.js"></script>
<script type="text/plain" id="editor"  name="content"  style="width:100%;height:200px;"></script>                                 
<script type="text/javascript">
                                 var isueditor=1;
            var editor = UE.getEditor('editor',{
                //这里可以选择自己需要的工具按钮名称,此处仅选择如下五个
                toolbars:[['source','fullscreen',  '|', 'undo', 'redo', '|', 'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|', 'rowspacingtop', 'rowspacingbottom', 'lineheight', '|', 'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|', 'indent', '|', 'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'link', 'unlink', 'anchor', '|', 'simpleupload', 'insertimage', 'scrawl', 'insertvideo', 'attachment', 'map', 'insertcode', '|', 'horizontal', '|', 'preview', 'searchreplace', 'drafts']],
            
                initialContent:'',
                //关闭字数统计
                wordCount:false,
                zIndex:2,
                //关闭elementPath
                elementPathEnabled:false,
                //默认的编辑区域高度
                initialFrameHeight:250
                //更多其他参数,请参考ueditor.config.js中的配置项
                //更多其他参数,请参考ueditor.config.js中的配置项
            });
                        editor.ready(function() {
            	editor.setDisabled();
            	});
                            $("#editor").find("*").css("max-width","362px");
        </script>              </div>
            </div>
                          
    

        
         <div class="layui-form-item">
                <label for="L_vercode" class="layui-form-label">验证码</label>
                <div class="layui-input-inline">
                  <input type="text"  id="code" name="code"   value="" required lay-verify="required" placeholder="图片验证码" autocomplete="off" class="layui-input">
                </div>
                <div class="layui-form-mid">
                  <span style="color: #c00;"><img class="hand" src="https://www.e-learn.cn/qa/user/code.html" onclick="javascript:updatecode();" id="verifycode"><a class="changecode"  href="javascript:updatecode();"> 看不清?</a></span>
                </div>
              </div>
                                  <div class="layui-form-item">
                    <input type="hidden" value="982965" id="ans_qid" name="qid">
   <input type="hidden" id="tokenkey" name="tokenkey" value=''/>
                <input type="hidden" value="Ruby On Rails 3, form_tag remote on responding to Ajax request" id="ans_title" name="title"> 
             
              <div class="layui-btn    layui-btn-disabled"  id="ajaxsubmitasnwer" >提交回复</div>
            </div>
          </form>
        </div>
      </div>
      <input type="hidden" value="982965" id="adopt_qid"	name="qid" /> 
      <input type="hidden" id="adopt_answer" value="0"	name="aid" />
    </div>
    <div class="layui-col-md4">
          
 <!-- 热门讨论问题 -->
     
 <dl class="fly-panel fly-list-one">
        <dt class="fly-panel-title">热议问题</dt>
            <!-- 本周热门讨论问题显示10条-->