0

I am using an Jquery Ajax call to deliver a file download to site users. The process is:

1)Users select various files they want, by clicking on them 2)I store their selections in a mysql database 3)I have a div panel on the right of the page that lists their files (like a basket) and provides a download button 4)If they click on the button, it runs a jquery ajax call to a php file to create a zip file, load all their selected files into the zip and then close the zip. Finally return the zip filename in json. 5)success: then fires a window.open to force the download

This all basically works, but there's a weird problem I can't work out and it's killing me!

Here's the bits of code:

First javascript:

//download files in a zip
$("#zipdownload").click(function(){
 $.ajax({
    type: "GET",
    url: "zipdload.php",
    dataType: "json",
    cache: false,
    success: function(data) {

//opens a small window for IE security thing
    window.open(data.archive,'download','left=20,top=20,width=300,height=20,toolbar=0,resizable=0');    
    // then clears all the divs to simulate the bag emptying
        $('#bagCounter').text("Empty!");
        $('#zipdownload').text(""); 
        $('#item-list').text("");           
        }
});

});

Then the layout:

//styled containers to create a sliding panel with a clickable tab
<div id="rightpanelouter">
<div id="rightpanelinner">
<?php if ($_SESSION['username']){
    echo $_SESSION['username'].'<br>Toolbox';
    };
?>

<div id="bagContents">
  <div id="item-list">
            <br> Show Bag
            //PHP to generate list of files
       </div>
       <br><br>
       <div id="zipdownload" style="cursor:pointer;">
           //this element has the action attached to fire function.
               <?php 
           if ($numOfBagDocs != 0){
               echo 'Download';
       }
        ?>
   </div>
</div>

If anyone is interested I can attach the PHP script too but I'm guessing that's not the problem.

The problem:

The script appears to run twice (at least).

I initially appended the zip filename with a now() stamp so they were always different. but I noticed sometimes the window.open tried to download a file with a now() stamp 1sec different to the saved file.

I then tried to change to a rand() number and that showed two different random numbers!

So I removed the append so the filename was always the same (just appended with the username) and that downloaded but simply kept appending the same zip file with new entries. All that would do is make the zip grow and grow.

So I tried to put a 'file_exists' and 'unlink in to delete the file before creating a zip. All that seemed to do was delete the file AFTER creating the zip and before the jscript download started !!! :-(

All this tells me the script is being called at least twice.

I've seen many entries similar to this but I can't seem to understand whether they apply to my problem. Once suggestion was to chain an 'unbind' before the click function and that just stopped it working, so no good.

The HTML I've attached is pretty much straight after the body tag and there are no other javascript calls within this section.

So apologies if there's a really dumb mistake here, but I've now spent many hours scouring around and just can't work it out.

I would REALLY appreciate any help. Thank you in advance.

TonyJ
  • 23
  • 1
  • 4
  • my guess is that when you make the initial $.ajax() GET request, your php file is returning a zip file and your browser is reading it and trying to automatically handle it. Then in your ajax response you are using that window.open to trigger it again – CrayonViolent Feb 01 '11 at 22:02
  • Hi, thanks for taking the time to comment. The php file is returning the filename within a json wrapper rather than a straight response, so that shouldn't be the problem. Thanks anyway. I'm still trying to work it out, one theory someone mentioned that might be relevant is that if I was calling this page from another, I might be loading jquery itself twice. So I'm just about to check that out. – TonyJ Feb 02 '11 at 16:19
  • OK, so I definitely done something stupid. I put in a few window.alerts on my ajax calls, not just this one and they're all doing it. Interestingly the loop count doubles each click. So I'm going to look for this symptom in other entries. If anyone knows what this is now, please let me know. I feel I'm getting closer! – TonyJ Feb 02 '11 at 17:07
  • SO I've added alerts at various events and shown that it's only an issue with .ajax calls and .load only fires once. Have browsed around and found a suggestion to use .one('click', function.. to call the ajax. So I'm going to try that now. – TonyJ Feb 02 '11 at 18:21

2 Answers2

2

So I've got to the bottom of it, without really understanding why. Lack of proper javascript education I guess! The problem was related to me loading a page from another page using a .load and linking the relevant JScript in the second page. However the DIV being clicked was inside the initial page (I remember now I moved it for aesthetic reasons).

So I moved the click function to the Jscript being called from the initial page itself and he presto it now only fires once!

So I don't understand why that would make a difference but it does, so I happy I can proceed.

Thanks for reading and I hope it helps someone else one day !

TonyJ
  • 23
  • 1
  • 4
1

I had the same issue. I solved it by adding

evt.stopImmediatePropagation();

to the function. Of course you have to add the evt to the function like:

$(document).on("click", "a.className", function (evt) {

    evt.stopImmediatePropagation();

    $.fileDownload($(this).prop('href'), {
        preparingMessageHtml: "File prepared...",
        failMessageHtml: "Error!",
    });

    return false;
});

It seems to occur, because there are nested elements which fire this event many times. See jQuery Click fires twice when clicking on label

Community
  • 1
  • 1
Dimitri
  • 11
  • 1