我在下面有一段代码,其中显示了2个下拉菜单,一个用于建筑物,另一个用于房间。当用户从其下拉菜单中选择一个建筑物时,它将使用ajax导航到room.php,在该脚本中,它编译一个查询并输出一个房间列表,然后在房间下拉菜单中显示页:
$sql = "SELECT DISTINCT Building FROM Room";
$sqlstmt=$mysqli->prepare($sql);
$sqlstmt->execute();
$sqlstmt->bind_result($dbBuilding);
$buildings = array(); // easier if you don't use generic names for data
$buildingHTML = "";
$buildingHTML .= '<select name="buildings" id="buildingsDrop" onchange="getRooms();">'.PHP_EOL;
$buildingHTML .= '<option value="">Please Select</option>'.PHP_EOL;
while($sqlstmt->fetch())
{
$building = $dbBuilding;
$buildingHTML .= "<option value='".$building."'>" . $building . "</option>".PHP_EOL;
}
$buildingHTML .= '</select>';
$roomHTML = "";
$roomHTML .= '<select name="rooms" id="roomsDrop">'.PHP_EOL;
$roomHTML .= '<option value="">Please Select</option>'.PHP_EOL;
$roomHTML .= '</select>';
?>
<script type="text/javascript">
function getRooms() {
var building = jQuery("#buildingsDrop").val();
jQuery('#roomsDrop').empty();
jQuery('#roomsDrop').html('<option value="">Please Select</option>');
jQuery.ajax({
type: "post",
url: "room.php",
data: { building:building },
success: function(response){
jQuery('#roomsDrop').append(response);
}
});
}
</script>
现在上面的代码适用于除Internet Explorer之外的所有浏览器。感谢一些关于SO的好建议我被告知要验证脚本,因为Internet Explorer在验证代码方面非常严格。
无论如何,在我的验证中,我意识到我有这个错误:
文档类型不允许元素“选项”在这里:
指向以下这一行:
jQuery('#roomsDrop').html('<option value="">Please Select</option>');
它声明它需要进入<select>
标签,我在技术上试图在上面的代码中做。我的问题是如何修复代码以通过验证,但是能够执行它所做的工作,从建筑物下拉菜单中选择建筑物后,在房间下拉菜单中显示房间列表?
以下是应用程序,请在Internet Explorer中打开应用程序,也可以在chrome,firefox,opera或safrai中打开。首先在其中一个非Internet浏览器浏览器中显示应用程序以查看应用程序的工作方式,然后在Internet Explorer中进行测试,您可以自己查看问题以及我想要实现的目标。
Application (Please open in Internet Explorer and in one other major browser)
更新:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Room </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="roomStyle.css">
</head>
<body>
<?php
// connect to the database
include('connect.php');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}
$building = isset($_POST['building']) ? $_POST['building'] : '';
$sql = "SELECT Room FROM Room WHERE Building = ?";
$sqlstmt=$mysqli->prepare($sql);
$sqlstmt->bind_param("s",$building);
$sqlstmt->execute();
$sqlstmt->bind_result($dbRoom);
$roomHTML = "";
while($sqlstmt->fetch()) {
$roomHTML .= "<option value='".$dbRoom."'>" . $dbRoom . "</option>".PHP_EOL;
}
echo $roomHTML;
$sqlstmt->execute();
?>
</body>
</html>
答案 0 :(得分:2)
问题是room.php
正在返回:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Room </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="roomStyle.css">
</head>
<body>
<option value='CW2/08'>CW2/08</option>
<option value='CW4/09'>CW4/09</option>
<option value='CW4/10'>CW4/10</option>
<option value='CW5/10'>CW5/10</option>
</body>
</html>
什么时候应该只返回这个(基于你如何使用响应):
<option value='CW2/08'>CW2/08</option>
<option value='CW4/09'>CW4/09</option>
<option value='CW4/10'>CW4/10</option>
<option value='CW5/10'>CW5/10</option>
虽然我不愿意这么说,但Internet Explorer是正确的(在这种情况下)。 <option>
元素不应该是<body>
元素的直接子元素。
这在Chrome中运行的原因(例如)Chrome只会将其附加到select#roomDrop
:
<title>Room </title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="roomStyle.css">
<option value="CW2/08">CW2/08</option>
<option value="CW4/09">CW4/09</option>
<option value="CW4/10">CW4/10</option>
<option value="CW5/10">CW5/10</option>
并且Chrome无法直观呈现<title>
元素中的<meta>
,<link>
或<select>
元素。
至少有几种方法可以解决这个问题。
room.php
更改为仅输出<option>
元素。getRooms()
功能更改为仅附加返回的<option>
元素。至于上面两个修正中的哪一个,它将取决于您使用room.php
的其他内容。还有其他解决方案(我确定),但最终将归结为修复PHP或修复AJAX调用。
没有看到room.php
的PHP源代码,我无法帮助解决第一个问题。第二种可以这样做:
function getRooms() {
'use strict';
var building = jQuery("#buildingsDrop").val(),
//use jQuery (or plain JavaScript) to build the option as a DOM element
defaultOption = $('<option />').text('Please Select').val('');
//append the DOM element, not an HTML string
jQuery('#roomsDrop').empty().append(defaultOption);
jQuery.ajax({
"type": "post",
"url": "room.php",
"data": {
"building": building
},
"success": function (response) {
//filter out the option elements
var opts = $(response).filter('option');
//and append only those
jQuery('#roomsDrop').append(opts);
},
"error": function (jqXHR, textStatus, errorThrown) {
//always good to have an error handler.
console.log(textStatus);
console.log(errorThrown);
}
});
}
您可能会注意到我使用jQuery将初始选项构建为DOM元素,而不是构建HTML字符串。我这样做是因为:
<强>更新强>
由于您已包含room.php
的PHP源代码,因此您可以将其修改为仅输出<option>
元素,如下所示:
<?php
// connect to the database
include('connect.php');
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
die();
}
$building = isset($_POST['building']) ? $_POST['building'] : '';
$sql = "SELECT Room FROM Room WHERE Building = ?";
$sqlstmt=$mysqli->prepare($sql);
$sqlstmt->bind_param("s",$building);
$sqlstmt->execute();
$sqlstmt->bind_result($dbRoom);
$roomHTML = "";
while($sqlstmt->fetch()) {
$roomHTML .= "<option value='".$dbRoom."'>" . $dbRoom . "</option>".PHP_EOL;
}
echo $roomHTML;
$sqlstmt->execute();
?>
也就是说,简单地删除与<option>
元素无关的所有内容。