Andrewstevens
Andrewstevens

Reputation: 59

Two dropdown-menues which are in relation to each other with php and javascript

I want to create two dropdown-menues which are in relation to each other. A "job-maincategory" and a "job-subcategory".

If you chose a "job-maincategory" in the "job-subcategory" only the jobs which are in relation to the "job-maincategory" should apear. I try to realise it with javascript-ajax. Sadly, I don´t get the thing to work and I´m looking for help.

Here is the link to the online example im working on:

Example

Here is the code of the mainfile with the two dropdownmenus:

<!DOCTYPE html>
<html>
<head>
<title>Dayjob - Kategorien</title>
<meta charset="UTF-8" />

<script src="js/jquery-3.2.1.js"></script>
<script src="js/categorydropdown.js"></script>

</head>
<body>
<?php

$servername = "xxxxxx";
$username = "xxxxxx";
$passwordmysql = "xxxxxx";
$dbname ="xxxxxx";

$conn = mysqli_connect($servername, $username, $passwordmysql, $dbname);    
mysqli_query($conn, "SET NAMES 'utf8'");

    $sqlgetcategory = "SELECT `jobcategory` FROM `jobcategory` ORDER BY `jobcategory` ASC";
    $jobcategory = $conn->query($sqlgetcategory);

        echo "<select name=\"selectjobcategorysubchoicemain\" id=\"selectjobcategorysubchoicemain\">";
        echo "<option value=\"\" disabled selected>Hauptategorie</option>";
        while ($schleife = $jobcategory->fetch_assoc()){
            echo "<option value=".$schleife['jobcategory'].">".$schleife['jobcategory']."</option>";
        }
        echo "<option value=\"nocategory\">Sonstiges..</option>";
        echo "</select>";


?>

        <select id="selectjobcatergorysub">
            <option value="0">- Select -</option>
        </select>

</body>
</html>

Here is the javascript-file which gets triggered on a change of the "job-maincategory":

$(document).ready(function(){

        $("#selectjobcategorysubchoicemain").change(function(){
            var data = $("#selectjobcategorysubchoicemain").serialize();
            window.alert(data);

            $.ajax({
                url: 'categorysubdropdown.php',
                type: 'post',
                data: data,
                dataType: 'json',
                success:function(response){

                    window.alert(response);

                    $("#selectjobcatergorysub").empty();


                    $("#selectjobcatergorysub").append("<option value='"+response+"'>"+response+"</option>");     


                }
            });
        });

    });

And here is the .php-file which gets triggered from ajax of the javascript-file:

<?php

$servername = "xxxxxx";
$username = "xxxxxx";
$passwordmysql = "xxxxxx";
$dbname ="xxxxxx";


$conn = mysqli_connect($servername, $username, $passwordmysql, $dbname);    
mysqli_query($conn, "SET NAMES 'utf8'");


    $choicemain = $_POST['selectjobcategorysubchoicemain'];



    $sqlgetcategorysub = "SELECT `jobcategory`, `jobcategorysub` FROM `jobcategorysub` WHERE `jobcategory` = '$choicemain' ORDER BY `jobcategorysub` ASC";

    $jobcategorysub = $conn->query($sqlgetcategorysub);


    $jobsubcategory_arr = array();

    while($row = mysqli_fetch_array($jobcategorysub) ){
    $subjobcat = $row['jobcategorysub'];
    $jobsubcategory_arr = array("jobcategorysub" => $subjobcat);
    }

echo json_encode($jobsubcategory_arr);

?>

The Problem at the moment is that I only get back "[object Object]" as response from php and i don´t know why. Thank you for your help.

Upvotes: 0

Views: 79

Answers (2)

IncredibleHat
IncredibleHat

Reputation: 4104

In light of the issues you were facing, here is a complete rewrite of your ajax php. The prior example I provided used a method your server must not have installed (fetch_all). As such, I have rewritten my example in light of that.

This will cover sql injection protection, as you are passing in a _POST variable from the world. Anyone can manipulate the value of that variable to take control of your sql query. This is why prepare is so important, and a must.

The output is now done using bind_result (and sql reduced to just one field return needed), since you do not have access to the easier one-line-method fetch_all. This is also adjusted to only return a single array of the values you need. NOT an array of objects (reduces needless {name:value} waste).

categorysubdropdown.php:

<?php
$servername    = "xxxxxx";// you really should keep this db setup in an include, 
$username      = "xxxxxx";// and then do include_once('/dbsetup.php');
$passwordmysql = "xxxxxx";
$dbname        = "xxxxxx";
$conn = new mysqli($servername, $username, $passwordmysql, $dbname);
$conn->set_charset("utf8");

if ( !empty($_POST['selectjobcategorysubchoicemain']) ) {
    $stmt = $conn->prepare("SELECT jc.jobcategorysub 
                            FROM jobcategorysub as jc 
                            WHERE jc.jobcategory = ? 
                            ORDER BY jc.jobcategorysub ASC");
    $stmt->bind_param('s',$_POST['selectjobcategorysubchoicemain']);
    $stmt->bind_result($jobcategorysub);
    $stmt->execute();

    $output = array();
    while ($stmt->fetch()) { $output[] = $jobcategorysub; }
    echo json_encode( $output );
}
?>

Your ajax should be this to work with the php output:

$.ajax({
    url: 'categorysubdropdown.php',
    type: 'post',
    data: data,
    dataType: 'json',
    success: function(response) {
        console.log(response);// to debug json return
        $("#selectjobcatergorysub").empty();
        for (var i = 0; i < response.length; i++ ){
            $("#selectjobcatergorysub").append(
                 "<option value='"+ response[i] +"'>"+ response[i] +"</option>"
            );
        }
    }
});

This loops on the response Array for each row by its length (which is an Array length, not character length), and then accesses the field by the i index. No need for object subnames, as the output from php does not include them.

This has all be tested on my older server that doesn't have fetch_all installed as well, and verified error free.

Upvotes: 1

Ngob
Ngob

Reputation: 491

As asked, Here is how to solve:

  1. Change your php script to return an array with all result:

PHP:

    // Init the displayed array
    $ret = [];
    while($row = mysqli_fetch_array($jobcategorysub) ){
      $subjobcat = $row['jobcategorysub'];
      $jobsubcategory_arr = array("jobcategorysub" => $subjobcat);
      // Add each line to the array to display
      $ret[] = $jobsubcategory_arr;
    }
    // display the array as json
    echo json_encode($ret);
  1. In your javascript, the construction of <option> is now wrong:

javascript:

// in your callback, you loop over the array returned
for (var i = 0; i < response.length; i++) {
   // Here you access one of the result (a line of the array)
   var r = response[i];
    // Construct your select by accessing variable from your object
    $("#selectjobcatergorysub").append("<option value='"+r.jobcategorysub +"'>"+r.jobcategorysub +"</option>");
}

Now: In your PHP you construct an array of array, each row contains one result, so each row contains one of your desired data. In your javascript, you construct the <select> from the array returned. If you are new to PHP i recommend to use a framework which help in being protected by most known vulnerability.

Upvotes: 1

Related Questions