显示显示表单提交进度的进度条

时间:2014-02-20 08:40:41

标签: javascript jquery asp.net-mvc-3 progress-bar progress

这个问题没有完全回答,请随意捐款!


我正在尝试在提交大型表单时显示简单的progress bar
该表单包含十几个字段,以及一些文件上载字段,用户可以在其中选择图片。然后,当他点击Create按钮时,会提交包含数据和图片的表单,并在DB中创建实体。 (只需点击一下即可提交表格和图片) 一切正常,但我想在提交过程中显示进度条
我发现很多教程解释了如何显示进度条,但我没有找到任何人解释如何显示进度条,指示方法完成的工作百分比,即我希望在提交过程中看到10%,25%等等。

所以,基本上,这就是我所做的:(这是一个ASP.NET MVC3项目)

@model MyModel

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "target-form", enctype = "multipart/form-data" }))
{
    //some Html.TextBoxFor() and other @Html.DropDownListFor

    @Html.TextBoxFor(m => m.File, new { type = "file"})

    <input type="submit" value="Create" class="submitButton" />

    <div id="progressBar"></div>
}

一个基本的控制器

[HttpPost]
public ActionResult Create(MyModel model)
{
    if (ModelState.IsValid)
    {
        DALLayer dal = new DALLayer()
        dal.AddEntity(model);

        return RedirectToAction("Index", "Home");
    }

    return null;
}

是否可以转换显示上传进度状态的<div>中的上一个progressBar


以下是我的要求:

        
  • 没有插件(这是一个个人项目,我想了解自己如何做到这一点)。
  •     
  • 交叉兼容,IE8 +(如果可能)
  •     
  • jQuery ok,但没有Flash。


非常感谢你 !

更新1 这是一个JSFIDDLE,我正在尝试调整this link,但没有成功......如果您认为可以提供帮助,那么欢迎您!

更新2 好的,我用acarlon's answer提交了我的表单XMLHttpRequest,数据正确地发布到控制器。但是,ProgressBar仍然没有出现!
我只需通过以下方式替换传递给控制器​​的数据:

formData = new FormData(document.getElementById("target-form") );
xhr.open("POST", "@Url.Action("MyMethod", "MyController")", true );

并尝试一些不同的标题,例如:

xhr.setRequestHeader("X-File-Name", $('#Files_0__File')[0].files[0].name);
xhr.setRequestHeader("X-File-Size", $('#Files_0__File')[0].files[0].size);
xhr.setRequestHeader("X-File-Type", $('#Files_0__File')[0].files[0].type);
//Also tried with "Content-Length" but it doesn't care about it.

(这里硬编码以确保它具有良好的价值。我会在循环中完成它,因为我会更放心。)

当我提交表单时,XMLHttpRequest发送包含以下字段:

  

readyState:4
  状态:0&lt; =应该是200,对吗?

error handler中,我有以下值:

  

已加载:0
  总数:883526
  键入:“错误”

所以数据会提交给我的控制器,但是我无法显示这个该死的进度条......

3 个答案:

答案 0 :(得分:4)

您可以使用XMLHttpRequest在上传文件时接收更新。还有各种jquery类型的包装器来实现相同的功能。我将使用XMLHttpRequest描述解决方案。 首先拦截表单提交。

$("#target-form").submit(function () {

然后创建XHR请求:

 xhr = new XMLHttpRequest();

然后注册以获得有关进度事件的通知:

xhr.upload.addEventListener( "progress", function ( evt )
{
    if( evt.lengthComputable )
    {
        var progressPercent = ( evt.loaded / evt.total ) * 100;
        showProgress( value );//your function.
    }
}, false );


//Some other events you will probably want to subscribe to
xhr.addEventListener( "load", function ()
{            
    fileUploadComplete( this.responseText );
}, false );

xhr.addEventListener( "error", function ( first, second, third )
{
    fileUploadComplete( "Error: Image format not supported." );
}, false );

xhr.addEventListener( "abort", function ()
{
    fileUploadComplete( "Error: Upload was cancelled. Please try again." );
}, false );

打开XHR传入任何参数(id显示为示例)

xhr.open( "post", '@Html.Raw( @Url.Action( "UploadImage", new { someId = id } ) )', true );

// Set appropriate headers                
xhr.setRequestHeader( "Content-Type", "multipart/form-data" );
xhr.setRequestHeader( "X-File-Name", name );

// Send the file
xhr.send( file );

然后在控制器中:

public ActionResult UploadImage( int someId, HttpPostedFileBase userFile  )
{
    ...    
}

您将在更新处理程序中收到更新。

长时间运行的服务器任务的扩展

如果服务器上有一些长时间运行的任务(例如将数据写入数据库),则需要在服务器上对操作进行分块(以便在完成每个块时提供更新)并实现代码处理可以从javascript查询的长时间运行的服务。见here。基本思想是在服务器端启动任务,并定期检查Javascript的进度。您可能希望有两个单独的进度条,一个用于上载,另一个用于服务器端操作。这为用户提供了更多信息 - 他们将知道文件上传已完成,现在正在进行一些服务器端操作。

答案 1 :(得分:2)

添加一个ajax定时器控件,用于检查服务器的进度并设置时间间隔(比如每2秒)。

在新线程上执行服务器任务。这将导致您的帖子在后台执行长任务时立即返回。启动ajax计时器。

当长任务工作时,让它更新一个包含完成的%工作的会话变量。

当计时器回发到服务器时,从会话变量中获取完成的%工作。

您可以通过设置内部div和外部div来设计进度条。将内部div的宽度设置为完成的%工作:$('#progressBarWorkDone')。css('width',WorkDone +'%');

<div id="progressBar" style="width:400px;">    
<div id="progressBarWorkDone" style="width:0px;height:10px;background-color:red;"><div/> 
<div/>

注意,如果您不知道如何使用计时器控件,您还可以使用setInterval(function(){AJAX CALLBACK GOES HERE},1000)从javascript执行AJAX调用;

然而,已经说过所有这一切只是简单地将动画gif放在进度条div中。隐藏div,然后在单击提交按钮时显示div。

<input type="submit" onclick="$('#progressBar').show();" value="Create" class="submitButton" />

<div id="progressBar" style="display:none;"><img src="myProgressBar.gif" /></div>

答案 2 :(得分:-2)

我曾经使用带有perl后端文件的SWF上传器(当时PHP没有支持上传进程),但看起来它已不再处于活跃开发状态了。

我还没有使用Plupload,但它看起来非常适合你。好像你可以拥有asp backend

祝你好运并保持干爽;)