Mohamed Mamdouh Mohamed Mamdouh - 3 months ago 9
PHP Question

making 3 select tag with php and ajax

this is my first day with AJAX, is easier than i imagine , i make one select tag that open another select tag and it work fine
that is the code...

test.php

<?php
require'models/category.php';
$object=new category;
$rows=$object->display_category();
?>

<!DOCTYPE html>
<html>
<head>
<script>
function showUser(str) {
if (str=="") {
document.getElementById("txtHint").innerHTML="choose a category";
return;
}
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","getTest.php?q="+str,true);
xmlhttp.send();
}
</script>
</head>
<body>

<form>
<select name="users" onchange="showUser(this.value)">

<option value="">Select a category:</option>

<?php
foreach($rows as $row){
$row['cat_name']=str_replace('-',' ',$row['cat_name']);

echo'<option value="'.$row['cat_id'].'">'.$row['cat_name'].'</option>';
}
?>
</select>
</form>
<br>
<div id="txtHint"><b>category info will be listed here.</b></div>
</body>
</html>


and this is getTest.php

<?php
require'models/connection.php';
$q = $_GET['q'];

$query="select * from category where parent_id='".$q."' ";

$stmt=$db->prepare($query);
$stmt->execute();

$result=$stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<form action='' method='get'>
<select name='select1'>
<?
foreach ($result as $one){
echo'<option value="'.$one["cat_id"].'">'.$one['cat_name'].'</option>';
}

?>
</select>
</form>


there is one select tag in test.php
and when i choose a certain option
another select tag open, which existing in getTest.php

now i want third select tag,,
when i choose from the second select tag , another one is appear.
i don't know where is that action must done ,, in test.php or in getTest.php

the third select that i want to appear of course is depends on the second select choice,,thanks in advance

Answer

I suggest you to change your codes like this, In this way you can use millions of selects without any problem. I commented my changes on your code to better visibility. test.php

<?php
require'models/category.php';
$object=new category;
$rows=$object->display_category();
?>

<!DOCTYPE html>
<html>
<head>
<script>
function showUser(str,targetId) {//// add targetId here
  if (str=="") {
    document.getElementById("txtHint").innerHTML="choose a category";
    return;
  } 
  if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
  } else { // code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  xmlhttp.onreadystatechange=function() {
    if (xmlhttp.readyState==4 && xmlhttp.status==200) {
      document.getElementById(targetId).innerHTML=xmlhttp.responseText;// this is my added data
      document.getElementById(targetId).style.display = 'block';//update #2
    }
  }
  xmlhttp.open("GET","getTest.php?q="+str,true);
  xmlhttp.send();
}
</script>
</head>
<body>

<form>
<select name="users" onchange="showUser(this.value,select1)"><!-- add ,1 here -->

<option value="">Select a category:</option>

<?php
foreach($rows as $row){
$row['cat_name']=str_replace('-',' ',$row['cat_name']);

echo'<option value="'.$row['cat_id'].'">'.$row['cat_name'].'</option>';
}
?>
</select>
<!-- This section is added completely -->
<br>
<select id='select1' name='select1' onchange="showUser(this.value,select2)" style="display:none">
</select>
</form>
<br>
<br>
<select id='select2' name='select2' style="display:none">
</select>
</form>
<br>
<!-- End of added section -->
<div id="txtHint"><b>query status will be listed here.</b></div> <!-- category info will not listed here -->
</body>
</html>

getTest.php

<?php
require'models/connection.php';
$q = $_GET['q'];
$level = $_GET['level'];

$query="select * from category where parent_id='".$q."' "; ////DANGER! There is a sql injection vulnerability! Don't do this in your main site never ever

$stmt=$db->prepare($query);

$stmt->execute();
$result=$stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($result as $one){
echo'<option value="'.$one["cat_id"].'">'.$one['cat_name'].'</option>';
}
?>

But there is a vulnerability in your sql query that makes your site in danger of sql injection attacks, changing the query code in getTest.php to this one is a good work. but you must check whole your codes with a pentester of course.

Vulnerable code

$query="select * from category where parent_id='".$q."' ";
$stmt=$db->prepare($query);
$stmt->execute();

must change to this one:

$query="select * from category where parent_id=:id ";
$stmt->execute(['id'=>$q]);

for more details about this problem, read this post: How can I prevent SQL-injection in PHP?