提交表单后如何关闭此窗口?

Posted

技术标签:

【中文标题】提交表单后如何关闭此窗口?【英文标题】:How can I close this window after submitting the form? 【发布时间】:2018-03-05 08:00:43 【问题描述】:

我有一个呈现部分的 JQuery 弹出窗口:

$(document).ready(function () 
  editUserItem();
);

    function editUserItem()
        var myWindow = window.open("", "MsgWindow", "width=600,height=400");
        myWindow.document.write("<%= j render partial: 'edit_user_item_form', locals: item: @user_item%>"); 
    


这是部分中的表格:

<div class="edititem">
    <h4>Edit "<%= item.name %>"</h4>
    <%= form_for current_user.user_items.build, url: user_items_path, method: :patch,remote: true, authenticity_token: true do |f| %>
        <%= f.hidden_field :id, value: item.id %>
        <%= f.text_field :name, value: item.name, class: "txt" %>
        <%= f.number_field :price, min: 0.00, :step => "0.01", value: item.price, class: "price"%>
        <%= f.select :category_id do %>
            <% current_user.categories.each do |category| %>
                <%= content_tag(:option, category.name, value: category.id) %>
            <% end %>
        <% end %>
        <%= f.submit "Update Item", class: 'submit-edit' %>
    <% end %>
</div>

我想在提交表单后关闭此窗口。我意识到 window.close() 只能用于已经用 window.open() 打开的窗口,但事实就是这样。这是我尝试过的:

$(document).ready(function () 
  editUserItem();
  closeWindow();
);

function editUserItem()
    var myWindow = window.open("", "MsgWindow", "width=600,height=400");
    myWindow.document.write("<%= j render partial: 'edit_user_item_form', locals: item: @user_item%>"); 
    closeWindow();


function closeWindow()
    $('.submit-edit').click(function() 
      myWindow.close();
    ); 

这不起作用。我不确定我的 JS 脚本是否可以“看到”我在表单中引用的提交按钮类,而是在提交时弹出窗口只是呈现默认的“update.html.erb”。

我还刚刚发现了模态窗口...据我所知,它会迫使用户在返回原始页面之前与其进行交互。在这种情况下这会更合适,我该如何实现呢?

@guest271314 的脚本经过一些修改以适合我的 Rails 应用程序后工作,但它仍然没有关闭窗口......也许我没有把它贴在正确的位置?我把它放在我的 form_for 下:

<div class="edititem">
    <h4>Edit "<%= item.name %>"</h4>
    <%= form = form_for current_user.user_items.build, url: user_items_path, method: :patch,remote: true, authenticity_token: true do |f| %>
        <%= f.hidden_field :id, value: item.id %>
        <%= f.text_field :name, value: item.name, class: "txt" %>
        <%= f.number_field :price, min: 0.00, :step => "0.01", value: item.price, class: "price"%>
        <%= f.select :category_id do %>
            <% current_user.categories.each do |category| %>
                <%= content_tag(:option, category.name, value: category.id) %>
            <% end %>
        <% end %>
        <%= f.submit "Update Item", class: 'submit-edit' %>
    <% end %>
</div>

<script>
  window.opener.console.log("form.html loaded");
  //const form = document.forms[0];
  form.onsubmit = (event) => 
    event.preventDefault();
    fetch("<%= user_items_path %>", 
        method: "PATCH",
        body: new FormData('<%= form %>')
      )
      .then(response => response.ok)
      .then(submitted => 
        if (submitted)
          window.close()
      )
      .catch(err => 
        window.opener.console.error(err)
      )
  
</script> 

【问题讨论】:

在附加到.submit-editclick 处理程序中的window.close 调用之前放置一个console.log('was called'),以确保在单击完成时调用它。单击.submit-edit 时,was called 是否会记录到控制台 @Oluwafemi Sule 不,它没有被记录 为什么const form = document.forms[0]被评论了? "&lt;%= user_items_path %&gt;"'&lt;%= form %&gt;' 在打开 document 时是否正确反映在 &lt;script&gt; 上?当值是服务器的完整路径和new FormData(form) 时会发生什么? 因为除非我将自己的表单插入到您的脚本中,否则表单不会提交。我更新了我的问题以包含整个表单 + 脚本 const form = document.forms[0] 仍应在打开的document 中引用&lt;form&gt;。如果不定义form,标识符将是未定义的。 【参考方案1】:

您可以阻止&lt;form&gt;提交的默认动作,使用FormDatafetch()提交&lt;form&gt;元素。在链式.then() 调用window.close()

<!DOCTYPE html>
<html>
<form>
  <input type="text">
  <input type="submit">
</form>
<script>
  window.opener.console.log("form.html loaded");
  const form = document.forms[0];
  form.onsubmit = (event) => 
    event.preventDefault();
    fetch("/path/to/server", 
        method: "POST",
        body: new FormData(form)
      )
      .then(response => response.ok)
      .then(submitted => 
        if (submitted)
          window.close()
      )
      .catch(err => 
        window.opener.console.error(err)
      )
  
</script>   
</html>

【讨论】:

老实说,我不知道这意味着什么,而且它似乎是为了复杂而故意复杂的。当然有一个更简单的解决方案。我真的只需要知道在哪里粘贴 window.close().... @Jim 该代码是 HTML document 的示例,包括要提交的 &lt;form&gt; 元素。而不是提交&lt;form&gt;,当用户点击&lt;input type="submit"&gt;POSTFormData对象表示&lt;form&gt;到服务器时,在服务器成功响应时关闭打开的window。代码实现预期的结果描述在顶上。不确定您所说的“复杂”或“更简单”是什么意思。在尝试不同的方法时没有考虑这些概念,只考虑满足要求。您也可以使用postMessagestorage 事件来满足要求。 好的,请原谅我缺乏 javascript 技能。所以我换掉了一些东西来适应这个脚本到我的应用程序中,但是现在在提交表单时我收到了一个“ActionController::InvalidAuthenticityToken”错误,并且我的表单不再被提交。我最初遇到了这个错误,并通过在我的 rails 表单中添加 'authenticity_token: true' 来修复它。也许我需要在我的 FormData 对象中添加类似的东西? HTML 中的示例&lt;form&gt; 没有设置name 属性。将name 属性包含在服务器期望的HTML 值中,请参阅plnkr.co/edit/zsAEes3b25LVtUv6P4dD?p=preview 以获取方法演示。提交&lt;form&gt; 后,一条消息会记录在window.openerconsole,然后window 应该关闭。 你的意思是这样吗?我做到了,抱歉我没有发布我更新的表格

以上是关于提交表单后如何关闭此窗口?的主要内容,如果未能解决你的问题,请参考以下文章

jsp 中用js提交表单并关闭本窗口的问题。

提交表单后模态弹出窗口未正确关闭

jsp 中用js提交表单并关闭本窗口的问题

表单提交后数据库插入数据出现乱码怎么解决

提交表单后如何防止模式关闭

关闭表单提交时打开的弹出窗口并触发单击父窗口