0

I have a PHP page with an else statement that filters out data from a SQL database by user input; here is some pseudo code:

NextPage.php

    //Include database configuration file
    include('../dbConfig.php'); 

    if(isset($_POST['pageno']) || isset($_POST['FetchFilters'])) {

        $limit = 10;    
        $pageno = $_POST['pageno'];
        $offset = !empty($pageno) ? $pageno: 1;

        $SQL = "

            SELECT * FROM list WHERE wt >= 2.5

        ";

        if($pageno >= 1) {


            if(isset($_POST["shape"])) {

                $shape_filter = implode("','", $_POST["shape"]);

                $SQL .= "

                    AND stoneshape IN('".$shape_filter."') 

                ";
            }

            if(isset($_POST["color"])) {

                $color_filter = implode("','", $_POST["color"]);

                $SQL .= "

                    AND stonecolor IN('".$color_filter."')

                ";

            }

            $SQL .= "

                ORDER BY wt ASC
                LIMIT 
                    $offset,
                    $limit

            ";

            $result = mysqli_query($db, $SQL);

            $output = '';

            if(isset($_POST["shape"]) && isset($_POST["color"]) && $row = mysqli_fetch_array($result)) {

                while($row = mysqli_fetch_array($result)) {

                    $output .=  '

                        <div class="Listing">

                            <!-- landing page -->
                            <a href="#ItemPage" class="ItemLink">

                                //Item Information goes here

                            </a>

                        </div>

                    ';

                }

            }

        } else {

            $output = '

                <h1 class="Error">
                    NO DATA MATCHES THAT
                </h1>

            ';

        }

        echo $output;

    }

?>

Then I have an AJAX call that paginates when an image (with the ID of #Loader in inView); here is it's pseudo code:

InfiniteScroll.js

$(document).ready(function(){

    $('#Loader').on('inview', function(event, isInView) {

        if (isInView) {

            //Pagination    
            var nextPage = parseInt($('#pageno').val()) + 1;

            //Filters
            var shape = get_filter('shape');
            var color = get_filter('color');

            $.ajax({

                type: 'POST',
                url: 'vendors/php/NextPage.php',
                data: {
                    pageno: nextPage,
                    shape: shape,
                    color: color
                },
                async: true,
                cache: false,
                error: 

                    function(jqXHR, strError) {

                        if(strError == 'timeout') {

                            // Do something. Try again perhaps?
                            alert('Seems like there was an error loading the next page.');

                        }

                    },

                success: 

                    function(data) {

                        $('#Container').append(data); //Container where the NextPage.php data appends to
                        $('#pageno').val(nextPage);

                        if(data != '') { //Here is where my question lyes
                            $('.Error').hide();     //Else statement on NextPage.php should 'hide' as there is data to show
                            $('#Loader').show();    //Show image for pagination
                        } else {
                            $('.Error').show();     //Else statement on NextPage.php should 'show' as there is data to show
                            $('#Loader').hide();    //Hide image for pagination 
                        }

                    },

                timeout: 3000

            });

        }

    });

});

//Gets values of filters for filters variables
function get_filter(class_name) {

    var filter = [];

    $('.'+class_name+':checked').each(function() {
        filter.push($(this).val());
    });

    return filter;

}

My problem is that the else statement on NextPage.php is treated as data so I don't know how to check if $row is showing. I want the .Error class to hide when there are $row(s) being shown else hide #Loader and show .Error. How can I check for .Error in my AJAX call?

4
  • You should consider returning your data as a JSON, and not as HTML. Then use a template to add it to the site. To return an error check this stackoverflow.com/questions/4417690/… Commented Mar 17, 2020 at 17:05
  • Your SQL is vulnerable to SQL injection attacks. You should use parametised queries since you're already using mysqli. Commented Mar 17, 2020 at 17:10
  • @scragar I'm going to use this tutorial to help me set parameters after I solve this problem. I just don't like working on two issues at the same time. It confuses me lol Commented Mar 17, 2020 at 17:23
  • @ariel Out of curiosity (i'm very new to all of this) what's wrong with returning the data as HTML? Commented Mar 17, 2020 at 18:06

1 Answer 1

0

To hide #Loader when there was not more data count the total amount iterations of SQL rows, and put that as a PHP variable alongside the current iteration. I then put both variables in a hidden input inside the PHPs while statement and using jQuery make each of the inputs attributes into a variable where I could then check if the numbers were matching, if so I would hide #Loader.

As for the Error (PHP's else statement) I checked if data had the class .Error and if so I would hide #Loader.

Here is pseudo code:

SQL Query (Window functions work with MySQL 8.0+ only)

...
    SELECT inv.*, COUNT(*) OVER() AS totalrows FROM list inv WHERE wt >= 2.5
...

NextPage.php

...
    $ListingCounter = 0; // Begin counting iterations of while loop

    $Output = '';

        if($RowCount > 0) {

            while($row = mysqli_fetch_array($MySQLiQuery)) {

                $ListingCounter++; // Count iterations
                $ListingCount = $ListingCounter + $Offset; // Continue counting iterations after $Limit

                $output .=  '

                        <div class="Listing">

                            <!-- landing page -->
                            <a href="#ItemPage" class="ItemLink">

                                //Item Information goes here

                            </a>

    <input id="StoneIteration" type="hidden" data-listing="'echo $ListingCount;'" data-totalrows="'echo $row['totalrows'];'">


                        </div>

                    ';
...

InfiniteScroll.js

...

success: 

    function(data) {

        $('#Container').append(data);
        $('#PageNo').val(NextPage);

        // If the hidden input inside each .Stone's data attributes content both match hide #Loader
        $('.Listing').each(function(index, element) {

            var TotalRowCount = $(element).find('[data-totalrows]').data('totalrows');
            var ListingCount = $(element).find('[data-listing]').data('listing');

            if(TotalRowCount != ListingCount) {
                $('#Loader').show();   // Show infinite scroll
            } else {
                $('#Loader').hide();   // Hide infinite scroll
            }

        });

        // If data has .Error hide #Loader
        if(data.indexOf('class="Error"') > -1) {
            $('#Loader').hide();   // Hide infinite scroll
        }

    }
...

I hope this helps someone. If you have any questions please ask!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.