简体   繁体   中英

How do I make filters work together using AJAX, PHP and MySQL

I have this table that shows a list of users and I'm trying to create some filters with selectbox to filter with some parameters. I'm building this table with a PHP script that I call with AJAX. This AJAX is activated when the user click on one of this selectbox.

This are the filters:

<div class="col-lg-6">                                
   <select class="form-control filter" name="category" id="category">
       <option>All</option>
       <option>Abraham</option>
       <option>Kevin</option>
       <option>Eric</option>
   </select>                                
</div>   
<div class="col-lg-6">                                
   <select class="form-control filter" name="datePeriod" id="datePeriod">
       <option>Today</option>
       <option>Yesterday</option>
       <option>Last 7 days</option>
       <option>Last month</option>
       <option>Last year</option>
   </select>                                
</div>
<div class="col">
   <div id="output"></div>
</div>

and this is the AJAX:

$(document).ready(function(){
    $('.filter').each(function () {
        $(this).change(function(){ 
            var filters = $(this).val(); 
            var dataString = "filters="+filters;

            $.ajax({
                type: "GET", 
                url: "processes/filters.php", 
                data: dataString, 
                success: function(result){ 
                    $("#output").html(result);
                }
            });
        });            
    });
    $("#datePeriod").trigger("change");
});

This is my PHP code:

<?php

    //Getting $datePeriod value for query
    if(isset($_GET['filters']) && $_GET['filters'] == "Today" && $_GET['filters'] == "All"){
        $datePeriod = 'AND DATE(VISIT_DATE) = CURDATE()';
        $category = "";
    }
    if(isset($_GET['filters']) && $_GET['filters'] == "Yesterday"){
        $datePeriod = 'AND VISIT_DATE >= DATE(NOW()) - INTERVAL 1 DAY';     
    }
    if(isset($_GET['filters']) && $_GET['filters'] == "Last 7 days"){
        $datePeriod = 'AND VISIT_DATE >= DATE(NOW()) - INTERVAL 7 DAY';
    }
    if(isset($_GET['filters']) && $_GET['filters'] == "Last month"){
        $datePeriod = 'AND VISIT_DATE >= DATE(NOW()) - INTERVAL 1 MONTH';
    }
    if(isset($_GET['filters']) && $_GET['filters'] == "Last year"){
        $datePeriod = 'AND VISIT_DATE >= DATE(NOW()) - INTERVAL 1 YEAR';
    }

    //Getting $category value for query
    if(isset($_GET['filters']) && $_GET['filters'] == "All"){
        $category = "";
    }
    if(isset($_GET['filters']) && $_GET['filters'] == "Abraham"){
        $category = "AND VISIT_REASON='Abraham'";
    }
    if(isset($_GET['filters']) && $_GET['filters'] == "Kevin"){
        $category = "AND VISIT_REASON='Kevin'";
    }
    if(isset($_GET['filters']) && $_GET['filters'] == "Eric"){
        $category = "AND VISIT_REASON='Eric'";
    }

    include('conn.php');

    mysqli_set_charset($conn, 'utf8');

    $orderBy = 'ORDER BY VISIT_DATE DESC';

    $sql = "SELECT * FROM queue WHERE ATTENDED='1' ".$category." ".$datePeriod." ".$orderBy." ";

    $result = mysqli_query($conn, $sql);

    //$ID = 'ID';
    $GUEST_NAME = 'GUEST_NAME';
    $GUEST_PHONE = 'GUEST_PHONE';
    $VISIT_REASON = 'VISIT_REASON';
    $VISIT_DATE = 'VISIT_DATE';

    echo '<table class="table table-striped">';
    echo "<tr>";
    //echo '<th scope="col">ID</th>';
    echo '<th scope="col">Name</th>';
    echo '<th scope="col">Phone</th>';
    echo '<th scope="col">Attended by</th>';
    echo '<th scope="col">Visit Date</th>';
    echo "</tr>";

    if (mysqli_num_rows($result) > 0) {

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

            echo "<tr>";
            //echo "<td>$row[$ID]</td>";
            echo "<td>$row[$GUEST_NAME]</td>";
            echo "<td>$row[$GUEST_PHONE]</td>";
            echo "<td>$row[$VISIT_REASON]</td>";
            echo "<td style='text-transform:uppercase;'>".date('M-d-Y g:i a', strtotime(str_replace('-','/', $row['VISIT_DATE'])))."</td>";
            echo "</tr>";

        }

    } else {
        echo "<td style='text-transform: none;'>No records to show.</td>";
    }

    echo '</table>';

    mysqli_close($conn);

?>

My problem is that I can't figure out how to build the correct conditions so the two filters can work together. I need that when the user select one filter the query build it self considering the value of the other one.

When I select the category filter I get "Undefined variable: datePeriod". When I select the datePeriod filter I get "Undefined variable: category".

I do not know if I'm doing it the wrong way. Maybe I'm not building the query in the correct way. I will appreciate any help or guidance.

You need to send both filters every time each of them changes:

JS:

$(document).ready(function(){
    $('.filter').change(function(){ 
        $.ajax({
            type: "GET", 
            url: "processes/filters.php", 
            data: {
                category: $('#category').val(),
                datePeriod: $('#datePeriod').val(),
            },
            success: function(result){ 
                $("#output").html(result);
            }
        });
    });            
    $("#datePeriod").trigger("change");
});

PHP:

<?php
if($_GET['category'] == "All"){
    $category = "";
} else if($_GET['category'] == "Abraham"){
    $category = "AND VISIT_REASON='Abraham'";
} else if( $_GET['category'] == "Kevin"){
    $category = "AND VISIT_REASON='Kevin'";
} else if($_GET['category'] == "Eric"){
    $category = "AND VISIT_REASON='Eric'";
} else {
    $category = '';
}

if($_GET['datePeriod'] == "Today"){
    $datePeriod = 'AND DATE(VISIT_DATE) = CURDATE()';
} else if($_GET['datePeriod'] == "Yesterday"){
    $datePeriod = 'AND VISIT_DATE >= DATE(NOW()) - INTERVAL 1 DAY';     
} else if($_GET['datePeriod'] == "Last 7 days"){
    $datePeriod = 'AND VISIT_DATE >= DATE(NOW()) - INTERVAL 7 DAY';
} else if($_GET['datePeriod'] == "Last month"){
    $datePeriod = 'AND VISIT_DATE >= DATE(NOW()) - INTERVAL 1 MONTH';
} else if($_GET['datePeriod'] == "Last year"){
    $datePeriod = 'AND VISIT_DATE >= DATE(NOW()) - INTERVAL 1 YEAR';
} else {
    $datePeriod = '';
}
// the rest of the file

Whilst not a complete solution to your question the following ought to give you a good idea about how to complete the solution. I do not use jQuery so below have opted to use a simple ajax function. the bit I think you might be most interested in is the states variable which stores the name/value of any select menu used on the page ~ found by querying the DOM. The values stored in that variable are then used in the ajax request so you are always going to have all values available in the PHP code and not suffer from the errors you mentioned above.

You could copy this and run it "As-is" to see how it works and then adopt, adapt and improve to suit your needs.

<?php

    /* Process ajax request */
    if( $_SERVER['REQUEST_METHOD']=='GET' && isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && $_SERVER['HTTP_X_REQUESTED_WITH']=='XMLHttpRequest' ){
        ob_clean();

        $args=array(
            'category'      =>  FILTER_SANITIZE_STRING,
            'datePeriod'    =>  FILTER_SANITIZE_STRING
        );
        $_GET = filter_input_array( INPUT_GET, $args );
        extract( $_GET );


        echo $category . ' ' . $datePeriod;
        /* process these variables to construct your sql query */

        exit();
    }
?>
<!doctype html>
<html>
    <head>
        <meta charset='utf-8' />
        <title>ajax filtering idea</title>
        <script>
            document.addEventListener('DOMContentLoaded',function(){
                /* Create a nodelist collection of select menus according to class "filter" */
                var col=document.querySelectorAll( 'select.filter' );

                /* Placeholder object to store the state of any menu that is changed */
                var states={};

                /* Iterate through nodelist collection and assign event listener to each */
                Array.prototype.slice.call( col ).forEach( function( menu ){

                    /* store initial state of all menus */
                    states[ menu.name ]=menu.value;

                    menu.addEventListener('change',function(e){
                        /* store this menu name & value after change */
                        states[ e.target.name ]=e.target.value;

                        /* send ajax request */
                        ajax.call( this, location.href, states, callback )
                    },false );
                });
            },false);

            /* basic ajax function */
            function ajax( url, payload, callback ){
                var xhr=new XMLHttpRequest();
                var params=[];
                for( var p in payload )params.push( p + '=' + payload[ p ] );

                xhr.onreadystatechange=function(){if( this.readyState==4 && this.status==200 )callback.call( this, this.response );};
                xhr.open( 'GET', url + '?' + params.join('&'), true );
                xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send( null );
            }
            /* very simple callback */
            var callback=function(r){
                document.getElementById('output').innerHTML=r
            };
        </script>
    </head>
    <body>
        <div class="col-lg-6">                                
           <select class="form-control filter" name="category" id="category">
               <option>All</option>
               <option>Abraham</option>
               <option>Kevin</option>
               <option>Eric</option>
           </select>                                
        </div>   
        <div class="col-lg-6">                                
           <select class="form-control filter" name="datePeriod" id="datePeriod">
               <option>Today</option>
               <option>Yesterday</option>
               <option>Last 7 days</option>
               <option>Last month</option>
               <option>Last year</option>
           </select>                                
        </div>
        <div class="col">
           <div id="output"></div>
        </div>
    </body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM