0

I have a web app where the user can create invoices. The application is based on jquery and ajax calls. The process flow to introduce the problem:

  1. User fill in the invoice form. Tick a checkbox to create a PDF.
  2. User clicks on the "Create invoice" button
  3. The application insert the invoices' data to the database with an AJAX call
  4. If the call returned successfully a FORM will be created with the invoices' data and it will be automatically submitted and than removed from the DOM. In this step the invoice will be created on the fly and the browser will start downloading the PDF.
  5. In the meantime the last AJAX call (getDeliveries()...) removes the invoice form and reloads the starting screen.

The problem is that the last ajax call canceled (it can be seen in Chrome error console) and the screen will be blank. No results loaded and it is so frustrating. I think the problem is that the form submission and the ajax call is overlapping.

Do you have any idea how to solve this issue? Any other solution to force download the file (where I can waiting to start to call the getDeliveries function)?

Here is the js code what I created:

        var str = $("#invoiceForm").serialize();

    $('#invoiceForm input[disabled], #invoiceForm select[disabled]').each( function() {
        str = str + '&' + this.id + '=' + $(this).val();
    });
    //Save or update the invoice first
    $.ajax({
        type: "POST",
        url: BASEURL+"productFuncs/setInvoice.php",
        data: "f="+f+"&print=1&"+str,
        success: function(data, textStatus){
            $("#addAjax").hide();
            $("#addButton").show();

            if ( !isNaN( parseInt(data) ) ) {

                //Print out                 
                if ( $("#pdf").is(":checked") ) {
                    //Print out to PDF      
                    var url = BASEURL+"productFuncs/getPrintOut.php";       

                    var inputs = '<input type="hidden" name="f" value="'+ f +'" />' +
                                '<input type="hidden" name="pdf" value="1" />' +
                                '<input type="hidden" name="copy" value="2" />' +
                                '<input type="hidden" name="orig_id" value="'+ data +'" />';

                    $('#invoiceForm input[disabled], #invoiceForm select[disabled]').each( function() {
                        inputs+='<input type="hidden" name="'+ this.id +'" value="'+ $(this).val() +'" />';
                    });                 

                    var pairs = $("#invoiceForm").serializeArray();
                    $.each( pairs, function(i, field) { 
                        inputs+='<input type="hidden" name="'+ field.name +'" value="'+ field.value +'" />'; 
                    });

                    //send request
                    $('<form action="'+ url +'" method="post">'+inputs+'</form>').appendTo('body').submit().remove();

                }
                else {              

                    //Print out to HTML and directly to printer
                    $.ajax({
                        type: "POST",
                        url: BASEURL+"productFuncs/getPrintOut.php",
                        data: "f="+f+"&copy=2&orig_id="+data+"&"+str,
                        dataType: "html",
                        success: function(data, textStatus){
                            $("#printOut").html(data);
                            //Delay because of the IE
                            var t=setTimeout(' $("#printedArea").print() ', 3000);                          
                        }
                    });
                }

                $('#newDeliveryNote, #leftSide, #rightSide').toggle();
                getDeliveries(f, '');                   
            }
            else {
                //Not enough quantity - we have to set the ID nothing to save the delivery again
                $('#invoiceForm input[name=id]').val("");
                alert( data );
            }


        }
    });

AJAX call in getDeliveries function:

        $.ajax({
        type: "GET",
        url: BASEURL+"productFuncs/getDeliveries.php",
        data: "d="+d+"&f="+f,
        success: function(data, textStatus){
            $("#rightSide").html(data);

            $("#cover").hide();     
            $("#ajaxMessage").fadeOut(200);
            jsLink();       
        }
    });
Tamas
  • 33
  • 5
  • Why you need to create this form on the fly? Can't you just send this request in a new window o create a link that the user clicks (or triggered automatically with jquery) to download the pdf? – davidbuzatto Aug 01 '12 at 21:46
  • Because I do not save the PDF to the server. I can force the browser to download the PDF in this way. Googled a lot but did not find other solution. This solution is from the Filament Groups' website. – Tamas Aug 01 '12 at 21:57

1 Answers1

1

I think that your form submission is the problem. You can create a link with the url to access the resource that creates the pdf, trigger a click and them remove it.

Something like:

// of course, you will change href to the url that will be used to generate the pdf
$( "body" ).append( "<a id='downloadLink' href='www.stackoverflow.com' target='_blank'></a>" );
$( "#downloadLink" )[0].click();
$( "#downloadLink" ).remove();

jsFiddle: http://jsfiddle.net/davidbuzatto/QGs5n/

Edit: To use POST, I think that this will help you. I found it here: Download File Using Javascript/jQuery

Community
  • 1
  • 1
davidbuzatto
  • 9,207
  • 1
  • 43
  • 50
  • Looks promising! But I need POST method because of the lot of data in the form. Do you have any idea for a POST method? – Tamas Aug 01 '12 at 22:06
  • I think I found a jQuery plugin that do the work. I posted in my answer. – davidbuzatto Aug 01 '12 at 22:11
  • Thanks David! That plugin uses the same method as I wrote (and another iframe method in some specific cases). BUT! Maybe I found something in the source of the plugin. I can setup a setTimeout and watching the downloading. If the file download completed I can fire the getDeliveries. I will try it and come back with the results. – Tamas Aug 01 '12 at 22:21
  • Hi Tamas. To observe the file download, maybe you can use what was discussed here: http://stackoverflow.com/questions/2343418/browser-event-when-downloaded-file-is-saved-to-disk The problem is different, but I think you can use some ideas to accomplish your task. – davidbuzatto Aug 01 '12 at 22:25
  • Hi David. This method: http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx is working perfectly. I adopted it to my app and ported to PHP. I give you the point because you showed me the way to the right direction. – Tamas Aug 03 '12 at 07:40
  • Hi Tamas. I'm glad that you were able to solve your problem! Best regards! – davidbuzatto Aug 03 '12 at 13:57