使用Ajax填充下拉框

9

好的,这是我在使用Ajax方面的第一次尝试,它让我感到非常疯狂,因为我真的无法理解它。我的目标是从数据库中填充第一个框中的客户,然后使用customerID使用select.php脚本从数据库中选择所有vehicleID。

发生的情况是选择了客户之后,什么也没有发生。

这是我的Test.php文件:

<?php include 'connectmysqli.php'; ?>
<html>

    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <title>Select test</title>
        <script src="./js/jquery/jquery.js"></script>
        <script type="text/javascript" charset="utf-8">
            $$('#customer')
                .on('change', function () {
                    $.getJSON('select.php', { customerId: $(this)
                            .val() }, function (data) {

                        var options = '';
                        for (var x = 0; x < data.length; x++) {
                            options += '<option value="' + data[x][
                                    'id'] + '">' + data[x]['reg'] +
                                '</option>';
                        }
                        $('#vehicle')
                            .html(options);
                    });
                });

        </script>
    </head>

    <body>
        <select id="customer">
                <?php
        $sql = <<<SQL
        SELECT *
        FROM `customers`
        SQL;
        if(!$result = $db->query($sql)){ die('There was an error running the query [' . $db->error . ']');}
        while($row = $result->fetch_assoc()){
        if ($row['bussinessname'] == ''){$name = $row['title'].' '.$name = $row['firstname'].' '.$name = $row['surname'];}else
        {$name = $row['bussinessname'];}
        echo '<option value="'.$row['customerID'].'">'.$name.'</option>';
        }
        echo '</select></p>'; ?>
        </select>
        <select id="vehicle">
                </select>
    </body>

</html>

这是我的select.php文件:
<?php include 'connectmysqli.php'; ?>
<?php
        $id = $_GET['customerId'];
        $sql = 'SELECT * FROM vehicles WHERE customerID = ' . $id;
        $result = $db->query($sql);

        $json = array();
        while ($row = $result->fetch_assoc()) {
          $json[] = array(
            'id' => $row['vehicleID'],
            'reg' => $row['reg'] // Don't you want the name?
          );
        }
        echo json_encode($json);

?>

我正在尝试将这个教程修改为与数据库一起使用,但目前我没有成功。 http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/ 在Chrome控制台中,我收到了以下错误信息:
Port error: Could not establish connection. Receiving end does not exist.     miscellaneous_bindings:235
chromeHidden.Port.dispatchOnDisconnect

尝试使用以下代码:$(document).on('change', "select#customer", function(){}); - Brewal
@Brewal 为什么会这样呢? - DevZer0
你能在控制台上检查一下,看看当选定该项时是否有连接正在建立吗? - DevZer0
我认为你的 select#customer 是动态添加的。这样会修复错误。但事实并非如此。你的控制台有任何错误吗? - Brewal
这不是你的脚本错误,它是由于某个Chrome扩展引起的,请禁用所有扩展并检查。 - Anil Gupta
显示剩余2条评论
3个回答

19

您的客户选择更改事件在选择器呈现在页面之前被分配。将事件处理程序移至 document.ready 中:

<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
    $('#customer').on('change', function (){
        $.getJSON('select.php', {customerId: $(this).val()}, function(data){
            var options = '';
            for (var x = 0; x < data.length; x++) {
                options += '<option value="' + data[x]['id'] + '">' + data[x]['reg'] + '</option>';
            }
            $('#vehicle').html(options);
        });
    });
});
</script>

我还将$$('#customer')更改为$('#customer')。最后,修复你的SQL注入漏洞:

$sql = 'SELECT * FROM vehicles WHERE customerID = ' . (int)$id;

将ID强制转换为整数将防止SQL注入攻击,但建议使用预处理语句

你提到的问题错误与你的代码无关,可能与Chrome扩展有关。


以下是改进后的构建车辆选项的代码,不属于问题的一部分:

$.getJSON('select.php', {customerId: $(this).val()}, function(data){
    var vehicle = $('#vehicle');

    for (var x = 0; x < data.length; x++) {
        vehicle.append(new Option(data[x].reg, data[x].id));
    }
});

改进有:
  • 将选择器存储在一个变量中,这样我们不必在每次循环迭代时查询DOM
  • 使用new Option(...).append()创建选项并将它们添加到车辆选择器中。像这样构建元素比创建原始HTML更好,因为这样你就不必担心数据中的字符,例如<> - 这些字符会破坏现有代码的HTML。
  • 您的数据被解码为JavaScript对象数组,因此首选对象表示法(data[x].id)而不是data[x]['id']

你是个传奇!谢谢你,我整个周末一直在想这到底是怎么回事,但是一直都没搞清楚!谢谢! - Iain Simpson
@IainSimpson 没问题 :) 请看我的编辑- 做了一些改进。 - MrCode

2

看起来你正在select.php的每个迭代中创建一个JSON对象数组。

下面的数组是在PHP中生成的,然后进行JSON编码,这是生成JSON字符串的最佳方式。

// select.php

$id = $_GET['customerId'];
$sql = 'SELECT * FROM vehicles WHERE customerID = ' . $id;
$result = $db->query($sql);

$json = array();
while ($row = $result->fetch_assoc()) {
  $json[] = array(
    'id' => $row['vehicleId'],
    'name' => $row['vehicleId'] // Don't you want the name?
  );
}
echo json_encode($json);

// Test.php

$('#customer').on('change', function (){
  $.getJSON('select.php', {customerId: $(this).val()}, function(data){

    var options = '';
    for (var x = 0; x < data.length; x++) {
      options += '<option value="' + data[x]['id'] + '">' + data[x]['name'] + '</option>';
    }
    $('#vehicle').html(options);
  });
});

容易受到 SQL 注入攻击,请小心。 - andy
@andy 谢谢。我只是为了简单起见,试图回答op的问题。然而,这是一个有效的观点。 - AlexP
我已经用新代码编辑了我的问题,但它仍然无法工作? - Iain Simpson
@IainSimpson 你改了 Test.php 吗? - AlexP
是的,我已经更新了它们,就像上面那样^^,我用新代码编辑了我的问题。 - Iain Simpson
显示剩余3条评论

2

也许尝试使用live而不是on。虽然它已被弃用,但我发现在元素未加载时更有可能起作用。

$$('#customer').on('change', function (){

改为

$('#customer').live('change', function (){


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接