0

I have a very ajax heavy website, its basically a SPA, but I wont label it that since it doesn't follow all the guidelines.

I have a store, which resides in a div on the page and its updated via jquery ajax and knockout. One of the final things I need is the ability to download pdf's from a third party web service. I am able to download the pdf using the following

<form action="/Dashboard/DownloadPdf" method="POST" style="display:none;" id="ProductDownload" data-bind="with: ProductToDownload">
    <input type="hidden" id="Name" name="Name" data-bind="value: Name"/>
    <input type="hidden" id="FileName" name="FileName" data-bind="value: FileName"/>
    <input type="hidden" id="Id" name="Id" data-bind="value: Id"/>
    <input type="hidden" id="Date" name="Date" data-bind="value: Date"/>
    <input type="hidden" id="Number" name="Number" data-bind="value: Number"/>
</form>

And I use knockout to populate ProductToDownload before submitting the form.

$('form').submit();

What I want to be able to do is give the user some indication that an action is taking place and has finished, such as throwing up a loader while the form is being fetched.

My problem lies with the ability to know when the form.submit() as finished.

How can I know when my form submit has finished so I can clean up loaders and such.

Also below is the code I use to pull down the pdf, it would be great if someone would verify I am doing it correctly.

[HttpPost]
    public void DownloadPdf(Product product)
    {
        var asr = Services.GetProduct(Token, product);
        Response.ClearHeaders();
        Response.ClearContent();
        Response.AppendHeader("Content-Disposition","attachment; filename=" + product.FileName);
        Response.ContentType = "application/pdf";
        Response.BinaryWrite(asr.Payload.Pdf);
        Response.End();
    }

Keep in mind that we do not store the PDF's locally, we request them from another service.

Zholen
  • 1,762
  • 2
  • 24
  • 53
  • Are you using JQuery to submit the form via AJAX? – Justin Russo Nov 06 '13 at 02:10
  • No, as it was my understanding that if i did that I wouldnt be able to return the pdf – Zholen Nov 06 '13 at 02:12
  • 1
    There's a similar question over here: http://stackoverflow.com/questions/1106377/detect-when-browser-receives-file-download – Cᴏʀʏ Nov 06 '13 at 02:15
  • @Cory The link you posted looks like a good answer, but can I use it if I am already sending a complex type? Can my signature be DownloadPdf(Product product, string downloadToken) ? I cant modify the product object its already expecting. – Zholen Nov 06 '13 at 02:56
  • @Cory if you Move your comment to a Answer I will accept it. – Zholen Nov 06 '13 at 16:12
  • @Zholen: I didn't really do any work other than finding the article. If I were you, I would mark your own answer as accepted and upvote the answer from the article I linked. I think this gives the credit where credit is due -- I'm not expecting any rep for this. Thanks though! – Cᴏʀʏ Nov 06 '13 at 16:18

1 Answers1

0

Cory's link from the comments was a great solution! I had to tweak it some since my call was already expecting a complex type and i could not pass any additional parameters.

    function Download() {
    $('.storeView').before($('#Loading').html()); //Put up loading

    var attempts = 20;
    var cookieId = vm.ProductToDownload().FileName; // This name is being sent in the parameters
    var downloadTimer = setInterval(function() {
        var token = $.cookie(cookieId); // I used the jquery.cookie.js plugin to clean things up
        if (token || attempts === 0) {
            $('.k-loading-mask').remove();
            clearInterval(downloadTimer);
            $.removeCookie(cookieId);
        }
        attempts--;
    }, 1000);
    $('form').submit();
}

Then on my Server

public ActionResult Download(Product product)
{
    .....
    System.Web.HttpContext.Current.Response.Cookies.Add(new HttpCookie(product.FileName, product.FileName));
    .....
}
Zholen
  • 1,762
  • 2
  • 24
  • 53