gpt4 book ai didi

php - MySQL/PHP/JS 动态填充下拉菜单

转载 作者:行者123 更新时间:2023-11-29 07:06:42 26 4
gpt4 key购买 nike

我正在开发基于数据库/网络的前端,但遇到了一个问题。首先,我有一个带有包含契约(Contract)列表的下拉菜单的表单。选择契约(Contract)后,我希望与该契约(Contract)相关的工作(从 MySQL 数据库中获取)填充第一个下拉菜单下方的第二个下拉菜单。

我本来可以将所有信息放在一个菜单中,但 8000 个条目的下拉菜单有点笨拙。

我的 PHP 和 HTML 勉强过得去,但对于我的目的来说已经足够了,然而我的 ECMA 经验仅限于 Flash MX 中的一点 ActionScript,这是很久以前的事了。我想尽可能避免使用第三方 JS 库(例如 jQuery),并且我不介意编写更多代码。我只需要知道这是否可行,并朝着正确的方向努力。

我现在闭嘴,这是获取契约(Contract) ID(和关联的客户端)的表单,以及不完整的工作菜单。

<select name='idcontract' onchange=''> 
<!--fetch/display contracts/clients-->
<?php
include 'sqldb.php';
$cntqres = mysqli_query($dbc, 'SELECT * FROM contract');
while ($cntrow = mysqli_fetch_array($cntqres))
{
$cliqres = mysqli_query($dbc, "SELECT * FROM client WHERE idclient = '$cntrow[idclient]'");
while ($clirow = mysqli_fetch_array($cliqres))
{
echo "<option value='$cntrow[idcontract]'>$cntrow[idcontract] $clirow[name]</option>";
}
}
?>
</select>
<select name='idjob'>
<option value='NULL'>Please select a contract</option>
<!--here goes the magical piece of code I don't know how to write-->
</select>

如有任何帮助,我们将不胜感激。

编辑:

这是 FeatherAJAX 调用的 PHP :

<?php
include 'sqldb.php';
$cnt = mysqli_real_escape_string($dbc, $_GET['cnt']);
$sql = "SELECT * FROM job WHERE idcontract='$cnt' ORDER BY job.idjob";
$jqres = mysqli_query($dbc, $sql);
$i = 1;
while (($jrow = mysqli_fetch_array($jqres)) && ($i < count($jrow)))
{
echo "idjob=><option value='$jrow[idjob]' id='$jrow[idjob]'>Job-$i $jrow[part_desc]</option>";
$i++;
}
?>

最佳答案

首先,您可能想要重写生成合约选项的代码块。循环查询结果并为每条记录执行另一个查询是低效的。根据您的查询,您也许可以使用此代码,它执行单个查询,然后基于该查询生成选项。 (我不得不在 ORDER 子句中使用虚构的列名。一般来说,您应该始终对记录集进行排序,以便结果具有确定的顺序——即使您不关心该顺序是什么。

<select name="idcontract" id="idcontract"> 
<!--fetch/display contracts/clients-->
<?php
include 'sqldb.php';
$clients = mysqli_query($dbc, '
SELECT ct.idcontract, ct.idclient, cl.name
FROM contract ct LEFT OUTER JOIN client cl ON ct.idclient = cl.idclient
ORDER BY ct.contractname, cl.clientname
');

while ($client = mysqli_fetch_array($clients)) {
echo "<option value=\"{$client[idcontract]}\">{$client[idcontract} {$client[name]}</option>";
}
?>
</select>
<select name="idjob" id="idjob">
<option value="NULL">Please select a contract</option>
</select>

对于您的问题,您要查找的代码实际上并没有出现在该注释所在的位置。您需要的是一个事件处理程序,它响应用户在第一个 SELECT 中选择一个选项;然后它应该获取该选项的值并从服务器请求一组键值对填充到第二个 SELECT 中。

像这样:

document.getElementById('idcontract').onchange = function(event) {
// grab currently selected value
var sValue = null;
for(var i = 0, imax = this.childNodes.length; i < imax; i++) {
var eOption = this.childNodes[i]; // shorthand
if(eOption.selected) {
sValue = eOption.value;
break;
}
}

if(!sValue) return;

// get the sub-options for this value
getSubOptions(sValue, function(XHR) {
// this code runs once the response comes back from the server
var aPairs = [];
var nlJobs = XHR.getElementsByTagName('jobs'); // assumptions #1 & #2: response is XML, includes <job> tag for each job

// extract key-value pairs from XML
for(var i = 0, imax = nlJobs.length; i < imax; i++) {
var xJob = nlJobs[i]; // shorthand
/*
assumption #3: <job> tag has "id" property
assumption #4: job name appears inside <job> tag
assumption #4.5: you've got an abstraction layer that normalizes XML node interfaces so that "text" and "textContent" are folded into "textContent"
*/
aPairs.push({ 'key': xJob.getAttribute('id'), 'value': xJob.textContent });
}

// given array of key-value pairs, rebuild select box
var eJobs = document.getElementById('idjob');

setOptions(eJobs, aPairs);
});
}

function setOptions(eNode, aPairs) {
if(!eNode || !eNode.nodeName || eNode.nodeName.toUpperCase() !== 'SELECT') return false;

// empty SELECT of all options
while(eNode.firstChild) {
eNode.removeChild(eNode.firstChild);
}

// build up new nodes
var eOpt = null;
for(var i = 0, imax = aPairs.length; i < imax; i++) {
eOpt = document.createElement('OPTION');
eOpt.value = aPairs[i].key;
eOpt.appendChild(document.createTextNode(aPairs[i].value));
eNode.appendChild(eOpt);
}
return true;
}

当然,这缺少了一个重要部分:您需要某种 AJAX 抽象层。你不需要从框架中获取它,一个好的库可以少于 50 行代码(例如,在 quirksmode.org 上查看 PPK 的 ajax 脚本),但你绝对需要一些东西。该层将提供两个好处:(1)跨浏览器兼容性; (2) 语法糖。

例如,上面的代码没有包含getSubOptions的定义。那是因为逻辑会根据 AJAX 抽象提供的接口(interface)而有所不同。不过,我们的想法是,您将针对您编写的脚本执行 GET 请求,该脚本接受参数并返回满足该请求的数据。在上面的代码中,我假设您编写的脚本将返回格式正确的 XML 数据,并使用 MIME 类型来标识它。或者,您可以使用 JSON(或 JSONP)、纯文本(例如 CSV 样式数据),甚至是您将直接插入到页面中的原始 HTML。

使用完整框架的好处是它们都提供了进行 DOM 操作的便捷方式(即又是语法糖)。

底线:您完全可以通过自主开发的方法来做到这一点(我很自豪地说我自己已经做到了)。但这将花费更长的时间——不仅因为它不那么方便,还因为您必须重新发明轮子 === 查找和修复代码中的错误,而不是利用某些库中经过良好测试的核心组件。

编辑:如果您想使用 JSON 而不是 XML 作为数据交换格式,您可以像这样修改传递给 getSubOptions 的响应处理程序:

getSubOptions(sValue, function(XHR) {
// this code runs once the response comes back from the server
var aPairs = eval(XHR.responseText); // assumes JSON defines an array of key-value pairs

// given array of key-value pairs, rebuild select box
var eJobs = document.getElementById('idjob');

setOptions(eJobs, aPairs);
});

下面是 JSON 的示例:

[ { key: '1234', value: 'Job #1' },
{ key: '2345', value: 'Job #2' },
...
];

在此示例中,JSON 结构方便地反射(reflect)了 setOptions 所需的属性名称;那就是说,keyvalue 看起来很无礼。

如果您打算将 JSON 用于数据,您可能希望将 JSONP 视为更安全的替代方案。真的很像,只是设计模式和上面的匿名回调技术有点不同。

编辑 2:修改响应者的示例代码:

<?php
include 'sqldb.php';
$cnt = mysqli_real_escape_string($dbc, $_GET['cnt']);
$sql = "SELECT * FROM job WHERE idcontract='$cnt' ORDER BY job.idjob";
$jqres = mysqli_query($dbc, $sql);
$i = 1;

// prepare the response
header('Content-Type: text/html');

while (($jrow = mysqli_fetch_array($jqres)) && ($i < count($jrow))) {
echo "<option value=\"$jrow[idjob]\" id=\"$jrow[idjob]\">Job-$i ${htmlentities(jrow[part_desc])}</option>";
$i++;
}
?>

关于php - MySQL/PHP/JS 动态填充下拉菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6919772/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com