无需刷新提交模态表单

3 投票
3 回答
13875 浏览
提问于 2025-04-18 15:04

我有一个弹出窗口,当我想在我的仪表板上添加一个新项目时会出现这个窗口。我已经用jquery的post方法让它工作了,但我无法阻止页面刷新。我想要的是在项目成功添加到数据库后,显示一个成功的消息,并在几秒钟后关闭弹出窗口,而不是刷新弹出窗口的父页面。

这是我的 modal

<div class="modal fade" id="add-project-dialog" tabindex="-1" role="dialog" aria-labelledby="basicModal" aria-hidden="true">
<div class="modal-dialog">
    <div class="modal-content">
        <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&amp;times;</button>
        <h4 class="modal-title" id="myModalLabel">Add a new Project</h4>
        </div>
        <div class="modal-body">
            <h3>New Project:</h3>
            <form class="form-horizontal" id="add-project-form" action="/projects/add" method="POST">
        <fieldset>
        <!-- Text input-->
        <div class="form-group">
          <label class="col-md-4 control-label" for="name">Project Name</label>
          <div class="col-md-4">
          <input id="name" name="name" type="text" placeholder="" class="form-control input-md">

          </div>
        </div>

        <!-- Text input-->
        <div class="form-group">
          <label class="col-md-4 control-label" for="description">Project Description</label>
          <div class="col-md-4">
          <input id="description" name="description" type="text" placeholder="" class="form-control input-md">

          </div>
        </div>

        <!-- Text input-->
        <div class="form-group">
          <label class="col-md-4 control-label" for="project_state">Project State</label>
          <div class="col-md-4">
          <input id="project_state" name="project_state" type="text" placeholder="" class="form-control input-md">

          </div>
        </div>

        </fieldset>
                            <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

                <button id="add-btn" class="btn" type="submit">Add</button>
                     </div>

            </form>
        </div>


</div>

这是我的 project-dashboard.js

AddProject = function(){
  $(document).ready(function() {
   $("#submit").submit(function(event){
       event.preventDefault();
       $.ajax({
           url: "/projects/add",
           type:"POST",
           data:
           {
            'name': $('#name').val(),
            'description': $('#description').val(),
            'project_state': $('#project_state').val()
           }
           });
        });
   });
 }

我的 views.py

class AddProject(webapp2.RedirectHandler):
    def get(self):
    template_values = {
        #'greetings': greetings,
        #'url_linktext': url_linktext,
        }
    path = os.path.join(os.path.dirname(__file__), '../templates/project-add.html')
    self.response.write(template.render(path, template_values))

def post(self):
    project = Project()
    project.name = self.request.get('name')
    project.description = self.request.get('description')
    project.project_state = self.request.get('project_state')
    time.sleep(2)
    project.put()
    self.redirect('/projects')

我尝试过去掉 self.redirect('/projects'),但这样只会让我进入一个空白页面,那个页面是 /projects/add(这是表单中的动作)。

3 个回答

0

这里有一段代码,可以让你在不刷新页面的情况下关闭弹窗,并且在按下回车键时提交弹窗内容并关闭,依然不刷新页面。

我在我的网站上设置了多个弹窗,其中一些弹窗在提交时会处理数据,而有些则不会。我为每个需要处理数据的弹窗创建了一个独特的ID。例如,在我的网页中:

HTML(弹窗底部):

 <div class="modal-footer form-footer"><br>
              <span class="caption">
                <button id="PreLoadOrders" class="btn btn-md green btn-right" type="button" disabled>Add to Cart&nbsp; <i class="fa fa-shopping-cart"></i></button>     
                <button id="ClrHist" class="btn btn-md red btn-right" data-dismiss="modal" data-original-title="" title="Return to Scan Order Entry" type="cancel">Cancel&nbsp; <i class="fa fa-close"></i></a>
              </span>
      </div>

jQUERY:

$(document).ready(function(){
// Allow enter key to trigger preloadorders form
    $(document).keypress(function(e) {       
      if(e.which == 13) {   
          e.preventDefault();   
                if($(".trigger").is(".ok")) //custom validation dont copy
                   $("#PreLoadOrders").trigger("click");
                else
                    return;
      }
    });
});

正如你所看到的,这个提交操作会进行数据处理,所以我为这个弹窗写了这段jQuery代码。现在假设我在这个网页中还有另一个弹窗,但这个弹窗不需要处理数据。因为一次只能打开一个弹窗,所以我在一个所有页面都能使用的全局php/js脚本中添加了另一个 $(document).ready(),并给弹窗的关闭按钮添加了一个叫: ".modal-close" 的类:

HTML:

<div class="modal-footer caption">
                <button type="submit" class="modal-close btn default" data-dismiss="modal" aria-hidden="true">Close</button>
            </div>

jQuery(包含global.inc):

  $(document).ready(function(){
         // Allow enter key to trigger a particular class button 
        $(document).keypress(function(e) {
                if(e.which == 13) {
                   if($(".modal").is(":visible")){   
                        $(".modal:visible").find(".modal-close").trigger('click');
                    }
                }
         });
    });

如果你按照这些步骤操作,你的弹窗在打开时就不会刷新页面了。

1

编辑:经过一些调试,发现问题在于使用了正确的id和合适的位置放置javascript代码,这一点在评论中提到过。

首先,避免页面刷新其实很简单,只需要确保不让默认事件运行;因为你在用jQuery,我建议你使用return false来结束这个函数,这样既可以“阻止默认行为”,又可以“停止事件传播”

所以你首先要检查一下你的javascript代码是否真的在运行,或者在执行过程中有没有出错。如果一切正常,最糟糕的情况就是项目没有被添加(可能是服务器那边出错),但页面应该不会刷新。

你的服务器端代码和页面刷新没有关系(前提是它被正确处理了),所以返回的结果其实不太重要。我建议返回新项目的id(这样你可以提供一个新创建项目的链接之类的),不过我偏题了……

1

问题在于,你把 .ready(foo) 这个处理程序放在了 AddProject 函数里面。我猜当调用 AddProject 时,文档已经加载完成了。

另一个问题是,在你的 HTML 代码中,表单的 ID 是 add-project-form,所以你应该使用 $("#add-project-form"),而不是 $("#submit")

$(document).ready(function () {
   $("#add-project-form").submit(function(event){
       event.preventDefault();
       $.ajax({
           url: "/projects/add",
           type:"POST",
           data:
           {
            'name': $('#name').val(),
            'description': $('#description').val(),
            'project_state': $('#project_state').val()
           }
           });
        });
   });
});

ready 处理程序放到 AddProject 函数外面,这样就能正常工作了(submit 处理程序会被添加)。

撰写回答