【问题标题】:Is it possible to call Javascript's onsubmit event programmatically on a form?是否可以在表单上以编程方式调用 Javascript 的 onsubmit 事件?
【发布时间】:2010-09-07 05:24:54
【问题描述】:

在 Ruby on Rails 中,我尝试使用 form_remote_tag 帮助器更新 div 标签的 innerHTML。每当关联的选择标签接收到 onchange 事件时,就会发生此更新。问题是,<select onchange="this.form.submit();">;不起作用。 document.forms[0].submit() 也没有。让form_remote_tag中生成的onsubmit代码执行的唯一方法是创建一个隐藏的提交按钮,并从select标签调用按钮上的click方法。这是一个有效的 ERb 部分示例。

<% form_remote_tag :url => product_path, :update => 'content', :method => 'get' do -%>
  <% content_tag :div, :id => 'content' do -%>
    <%= select_tag :update, options_for_select([["foo", 1], ["bar", 2]]), :onchange => "this.form.commit.click" %>
    <%= submit_tag 'submit_button', :style => "display: none" %>
  <% end %>
<% end %>

我想做的是这样的,但它不起作用。

<% form_remote_tag :url => product_path, :update => 'content', :method => 'get' do -%>
  <% content_tag :div, :id => 'content' do -%>
    # the following line does not work
    <%= select_tag :update, options_for_select([["foo", 1], ["bar", 2]]), :onchange => "this.form.onsubmit()" %>
  <% end %>
<% end %>

那么,有什么办法可以去掉这个用例的不可见提交按钮?

似乎有些混乱。所以,让我解释一下。基本问题是submit()没有调用渲染到表单中的onsubmit()代码。

Rails 从这个 ERb 呈现的实际 HTML 表单如下所示:

<form action="/products/1" method="post" onsubmit="new Ajax.Updater('content', '/products/1', {asynchronous:true, evalScripts:true, method:'get', parameters:Form.serialize(this)}); return false;">
  <div style="margin:0;padding:0">
    <input name="authenticity_token" type="hidden" value="4eacf78eb87e9262a0b631a8a6e417e9a5957cab" />
  </div>
  <div id="content">
    <select id="update" name="update" onchange="this.form.commit.click">
      <option value="1">foo</option>
      <option value="2">bar</option>
    </select>
    <input name="commit" style="display: none" type="submit" value="submit_button" />
  </div>
</form>

我想取消不可见的提交按钮,但使用直接的 form.submit 似乎不起作用。所以,我需要一些方法来调用表单的 onsubmit 事件代码。

更新:如果 Rails 没有生成 return(false);,Orion Edwards 解决方案将起作用。我不确定哪个更糟,向不可见的提交按钮发送幻像点击或在使用 javascript 字符串替换删除返回调用后调用 getAttribute('onsubmit') 调用上的 eval !

【问题讨论】:

    标签: javascript ruby-on-rails ruby


    【解决方案1】:

    我知道这个问题有点老了,但你到底在做什么 eval 呢?

    document.getElementById('formId').onsubmit();
    document.getElementById('formId').submit();
    

    document.formName.onsubmit();
    document.formName.submit();
    

    当一个文档的 DOM 被加载时,事件不再是字符串,它们是函数。

    alert(typeof document.formName.onsubmit); // function
    

    因此,没有理由将函数转换为字符串,以便对其进行评估。

    【讨论】:

      【解决方案2】:

      给您的表单一个id

      然后

      document.getElementById('formid').submit();
      

      如果您通过 innerHTML 将 Javascript 加载到 div,它将无法运行...仅供参考。

      【讨论】:

        【解决方案3】:

        如果您必须使用 Rail 的内置 Javascript 生成,我会使用 Orion 的解决方案,但需要稍作改动以补偿返回码。

        eval ('(function(){' + code + '})()');
        

        但是,在我看来,从长远来看,将 Javascript 代码分离到外部文件或单独的可调用函数中会更轻松。

        【讨论】:

          【解决方案4】:

          不要。

          你有一个解决方案。

          停下来,继续下一个功能点。

          我知道,它不漂亮,但有更大的问题。

          【讨论】:

            【解决方案5】:

            不确定您是否有答案,但在选择的onclick 函数中,调用onsubmit 而不是submit

            【讨论】:

              【解决方案6】:

              理论上,eval ('function(){' + code + '}()'); 之类的东西可以工作(尽管语法失败)。即使这确实有效,通过选择 onchange 调用 eval 仍然有点像贫民窟。另一种解决方案是以某种方式让 Rails 将 onsubmit 代码注入到 select 标签的 onchange 字段中,但我不确定是否有办法做到这一点。 ActionView 有 link_to_remote,但没有明显的帮助可以在 onchange 字段中生成相同的代码。

              【讨论】:

                【解决方案7】:

                如果您实际上并不想提交表单,而只是调用发生在 onsubmit 中的任何代码,您可以这样做:(未经测试)

                var code = document.getElementById('formId').getAttribute('onsubmit');
                eval(code);
                

                【讨论】:

                • 理论上可行,但我仍然在生产中使用我的原始代码,以避免使用 eval。
                猜你喜欢
                • 2010-11-16
                • 2018-09-01
                • 2018-07-23
                • 2011-03-30
                • 1970-01-01
                • 1970-01-01
                • 2022-11-22
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多