PHP/Jquery issue populating 3 dynamic select boxes - javascript

I am quite new to PHP and JQuery and am struggling with 3 dynamic select boxes. The first one should contain a list of my instruments. The second one a list of categories, and the third should contain a list of subcategories, based on the selected value of the category and selected instrument. Have followed some great tutorials on the matter, but none seem exactly what I need. So far, managed to populate the instruments and the categories select box correctly, but when clicking on the categories select box to select the value I want, it malfunctions, the subcategories box stay empty. I believe the problem is because I do not send the instrumentID correctly when the categories onchange occurs, but cannot seem to find how to properly send it. Can anyone help me please ?
This is my code so far :
<?php
$query = "SELECT * FROM instruments ORDER BY name ASC";
$result = $db->query($query)->results();
?>
<div class = "form-group col-md-3>"
<select name="instrument_id" id="instrument_id">
<option value="">-Select Instrument-</option>
<?php
foreach($result as $row){
echo '<option value="'.$row->id.'">'.$row->name.'</option>';
}
?>
</select>
</div>
<div class="form-group col-md-3">
<label for="category_id" class="control-label">Category</label>
<select id="category_id" name="category_id" class="form-control input-sm">
<option value="">-Select Category-</option>
</select>
</div>
<div class="form-group col-md-3">
<label for="subcategory_id" class="control-label">Subcategory</label>
<select id="subcategory_id" name="subcategory_id" class="form-control input-sm">
<option value="">-Select Subcategory-</option>
</select>
</div>
<script>
$(document).ready(function(){
$('#instrument_id').on('change', function(){
const instrumentID = $(this).val();
if(instrumentID){
$.ajax({
type:'POST',
url:'<?=PROOT?>admindocuments/get_categories',
data:{instrument_id: instrumentID},
success:function(html){
$('#category_id').html(html);
$('#subcategory_id').html('<option value="">-Select Subcategory-</option>');
}
});
}else{
$('#category_id').html('<option value="">-Select Category- </option>');
$('#subcategory_id').html('<option value="">-Select Subcategory- </option>');
}
});
$('#category_id').on('change', function(){
const categoryID = $(this).val();
const instrumentID = $('#instrument_id').val();
if(categoryID){
$.ajax({
type:'POST',
url:'<?=PROOT?>admindocuments/get_subcategories',
data: {
category_id: categoryID,
instrument_id: instrumentID,
},
success:function(html){
$('#subcategory_id').html(html);
}
});
}else{
$('#subcategory_id').html('<option value="">-Select Subcategory- </option>');
}
});
});
</script>
And this is the code in my get_categories.php and get_subcategories.php file :
get_categories :
<?php
if($_POST["instrument_id"]){
$query = "SELECT * FROM categories ORDER BY name ASC";
$result = $db->query($query)->results();
echo '<option value="">-Select Category-</option>';
foreach($result as $row){
echo '<option value="'.$row->id.'">'.$row->name.'</option>';
}
}
?>
get_subcategories :
<?php
if($_POST["category_id"] && !empty($_POST["instrument_id"])){
$query = "SELECT * FROM subcategories WHERE category_id = ".$_POST['category_id']." AND instrument_id = ".$_POST['instrument_id']." ORDER BY name ASC";
$result = $db->query($query)->results();
echo '<option value="">-Select Subcategory-</option>';
foreach($result as $row){
echo '<option value="'.$row->id.'">'.$row->name.'</option>';
}
}
What am I doing wrong ? Please help me.
Kind regards

The root of your problem is that you aren't sending the instrument id at all when getting subcategories. First you need to fetch it in your handler, since your select has an id, it's easy:
$('#category_id').on('change', function(){
const categoryID = $(this).val(); // I changed var to const here, read more about it below
const instrumentID = $('#instrument_id').val(); // this line added
Here you can read about using const and let over var.
And then you need to send it in AJAX data:
// sending it as an object is more readable and PHP reads it just the same
data: {
category_id: categoryID,
instrument_id: instrumentID,
}
Now you also need to fix your PHP side. As it currently stands, if you send this kind of data, your first branch would be activated because instrument id is set in both cases:
if (!empty($_POST["instrument_id"])) {
// get categories
} elseif(!empty($_POST["category_id"])) {
// get subcategories
}
What you should be checking for instead is if both parameters are set (that's how you determine you need subcategories):
if (!empty($_POST["instrument_id"]) && !empty($_POST["category_id"])) {
// get subcategories
} elseif (!empty($_POST["category_id"]) && empty($_POST["instrument_id"])) {
// get categories
}
But a much cleaner solution would be to simply have two PHP scripts, one for categories and one for subcategories. Then you wouldn't need this complex if-elseif structure and your tasks would be logically separated (currently, you're using a file called get_subcategories to get both subcategories and categories, so it isn't really aptly named).
Another thing you should avoid at all costs is building queries by directly inserting parameters:
$query = "SELECT * FROM subcategories WHERE category_id = ".$_POST['category_id']." AND instrument_id = ".$_POST['instrument_id']." ORDER BY name ASC";
This kind of practice leaves you wide open to SQL injection. You should use prepared statements instead.

Related

PHP-jquery-ajax dynamic dependent selection - difficulty

I'm programming a simple form with a dynamic dependent selection. There are two files. One is a php file with html, javascript and php inside, the second is a php file to get data for the second selection and send them back in json format. In the first (and main) file I have the form with two select fields. First field is for province, second is for towns. Data are in a MySQL db, two tables, table_provinces for provinces (103 rows) and table_towns for towns (8000 rows). Normally connect to the db as usual and also link to jquery using a javascript link. First I get provinces options for the first select field, using php to get the values from table_provinces of the db. Then with the javascript " on('change',function(){ here I use ajax...}) " I pass the selected value using ajax to a php file that might extract towns from table_towns and give back (in json format) values to populate the second select field. Javascript gets correctly the selected value from the first selection field (I used an alert to know it), but nothing more happens. So this is the code.
Link to jquery:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
HTML first select field:
<form method="post" action="usemychoice.php">
<select id="province" name="province" color="white">
<option value="" selected>Select a province</option>
This is how I populate the first select field:
<?php
$sql = "SELECT * FROM table_provinces";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_assoc($result)) {
echo "<option value='".$row['prov']."'>".$row['extended_province']."</option>";
}
} else {
echo "Error: ..........";
}
?>
And after closing that field with a /select I have this code to get values for populating with town names the second select field:
<script type="text/javascript">
$(document).ready(function(){
$('#province').on('change',function(){
var provinceID = $(this).val();
if(provinceID){
window.alert("ok you've chosen the province "+provinceID);
$.ajax({
type:'POST',
url:'get_towns.php',
data: 'prov='+provinceID,
success:function(html){
$('#town').html(html);
}
});
}else{
$('#town').html('<option value="">Please select the province first</option>');
}
});
});
</script>
This is the get_town.php code:
<?php
//*****after a require to the connection db routine"
if(!empty($_POST["prov"])) {
$sql = "SELECT * FROM table_towns WHERE prov LIKE '%" .$_POST['prov']."%'";
$result = mysqli_query($conn, $sql);
$json = [];
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_assoc($result)) {
$json[$row['prov']] = $row['town'];
} else {
echo "Error: .................";
}
echo json_encode($json);
}
?>
Finally I have the html code :
<select id="town" name="town" color="white">
<option value="" selected>Select province first</option>
At the end of the day, the code has something wrong because I don't get any data back from get_town.php to populate the second select field, and since I didn't see a window.alert that I've put there to check ongoing execution (you don't see it in the code posted here), it seems that is not executed. Any help?
url:'get_towns.php',
Isn't it get_town.php without plural ?
Apparently it seems that the output of get_town.php is JSON
echo json_encode($json);
but in your JS it is directly output to an html element
$('#town').html(html);
Solution:
Either modify get_town.php to send html OR modify the success function in JS to convert received JSON to proper html.
I hope this will help.
UPDATE:
Replace this part of php
while($row = mysqli_fetch_assoc($result)) {
$json[$row['prov']] = $row['town'];
}
with something
echo '<option value="" selected>Select Town</option>';
while($row = mysqli_fetch_assoc($result)) {
echo '<option value="'.$row['town'].'" color="white">'.$row['town'].'</option>';
}
and finally remove the line
echo json_encode($json);

How to display data with radio buttons based on drop down selection?

I'm trying to dynamically generate radio buttons with data in front of them. The data that is to be displayed in front of the radio button is based on a drop down selection, which also displays some data in a text box using javascript.
I tried taking the selected option in a string and use it in the next query, but I know I am doing it wrong.
Database Connection
$db = pg_connect("");
$query = "select account_name,account_code,address1,address2,address3 FROM
customers";
$result = pg_query($db,$query);
//NEW QUERY
$sql1= "select name from conferences";
$result1= pg_query($db, $sql1);
//END
//New Code
<select class="form-control" id="conference" name="conference">
<option value="">Select Conference...</option>
<?php while($rows1 = pg_fetch_assoc($result1)) { ?>
<option value="<?= $rows1['code']; ?>"><?= $rows1['name']; ?></option>
<?php } ?>
</select>
<br>
// END OF NEW CODE
Dropdown to select the data.
<select onchange="ChooseContact(this)" class="form-control"
id="account_name" name="account_name" >
<?php
while($rows= pg_fetch_assoc($result)){
echo '<option value=" '.$rows['address1'].' '.$rows['address2'].'
'.$rows['address3'].''.$rows['account_code'].'">'.$rows['account_name'].'
'.$_POST[$rows['account_code']].'
</option>';
}?>
</select>
Displaying data in the text area based on the selcted value using javascript. (The code works fine till here)
<textarea readonly class="form-control" style="background-color: #F5F5F5;"
id="comment" rows="5" style="width:700px;"value=""placeholder="Address...">
</textarea>
<script>
function ChooseContact(data) {
document.getElementById ("comment").value = data.value;
}
</script>
Displaying data in front of the radio buttons based on the selected option(This code works if I use some random value in the query, but not if I use the selected value 'account_code' from the previous query. I'm using POST GET method to carry the selected value)
<?php
//NEW CODE
$sql = "select order_number, order_date from orders where
customer_account_code = '3000614' and conference_code='DS19-'"; <-Data
gets displayed when put random value like this.
$code = $_GET[$rows['account_code']];
$conf = $_GET[$rows1['conference_code']];
$sql = "select order_number, order_date from orders where
customer_account_code = '$code' and conference_code= '$conf']"; <- But I
want to display the data against the selected value, i.e, the 'account_code'
in the variable $code from the dropdown select
//END
$res = pg_query($db,$sql);
while($value = pg_fetch_assoc($res) ){
echo "<input type='radio' name='answer'
value='".$value['order_number']." ".$value['order_date']."'>"
.$value['order_number'].$value['order_date']." </input><br />";
}
?>
I need to help to find a way to put the selected 'account_code' in a variable and use it in the $sql query.
Please try with this code : (It's work for me)
1- Add this line to your HTML <head>:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" type="text/javascript"></script>
2- Edit your CODE to this:
Dropdown to select the data:
<select class="form-control" id="account_name" name="account_name">
<option value=""></option>
<?php while($rows = pg_fetch_assoc($result)) { ?>
<option value="<?= $rows['address1'].' '.$rows['address2'].' '.$rows['address3'].'-'.$rows['account_code']; ?>"><?= $rows['account_name']; ?></option>
<? } ?>
</select>
Displaying data in the text area based on the selected value using jQuery:
<textarea readonly class="form-control" style="background-color: #F5F5F5;"
id="comment" rows="5" style="width:700px;" value="" placeholder="Address..."></textarea>
jQuery Code:
<script type="text/javascript">
$('#comment').val($('#account_name').val()); // MAKE A DEFAULT VALUE
(function($) {
$('#account_name').change(function() {
$('#results').html(''); // REMOVE THE OLD RESULTS
var option = $(this).val();
$('#comment').val(option);
// EDIT RADIO WITH AJAX
$.ajax({
type: "POST",
url: "path/test.php",
dataType:'JSON',
data: $('#account_name').serialize()
}).done(function(data) {
for (var i = 0; i < data.length; i++) {
// ADD RADIO TO DIV RESULTS
$('#results').append('<input type="radio" name="answer" value="'+data[i].order_number+'">'+data[i].order_date+'</input><br>');
}
});
});
})(jQuery);
</script>
after that, add this HTML to your page, to show RESULTS FROM AJAX DATA
<!-- RADIOs -->
<div id="results"></div>
3- Create a new file like path/test.php
in this file, use this CODE to return values with JSON :)
<?php
header('Content-type: application/json');
// CONNECT (JUST USE YOUR CUSTOM CONNECTION METHOD & REQUIRE CONFIG FILE IF YOU WANT)
$db = pg_connect("");
$value = explode('-', $_POST['account_name']);
// EXPLODE AND GET LAST NUMBER AFTER < - >
$code = (int) end($value);
$sql = "select order_number, order_date from orders where customer_account_code = '$code'";
$res = pg_query($db, $sql);
// CREATE JSON RESULTS
$is = '';
while($data = pg_fetch_assoc($res)) {
$is .= json_encode($data).', ';
}
// AND GET ALL
echo '['.substr($is, 0, -2).']';
?>

How can I have a PHP query select a certain table based on a drop down list selection?

I have a web program where the goal is plot data points for a certain Kiln that the user has selected. My problem is when a user wants to select a new Kiln, how can I update all the separate JSON pages to where the data is pulled from the new table they selected?
Here is my drop down list creater code.
<p class="navleft">
Kiln Number:<br>
<select name="kilns" id="kilns">
<?php
$sql = "SHOW TABLES FROM history";
$result = mysqli_query($con,$sql);
while($table = mysqli_fetch_array($result)) { // go through each row that was returned in $result
echo ("<option value='". $table[0] . "'>" . $table[0] . "</option>");
}
?>
</select>
</p>
And here is one of the php pages where I select all the data from a value in a table and turn it into a JSON file.
<?php
$con = mysqli_connect("localhost","KilnAdmin","KilnAdmin","history");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
mysqli_select_db($con,"history") or die ("no database");
//Fetch Data
$query = "SELECT * FROM k1_history LIMIT 1000";
$result = mysqli_query($con,$query);
if ($result) {
$data = array();
while($row = mysqli_fetch_assoc($result)) {
//$data[] = $row;
$data[] = array(
"date" => $row[ 'Timestamp' ],
"value" => $row[ 'DryBulbFront' ]
);
}
echo json_encode($data);
}
else {
echo "Error";
}
?>
Where is says k1_history, how can I get that to be the selection from the user in the dropbox menu from the other page?
In this kind of scenario you have to strongly pay attention to avoid SQL injection. Use a whitelist approach as mentioned by Konstantinos Vytiniotis and check this out How can I prevent SQL injection in PHP?
If I understand correctly what you want, then what you need is Ajax.
You have to populate the select like you do and on each select, make an Ajax call to a .php where you will handle what the user has chosen. In your case this .php file is going to take the table name the user chose, run a query and return some results back to the html. For demonstration purposes, I'll explain with an example.
Let's say in your .html you have a select like this:
Select Value:
<select name="kilns" id="kilns">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
What defined in the value property of the option is what you are gonna pass to the .php file I mentioned. To do that, you use Ajax, so inside some script tags you have:
$('#kilns').on('change', function(e) {
var data = {'kilns': this.value};
$.ajax({
type: 'POST',
url: 'submit.php',
data: data,
dataType: 'json'
}).done(function(msg) {
alert(msg);
});
});
What this does is that every time a user selects something from the select, then this function is called, where the select's value (var data = {'kilns': this.value};) is being sent to a file named submit.php, via POST. The submit.php could look like this:
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
$kilns_error = 0;
if (isset($_POST['kilns']) && !empty($_POST['kilns'])) {
$kilns = $_POST['kilns'];
} else {
$kilns = null;
$kilns_error = 1;
}
if ($kilns_error != 1) {
echo json_encode($kilns);
}
}
What happens here is after we check we have indeed a POST REQUEST, we check whether the value is undefined or empty. After this simple check, we proceed to echo json_encode($kilns); where we return the value that we initially sent to the .php script, which in fact is the value the user selected.
In your case, what you have to do it to actually do some things in the .php script and not just return the value that you called it with. Also, make sure to pass the value you take through a whitelist to ensure that the user selects an actual table and is not trying to create problems for your database, cause it would be really easy to just change the value of what he is going to select before actually selecting it. Have a look at the prepared statements of the mysqli and PDO.

Getting form data from both dependent drop down lists to php

I have a form on my page which includes 2 dependent drop down lists. When user selects value from 1st list, it populates the second list and user then selects value from 2nd list.
I want to submit form data to php page to insert into table in mysql, but when it submits, all data is passed EXCEPT value from 2nd list. Value from 1st list and other input fields are passed OK.
I've tried everything I know and I can't make this work. Any ideas how to implement this?
This is the form from index2.php (EDIT: simplified the form element):
<form name="part_add" method="post" action="../includes/insertpart.php" id="part_add">
<label for="parts">Choose part</label>
<select name="part_cat" id="part_cat">
<?php while($row = mysqli_fetch_array($query_parts)):?>
<option value="<?php echo $row['part_id'];?>">
<?php echo $row['part_name'];?>
</option>
<?php endwhile;?>
</select>
<br/>
<label>P/N</label>
<select name="pn_cat" id="pn_cat"></select>
<br/>
<input type="text" id="manufactured" name="manufactured" value="" placeholder="Manufactured" />
<input id="submit_data" type="submit" name="submit_data" value="Submit" />
</form>
And this is javascript:
$(document).ready(function() {
$("#part_cat").change(function() {
$(this).after('<div id="loader"><img src="img/loading.gif" alt="loading part number" /></div>');
$.get('../includes/loadpn.php?part_cat=' + $(this).val(), function(data) {
$("#pn_cat").html(data);
$('#loader').slideUp(200, function() {
$(this).remove();
});
});
});
});
And this is php to load 2nd list:
<?php
include('db_connect.php');
// connects to db
$con=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$part_cat = $_GET['part_cat'];
$query = mysqli_query($con, "SELECT * FROM pn WHERE pn_categoryID = {$part_cat}");
while($row = mysqli_fetch_array($query)) {
echo "<option value='$row[part_id]'>$row[pn_name]</option>";
}
?>
I am getting $part_cat from 1st list to insertpart.php, but $pn_cat.
EDIT: this is insertpart.php (simplified and it just echos resuls)
<?php
//Start session
session_start();
//Include database connection details
require_once('../includes/db_details.php');
//DB connect
$con=mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
// Check connection
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// escape variables for security
// find part name based on ID
$part_typeID = mysqli_real_escape_string($con, $_POST['part_cat']);
$part_name_result = mysqli_query($con, "SELECT part_name FROM parts WHERE part_id = $part_typeID");
$part_row = mysqli_fetch_array($part_name_result, MYSQL_NUM);
$part_type = $part_row[0];
echo"part_type='$part_type'";
//find pn value based on id
$pn_typeID = mysqli_real_escape_string($con, $_GET['pn_cat']);
$pn_name_result = mysqli_query($con, "SELECT pn_name FROM pn WHERE pn_id = $pn_typeID");
$pn_row = mysqli_fetch_array($pn_name_result, MYSQL_NUM);
$pn = $pn_row[0];
echo"pn='$pn'";
mysqli_close($con);
?>
It's still work in progress, so the code is ugly, and I know I'm mixing POST and GET that is being rectified. If I echo $pn_cat on this page there is no output, $part_type is OK.
Can you try swapping the $_GET in
$pn_typeID = mysqli_real_escape_string($con, $_GET['pn_cat']);
with $_POST?
$pn_typeID = mysqli_real_escape_string($con, $_POST['pn_cat']);
EDIT: based on asker's feedback and idea for a work-around
NOTE: This edit is based on what you suggested, even though I tested your original code and received satisfactory results (after I removed the PHP and MySQL from the code and replaced them with suitable alternatives).
The Work-Around
Here's the HTML for the hidden field:
<input type="hidden" id="test" name="test" value="" placeholder="test" />
Here's a simple Javascript function:
function setHiddenTextFieldValue(initiator, target){
$(initiator).change(function() {
$(target).val($(this).val());
});
}
You can call the above function within the function(data) { of your original code with something like:
setHiddenTextFieldValue('#pn_cat', '#test'); // note the hashes (#)
I also recommend you to hard-code the following HTML into your HTML and PHP files, right before the looping of the <option>s begin:
<option value="" disabled selected="selected">Select</option>
The above line could improve user experience, depending on how you want your code to work. Note however, that this is entirely optional.
Solved it! It was just a stupid typo, can't believe I've lost 2 days over this!
In loadpn.php instead of:
$row[part_id]
it should read:
$row[pn_id]
For some reason drop down worked, but offcourse value of pn_cat wasn't being set.
Also this works in setting 2 field values (which now I don't need but if somebody wants to know):
$(document).ready(function() {
$("#part_cat").change(function() {
$('#pn_hidden').val($(this).val());
});
$("#pn_cat").change(function() {
$('#pn_hidden2').val($(this).val());
});
});
Also changed js to post:
$(document).ready(function() {
$("#part_cat").change(function() {
$.post('../includes/loadpn.php', 'part_cat=' + $(this).val(), function(data) {
$("#pn_cat").html(data);
});
});
});
And thanks for the:
<option value="" disabled selected="selected">Select</option>
It really helps with user experience.

Dropdown based on previous selection is not populating at all

I am trying to fill in a dropdown list from a mysql table based on the selection on a previous dropdown.
I have looked at many questions asking how to do this and came up wit the follwing, however nothing is happening to my second dropdown when I select something from the first.
I have newStock.php with the following script in the head.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
<script type="text/javascript">
$(function(){
$('#field').change(function(){ //on change event
var fieldVal = $('#field').val(); //<----- get the value from the parent select
$.ajax({
url : 'process.php', //the url you are sending datas to which will again send the result
type : 'GET', //type of request, GET or POST
data : { fieldValue: fieldVal}, //Data you are sending
success : function(data){$('#field2').html(data)}, // On success, it will populate the 2nd select
error : function(){alert('an error has occured')} //error message
})
})
})
</script>
With the two drop downs created in the body:
<?php
connect('final');//connect to DB
$sql = mysql_query("SELECT * FROM stockcata");
while ($row = mysql_fetch_array($sql)){
echo '<option value='.$row['id'].'>' .$row['Catagory']. '</option>';
}
?>
</Select> </label>
<input type="text" name="addCatagory" />
<label><span>Section</span>
<Select name="field2" id="field2">
</Select> </label>
And the following process.php used to query my database and provide the options to fill in the second drop down
<?php
require("header.php");
connect('final');
$temp = $_GET['fieldValue'];
$result = mysql_query("SELECT * FROM stocksection WHERE cataID = '$temp'");
while ($row = mysql_fetch_array($result)){
echo '<option value='.$row['id'].'>' .$row['section']. '</option>';
}
?>
Nothing happens in the second dropdown, I have no idea why.
Edit.........
I tried to debug it further. My database is set up with 2 tables;
Section: ID, title, Catagory_ID
and Catagory: ID, Title
When it queries the section table it is only returning data with a Catagory_ID of 0, no matter what option I chose from the drop down
The data in the success of your ajax call is not the string you think it is. You probably want something like this:
success : function(data){$('#field2').html(data.d)}, // On success,
Try a console.log(data.d); if that doesn't work to see what you are returning.

Categories

Resources