避免形成多个提交并在完成后重新启用

时间:2011-05-11 10:44:00

标签: javascript jquery

我有一个表单,允许查看页面中的数据或根据按下的提交按钮在csv中下载。

由于这是一个数据库查询,我想避免用户多次提交(你知道用户的食指在鼠标左键上有多重。 。)避免数据库过载,也让用户更轻松......

我写了这个小jQuery代码,用 Processing替换提交按钮,请等待和经典动画旋转gif

$(document).ready(function(){
    //preload wait img
    var $waitImg = $('<img />').attr('src', '/img/wait.gif')
    $('.wait').click(function(){
        $(':submit').hide();
        $(this).after($('<span>Processing, please wait...</span>').prepend($waitImg));
    });
});

一切正常但有一些缺点:

  • 当用户看到结果然后按浏览器的后退按钮时,他将再次获得处理,请等待句子并且没有提交按钮(如果他只想编辑某些内容并进行新查询,该怎么办)
  • 在提示用户下载CSV文件后,他继续被告知等待......

解决方案可能是检测用户回来或下载盯着或以其他方式告诉他工作正在进行中。

越简单越好。

2 个答案:

答案 0 :(得分:1)

  

当用户看到结果然后按浏览器的后退按钮时,他将再次获得处理,请等待句子并且没有提交按钮(如果他只想编辑某些内容并进行新查询,该怎么办)

浏览器正在缓存页面。您可以尝试重置值/删除$(document).ready()中的加载图片,当用户使用onunload诀窍按下后退按钮时,该图片会触发:Is there a cross-browser onload event when clicking the back button?

  

提示用户下载CSV文件后,他不断被告知等待......

如果没有服务器的帮助,将无法检测到这一点。最简单的方法是通过ajax“ping”服务器,服务器将告诉客户端下载是否已启动/发送给用户。这可以通过重复性每隔3秒调用服务器来查看下载是否已启动,如果是,则重置/隐藏加载图像和文本。

你可以使用延迟的jQuery来帮助实现这一简单和良好的语法。

的jQuery

function downloadStarted()
{
  var $def = $.Deferred();

  var check = function() {
     $.get('/ajax/check-download-status', function(response) {
        if (response.started)
        {
          $def.resolve();
        }
        else
        {
          //Check again in 3 seconds
          setTimeout(check, 3000);
        }
      }, 'json');
  };

  check();

  return $def.promise();
}

<强>用法:

var success = function() { /* reset/hide loading image */ }
$.when(downloadStarted()).then(success);

PHP /服务器端

在服务器端,ajax / check-download-status将如下所示:

session_start();
$json['started'] = 0;
if ($_SESSION['download_started']) $json['started'] = 1;
return json_encode($json);

显然,当您的csv文件发送到客户端时,请将$_SESSION['download_started']设置为1。

答案 1 :(得分:0)

发现这个:

Detecting the File Download Dialog In the Browser

这是我的代码基于它:

<强> HTML

<form ...> 
    <fieldset> 
    ...
    <div> 
        <input class="wait" id="submit" name="submit" type="submit" value="View" /> 
        <input class="wait" id="submit" name="submit" type="submit" value="Download as CSV" /> 
    </div> 
    </fieldset> 
</form> 

<强>的javascript

$(document).ready(function(){
    var cookieCheckTimer;
    var cookieName = 'download_token';
    var $wait = $('.wait');
    var $waitMsg = $('<span>Processing, please wait...</span>').prepend(
        $('<img />').attr('src', '/img/wait.gif').css({
            'vertical-align': 'middle',
            'margin-right': '1em'
        }));
    //add hidden field to forms with .wait submit
    $wait.parent().each(function(){
        $(this).append($('<input />').attr({
            'type': 'hidden',
            'name': cookieName,
            'id': cookieName
        }));
    });
    $wait.click(function(){
        var token = new Date().getTime();
        //set token value
        $('#' + cookieName).val(token);
        //hide submit buttons
        $(':submit').hide();
        //append wait msg
        $(this).after($waitMsg);

        cookieCheckTimer = window.setInterval(function () {
            if ($.cookie(cookieName) == token){
                //clear timer
                window.clearInterval(cookieCheckTimer);
                //clear cookie value
                $.cookie(cookieName, null);
                //detach wait msg
                $waitMsg.detach();
                //show again submit buttons
                $(':submit').show();
            }
        }, 1000);
    });
});

服务器端如果在请求参数中找到download_token密钥,则会设置包含其名称和值的Cookie。

这是我的控制器__before__的python(pylons)代码:

<强>蟒

cookieName = 'download_token'
#set file download coockie if asked
if cookieName in request.params:
    response.set_cookie(cookieName,
        #str: see http://groups.google.com/group/pylons-discuss/browse_thread/thread/7d42f3b28bc6f447
        str(request.params.get(self._downloadTokenName)),
        expires=datetime.now() + timedelta(minutes=15))

我将Cookie过期时间设置为15分钟,以便不填写客户端Cookie,您可以根据任务所需的时间选择合适的持续时间。

这也适用于浏览器后退按钮问题,因为返回时会找到cookie并恢复按钮。