I’m trying to make a "sort" button. When someone chooses something from a list (HTML select) it will sort items from my database on my HTML page.
// head
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(function () {
$('#sort_form').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: "post",
url: 'php/file-php.php',
data: new FormData(this),
processData: false,
contentType: false,
success: function () {
alert($("#sort").val());
},
error: function () {
}
});
});
});
</script>
// HTML
<?php require "php/file-php.php"; ?>
<form method="POST" id="sort_form" action="php/file-php.php" enctype='multipart/form-data'>
<input type="submit" id="sort_btn" value="Sort">
<select name="sort" id="sort">
<optgroup label="alphabetically">
<option value="alphabet_p">
A-Z
</option>
<option value="alphabet_rev_p">
Z-A
</option>
</optgroup>
<optgroup label="in whole portion">
<option value="kcal_low_a">
Kcal (to highest)
</option>
<option value="kcal_high_a">
Kcal (to lowest)
</option>
</optgroup>
</select>
</form>
<?php
recipe_list_dishes();
?>
// PHP (php/file-php.php)
<?php
function recipe_list_dishes() {
$con = mysqli_connect("localhost", "root", "", "cookbook");
$sort = $_POST["sort"];
$dish_type = "'dishes'";
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY name";
$kcal_query = "(fat * 9 + carbohydrates * 4 + fiber * 2 + protein * 4)";
$carbohydrates = "carbohydrates / 10";
$wpts_query = "(fat * 9 + protein * 4) / 100";
switch ($sort) {
case "alphabet_p":
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY name";
break;
case "alphabet_rev_p":
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY name DESC";
break;
case "kcal_low_a":
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY $kcal_query";
break;
case "kcal_high_a":
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY $kcal_query DESC";
break;
}
$res = mysqli_query($con,$sql);
while($row = mysqli_fetch_assoc($res)) {
$recipename = $row['name'];
$fat = (int)$row['fat'];
$carbohydrates = (int)$row['carbohydrates'];
$fiber = (int)$row['fiber'];
$protein = (int)$row['protein'];
$weight = (int)$row['weight'];
$portion = (int)$row['portion'];
$kcal = ($fat * 9) + ($carbohydrates * 4) + ($fiber * 2) + ($protein * 4);
$cp = $carbohydrates / 10; // Carbohydrate portion = 10g carbs
$wpts = ($fat * 9 + $protein * 4) / 100; // Warsaw Pump Therapy School = (fat kcal + protein kcal) / 100
echo "<a href='".$recipename."'>".$recipename."</a>";
echo "Whole:<br>";
echo round($kcal, 1)." kcal<br>";
echo round($cp, 1)." WW<br>";
echo round($wpts, 1)." WBT<br>";
echo "<br>";
echo "<img src='uploads/".$row['image']."' class='imageaaa'>";
}
mysqli_close($con);
}
?>
Note: there is more code, this is just a shortened version.
When I’m trying to display elements from my database in my HTML file, there is an error
Warning
: Undefined array key "sort" in
C:xampphtdocsphpfile-php.php
on line
5 (line 5 = $sort = $_POST["sort"];)
I checked it in js with $("#sort").val();
and it seems to work correctly.
It had worked before I used AJAX, but I’m forced to do it this way (I don’t want the page to be reloaded after the button submit).
Also, the form isn’t sent (items are not being sorted).
How can I fix it?
Edit with new code:
<script>
$(function () {
$('#sort_form').on('submit', function (e) {
e.preventDefault();
$.ajax({
type: "post",
url: 'php/file-php.php',
data: new FormData(this),
processData: false,
contentType: false,
success: function () {
alert($("#sort").val());
},
error: function () {
}
});
});
});
</script>
HTML
<form method="POST" id="sort_form" enctype='multipart/form-data'>
<input type="submit" id="sort_btn" value="Sort">
<select name="sort" id="sort">
<optgroup label="alphabetically">
<option value="alphabet_p">
A-Z
</option>
<option value="alphabet_rev_p">
Z-A
</option>
</optgroup>
<optgroup label="in whole portion">
<option value="kcal_low_a">
Kcal (to highest)
</option>
<option value="kcal_high_a">
Kcal (to lowest)
</option>
</optgroup>
</select>
</form>
<?php require "php/display.php" ?> // it displays nothing without it
<?PHP
recipe_list_dishes();
?>
<?PHP
recipe_list_desserts();
?>
<?PHP
recipe_list_snacks();
?>
//php (php/file-php.php)
<?php
$con = mysqli_connect("localhost", "root", "", "cookbook");
$sort = $_POST["sort"];
$dish_type = "'dania'";
$kcal_query = "(fat * 9 + carbohydrates * 4 + fiber * 2 + protein * 4)";
$carbohydrates = "carbohydrates / 10";
$wpts_query = "(fat * 9 + protein * 4) / 100";
switch ($sort) {
case "alphabet_p":
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY name";
break;
case "alphabet_rev_p":
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY name DESC";
break;
case "kcal_low_a":
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY $kcal_query";
break;
case "kcal_high_a":
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY $kcal_query DESC";
break;
}
echo $sort." hello";
mysqli_close($con);
?>
// PHP (php/display.php)
<?php
require "php/file-php.php";
function recipe_list_dishes() {
$con = mysqli_connect("localhost", "root", "", "cookbook");
$dish_type = "'dishes'";
$sql = "SELECT * FROM product WHERE type = $dish_type ORDER BY name";
$res = mysqli_query($con,$sql);
while($row = mysqli_fetch_assoc($res)) {
$recipename = $row['name'];
$fat = (int)$row['fat'];
$carbohydrates = (int)$row['carbohydrates'];
$fiber = (int)$row['fiber'];
$protein = (int)$row['protein'];
$weight = (int)$row['weight'];
$portion = (int)$row['portion'];
$kcal = ($fat * 9) + ($carbohydrates * 4) + ($fiber * 2) + ($protein * 4);
$cp = $carbohydrates / 10; // Carbohydrate portion = 10g carbs
$wpts = ($fat * 9 + $protein * 4) / 100; // Warsaw Pump Therapy School = (fat kcal + protein kcal) / 100
echo "<a href='".$recipename."'>".$recipename."</a>";
echo "Whole:<br>";
echo round($kcal, 1)." kcal<br>";
echo round($cp, 1)." WW<br>";
echo round($wpts, 1)." WBT<br>";
echo "<img src='uploads/".$row['image']."' class='imageaaa'>";
}
mysqli_close($con);
}
?>
There can be some mistakes because I have to change some names to English. As you can see I have more functions to display the data, they have a different $dish_type
value.
2
Answers
In the file-php.php file you need to set an isset condition to get the data posted via ajax on this file.
Remove the function "recipe_list_dishes" and put the code inside the isset() condition.
Thus in the file-php.php file you need to start with the condition stated below:
Another thing that is not according to the standards that I found at the end of your file-php.php is:
REPLACE IT WITH THE CODE PROVIDED BELOW:
outside the while loop you can
This $response contains some HTML which will be returned to the AJAX success function as a response from the PHP file
Gathering the data
You have this JS code for submit:
Here you instantiate FormData, passing
this
, that is, the element whose event is being processed. It would not hurt to use a debugger and check the result ofFormData
instantiation, see whether your sort is indeed loaded. Of course, this should be the case, given the fact that yourselect
tag has thename
ofsort
, but it is not necessarily the case.Check the request data
When you test this in the browser, looking for
$("#sort").val()
actually checks whether the element with theid
ofsort
has a (proper) value. However, if this element has a proper value, that does not mean that it is actually being sent to the server via the request. You only assume that if the value is proper, then it is being sent.To actually test this, you will need to open the Dev Tools of your browser, navigate to the Network tab and see the requests being sent. When this preparement is done, you can submit your form via AJAX (click on the button) and see a new line in the requests grid of the Network tab of the Dev Tools of your browser. See what is being sent in the payload tab if you have such a tab or wherever your browser shows the request parameters. If you see the
sort
parameter there with proper value, THEN you know that yoursort
value was successfully sent to the server.Separate the initial page load from the submit of your form
As it is, your code calls
recipe_list_dishes();
just after yourform
is defined. So,recipe_list_dishes()
is called before you submitted theform
and at this stage, you do not have anything resembling a$_POST["sort"]
at the server-side, which gives you the warning you have mentioned in your question.You will need to avoid calling this function just after your HTML and, instead, make sure that it’s properly reached when you actually submit your
form
. So, first your page is loaded, then, you submit yourform
. Your code that runs when the page initially loads assumes that asort
was already submitted, which of course does not happen when you load your page, it only happens when you actually submit theform
.Default your sort value
You have this code
which assumes that whenever this code runs, you have a posted
sort
. Don’t assume that. Instead, default it to some value, so, if for whatever reason sort is not properly defined, the page and the form would still be operational (for example if you or one of your colleagues mistakenly remove the sort select, or rename it or whatever, then, instead of having errors, the sort would fail gracefully). So, let’s use a default if needed:SQL injection
Finally, you do not protect your code. You should use parameterized queries to sanitize and protect against SQL injection. I admit that as it stands, your code looks to be safe, but it’s only an accident, because the one parameter that you receive is not actually injected into your SQL code, but that could change anytime, so I strongly advise you to look into SQL injection, sanitize your code and, if you will get parameters that are actually injected into your query, if you apply this good practice, then it is unlikely that you would end up with a vulnerability. While, with your current code, which ignores this danger after some evolution can easily become vulnerable.