поиск по блокам

имеется форма поиска. поиск будет осуществляться по отдельности( 1 из 3 любой). event_date по типу text. в бд будет храниться как дд.мм.гггг и гггг. как мне реализовать. при таком коде у меня лишь работает период. как то нужно допилить и поиск по ключевым словам и точная дата. много разных вариантов попробовал.

    <form method="POST" class="search-form" action="search.php">
        <div class="search-row">
            <div class="search-container">
                <div class="bordered-container">
                    <label for="searchByName">Поиск по ключевым словам</label>
                    <input type="text" class="text-center" id="searchByName" name="searchByName">
                </div>
            </div>

            <div class="search-container">
                <div class="bordered-container" style="display: flex; flex-direction: column; align-items: center;">
                    <label for="startDate">Период</label>
                    <div style="display: flex;">
                        <input type="text" id="startDate" name="startDate" class="text-center"
                            style="margin-right: 10px;">
                        <input type="text" id="endDate" name="endDate" class="text-center">
                    </div>
                </div>
            </div>

            <div class="search-container">
                <div class="bordered-container"> <label for="exactDate">Точная дата</label> <input type="text"
                        id="exactDate" onblur="validateDate(this)" oninput="formatDate(this)" placeholder="дд.мм.гггг"
                        class="text-center" name="exactDate"></div>
            </div>
        </div>
    </form>

    <script>
        document.querySelector('.search-form').addEventListener('submit', function (e) {
            e.preventDefault();
            var searchByName = document.getElementById('searchByName').value;
            var startDate = document.getElementById('startDate').value;
            var endDate = document.getElementById('endDate').value;
            var exactDate = document.getElementById('exactDate').value;
            searchResults(searchByName, startDate, endDate, exactDate);
        });

        document.querySelector('.search').addEventListener('click', function (e) {
            e.preventDefault();
            var searchByName = document.getElementById('searchByName').value;
            var startDate = document.getElementById('startDate').value;
            var endDate = document.getElementById('endDate').value;
            var exactDate = document.getElementById('exactDate').value;
            searchResults(searchByName, startDate, endDate, exactDate);
        });

        document.querySelector('.clear').addEventListener('click', function (e) {
            e.preventDefault();
            document.getElementById('searchByName').value = '';
            document.getElementById('startDate').value = '';
            document.getElementById('endDate').value = '';
            document.getElementById('exactDate').value = '';
            clearSearchResults();
        });

        function searchResults(searchByName, startDate, endDate, exactDate) {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    document.getElementById('searchResults').innerHTML = this.responseText;
                }
            };
            xhttp.open("POST", "search.php", true);
            xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhttp.send("searchByName=" + searchByName + "&startDate=" + startDate + "&endDate=" + endDate + "&exactDate=" +
                exactDate);
        }

        function clearSearchResults() {
            document.getElementById('searchResults').innerHTML = '';
        }
    </script>
    </form>
    <br>
    <div class="text-center" id="searchResults">

    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

search.php

<?php
require_once 'connect.php';

$searchByName = $_POST['searchByName'];
$startDate = $_POST['startDate'];
$endDate = $_POST['endDate'];
$exactDate = $_POST['exactDate'];

$formattedStartDate = (new DateTime(str_replace('.', '-', $startDate)))->format('Y-m-d');
$formattedEndDate = (new DateTime(str_replace('.', '-', $endDate)))->format('Y-m-d');

$sql = "SELECT events.*, files.file_name, files.file_path    
        FROM events    
        LEFT JOIN event_files ON events.event_id = event_files.event_id    
        LEFT JOIN files ON event_files.file_id = files.file_id
        WHERE 1 ";

$conditions = [];
$params = [];
$paramTypes = "";

// Условие для поиска по ключевым словам
if (!empty($searchByName)) {
    $conditions[] = "event_name LIKE ?";
    $paramTypes .= "s";
    $searchByNameParam = '%' . $searchByName . '%';
    $params[] = &$searchByNameParam;
}

// Условие для диапазона дат
if (!empty($formattedStartDate) && !empty($formattedEndDate)) {
    $conditions[] = "(STR_TO_DATE(events.event_date, '%d.%m.%Y') BETWEEN ? AND ?) OR (LENGTH(events.event_date) = 4 AND events.event_date BETWEEN ? AND ?)";
    $paramTypes .= "ssss";
    $params[] = &$formattedStartDate;
    $params[] = &$formattedEndDate;
    $params[] = &$formattedStartDate;
    $params[] = &$formattedEndDate;
}

// Условие для точной даты
if (!empty($exactDate)) {
    $conditions[] = "(LENGTH(events.event_date) = 4 AND events.event_date LIKE ?)";
    $paramTypes .= "s";
    $exactDateParam = '%' . $exactDate . '%';
    $params[] = &$exactDateParam;
}

// Соберем все условия
if (!empty($conditions)) {
    $sql .= " AND " . implode(" AND ", $conditions);

    $stmt = $conn->prepare($sql);
    if ($stmt === false) {
        die('Error preparing the query: ' . $conn->error);
    }

    // Привяжем параметры
    $stmt->bind_param($paramTypes, ...$params);


    echo $sql;

    if ($stmt->execute()) {
        $result = $stmt->get_result();

        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                echo '<div class="card mb-3">';
                echo "<h5 class='card-title'>Дата события: " . str_replace('!', '.', $row["event_date"]) . "</h5>";
                echo "<h6 class='card-subtitle mb-2 text-muted'>Название события: " . $row["event_name"] . "</h6>";
                echo "<p class='card-text'>Описание события: " . $row["event_description"] . "</p>";
                echo "</div>";
            }
        } else {
            echo "No events found.";
        }
    } else {
        die('Error executing the query: ' . $stmt->error);
    }

    $stmt->close();
} else {
    echo "No conditions provided.";
}

$conn->close();
?>

Ответы (1 шт):

Автор решения: Grovli

search.php

<?php
require_once 'connect.php';

// Initialize variables for each input
$searchByName = $_POST['searchByName'];
$startDate = $_POST['startDate'];
$endDate = $_POST['endDate'];
$exactDate = $_POST['exactDate'];

// Construct the base SQL query
$sql = "SELECT events.*, files.file_name, files.file_path    
        FROM events    
        LEFT JOIN event_files ON events.event_id = event_files.event_id    
        LEFT JOIN files ON event_files.file_id = files.file_id
        WHERE 1 ";

// Initialize parameters and parameter types
$params = [];
$paramTypes = "";

// Search by keywords
if (!empty($searchByName)) {
    $sql .= " AND (event_name LIKE ? OR event_description LIKE ?)";
    $paramTypes .= "ss";
    $searchParam = '%' . $searchByName . '%';
    $params[] = $searchParam;
    $params[] = $searchParam; // Use the same search parameter for event_description
}

// Search by date range
if (!empty($startDate) && !empty($endDate)) {
    $sql .= " AND (
        (
            LENGTH(events.event_date) = 4 AND
            (
                STR_TO_DATE(CONCAT(events.event_date, '-01-01'), '%Y-%m-%d') BETWEEN ? AND ?
            )
        ) OR (
            LENGTH(events.event_date) != 4 AND
            (
                STR_TO_DATE(events.event_date, '%d.%m.%Y') BETWEEN ? AND ?
            )
        )
    )";
    $paramTypes .= "ssss";

    $startDate = date_create_from_format('d.m.Y', $startDate)->format('Y-m-d');
    $endDate = date_create_from_format('d.m.Y', $endDate)->format('Y-m-d');

    $params[] = $startDate;
    $params[] = $endDate;
    $params[] = $startDate;
    $params[] = $endDate;
}

// Search by exact date
if (!empty($exactDate)) {
    $sql .= " AND (LENGTH(events.event_date) = 4 AND events.event_date LIKE ? OR STR_TO_DATE(events.event_date, '%d.%m.%Y') = STR_TO_DATE(?, '%d.%m.%Y'))";
    $paramTypes .= "ss";
    $exactDateParam = '%' . $exactDate . '%';
    $params[] = $exactDateParam;
    $params[] = $exactDate;
}

// Prepare and execute the query if conditions are provided
if (!empty($params)) {
    $stmt = $conn->prepare($sql);

    if ($stmt === false) {
        die('Error preparing the query: ' . $conn->error);
    }

    $stmt->bind_param($paramTypes, ...$params);

    if ($stmt->execute()) {
        $result = $stmt->get_result();

        if ($result->num_rows > 0) {
            while ($row = $result->fetch_assoc()) {
                echo '<div class="card mb-3">';
                echo "<h5 class='card-title'>Дата события: " . str_replace('!', '.', $row["event_date"]) . "</h5>";
                echo "<h6 class='card-subtitle mb-2 text-muted'>Название события: " . $row["event_name"] . "</h6>";
                echo "<p class='card-text'>Описание события: " . $row["event_description"] . "</p>";
                echo "</div>";
            }
        } else {
            echo "No events found.";
        }
    } else {
        die('Error executing the query: ' . $stmt->error);
    }

    $stmt->close();
} else {
    echo "No conditions provided.";
}

$conn->close();
?>

index.html

    <form method="POST" class="search-form" action="search.php">
        <div class="search-row">
            <div class="search-container">
                <div class="bordered-container">
                    <label for="searchByName">Поиск по ключевым словам</label>
                    <input type="text" class="text-center" id="searchByName" name="searchByName">
                </div>
            </div>

            <div class="search-container">
                <div class="bordered-container" style="display: flex; flex-direction: column; align-items: center;">
                    <label for="startDate">Период</label>
                    <div style="display: flex;">
                        <input type="text" id="startDate" name="startDate" class="text-center"
                            style="margin-right: 10px;">
                        <input type="text" id="endDate" name="endDate" class="text-center">
                    </div>
                </div>
            </div>

            <div class="search-container">
                <div class="bordered-container"> <label for="exactDate">Точная дата</label> <input type="text"
                        id="exactDate" onblur="validateDate(this)" oninput="formatDate(this)" placeholder="дд.мм.гггг"
                        class="text-center" name="exactDate"></div>
            </div>
        </div>
    </form>
    <!-- скрипт для поиска в бд с ajax -->
    <script>
        document.querySelector('.search-form').addEventListener('submit', function (e) {
            e.preventDefault();
            var searchByName = document.getElementById('searchByName').value;
            var startDate = document.getElementById('startDate').value;
            var endDate = document.getElementById('endDate').value;
            var exactDate = document.getElementById('exactDate').value;
            searchResults(searchByName, startDate, endDate, exactDate);
        });

        document.querySelector('.search').addEventListener('click', function (e) {
            e.preventDefault();
            var searchByName = document.getElementById('searchByName').value;
            var startDate = document.getElementById('startDate').value;
            var endDate = document.getElementById('endDate').value;
            var exactDate = document.getElementById('exactDate').value;
            searchResults(searchByName, startDate, endDate, exactDate);
        });

        document.querySelector('.clear').addEventListener('click', function (e) {
            e.preventDefault();
            document.getElementById('searchByName').value = '';
            document.getElementById('startDate').value = '';
            document.getElementById('endDate').value = '';
            document.getElementById('exactDate').value = '';
            clearSearchResults();
        });

        function searchResults(searchByName, startDate, endDate, exactDate) {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    document.getElementById('searchResults').innerHTML = this.responseText;
                }
            };
            xhttp.open("POST", "search.php", true);
            xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhttp.send("searchByName=" + searchByName + "&startDate=" + startDate + "&endDate=" + endDate + "&exactDate=" +
                exactDate);
        }

        function clearSearchResults() {
            document.getElementById('searchResults').innerHTML = '';
        }
    </script>
    </form>
    <br>
    <div class="text-center" id="searchResults">

    </div>

    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
→ Ссылка