我有一些基本的ColdFusion代码来创建两个选择列表。当我从第一个下拉列表中选择一个项目时,我希望第二个项目根据第一个列表中选择的内容自动更改。
例如,假设我从下拉列表1中选择部门“IT”,下拉列表2应该只显示IT人员的fullname
。
<cfquery name="getDept" datasource=PMS>
SELECT DISTINCT DEPT
FROM APP_END
</cfquery>
<cfquery name="getFULLNAME" datasource=PMS>
SELECT FULLNAME
FROM APP_END
ORDER BY FULLNAME
</cfquery>
<!--- Dropdown 1 and 2 --->
<select name="Drop1">
<cfoutput query="getDept">
<option label="#DEPT#"></option>
</cfoutput>
</select>
<!--- ??? HOW TO LINK DROPDOWN 1 AND DROPDOWN 2 ??? --->
<select name="Drop2">
<cfoutput query="getFULLNAME">
<option value="#getFULLNAME.FULLNAME#">
#getFULLNAME.FULLNAME#
</option>
</cfoutput>
</select>
答案 0 :(得分:1)
(This is more of a how to for others since searching didn't pull up any complete references on how to tackle related selects ...)
There are different ways to do it. One way is using jQuery to populate the select lists with an ajax call to a CFC. The CFC would return the query data from the CF server. It's not as hard as it sounds. My advice is take it one piece at a time.
let's say I choose department "IT" from dropdown 1, dropdown 2 should only show the fullname of IT people.
Start by creating a query that does just that. Create a variable to hold the currently selected department. Use it as a filter in the query. Dump the query results to ensure they're what you expected.
<cfset arguments.dept = "IT">
<cfquery name="getFULLNAME" datasource=PMS>
SELECT FULLNAME
FROM APP_END
WHERE DEPT = <cfqueryparam value="#arguments.dept#" cfsqltype="cf_sql_varchar">
ORDER BY FULLNAME
</cfquery>
<cfdump var="#getFullName#" label="Debug Query Results">
Then move on to wrapping that query in a function, so you can call it from ajax. Create a single component file. Inside it, add a function named getEmployees
, to return the employee data as an array of structures.
Again, test the function to verify everything is working before moving on to the next piece. Then repeat the same process for departments, by adding another function to the component, named getDepartments
.
testPage.cfm
<cfset obj = new NameOfYourComponent()>
<cfset employees = obj.getEmployees("IT")>
<cfdump var="#employees#">
YourComponentName.cfc
<cfcomponent>
<cffunction name="getEmployees" returntype="array" access="remote">
<!--- required arguments --->
<cfargument name="dept" type="string" required="true">
<!--- get data --->
<cfquery name="Local.qry" datasource="#variables.yourDSN#">
SELECT DISTINCT FULLNAME
FROM APP_END
WHERE DEPT = <cfqueryparam value="#arguments.dept#" cfsqltype="cf_sql_varchar">
ORDER BY FULLNAME
</cfquery>
<!--- build array of structures with list data --->
<cfset Local.data = []>
<cfloop query="Local.qry">
<cfset arrayAppend(Local.data, {"value"= fullName, "label" = fullName})>
</cfloop>
<!--- return results --->
<cfreturn local.data>
</cffunction>
</cfcomponent>
Finally, create the form and use $getJSON() to invoke the CFC with ajax, and populate the select lists.
Javascript:
<script type="text/javascript">
$(document).ready(function() {
// populate department list
var listToPopulate = $("#department");
var urlToInvoke = "NameOfYourComponent.cfc?method=getDepartments&returnformat=json";
fillList(listToPopulate, urlToInvoke);
// when department changes, populate employees list
$("#department").change(function(){
var dataToSend = { dept: $("#department").val() };
var listToPopulate = $("#employee");
var urlToInvoke = "NameOfYourComponent.cfc?method=getEmployees&returnformat=json";
fillList(listToPopulate, urlToInvoke, dataToSend);
});
// make ajax call to get data, then fill given list
function fillList(listToPopulate, urlToInvoke, dataToSend) {
$.getJSON( urlToInvoke // Invokes a CFC on the server
, dataToSend // Any arguments to send to CFC. May be null
, function(response){ // Use returned data to fill select list
// Clears everything except 1st option
listToPopulate.find('option:not(:first)').remove();
// Fill list with data
$.each( response, function(index, data) {
listToPopulate.append(new Option(data.value, data.label));
});
})
.fail(function(err) {
// Do something on error
console.log( "Error "+ err.statusText );
})
}
});
</script>
Form:
<form>
<select id="department">
<option value="0">-- Select a Department --</option>
</select>
<select id="employee">
<option>-- Select an Employee --</option>
</select>
</form>
Having said all that, don't know how much latitude you have with the structure, but it's usually better to use unique id's for a <select>
list "value", like "employeeid" and "deptid", instead of names.
答案 1 :(得分:0)
通常情况下,我们可以使用id
来映射该值,如果我们没有任何要映射的内容,我们可以使用index
。但在这种情况下,您必须有2个选项,具有相同的选项顺序。请查看下面的代码段:
// Map using value
$('#select-1').on('change', function() {
$('#select-2').val(this.value);
});
// Map using index
$('#select-3').on('change', function() {
$('#select-4').val($('#select-4 option:eq('+ this.selectedIndex +')').val());
});
$('select[name="select-3"]').on('change', function() {
$('select[name="select-4"]').val($('select[name="select-4"] option:eq('+ this.selectedIndex +')').val());
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Map using value</h2>
<select id="select-1">
<option value="01">Department 1</option>
<option value="02">Department 2</option>
<option value="03">Department 3</option>
</select>
<select id="select-2">
<option value="01">Name 1</option>
<option value="02">Name 2</option>
<option value="03">Name 3</option>
</select>
<h2>Map using index</h2>
<select name="select-3">
<option>Department 1</option>
<option>Department 2</option>
<option>Department 3</option>
</select>
<select name="select-4">
<option>Name 1</option>
<option>Name 2</option>
<option>Name 3</option>
</select>
&#13;
我看到您的选择不具有相同的值,因此您无法使用第一个解决方案。
所以让我们试试第二个(使用索引)。将此代码放入<script></script>
$('select[name="Drop1"]').on('change', function() {
$('select[name="Drop2"]').val($('select[name="Drop2"] option:eq('+ this.selectedIndex +')').val());
});
您的HTML文件如下所示:
<html>
<head>
<style></style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$('select[name="Drop1"]').on('change', function() {
$('select[name="Drop2"]').val($('select[name="Drop2"] option:eq('+ this.selectedIndex +')').val());
});
</script>
</head>
<body>
<cfquery name="getDept" datasource=PMS>
SELECT DISTINCT DEPT
FROM APP_END
</cfquery>
<cfquery name="getFULLNAME" datasource=PMS>
SELECT FULLNAME
FROM APP_END order by FULLNAME
</cfquery>
<!--- Dropdown 1 and 2 --->
<select name="Drop1">
<cfoutput query="getDept">
<option label="#DEPT#"></option>
</cfoutput>
</select>
<!--- ??? HOW TO LINK DROPDOWN 1 AND DROPDOWN 2 ??? --->
<select name="Drop2">
<cfoutput query="getFULLNAME">
<option value="#getFULLNAME.FULLNAME#">#getFULLNAME.FULLNAME#</option>
</cfoutput>
</select>
<!--- Dropdown 1 and 2 --->
</body>
</html>
<!-- end html -->
答案 2 :(得分:0)
DEPARTMENT1
和DEPARTMENT2
之间必须存在关系。因为,当我们说改变一个选择时,第二个选择需要输入(第一个选择值 - 选项值)来触发或获取DEPARTMENT2
的数据。
因此,在第二个查询中,应该提供另外一个参数(在这种情况下是选项值),以便查询仅获取所选部门的数据。这样,代码将更易于理解,也有助于更好的调试。