Dealing with search query and action - php

I did a search feature that will enable users to search and see result from database.
First - I want to transfer the search query (What the user searched for) into the search action (searchact.php)
When A user fills the input field below (form) and hit search...
<form action="searchact.php" class=" form-inline" method="post">
<div class="form-group">
<input type="text" name="word" class="form-control" placeholder="House key word">
</div>
<div class="form-group">
<select name="location" class="form-control">
<option value="Bosso">Bosso Campus</option>
<option value="GK">Gidan Kwano Campus (GK)</option>
</select>
</div>
<div class="form-group">
<select name="price" class="form-control">
<option>10-49k</option>
<option>50-99k</option>
<option selected>100-149k</option>
<option>150-199k</option>
</select>
</div>
<input type="submit" class="submit" name="submit" value="Search...">
</form>
I want the next page url (searchact.php) to be something like
wwww.test.com/searchact.php?q=word&location=Bosso&price=10-49k
This is searchact.php
<?php
if($_POST["submit"])
{
$word = $_POST["word"];
$location = $_POST["location"];
$price = $_POST["price"];
$sql = "INSERT INTO search (word,location,price) VALUES (:word,:location,:price)";
$q = $connecDB->prepare($sql);
$q->execute(array(':word'=>$word, ':location'=>$location, ':price'=>$price));
if($q)
{
$query = "SELECT * FROM house WHERE location LIKE :location AND tag LIKE :info AND range LIKE :range order by id desc LIMIT 10";
$stmt = $connecDB->prepare($query);
$stmt->bindValue(':info', '%' . $word . '%', PDO::PARAM_INT);
$stmt->bindValue(':location', '%' . $location . '%', PDO::PARAM_INT);
$stmt->bindValue(':range', '%' . $price . '%', PDO::PARAM_INT);
$stmt->execute();
if ($stmt->rowCount() > 0) {
$result = $stmt->fetchAll();
foreach( $result as $row ) {
$hid=$row["id"];
$name=$row["name"];
?>
<!--Some Html-->
<?php
}}
else {
echo 'No result found';
}
}}
?>
2nd - How do I make sure that a user actually searched for something without manually visiting "searchact.php"
Like.. How do I redirect a user to an error page when they just visit the searchact.php without inputing any search query.

Related

How to pass value in php

In my home page, I have a search bar with a button at the top of my page and I displayed all my songs using their title from my database underneath that.
The search bar is working fine since every song title I typed, it took me to the correct detail page.
I'm just wondering how can I also click on the song title and take me to each song detail page.
Home page
<?php
require_once '../config.php';
$sql = 'SELECT title FROM song ORDER BY title ASC;';
$stmt = $conn->prepare($sql);
$stmt->execute(['title' => $title]);
// fetch all rows
$songTitle = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
//Search bar
<form action="chord/details.php" method="post" class="p-3">
<div class="input-group">
<input type="text" name="search" id="search" class="form-control form-control-lg rounded-0 border-primary width =250px;" placeholder="Search..." autocomplete="off" required>
<div class="input-group-append">
<input type="submit" name="submit" value="Search" class="btn btn-primary rounded-right">
</div>
</div>
</form>
// Here I display all my songs from the database using their title
<?php
foreach ($songTitle as $song) {
// I'm not sure how to modify here.
echo "<a href='chord/details.php'>{$song['title']} <br> </a>";
} ?>
Details page
//This is working fine with Search Bar
<?php
require_once '../config.php';
if (isset($_POST['submit'])) {
$title = $_POST['search'];
$sql = 'SELECT * FROM song WHERE title = :title';
$stmt = $conn->prepare($sql);
$stmt->execute(['title' => $title]);
$row = $stmt->fetch();
} else {
header('location: .');
exit();
}
?>
//Display the song lyrics here
<div>Original Key: <?= ucfirst($row['chord']) ?></div><br>
<pre data-key=<?= ucfirst($row['chord']) ?> id="pre">
<?= ucfirst($row['lyrics']) ?>
</pre>
You can use the get HTTP method to send the id of the song to the details.php page and query to the database on that id.
And it's always a good practice to use the GET HTTP method for searching actions. As mickmackusa said in the comment:
$_POST is most appropriate when "writing" data server-side. $_GET is
most appropriate when "reading" data server-side.
So change the code on the Home page as below:
<?php
require_once '../config.php';
// query changed to fetch id as well
$sql = 'SELECT id , title FROM song ORDER BY title ASC;';
$stmt = $conn->prepare($sql);
$stmt->execute(['title' => $title]);
// fetch all rows
$songTitle = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!-- here we change the method to get -->
<form action="chord/details.php" method="get" class="p-3">
<div class="input-group">
<input type="text" name="search" id="search" class="form-control form-control-lg rounded-0 border-primary width =250px;" placeholder="Search..." autocomplete="off" required>
<div class="input-group-append">
<input type="submit" name="submit" value="Search" class="btn btn-primary rounded-right">
</div>
</div>
</form>
<?php
foreach ($songTitle as $song) {
// we add the id to the link
echo "<a href='chord/details.php?id={$song['id']}'>{$song['title']} <br> </a>";
}
?>
And change the detail.php like below:
<?PHP
//This is working fine with Search Bar
require_once '../config.php';
if (isset($_GET['search']) OR isset($_GET['id'])) {
$condition = "";
$value = "";
if (!empty($_GET['id'])) {
$condition = "id = :value";
$value = $_GET['id'];
}
elseif (!empty($_GET['search'])) {
$condition = "title = :value";
$value = $_GET['search'];
}
$sql = 'SELECT * FROM song WHERE ' . $condition;
$stmt = $conn->prepare($sql);
$stmt->execute(['value' => $value]);
$row = $stmt->fetch();
} else {
header('location: .');
exit();
}
?>
//Display the song lyrics here
<div>Original Key: <?= ucfirst($row['chord']) ?></div><br>
<pre data-key=<?= ucfirst($row['chord']) ?> id="pre">
<?= ucfirst($row['lyrics']) ?>
</pre>
It's also a good idea to use LIKE for searching in the title like below:
if (!empty($_POST['search'])) {
$condition = "title LIKE :value";
$value = "%" . $_POST['search'] . "%";
}
Assuming you have an id column in the song table. You could do something like this:
<?php
require_once '../config.php';
$sql = 'SELECT id, title FROM song ORDER BY title ASC;';
$stmt = $conn->prepare($sql);
$stmt->execute();
// fetch all rows
$songTitle = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
//Search bar
<form action="chord/details.php" method="post" class="p-3">
<div class="input-group">
<input type="text" name="search" id="search" class="form-control form-control-lg rounded-0 border-primary width =250px;" placeholder="Search..." autocomplete="off" required>
<div class="input-group-append">
<input type="submit" name="submit" value="Search" class="btn btn-primary rounded-right">
</div>
</div>
</form>
// Here I display all my songs from the database using their title
<?php
foreach ($songTitle as $song) {
// I'm not sure how to modify here.
echo "<a href='chord/details.php?id=".$song['id]."'>{$song['title']} <br> </a>";
} ?>
Details page
//This is working fine with Search Bar
<?php
require_once '../config.php';
if (isset($_POST['submit'])) {
$title = $_POST['search'];
$sql = 'SELECT * FROM song WHERE title = :title';
$stmt = $conn->prepare($sql);
$stmt->execute(['title' => $title]);
$row = $stmt->fetch();
} elseif (!empty($_REQUEST['id'])) {
$sql = 'SELECT * FROM song WHERE id = :id';
$stmt = $conn->prepare($sql);
$stmt->execute(['id' => $_REQUEST['id']]);
$row = $stmt->fetch();
} else {
header('location: .');
exit();
}
?>
//Display the song lyrics here
<div>Original Key: <?= ucfirst($row['chord']) ?></div><br>
<pre data-key=<?= ucfirst($row['chord']) ?> id="pre">
<?= ucfirst($row['lyrics']) ?>
</pre>

How to Save select option value data instead of Id using PHP MYSQL

How best can I save a select option value name instead of the id using just Ajax, PHP and MYSQL.
I tried many ways but for now when I select the data and store back it keeps saving generated id and that's not what I want.
When i decided to change the id of the selection option to value i the values does show on the drop down.
Details.php
<form method="post" name="signup" onSubmit="return valid();">
<label class="control-label">Profile ID</label>
<select id="employee" name="regcode" class="form-control">
<option value="" selected="selected">Select Profile ID</option>
<?php
$sql = "SELECT id,regcode FROM tbstudentprofile";
$query = $dbh->prepare($sql);
$query->execute();
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
?>
<option name="regcode" value="<?php echo $row["id"]; ?>">
<?php echo $row["regcode"]; ?> </option>
<?php } ?>
</select>
<div class=" form-group1 form-last>
<label class=" control-label">Status</label>
<textarea name="status" row="2"></textarea>
</div>
<button type="submit" name="save">Save </button>
</form>
enter code here
query
if (isset($_POST['save'])) {
$regcode = $_POST['regcode'];
$status = $_POST['status'];
$sql = "INSERT INTO studentschooltbl(regcode,status) VALUES(:regcode,:status)";
$query = $dbh->prepare($sql);
$query->bindParam(':regcode', $regcode, PDO::PARAM_STR);
$query->bindParam(':status', $status, PDO::PARAM_STR);
$query->execute();
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$lastInsertId = $dbh->lastInsertId();
if ($lastInsertId) {
$msg = " Registration successfully";
} else {
$error = "error";
}
}

SQL Checkbox search which displays list of items that are in my database

I'm setting up a directory page that displays different workouts depending on what is searched through a text field(which works) and/or checkboxes(Doesn't work)
I don't know if it's possible without a submit button but I would like it to search for items as well as letting it search for multiple checkboxes
I've tried looking on the internet for help but I can't find anything that's related to my project.
$sqlBrowse = "SELECT * FROM workoutLibrary
WHERE name LIKE :findInName
OR bodyPart LIKE :findInBodyPart
OR muscleGroup LIKE :findInMuscleGroup
OR equipment LIKE :findInEquipment
ORDER BY name";
$searchTerm = '';
$search = '%';
if (isset($_POST['search'])) {
$searchTerm = $_POST['search'];
$search = '%' . $searchTerm . '%';
$stmt = $conn->prepare($sqlBrowse);
$stmt->bindParam(":findInName", $search);
$stmt->bindParam(":findInBodyPart", $search);
$stmt->bindParam(":findInMuscleGroup", $search);
$stmt->bindParam(":findInEquipment", $search);
$stmt->execute();
$exercises = $stmt->fetchAll();
}
else if (isset($_POST['checklist'])) {
$searchTerm = $_POST['checklist'];
$search = '%' . $searchTerm . '%';
$stmt = $conn->prepare($sqlBrowse);
$stmt->bindParam(":findInEquipment", $search);
$stmt->execute();
$exercises = $stmt->fetchAll();
}
?>
HTML:
<form action="directory.php" method="post">
<input type="checkbox" name="checklist[]" class="check" value="Dumbell"> Dumbbell<br>
<input type="checkbox" name="checklist[]" class="check" value="kettlebell"> Kettlebell<br>
</form>
<div class="col-sm-10">
<h1 class="theTitle"> Workout Directory </h1>
<div class="d-flex flex-wrap">
<?php
foreach ($exercises as $exercise) {
?>
<div class="card" id="workoutCard">
<div class="card-header"> <?= $exercise->name ?> </div>
<div class="card-body">
<div class="thumbnail"> </div>
<div class="info">
<a id="subTitle">Body Parts:</a> <?= $exercise->bodyPart ?><BR>
<a id="subTitle">Muscle Group:</a> <?= $exercise->muscleGroup ?><BR>
<a id="subTitle">Equipment Used:</a> <?= $exercise->equipment ?>
</div>
</div>
</div>
<?php
}
?>
My search bar works perfectly so I haven't displayed the HTML for it.
I'm a beginner so I'm not sure where I've gone wrong, I'm not sure if I can have two PDO execute statements under the same name variable.
Any help or tips will be appreciated
UPDATE: One checkbox will now display all relevant info (without the checklist[]) but it doesn't work for two of them(I believe I need the checklist[] to make the two work)
so my new question is, how do I make it so that :
$search = '%' . $searchTerm . '%';
displays more then the one searchTerm
I assume you want the form to post back when a user checks a check box? If so, add a click event to the check boxes which posts the form, eg
<input type="checkbox" name="checklist[]" class="check" onclick='document.forms[0].submit();' value="Dumbell"> Dumbbell<br>
<input type="checkbox" name="checklist[]" class="check" onclick='document.forms[0].submit();' value="kettlebell"> Kettlebell<br>
For the array to string conversion error, it is because of the checklist attribute in the form fields.
As you are using a checklist[] (which is an array) in your form, you will have to a loop to get the values:
else if (isset($_POST['checklist'])) {
$searchArray = $_POST['checklist'];
foreach ($searchArray as $searchTerm)
{
$search = '%' . $searchTerm . '%';
$stmt = $conn->prepare($sqlBrowse);
$stmt->bindParam(":findInEquipment", $search);
$stmt->execute();
$exercises = $stmt->fetchAll();
}
}

How to populate dropdown field pre-selected with the existing data from another MySQL table?

In my database I have 2 tables:
To insert data, I have a form that populates dropdown options from the table formulation. This is what the insert form for formulation dropdown looks like:
<?php
$formulation = '';
$query = "SELECT * FROM formulation";
$result = mysqli_query($connect, $query);
while ($row = mysqli_fetch_array($result)) {
$formulation .= '<option value="' . $row["formulationID"] . '">' . $row["formulation_name"] . '</option>';
}
?>
<select>
<option value="">Select formulation</option>
<?php echo $formulation; ?>
</select>
Now I am working on the ‘Update’ form. But my question is how can I populate the ‘Formulation’ field dropdown with the data from the formulation table (like as the insert form) but pre-selected with the existing formulation value for the name from the items table? Like this image below:
I am having problem with how I should build the form. How should I proceed with this form?
<?php
$output = array('data' => array());
$sql = "SELECT * FROM items";
$query = $connect->query($sql);
while ($row = $query->fetch_assoc()) {
$output['data'][] = array(
$row['name'],
);
}
echo json_encode($output);
?>
<form action=" " method="POST">
<div>
<label>Name</label>
<input type="text"><br>
<label>Formulation</label>
<select >
<!--What should be the codes here? -->
</select>
</div>
<button type = "submit">Save changes</button>
</form>
Thanks in advance for your suggestion.
Note: I'm not a user of mysqli so maybe there will be some error, but you will get the idea. This will not tackle the update part, just the populate part
Since you are editing a certain item, I will assume that you have something to get the item's itemID.
<?php
$sql = "SELECT * FROM items WHERE itemID = ?";
$query = $connect->prepare($sql);
$query->bind_param("s", $yourItemID);
$query->execute();
$result = $query->fetch_assoc();
$itemName = $result['name'];
$itemFormulation = $result['formulation_fk'];
//now you have the name and the formulation of that certain item
?>
<form action=" " method="POST">
<div>
<label>Name</label>
<input type="text" value="<?php echo $itemName; ?>"><br>
<label>Formulation</label>
<select >
<?php
$query = "SELECT * FROM formulation";
$result = mysqli_query($connect, $query);
while ($row = mysqli_fetch_array($result)) {
?>
<option value="<?php echo $row['formulationID']; ?>" <?php echo ($row['formulationID'] == $itemFormulation) ? 'selected' : ''; ?>>
<?php echo $row['formulation_name']; ?>
</option>
<?php
}
?>
</select>
</div>
<button type = "submit">Save changes</button>
</form>
I changed the code to better suit the problem, there may be typos, just comment for clarification
If I have understand Your question... You have to put Your result into a string. For example:
<?php
$output = array('data' => array());
$sql = "SELECT * FROM items";
$query = $connect->query($sql);
$option = '';
while ($row = $query->fetch_assoc()) {
$name=$row['name'],
$option.='<option value="$name">$name</option>'
}
echo json_encode($output);
?>
<form action=" " method="POST">
<div>
<label>Name</label>
<input type="text"><br>
<label>Formulation</label>
<select >
<?=$option?>
</select>
</div>
<button type = "submit">Save changes</button>
</form>
I hope to be of help
This should do the trick:
<?php
$itemsSql = "SELECT * FROM items WHERE itemId = 5";
$itemQuery = $connect->query($sql);
$item = $itemQuery->fetch_assoc();
$formulationsSql = "SELECT * FROM formulation";
$formulationsQuery = $connect->query($sql);
$formulations = $itemQuery->fetch_assoc();
?>
<form action="updateItem" method="POST">
<div>
<label>Item Name</label>
<input type="text" value="<?= $item[0]['name']; ?>"><br>
<label>Formulation</label>
<select>
<?php foreach($formulations as $formulation){
echo '<option value="'. $formulation['formulationId'].'">' .
$formulation['formulation_name'] . '</option>';
} ?>
</select>
</div>
<button type = "submit">Save changes</button>
</form>

Refining PDO results from MySQL database with Text Box

I'm currently retrieving data from a MySQL database using PDO. I'm using a foreach to display the data onto a page, and wish for the user to be able to enter a search term into a input field, hit the submit button, and then only results who's title contains the search term are returned.
Here is my current code:
file_functions.php - Where the SQL query function is located
function getbycategory($category, $limit){
global $db;
if (isset($category) AND $category != "all") {
$sm = $db->prepare ("SELECT * FROM parts WHERE main_category = :category");
$sm->bindParam(':category', $category, PDO::PARAM_INT);
} else {
$sm = $db->prepare ("SELECT * FROM parts");
}
$sm->execute();
return $sm->fetchAll();
}
files.php - Where the results are displayed
$files = getbycategory($_GET['filter']);
foreach($files as $file){
echo'<div class="col-lg-" id="file-'.$file['id'].'">
<div class="file-list-item first" id="">
<img class="file-image" height="120px" width="180px" src="'.$file['image_url'].'" />
<div class="file-text">
<h3><strong>'.$file['name'].'</strong></h3>
Submitted by: '.$file['submitter'].'<br/>
Author: '.$file['author'].'<br />
Category: '.ucfirst($file['subcategory']).'<br />
Description: '.substr($file['description'],0,45).'...
</div>
<div class="download">
<a target="_blank" href="'.$file['download_url'].'" class="btn-success btn btn-default">Download</a>
Report as Broken<br /><br />';
if($file['is_broken']){
echo '<span class="broken"><i data-toggle="tooltip" data-placement="left" id="broken" title="This file has been reported as broken and is awaiting review." class="fa fa-warning fa-2x"></i></span>';
}
echo '
</div>
</div>
</div>';
};
?>
Below is the form used to refine the results. Currently the filter dropdown menu works for the filter, but the search term does not. This is what I wish to implement
<form method="get">
<select name="filter">
<option <?php if($_GET['filter'] == "all" OR !isset($_GET['filter'])){echo 'selected';} ?> value="all">View All Files</option>
<option <?php if($_GET['filter'] == "1") {echo 'selected';} ?> value="1">View Vehicles Only</option>
<option <?php if($_GET['filter'] == "2") {echo 'selected';} ?> value="2">View Lighting Equiptment</option>
</select>
<input type="submit" value="Filter Results"/><br /><br />
<input type="text" name="search" placeholder="Enter a search term" />
<input type="submit" value="Search Results"/>
</form>
To summarise, I wish to use the text field in the bottom snippet of code to refine the results displayed in files.php by comparing their title to the search term.
I wish to compare the search term to the $file['name'].
Many thanks.
Ok, let me step you through it using a simple LIKE comparison...
First, the method signature. Globals are a bad idea so we'll include the PDO instance
function getbycategory(PDO $db, $category = null, $search = null, $limit = null)
Now, build the query and collect parameters as you go.
$params = [];
$where = [];
if ($category !== null) {
$where[] = 'main_category = :category';
$params[':category'] = [
'val' => (int) $category,
'type' => PDO::PARAM_INT
];
}
if ($search !== null) {
$where[] = "LOWER(`name`) LIKE CONCAT('%', LOWER(:search), '%')";
$params[':search'] = [
'val' => (string) $search,
'type' => PDO::PARAM_STR
];
}
$query = sprintf('SELECT * FROM `parts` %s', implode(' AND ', $where));
if ($limit !== null) {
$query .= ' LIMIT :limit';
$params[':limit'] = [
'val' => (int) $limit,
'type' => PDO::PARAM_INT
];
}
$stmt = $db->prepare($query);
foreach ($params as $key => $param) {
// use bindValue to avoid problems with variable references in the loop
// see http://stackoverflow.com/questions/4174524/binding-params-for-pdo-statement-inside-a-loop
$stmt->bindValue($key, $param['val'], $param['type']);
}
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);

Categories