Jump to content

Recommended Posts

Ok ill try and explain this as best i can.

I have client.php which includes a file called 'Functions/Common_Functions.php';

on this clients.php page it has a form, the form is a mixture of html and script.

include 'Functions/Common_Functions.php';
 func_header();
 header_client_search();
 func_endheader();
 func_TopMenu();
 menu_items();
 
 

 ?>
 <br><br>
 <form method="post" action=<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>>
 <?php if (isset($_GET['error'])) { ?>
            <p class="error"><?php echo $_GET['error']; ?></p>
        <?php 
                               } 
        client_search();
        client_search_script();
       // $clientSearch = ($_POST['clientSearch']);
        ?>
   
<input type="submit" value="Search">
</form>


 <?php 
 
 // Check if the form is submitted
 if ($_SERVER["REQUEST_METHOD"] == "POST") {
     // Process form data if needed
     echo "formposted";
echo $clientSearch;
$clientSearch = isset($_POST['clientSearch']) ? $_POST['clientSearch'] : '';
echo "Form posted with clientSearch value: " . htmlspecialchars($clientSearch);
echo $clientSearch;
 }

 

The two functions client_search(); and client_Search_script(); go out and query mysql clients table so as you start typing a clients name the options get smaller "suggestive text".  This part is working well. However when I submit the form for the life of me I cannot get the clients name captured on submit. 

This is the script code located in common_functions.php

function header_client_search(){
  echo "<style>";
  echo "  #suggestions {";
  echo " position: absolute;";
  echo " max-height: 200px;";
  echo " overflow-y: auto;";
  echo " border: 1px solid #ccc;";
  echo "  background-color: #fff;";
  echo "}";

  echo ".suggestion {";
  echo " padding: 8px;";
  echo " cursor: pointer;";
  echo " background-color: #cccccc;";
  echo "}";

  echo ".suggestion:hover {";
 // echo "  background-color: #f2f2f2;";
  echo "  background-color: #cccccc;";
  echo " }";
  echo "</style>";
}

function client_search(){
    echo "<h1 color=#00000>Client Search</h1>";
    echo "<label for='clientSearch'>Search Clients:</label>";
    echo "<input type='text' id='clientSearch' oninput='getSuggestions(this.value)'>";
    echo "<div id='suggestions'></div>";
}
function client_search_script(){
    echo "<script>";
    echo "function getSuggestions(query) {";
    echo "if (query.length === 0) {";
        echo "document.getElementById('suggestions').innerHTML = '';";
        echo "return;";
        echo " }";
    //echo "// Make an asynchronous request to fetch suggestions";
    echo "var xhttp = new XMLHttpRequest();";
        echo "xhttp.onreadystatechange = function() {";
         echo "if (this.readyState == 4 && this.status == 200) {";
                echo "document.getElementById('suggestions').innerHTML = this.responseText;";
            echo "}";
        echo "};";
    echo "xhttp.open('GET', 'get_suggestions.php?q=' + query, true);";
    echo "xhttp.send();";
    echo "}";
    echo "function selectSuggestion(value) {";
        echo "document.getElementById('clientSearch').value = value;";
        echo "document.getElementById('suggestions').innerHTML = '';";
        echo " }";
        echo "</script>";

}

and incase you need it this is the get_suggestions.php file

<?php
// Include your database connection logic here
include('Functions/db_con.php');

// Get the search query from the URL parameter
$q = $_GET['q'];

// Prepare and execute the query to fetch client names based on the search query
$query = "SELECT DISTINCT CompanyName FROM Customer WHERE CompanyName LIKE :query";
$stmt = $pdo->prepare($query);
$stmt->bindValue(':query', '%' . $q . '%', PDO::PARAM_STR);
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Output the suggestions as a list
foreach ($results as $row) {
    echo '<div class="suggestion" onclick="selectSuggestion(\'' . $row['CompanyName'] . '\')">' . $row['CompanyName'] . '</div>';
}
?>

What I have tried to do is muck around with 

$clientSearch = isset($_POST['clientSearch']) ? $_POST['clientSearch'] : '';

echo "Form posted with clientSearch value: " . htmlspecialchars($clientSearch);

 

and  these

$clientSearch = document.getElementById('clientSearch');

echo $clientSearch;

but I can never get the customer name back after submitting form I just get client search value: blank like in the picture below. Where am I going wrong?

 

clientsearch.thumb.png.c633830d871ae26aa3006d2eca924ed6.png

programming already is a tedious typing task. don't make it harder than it needs to be. buried within the unnecessary echoing of static html markup, is the problem. form fields must have a name='...' attribute for the value to be included in the submitted form data.

here's a list of practices the will simplify and help secure the code -

  1.  use 'require' for things your code must have for it to work
  2. to get a form to submit to the same page it is on, leave out the entire action attribute
  3. don't pass display messages or message flag values through the url, as this opens your site to phishing attacks
  4. any dynamic value you output in a html context needs htmlentities/htmlspecialchars applied to it to help prevent cross site scripting. you have some cases using this and some that are not
  5. the search form needs to be a get method form, it needs to be sticky and repopulate the field value with any existing data so that the user can just alter the value if a search didn't produce the result they were looking for
  6. the code for any page needs to be laid out in this general order - 1) initialization, 2) post method form processing, 3) get method business logic - get/produce data needed to display the page, 4) html document
  7. don't copy variables to other variables for nothing. just use the original variables
  8. you need to trim all user entered data, mainly so that you can detect if it was all white-space characters
  9. you need to validate all inputs before using them
  10. don't echo static css/html/javascript
  11. functions should return the result they produce, i.e. don't echo output inside a function, return it to the calling code
  12. don't use php functions, with css/html/javascript in them to build the html document
  13. use implicit binding and simply supply an array of input values to the PDOstatement ->execute([...]) call
  14. set the default fetch mode to assoc when you make the PDO connection so that you don't need to specify it in each fetch statement
  15. require/include are not functions. the () around the path/filename do nothing and should be removed

My approach would be to divide the content into three files, although it's feasible to combine everything into a single file. Nonetheless, I'd still make an effort to keep the code and HTML distinct and separate as much as possible.

  1. Client's search page - example clients.php (form to search)
  2. JavaScript file - example clients.js
  3. PHP search results file - example client_results.php

Here's an example of what I'm trying to express:

My HTML form (edit_cms.php):

    <div class="search-form-container">
        <form id="searchForm">
            <div class="input-group">
                <label for="heading">Heading:</label>
                <select class="select-css" id="heading" name="heading">
                    <option value="" disabled selected>Select Heading</option>
                    <?php
                    foreach ($records as $record) {
                        echo '<option value="' . $record['heading'] . '">' . $record['heading'] . '</option>';
                    }
                    ?>
                </select>
            </div>
            <div class="input-group">
                <label for="searchTerm">Search Product Content:</label>
                <input type="text" placeholder="Search Content" id="searchTerm" class="input-field" autofocus required>
            </div>
            <button class="search_button" type="submit">Search</button>
        </form>
    </div>

A little bit of my JavaScript code (edit_cms.js):

        async function displayRecord(searchTerm = null, selectedHeading = null) {
            const requestData = {};
            if(searchTerm !== null) requestData.searchTerm = searchTerm;
            if(selectedHeading !== null) requestData.heading = selectedHeading;

            try {
                const response = await fetch("search_cms_records.php", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                    },
                    body: JSON.stringify(requestData),
                });

                const data = await response.json();
                console.log(data); // Add this line
                if (data.message) {
                    resultInput.value = '';
                    resultInput.placeholder = data.message;
                } else if (data.error) {
                    console.error(data.error);
                } else {
                    const row = data[0];
                    console.log(row);
                    idInput.value = row.id;
                    image_for_edit_record.src = row.thumb_path;
                    image_for_edit_record.alt = row.heading;
                    category.value = row.category;
                    category.textContent = `${row.category.charAt(0).toUpperCase()}${row.category.slice(1)}`;
                    heading.value = row.heading;
                    content.value = row.content;
                    resizeTextarea(content);
                }
            } catch (error) {
                console.error("Error:", error);
            }
        }

and my PHP file with a little bit of the code that gets the results (search_cms_records.php):
 

    // Get the request body and decode it as JSON.
    $request = json_decode(file_get_contents('php://input'), true);

    // Extract the search term and heading from the request, if they exist.
    $searchTerm = $request['searchTerm'] ?? null;
    $heading = $request['heading'] ?? null;

    // If a search term was provided, use a full-text search on the 'content' field.
    // Before this can work, you'll need to make sure your content column is indexed for full-text searching.
    // You can do this with the following SQL command:
    // Example:
    // ALTER TABLE cms ADD FULLTEXT(content);
    if($searchTerm !== null) {
        $sql = "SELECT * FROM cms WHERE MATCH(content) AGAINST(:searchTerm IN NATURAL LANGUAGE MODE) LIMIT 1";
        $stmt = $pdo->prepare($sql);
        $stmt->bindValue(':searchTerm', $searchTerm);

        // If a heading was provided, search for exact matches on the 'heading' field.
    } else if($heading !== null) {
        $sql = "SELECT * FROM cms WHERE heading = :heading LIMIT 1";
        $stmt = $pdo->prepare($sql);
        $stmt->bindValue(':heading', $heading);

        // If neither a search term nor a heading was provided, throw an exception.
    } else {
        throw new Exception("No valid search term or heading provided");
    }

    // Execute the prepared statement.
    $stmt->execute();

    // Fetch the results and handle them as needed.
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // If results were found, return them to the client as JSON.
    if ($results) {
        echo json_encode($results);
    } else {
        echo json_encode(['message' => 'No results found.']);
    }

My argument is that debugging becomes simpler when most of the code is organized and separated as much as possible within its respective programming language.

The previous posters provided some good input and identified the issue - but maybe not as directly as it could be.

The issue is that you do not provide the input field a name, i.e. name="clientSearch" or something like that

function client_search(){
    echo "<h1 color=#00000>Client Search</h1>";
    echo "<label for='clientSearch'>Search Clients:</label>";
    echo "<input type='text' id='clientSearch' oninput='getSuggestions(this.value)'>"; //What is the name of this field???
    echo "<div id='suggestions'></div>";
}

But, they are also correct that the organization of the code is problematic. I see no reason to create a function for creating that form field. I am big on writing code one and reusing it (that's assuming you use this field in multiple places) - but in the case of a field within a form it makes it difficult to "see" the entire form.

Also, whenever I'm trying to debug issues with data passed from a form, I'll simply output the contents of $_POST or $_GET to the page.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.