Link to home
Start Free TrialLog in
Avatar of Robert Granlund
Robert GranlundFlag for United States of America

asked on

AJAX to call a page

AJAX to call a page.  I have a button that when clicked it will download a csv doc.  I need to attache an AJAK Call so as to return/ download an additional CSV.  The AJAX Call to the page works but it is not downloading the CSV.

   <script>
                                                $(document).ready(function () {
                                                    $('#order_button').click(function () {

                                                        $.ajax({
                                                            url: '<?php echo base_url(); ?>download_order.php',
                                                            method: 'post',
                                                            data: {term: $('#download_child').val()},
                                                        })
                                                    });
                                                });
                                            </script>
                                            <form action="<?php echo base_url('download.php'); ?>" method="POST">
                                                <button type="submit" id="order_button" name="download_csv" class="download-csv-btn"><i class="fa fa-download"></i> Download All Data</button>
                                                <input type="hidden" value="True" id="download_child" />
                                            </form>

Open in new window


downlod_order.php
$db = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // turn on exceptions



try {


     $sql = "SELECT * FROM ItpChildren";
    
    $returns = $db->prepare($sql);

    $returns->execute();
} catch (exception $e) {
    echo "Search Query Failed: " . $e->getMessage();
}

$results = $db->query( $sql )->fetchAll( PDO::FETCH_GROUP|PDO::FETCH_OBJ );

//var_dump( $results ); die();
  
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=ItpChildren.csv');
        $output = fopen("php://output", "w");

        fputcsv($output, array('ID', 
            'Total Joint Replacement Prehab / Rehab',
            'Sports Medicine Prehab / Rehab',
            'Orthopedic Trauma  Rehab',
            'Non-Surgical Orthopedic Prehab / Rehab',
            'Spine Prehab / Rehab',
            'Other Use',
            'Other Notes',
            'ROM3 PortableConnect TM Cycle', 
            'Number of ROM3 PortableConnect TM Cycle',
            'ROM3 Pro Cycle (Recumbent Bike)',
            'Number of ROM3 Pro Cycle (Recumbent Bike)',
            'Payer Mix',
            'Medicare Percentage',
            'Medicaid Percentage',
            'Medicare Reinbursments',
            'Medicaid Reimbursement', 
            'Medicare Comment',
            'Medicaid Comment',
            'Private Insurance Percentage',
            'Private Insurance Reimbursement',
            'Private Insurance Comment',
            'Pay Cash Percentage',        
            'Patient Pay Comment',    
            'Workers Comp Percentage',        
            'Workers Comp Comment', 
            'TRICARE Percentage',
            'TRICARE Comment',
            'VA Health Care Percentage',
            'VA Health Care Comment',
            'Signature'
        ));

         while ($row = $returns->fetch(PDO::FETCH_GROUP)): 
            fputcsv($output, $row);
        endwhile;

        fclose($output);
      

Open in new window

Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

OK. A few issues with your code. You seem to be mixing up a prepared statement and a standard query. You're also calling fetchAll on the standard query, and then trying a while loop over the prepared query.

Your AJAX call is POSTing a 'term' value to your script, but you don't seem to using it anywhere. Your AJAX script is also not handling any response back from the server.

If you're not going to be dealing with user input such as POST or GET, then a standard query is fine. If you are dealing with input, then you should use a prepared query. Both execute() and query() return a PDO Statement, so you could then call either fetchAll() or fetch() on them.

However, you're grouping the results from the query (PDO::FETCH_GROUP), which means you can't use fetch() - you'll need to use fetchAll(), and if you do that you'll need to use a foreach loop instead of a while loop.

When you fetchAll with FETCH_GROUP, you will get back an array of arrays grouped by the first column in your query. You're using SELECT *, so it's likely that the first column back would be the primary key, which makes grouping pointless as the Primary is unique, so everything would be a group of one.

Finally, you're setting the default Fetch mode to OBJECT, which means you'll receive Objects back, but fputcsv expects Arrays. Either set the default mode to PDO::FETCH_ASSOC or pass that into the fetch() methods.

Ignoring the GROUP options and the POSTed data for a minute, have a look at this:

error_reporting(E_ALL);
ini_set('display_errors', 1);

include 'db.php'; // connect to the db

$results = $db->query("SELECT col1, col2, col3 FROM yourTable"); // select your data

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename=ItpChildren.csv');

$output = fopen("php://output", "w");

fputcsv( $output, array( 'Column 1', 'Column 2', 'Column 3' ) ); 

while ( $row = $results->fetch(PDO::FETCH_ASSOC) ): 
    fputcsv( $output, $row );
endwhile;

fclose($output);

Open in new window

Before messing around with AJAX, I would just call your script directly. You can also comment out the 2 header() lines so you'll see the data being displayed in your browser instead of being written to a file.

One other to bear in mind - when using fputcsv, you line endings will be just a NewLine. This is fine on Unix based systems, but Windows won't like it - that expects CarriageReturns. If that's a problem, you may have to switch to an alternative file writing technique.
Avatar of Robert Granlund

ASKER

The following works correctly when accessed directly:

$db = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // turn on exceptions

$sql = "SELECT * FROM ItpChildren";

    
$results = $db->query($sql);

//var_dump( $results ); die();
  
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=ItpChildren.csv');
        $output = fopen("php://output", "w");

        fputcsv($output, array('ID', 
            'Total Joint Replacement Prehab / Rehab',
            'Sports Medicine Prehab / Rehab',
            'Orthopedic Trauma  Rehab',
            'Non-Surgical Orthopedic Prehab / Rehab',
            'Spine Prehab / Rehab',
            'Other Use',
            'Other Notes',
            'ROM3 PortableConnect TM Cycle', 
            'Number of ROM3 PortableConnect TM Cycle',
            'ROM3 Pro Cycle (Recumbent Bike)',
            'Number of ROM3 Pro Cycle (Recumbent Bike)',
            'Payer Mix',
            'Medicare Percentage',
            'Medicaid Percentage',
            'Medicare Reinbursments',
            'Medicaid Reimbursement', 
            'Medicare Comment',
            'Medicaid Comment',
            'Private Insurance Percentage',
            'Private Insurance Reimbursement',
            'Private Insurance Comment',
            'Pay Cash Percentage',        
            'Patient Pay Comment',    
            'Workers Comp Percentage',        
            'Workers Comp Comment', 
            'TRICARE Percentage',
            'TRICARE Comment',
            'VA Health Care Percentage',
            'VA Health Care Comment',
            'Signature'
        ));

        while ( $row = $results->fetch(PDO::FETCH_ASSOC) ): 
    fputcsv( $output, $row );
endwhile;

fclose($output);
      

Open in new window


It's just getting the AJAX to call the page so it downloads.
The on click works but the page does not open/download:

 <script>
                                                $(document).ready(function () {
                                                    $('#order_button').click(function () {

                                                        $.ajax({
                                                            url: '<?php echo base_url(); ?>download_order.php'
                                                        })
                                                    });
                                                });
                                            </script>
                                            <form action="<?php echo base_url('download.php'); ?>" method="POST">
                                                <button type="submit" id="order_button" name="download_csv" class="download-csv-btn"><i class="fa fa-download"></i> Download All Data</button>
                                                <input type="hidden" value="True" id="download_child" />
                                            </form>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The only thing that works is the action on the form button.

     <script>
                                                $(document).ready(function () {
                                                    $('#order_button').click(function () {
                                                       
                                                        window.location = '<?php echo base_url('download_order.php'); ?>';
                                                    });
                                                });
                                            </script>
                                            <form action="<?php echo base_url('download.php'); ?>" method="POST">
                                                <button type="submit" id="order_button" name="download_csv" class="download-csv-btn"><i class="fa fa-download"></i> Download All Data</button>
                                            </form>

Open in new window


I'm confused on why this won't work.  The point here is to get 2 CSV's to download.  I will keep messing with it.
Right. The reason why the button on the form is working is because it's a submit button, and you're doing nothing to stop that from firing. To prevent the form from working you'd need to edit your jQuery slightly:

$('#order_button').click(function (e) {
    e.preventDefault();
    window.location = '<?php echo base_url('download_order.php'); ?>';
});

Open in new window

This will now stop the form from submitting and fire your jQuerry method instead. You can't have both working at the same time - it's one or the other.
Is there any way to writ it so when one is don downloading the csv the other will fore and then download that csv?  I need to down load 2 csv's.  Unless there is a way to make the second csv as a next tab on the original.  I may google that.
OK. You have a few options.

1. You have 2 links on your page - each one downloads a specific file.
2. You make one request to the server, and zip up 2 files and then download the zip
3. You write the data to Excel so you can keep the data on 2 separate sheets

CSV files can't have different 'sheets' - it's effectively a flat file format.
Is there documentation on how to do option 2?
2. You make one request to the server, and zip up 2 files and then download the zip
Yeah there is but you'd need to break your requirements into a few parts.

First off, you'd need to create your CSV file (you've already got most of the code to do that)

Then you'd need to create a Zip file containing the 2 files. PHP has the built-in ZipArchive class - you see the docs here. Here's  a page with some simple examples on how to use it -> http://php.net/manual/en/zip.examples.php

Finally, you need to force the browser to download the file. Again, you've sort of got the code for this above (the header() calls). You can see a decent example of this here -> http://thisinterestsme.com/create-zip-file-php/