Bootstrap CDN
https://getbootstrap.com/docs/4.3/getting-started/introduction/
https://jqueryui.com/datepicker/
The datepicker is tied to a standard form input field. Focus on the input (click, or use the tab key) to open an interactive calendar in a small overlay. Choose a date, click elsewhere on the page (blur the input), or hit the Esc key to close.
https://datatables.net/
DataTables is a powerful jQuery plugin for creating table listings and adding interactions to them. It provides searching, sorting and pagination without any configuration.
CREATE TABLE `employee` (
`id` int(11) NOT NULL,
`name` varchar(100) NOT NULL,
`position` varchar(100) NOT NULL,
`office` varchar(100) NOT NULL,
`age` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`created_at` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `employee` (`id`, `name`, `position`, `office`, `age`, `salary`, `created_at`) VALUES
(1, 'Tiger Wood', 'Accountant', 'Tokyo', 36, 5689, '2020-01-09'),
(2, 'Mark Oto Ednalan', 'Chief Executive Officer (CEO)', 'London', 56, 5648, '2020-02-15'),
(3, 'Jacob thompson', 'Junior Technical Author', 'San Francisco', 23, 5689, '2020-03-01'),
(4, 'cylde Ednalan', 'Software Engineer', 'Olongapo', 23, 54654, '2020-01-24'),
(5, 'Rhona Davidson', 'Software Engineer', 'San Francisco', 26, 5465, '2020-01-11'),
(6, 'Quinn Flynn', 'Integration Specialist', 'New York', 53, 56465, '2020-02-23'),
(8, 'Tiger Nixon', 'Software Engineer', 'London', 45, 456, '2020-03-04'),
(9, 'Airi Satou updated', 'Pre-Sales Support updated', 'New York', 25, 4568, '2020-04-28'),
(10, 'Angelica Ramos updated', 'Sales Assistant updated', 'New York', 45, 456, '2020-01-12'),
(11, 'Ashton updated', 'Senior Javascript Developer', 'Olongapo', 45, 54565, '2020-02-06'),
(12, 'Bradley Greer', 'Regional Director', 'San Francisco', 27, 5485, '2020-03-21'),
(13, 'Brenden Wagner', 'Javascript Developer', 'San Francisco', 38, 65468, '2020-04-14'),
(14, 'Brielle Williamson', 'Personnel Lead', 'Olongapo', 56, 354685, '2020-01-29'),
(15, 'Bruno Nash', 'Customer Support', 'New York', 36, 65465, '2020-02-22'),
(16, 'cairocoders', 'Sales Assistant', 'Sydney', 45, 56465, '2020-03-10'),
(17, 'Zorita Serrano', 'Support Engineer', 'San Francisco', 38, 6548, '2020-04-26'),
(18, 'Zenaida Frank', 'Chief Operating Officer (COO)', 'San Francisco', 39, 545, '2020-01-17'),
(19, 'Sakura Yamamoto', 'Support Engineer', 'Tokyo', 48, 5468, '2020-02-01'),
(20, 'Serge Baldwin', 'Data Coordinator', 'Singapore', 85, 5646, '2020-03-19'),
(21, 'Shad Decker', 'Regional Director', 'Tokyo', 45, 4545, '2020-04-21');
ALTER TABLE `employee`
ADD PRIMARY KEY (`id`);
ALTER TABLE `employee`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=22;
index.php
//index.php
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.0/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.13.0/jquery-ui.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<!-- Datatables -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.3/css/jquery.dataTables.min.css" />
<script type="text/javascript"src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
<title>PHP Mysqli OOP Date Range Filter Ajax Datatables</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12 mt-5">
<h1 class="text-center">PHP Mysqli OOP Date Range Filter Ajax DataTables</h1>
<hr>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-6">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text bg-info text-white" id="basic-addon1"><i class="fas fa-calendar-alt"></i></span>
</div>
<input type="text" class="form-control" id="start_date" placeholder="Start Date">
</div>
</div>
<div class="col-md-6">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text bg-info text-white" id="basic-addon1"><i class="fas fa-calendar-alt"></i></span>
</div>
<input type="text" class="form-control" id="end_date" placeholder="End Date">
</div>
</div>
</div>
<div>
<button id="filter" class="btn btn-outline-info btn-sm">Filter</button>
<button id="reset" class="btn btn-outline-warning btn-sm">Reset</button>
</div>
<div class="row mt-3">
<div class="col-md-12">
<div class="table-responsive">
<table class="table table-borderless display nowrap" id="records" style="width:100%">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Salary</th>
<th>Date</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Font Awesome -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
<script>
$(function() {
$("#start_date").datepicker({
"dateFormat": "yy-mm-dd"
});
$("#end_date").datepicker({
"dateFormat": "yy-mm-dd"
});
});
// Fetch records
function fetch(start_date, end_date) {
$.ajax({
url: "records.php",
type: "POST",
data: {
start_date: start_date,
end_date: end_date
},
dataType: "json",
success: function(data) {
// Datatables
var i = "1";
$('#records').DataTable({
"data": data,
"dom": "<'row'<'col-sm-12 col-md-4'l><'col-sm-12 col-md-4'B><'col-sm-12 col-md-4'f>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
// responsive
"responsive": true,
"columns": [{
"data": "id"
},
{
"data": "name"
},
{
"data": "position"
},
{
"data": "office"
},
{
"data": "salary"
},
{
"data": "created_at"
}
]
});
}
});
}
fetch();
// Filter
$(document).on("click", "#filter", function(e) {
e.preventDefault();
var start_date = $("#start_date").val();
var end_date = $("#end_date").val();
if (start_date == "" || end_date == "") {
alert("both date required");
} else {
$('#records').DataTable().destroy();
fetch(start_date, end_date);
}
});
// Reset
$(document).on("click", "#reset", function(e) {
e.preventDefault();
$("#start_date").val(''); // empty value
$("#end_date").val('');
$('#records').DataTable().destroy();
fetch();
});
</script>
</body>
</html>
records.php
//records.php
<?php
include 'model.php';
$model = new Model();
if (isset($_POST['start_date']) && isset($_POST['end_date'])) {
$start_date = $_POST['start_date'];
$end_date = $_POST['end_date'];
$rows = $model->date_range($start_date, $end_date);
} else {
$rows = $model->fetch();
}
echo json_encode($rows);
model.php
//model.php
<?php
class Model
{
private $server = "localhost";
private $username = "root";
private $password = "";
private $db = "testingdb";
private $conn;
public function __construct()
{
try {
$this->conn = new mysqli($this->server, $this->username, $this->password, $this->db);
} catch (\Throwable $th) {
//throw $th;
echo "Connection error " . $th->getMessage();
}
}
public function fetch()
{
$data = [];
$query = "SELECT * FROM employee";
if ($sql = $this->conn->query($query)) {
while ($row = mysqli_fetch_assoc($sql)) {
$data[] = $row;
}
}
return $data;
}
public function date_range($start_date, $end_date)
{
$data = [];
if (isset($start_date) && isset($end_date)) {
$query = "SELECT * FROM employee WHERE created_at > '$start_date' AND created_at < '$end_date'";
if ($sql = $this->conn->query($query)) {
while ($row = mysqli_fetch_assoc($sql)) {
$data[] = $row;
}
}
}
return $data;
}
}