Coldfusion/Lucee 多个条件 select 通过 AJAX
Coldfusion/Lucee multiple conditional select via AJAX
我目前正在自学(再自学)JavaScript 和 jQuery 以重写在 Lucee 上运行的遗留应用程序。
部分重写需要对基本功能进行多项添加。一个具体的添加是将“街道名称”select 字段添加到现有的“县名”->“城市名称”select 字段。
我发现了这个 Whosebug 问题:Coldfusion conditional select option does not work in IE9, Chrome and Firefox
使用该问题的基础;我写了以下内容:
<!--- county.cfm --->
<cfif structKeyExists(url,'work_area_county_id')>
<cfset loadState() />
</cfif>
<cfif structKeyExists(url,'work_area_city_id')>
<cfset loadStreet() />
</cfif>
<cfset loadCounty() />
<cffunction name="loadCounty">
<cfquery name="qCounty">
SELECT work_area_county_id, work_area_county_name FROM work_area_county
</cfquery>
</cffunction>
<cffunction name="loadState">
<cfset variables.work_area_county_id = url.work_area_county_id />
<cfquery name="qCity">
SELECT work_area_city_id, work_area_city_name, work_area_county_id FROM work_area_city WHERE work_area_county_id = <cfqueryparam value="#variables.work_area_county_id#" cfsqltype="cf_sql_int">
</cfquery>
<cfoutput>
<select name="state" class="form-control">
<option value="">Select City</option>
<cfloop query="qCity">
<option value="#work_area_city_id#">#work_area_city_name#</option>
</cfloop>
</select>
</cfoutput>
</cffunction>
<cffunction name="loadStreet">
<cfset variables.work_area_city_id = url.work_area_city_id />
<cfquery name="qStreet">
SELECT work_area_street_id, work_area_street_name, work_area_city_id FROM work_area_street WHERE work_area_city_id = <cfqueryparam value="#variables.work_area_city_id#" cfsqltype="cf_sql_int">
</cfquery>
<cfoutput>
<select name="state" class="form-control">
<option value="">Select Street</option>
<cfloop query="qStreet">
<option value="#work_area_street_id#">#work_area_street_name#</option>
</cfloop>
</select>
</cfoutput>
</cffunction>
<!--- display.cfm --->
<cfinclude template="includes/county.cfm">
<cfoutput>
<form name="state_populate">
<select name="county" id="county">
<option value="0">Select</option>
<cfloop query="qCounty">
<option value="#work_area_county_id#">
#work_area_county_name#
</option>
</cfloop>
</select>
<div id="city">
<select name="city" class="form-control">
<option value="">Select</option>
</select>
</div>
<div id="street">
<select name="street" class="form-control">
<option value="">Select</option>
</select>
</div>
</form>
</cfoutput>
// The JS
$('#county').change(function() {
var value = $('#county').val();
$.ajax({
type: "get",
url:'includes/county.cfm?work_area_county_id='+value,
success: function(response) {
$('#city').html(response);
},
error: function(jqXHR, status, error) {
console.log(status + ": " + error);
}
});
});
上面的代码在 selecting "County Name" 时运行良好。它在第二个 select 字段中正确显示“城市名称”。然后我尝试在第三个 select 字段中添加“街道名称”并添加我“认为”应该适用于 CFML 和 HTML 的内容。当我到达代码的 JS 部分时,我撞到了砖墙。我似乎找不到,也许是因为缺少正确的搜索词,如何添加额外的 AJAX 调用。
我发现了这个问题:Parallel asynchronous Ajax requests using jQuery
有多个答案,但我“认为”与我的问题相关的最接近的答案是:
$.whenAll({
val1: $.getJSON('/values/1'),
val2: $.getJSON('/values/2')
})
.done(function (results) {
var sum = results.val1.value + results.val2.value;
$('#mynode').html(sum);
});
我相信他们被称为“承诺”?
代码需要防止第二个 select 字段“城市名称”发生变化,并正确使用具有多个值的 AJAX“url”参数。我知道参考上面的代码,URL 部分可能需要与此“类似”的东西:
url:'includes/county.cfm?work_area_county_id='+ value + '&work_area_city_id=' + value
供考虑:
- 我知道我的代码不是很好而且我知道它可以写得更好。我正在努力改进。
- 我不是全职编码员,但我断断续续地编码多年。我仍然认为自己是 CFML/JavaScript/jQuery 的新手,所以很多方法都让我头疼。
- 代码会用cfscript写,以后转成CFC。现在我让它变得简单并使用了标签。
- 我从 display.cfm.
中删除了不相关的 HTML 代码
如有任何意见或指导,我们将不胜感激! :D
我将向您展示我将如何处理此类任务的示例。我的回答可能不是最好或最干净的解决方案:我过去的编码实践很糟糕(我仍然倾向于写意大利面条,而且我一直在努力反对这样做)。但是,我正在改变那些坏习惯,这很有趣。
我的解决方案是用 OOP 方法编写的。我真的建议每个人都尝试走这条路,因为很快就会开始感觉更自然:感觉不错,尤其是当您需要修复或扩展代码时。
那时我也会尝试使用 cfscript 而不是标签,因为使用组件和函数编写 OOP 更简单,特别是如果您有一些使用 JavaScript 的经验(这在某种程度上是相似的)。但是,我提供了标记方法,因为我认为这就是您想要的。
这个解决方案基本上由 4 个文件组成:
- display.cfm:条目template/page.
- components/CountiesDAO.cfc: 一个组件,作为您所在县的数据访问对象,具有相应的 getter。请注意,我正在使用 QoQ 模拟数据库请求。您应该能够使用您的数据源而不是那里的真实数据。
- countyForm.js: JavaScript文件用jQueryajax函数获取数据延迟对象并填充html 包含响应数据的容器(有关更多信息,请参阅我在代码中的注释)。
- ajaxAPI.cfm:模板echos/outputs所有数据为JSON为您jQueryajax请求。
主要问题是您需要为每个 ajax 请求检索更多 JavaScript 承诺。在 jQuery 中,延迟对象会发生这种情况。
文件如下:
1。 display.cfm:
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Page Title</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<body>
<cfset CountiesDAO= new components.CountiesDAO() />
<cfset queryWorkAreaCounties=CountiesDAO.getWorkAreaCounties()>
<cfoutput>
<select id="county">
<option value="0">Select</option>
<cfloop query="queryWorkAreaCounties">
<option value="#queryWorkAreaCounties.work_area_county_id#">
#queryWorkAreaCounties.work_area_county_name#
</option>
</cfloop>
</select>
<div id="cityContainer"></div>
<div id="streetContainer"></div>
</cfoutput>
<!-- embedded jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="countyForm.js"></script>
</body>
</html>
2。 components/CountiesDAO.cfc
<cfcomponent>
<cffunction name="init">
<cfset variables.queriesQoQ["work_area_counties"]=createWorkAreaCounties()>
<cfset variables.queriesQoQ["Work_area_cities"]=createWorkAreaCities()>
<cfset variables.queriesQoQ["Work_area_streets"]=createWorkAreaStreets()>
<cfreturn this>
</cffunction>
<!--- functions to create Data to emulate a DB with QoQ --->
<cffunction name="createWorkAreaCounties"
access="private"
returntype="query"
hint="create query to simulate a DB data table for QoQ">
<cfset work_area_countyTable= queryNew(
"work_area_county_id, work_area_county_name",
"integer,varchar",
[
{"work_area_county_id":1,"work_area_county_name":"Los Angeles County"},
{"work_area_county_id":2,"work_area_county_name":"Cook County"},
{"work_area_county_id":3,"work_area_county_name":"Harris County"},
{"work_area_county_id":4,"work_area_county_name":"Maricopa County"}
])/>
<cfreturn work_area_countyTable>
</cffunction>
<cffunction name="createWorkAreaCities"
access="private"
returntype="query"
hint="create query to simulate a DB data table for QoQ">
<cfset work_area_cityTable= queryNew(
"work_area_city_id, work_area_city_name, work_area_county_id",
"integer,varchar,integer",
[
{"work_area_city_id":1,"work_area_city_name":"Agoura Hills" , "work_area_county_id":1},
{"work_area_city_id":2,"work_area_city_name":"Alhambra" , "work_area_county_id":1},
{"work_area_city_id":3,"work_area_city_name":"Bradbury" , "work_area_county_id":1},
{"work_area_city_id":4,"work_area_city_name":"Arlington Heights" , "work_area_county_id":2},
{"work_area_city_id":5,"work_area_city_name":"Bellwood" , "work_area_county_id":2},
{"work_area_city_id":6,"work_area_city_name":"Bridgeview" , "work_area_county_id":2},
{"work_area_city_id":7,"work_area_city_name":"Baytown" , "work_area_county_id":3},
{"work_area_city_id":8,"work_area_city_name":"Cove" , "work_area_county_id":3},
{"work_area_city_id":9,"work_area_city_name":"The Woodlands" , "work_area_county_id":3},
{"work_area_city_id":10,"work_area_city_name":"Avondale" , "work_area_county_id":4},
{"work_area_city_id":11,"work_area_city_name":"Phoenix" , "work_area_county_id":4},
{"work_area_city_id":12,"work_area_city_name":"Glendale" , "work_area_county_id":4},
])/>
<cfreturn work_area_cityTable>
</cffunction>
<cffunction name="createWorkAreaStreets"
access="private"
returntype="query"
hint="create query to simulate a DB data table for QoQ">
<cfset work_area_streetTable= queryNew(
"work_area_street_id, work_area_street_name, work_area_city_id",
"integer,varchar,integer",
[
{"work_area_street_id":1,"work_area_street_name":"Street One Agoura Hills", "work_area_city_id": 1 },
{"work_area_street_id":2,"work_area_street_name":"Street Two Agoura Hills", "work_area_city_id": 1 },
{"work_area_street_id":3,"work_area_street_name":"Street Three Agoura Hills", "work_area_city_id": 1 },
{"work_area_street_id":4,"work_area_street_name":"Street One Alhambra", "work_area_city_id": 2 },
{"work_area_street_id":5,"work_area_street_name":"Street Two Alhambra", "work_area_city_id": 2 },
{"work_area_street_id":6,"work_area_street_name":"Street Three Alhambra", "work_area_city_id": 2 },
{"work_area_street_id":7,"work_area_street_name":"Street One Bradbury", "work_area_city_id": 3 },
{"work_area_street_id":8,"work_area_street_name":"Street Two Bradbury", "work_area_city_id": 3 },
{"work_area_street_id":9,"work_area_street_name":"Street One Arlington Heights", "work_area_city_id": 4 },
{"work_area_street_id":10,"work_area_street_name":"Street Two Arlington Heights", "work_area_city_id": 4 },
{"work_area_street_id":11,"work_area_street_name":"Street One Bellwood", "work_area_city_id": 5 },
{"work_area_street_id":12,"work_area_street_name":"Street Two Bellwood", "work_area_city_id": 5 },
{"work_area_street_id":13,"work_area_street_name":"Street One Bridgeview", "work_area_city_id": 6 },
{"work_area_street_id":14,"work_area_street_name":"Street Two Bridgeview", "work_area_city_id": 6 },
{"work_area_street_id":15,"work_area_street_name":"Street One Baytown", "work_area_city_id": 7 },
{"work_area_street_id":16,"work_area_street_name":"Street Two Baytown", "work_area_city_id": 7 },
{"work_area_street_id":17,"work_area_street_name":"Street One Cove", "work_area_city_id": 8 },
{"work_area_street_id":18,"work_area_street_name":"Street Two Cove", "work_area_city_id": 8 },
{"work_area_street_id":19,"work_area_street_name":"Street One The Woodlands", "work_area_city_id": 9 },
{"work_area_street_id":20,"work_area_street_name":"Street Two The Woodlands", "work_area_city_id": 9 },
{"work_area_street_id":21,"work_area_street_name":"Street One Avondale", "work_area_city_id": 10 },
{"work_area_street_id":22,"work_area_street_name":"Street Two Avondale", "work_area_city_id": 10 },
{"work_area_street_id":23,"work_area_street_name":"Street One Phoenix", "work_area_city_id": 11 },
{"work_area_street_id":24,"work_area_street_name":"Street Two Phoenix", "work_area_city_id": 11 },
{"work_area_street_id":25,"work_area_street_name":"Street One Glendale", "work_area_city_id": 12 },
{"work_area_street_id":26,"work_area_street_name":"Street Two Glendale", "work_area_city_id": 12 },
])/>
<cfreturn work_area_streetTable>
</cffunction>
<cffunction name="getWorkAreaCounties"
access="public"
returntype="query"
hint="function to return all counties">
<cfset work_area_county=queriesQoQ["work_area_counties"]>
<cfquery name="qCity" dbtype="query" >
SELECT * FROM work_area_county
</cfquery>
<cfreturn qCity>
</cffunction>
<cffunction name="getWorkAreaCitiesByCountyID"
access="public"
returntype="query"
hint="function to return all cities of a county">
<cfargument type="numeric" name="countyid" required="true">
<cfset work_area_city=queriesQoQ["work_area_cities"]>
<cfquery name="qCity" dbtype="query" >
SELECT work_area_city_id, work_area_city_name, work_area_county_id
FROM work_area_city
WHERE work_area_county_id = <cfqueryparam value="#arguments.countyid#" cfsqltype="cf_sql_int">
</cfquery>
<cfreturn qCity>
</cffunction>
<cffunction name="getWorkAreaStreetsByCityID"
access="public"
returntype="query"
hint="function to return all streets of a city">
<cfargument type="numeric" name="cityid" required="true">
<cfset work_area_street=queriesQoQ["work_area_streets"]>
<cfquery name="qStreet" dbtype="query" >
SELECT work_area_street_id, work_area_street_name, work_area_city_id
FROM work_area_street
WHERE work_area_city_id = <cfqueryparam value="#arguments.cityid#" cfsqltype="cf_sql_int">
</cfquery>
<cfreturn qStreet>
</cffunction>
</cfcomponent>
3。 countyForm.js
// ajax function
function sendAjaxAndUpdateForm(
url,
selectorForValue,
selectorForHTMLResponse ,
callbackFunction ){
let value = $( selectorForValue ).val();
/* return the ajax request as deferred object with done()/fail(). For more information, please see:
* https://api.jquery.com/jquery.ajax/
*
*/
return $.ajax({
method: "GET",
url: url + value,
}).done( function( result ) {
//populate HTML div with returned html
$( selectorForHTMLResponse ).html( result.contentHTML );
// invoke callback if a callback has been submitted
if ( callbackFunction && typeof( callbackFunction ) === "function") {
callbackFunction();
}
}).fail( function( e ) {
//log some info and alert about fail
console.dir( e.responseText );
alert('Ops! Something went wrong!');
});
}
$( document ).ready(function() {
// add listeners to HTML container and make use of callbacks
$('#county').change(
function() {
sendAjaxAndUpdateForm(
url='ajaxAPI.cfm?work_area_county_id=',
selectorForValue='#county',
selectorForHTMLResponse='#cityContainer',
callbackFunction= function(){ $('#city').change(
function() {
sendAjaxAndUpdateForm(
url='ajaxAPI.cfm?work_area_city_id=',
selectorForValue='#city',
selectorForHTMLResponse='#streetContainer',
callbackFunction=function(){ $('#street').change(
function(){ alert( 'Street ID:' + $('#street').val() + 'for \'' + $( '#street option:selected' ).text() + '\' selected.' )} )
}
);
})
}
);
});
});
4. ajaxAPI.cfm
<!--- Function to output content as JSON for a response of the ajax request --->
<cffunction name="outputJSON"
access="private"
returntype="void"
hint="function to output data as application/json">
<cfargument type="struct" name="contentStruct" required="true">
<cfcontent reset = "true">
<cfheader name="content-type" value="application/json">
<cfoutput>#serializeJSON( contentStruct )#</cfoutput>
<cfabort>
</cffunction>
<!--- instantiate Data Access Object Component--->
<cfset CountiesDAO = new components.CountiesDAO() />
<cfif structKeyExists(url, "work_area_county_id")
and len( work_area_county_id ) gt 0>
<cfset queryWorkAreaCities=CountiesDAO.getWorkAreaCitiesByCountyID( url.work_area_county_id )>
<cfsavecontent variable="result.contentHTML">
<cfoutput>
<select name="city" id="city" class="form-control">
<option value="">Select City</option>
<cfloop query="queryWorkAreaCities">
<option value="#queryWorkAreaCities.work_area_city_id#">#queryWorkAreaCities.work_area_city_name#</option>
</cfloop>
</select>
</cfoutput>
</cfsavecontent>
<!--- echo json --->
<cfset outputJSON( result )>
</cfif>
<cfif structKeyExists( url, "work_area_city_id" ) and len( work_area_city_id ) gt 0>
<cfset queryWorkAreaStreets=CountiesDAO.getWorkAreaStreetsByCityID( url.work_area_city_id )>
<cfsavecontent variable="result.contentHTML">
<cfoutput>
<select name="street" id="street" class="form-control">
<option value="">Select Street</option>
<cfloop query="queryWorkAreaStreets">
<option value="#queryWorkAreaStreets.work_area_street_id#">#queryWorkAreaStreets.work_area_street_name#</option>
</cfloop>
</select>
</cfoutput>
</cfsavecontent>
<!--- echo json --->
<cfset outputJSON( result )>
</cfif>
上述解决方案还远未完成,但它应该只是给您一个选择,让您可以开始尝试并找点乐子。
(之前开始写这个,后来被拉走了....)
老实说,county.cfm
脚本让我印象深刻,因为它过于努力地想要成为“每个人的一切”:)。它充当 ajax 的 cfinclude 和 端点,同时检索数据和生成 html。导致代码的可读性和复杂性比 IMO 所必需的要低。
更简洁的方法是将数据检索和 html/dom 操作分开。让 CF 服务器处理数据检索,让客户端操作 DOM。这样只需要两 (2) 个脚本。
创建一个只有 returns 数据的 cfc。然后在表单内,通过 ajax 调用 cfc 函数,并使用响应将 javascript.
填充到 select 列表中
YourComponent.CFC
首先创建一个具有三个远程函数的组件:getCounties()
、getCities(selected_county_id)
、getStreets(selected_city_id)
。每个函数只运行一个查询,returns 结果作为结构数组,格式为 json 字符串。
<cfcomponent>
<cffunction name="getCounties" access="remote" returntype="string" returnFormat="plain">
<!--- query is a function local object, use "local" scope --->
<cfquery name="local.result">
SELECT work_area_county_id, work_area_county_name
FROM work_area_county
ORDER BY work_area_county_name
</cfquery>
<!--- convert query into workable format: array of structures --->
<cfreturn serializeJSON(local.result, "struct")>
</cffunction>
<cffunction name="getCities" access="remote" returntype="string" returnFormat="plain">
<cfargument name="work_area_county_id" type="numeric" required="true">
<cfquery name="local.result">
SELECT work_area_city_id, work_area_city_name
FROM work_area_city
<!--- correct sql type is "integer" or "cf_sql_intEGER" --->
WHERE work_area_county_id = <cfqueryparam value="#arguments.work_area_county_id#" cfsqltype="integer">
ORDER BY work_area_city_name
</cfquery>
<cfreturn serializeJSON(local.result, "struct")>
</cffunction>
<cffunction name="getStreets" access="remote" returntype="string" returnFormat="plain">
<cfargument name="work_area_city_id" type="numeric" required="true">
<cfquery name="local.result">
SELECT work_area_street_id, work_area_street_name
FROM work_area_street
WHERE work_area_city_id = <cfqueryparam value="#arguments.work_area_city_id#" cfsqltype="integer">
ORDER BY work_area_street_name
</cfquery>
<cfreturn serializeJSON(local.result, "struct")>
</cffunction>
</cfcomponent>
Display.cfm
在表单内,添加 ajax 调用以填充列表。在加载文档时填充“县”列表,并在适当的更改事件中填充“city/street”列表。还有改进的空间,但这里有一个小例子
<script type="text/javascript">
$(document).ready(function()
{
// On load, populate county list
$.getJSON(
"YourComponent.cfc?method=getCounties",{},
function(response){
fillList("#county", response, "work_area_county_id", "work_area_county_name");
// refresh city and state
$("#city").trigger("change");
});
// When county changes, re-populate cities
$("#county").on("change", function(evt) {
var county_id = $(this).val();
$.getJSON(
"YourComponent.cfc?method=getCities&work_area_county_id="+ county_id, {},
function(response){
fillList("#city", response, "work_area_city_id", "work_area_city_name")
// refresh city and state
$("#city").trigger("change");
});
});
// On city change, re-populate streets
$("#city").on("change", function(evt) {
$('#street').attr('disabled', true);
var city_id = $(this).val();
$.getJSON(
"YourComponent.cfc?method=getStreets&work_area_city_id="+ city_id, {},
function(response){
fillList("#street", response, "work_area_street_id", "work_area_street_name")
});
});
// populates select list with provided data
function fillList( id, rows, value, text) {
// reinitialize
$( id ).empty().append( $("<option>")
.text( "Select" )
.val( 0 )
);
// populate
$.each(rows, function(index, data) {
$(id).append( $("<option>")
.val( data[value] )
.text( data[text] )
);
});
// enable
$(id).attr('disabled', false);
}
});
</script>
<form name="state_populate">
<!--- select list must have an "id" --->
<select id="county" name="county">
<option value="0">Select</option>
</select>
<select id="city" name="city">
<option value="0">Select</option>
</select>
<select id="street" name="street">
<option value="0">Select</option>
</select>
</form>
对于未来的观众;我想 post 自己回答我的问题。在等待答案被 posted 时,我一直在尝试让代码正常工作。很多天过去了,我在下面粘贴的是结果。
由于 AndreasRu 和 SOS 的答案都更好,所以我最终没有使用我写的东西。也许有人可以用我的代码作为不该做什么的例子。 :D
我的 CFC:
component displayname="pull_locations" output="false" {
public function getCounties(returntype="query") {
getCounties = queryExecute(
sql = "SELECT work_area_county_id, work_area_county_name FROM work_area_county"
);
return getCounties;
}
remote function getCitiesByCounty(required numeric county_id) returnFormat="JSON" {
getCity = queryExecute(
sql = "SELECT work_area_county_id, work_area_city_id, work_area_city_name FROM work_area_city WHERE work_area_county_id = :need",
params = {
need: {
value: arguments.county_id,
type: "cf_sql_integer"
}
}
);
rData = {
"status" = "success",
"data" = queryToArray(getCity)
};
return serializeJSON(rData);
}
remote function getStreetsByCity(required numeric city_id) returnFormat="JSON" {
getStreet = queryExecute(
sql = "SELECT work_area_city_id, work_area_street_id, work_area_street_name FROM work_area_street WHERE work_area_city_id = :need",
params = {
need: {
value: arguments.city_id,
type: "cf_sql_integer"
}
}
);
rData = {
"status" = "success",
"data" = QueryToArray(getStreet)
};
return serializeJSON(rData);
}
// Thank you Ben Nadel! :D
public function queryToArray(required query Data) output=false {
var LOCAL = StructNew();
LOCAL.Columns = ListToArray( ARGUMENTS.Data.ColumnList );
LOCAL.QueryArray = ArrayNew( 1 );
for (LOCAL.RowIndex = 1 ; LOCAL.RowIndex LTE ARGUMENTS.Data.RecordCount ; LOCAL.RowIndex = (LOCAL.RowIndex + 1)){
LOCAL.Row = StructNew();
for (LOCAL.ColumnIndex = 1 ; LOCAL.ColumnIndex LTE ArrayLen( LOCAL.Columns ) ; LOCAL.ColumnIndex = (LOCAL.ColumnIndex + 1)){
LOCAL.ColumnName = LOCAL.Columns[ LOCAL.ColumnIndex ];
LOCAL.Row[ LOCAL.ColumnName ] = ARGUMENTS.Data[ LOCAL.ColumnName ][ LOCAL.RowIndex ];
}
ArrayAppend( LOCAL.QueryArray, LOCAL.Row );
}
return LOCAL.QueryArray;
}
}
我的JavaScript/jQuery:
function loadCity(county) {
if(county != '') {
$.ajax({
url: "cfc/data.cfc?method=getCitiesByCounty",
dataType: "json",
type: "get",
async: false,
cache: false,
data: {
county_id: county,
},
success: function (response) {
response = JSON.parse(response);
if(response.status == 'success') {
rData = response.data;
let html = '<option value="">Select City</option>';
rData.forEach(element => {
html += '<option value="'+element.WORK_AREA_CITY_ID+'">'+element.WORK_AREA_CITY_NAME+'</option>';
});
$('#city').html(html);
let html2 = '<option value="">Select Street</option>';
$('#street').html(html2);
}
else {
alert('Error occured while pulling City name.');
}
},
error: function(jqXHR, status, error) {
console.log(status + ": " + error);
}
})
}
}
function loadStreet(city) {
if(city != '') {
$.ajax({
url: "cfc/data.cfc?method=getStreetsByCity",
dataType: "json",
type: "get",
async: false,
cache: false,
data: {
city_id: city,
},
success : function(response) {
response = JSON.parse(response);
if(response.status == 'success') {
rData = response.data;
let html = '<option value="">Select Street</option>';
rData.forEach(element => {
html += '<option value="'+element.WORK_AREA_STREET_ID+'">'+element.WORK_AREA_STREET_NAME+'</option>';
});
$('#street').html(html);
}
else {
alert('Error occured while pulling Street name.');
}
},
error: function(jqXHR, status, error) {
console.log(status + ": " + error);
}
})
}
}
我目前正在自学(再自学)JavaScript 和 jQuery 以重写在 Lucee 上运行的遗留应用程序。
部分重写需要对基本功能进行多项添加。一个具体的添加是将“街道名称”select 字段添加到现有的“县名”->“城市名称”select 字段。
我发现了这个 Whosebug 问题:Coldfusion conditional select option does not work in IE9, Chrome and Firefox
使用该问题的基础;我写了以下内容:
<!--- county.cfm --->
<cfif structKeyExists(url,'work_area_county_id')>
<cfset loadState() />
</cfif>
<cfif structKeyExists(url,'work_area_city_id')>
<cfset loadStreet() />
</cfif>
<cfset loadCounty() />
<cffunction name="loadCounty">
<cfquery name="qCounty">
SELECT work_area_county_id, work_area_county_name FROM work_area_county
</cfquery>
</cffunction>
<cffunction name="loadState">
<cfset variables.work_area_county_id = url.work_area_county_id />
<cfquery name="qCity">
SELECT work_area_city_id, work_area_city_name, work_area_county_id FROM work_area_city WHERE work_area_county_id = <cfqueryparam value="#variables.work_area_county_id#" cfsqltype="cf_sql_int">
</cfquery>
<cfoutput>
<select name="state" class="form-control">
<option value="">Select City</option>
<cfloop query="qCity">
<option value="#work_area_city_id#">#work_area_city_name#</option>
</cfloop>
</select>
</cfoutput>
</cffunction>
<cffunction name="loadStreet">
<cfset variables.work_area_city_id = url.work_area_city_id />
<cfquery name="qStreet">
SELECT work_area_street_id, work_area_street_name, work_area_city_id FROM work_area_street WHERE work_area_city_id = <cfqueryparam value="#variables.work_area_city_id#" cfsqltype="cf_sql_int">
</cfquery>
<cfoutput>
<select name="state" class="form-control">
<option value="">Select Street</option>
<cfloop query="qStreet">
<option value="#work_area_street_id#">#work_area_street_name#</option>
</cfloop>
</select>
</cfoutput>
</cffunction>
<!--- display.cfm --->
<cfinclude template="includes/county.cfm">
<cfoutput>
<form name="state_populate">
<select name="county" id="county">
<option value="0">Select</option>
<cfloop query="qCounty">
<option value="#work_area_county_id#">
#work_area_county_name#
</option>
</cfloop>
</select>
<div id="city">
<select name="city" class="form-control">
<option value="">Select</option>
</select>
</div>
<div id="street">
<select name="street" class="form-control">
<option value="">Select</option>
</select>
</div>
</form>
</cfoutput>
// The JS
$('#county').change(function() {
var value = $('#county').val();
$.ajax({
type: "get",
url:'includes/county.cfm?work_area_county_id='+value,
success: function(response) {
$('#city').html(response);
},
error: function(jqXHR, status, error) {
console.log(status + ": " + error);
}
});
});
上面的代码在 selecting "County Name" 时运行良好。它在第二个 select 字段中正确显示“城市名称”。然后我尝试在第三个 select 字段中添加“街道名称”并添加我“认为”应该适用于 CFML 和 HTML 的内容。当我到达代码的 JS 部分时,我撞到了砖墙。我似乎找不到,也许是因为缺少正确的搜索词,如何添加额外的 AJAX 调用。
我发现了这个问题:Parallel asynchronous Ajax requests using jQuery
有多个答案,但我“认为”与我的问题相关的最接近的答案是:
$.whenAll({
val1: $.getJSON('/values/1'),
val2: $.getJSON('/values/2')
})
.done(function (results) {
var sum = results.val1.value + results.val2.value;
$('#mynode').html(sum);
});
我相信他们被称为“承诺”?
代码需要防止第二个 select 字段“城市名称”发生变化,并正确使用具有多个值的 AJAX“url”参数。我知道参考上面的代码,URL 部分可能需要与此“类似”的东西:
url:'includes/county.cfm?work_area_county_id='+ value + '&work_area_city_id=' + value
供考虑:
- 我知道我的代码不是很好而且我知道它可以写得更好。我正在努力改进。
- 我不是全职编码员,但我断断续续地编码多年。我仍然认为自己是 CFML/JavaScript/jQuery 的新手,所以很多方法都让我头疼。
- 代码会用cfscript写,以后转成CFC。现在我让它变得简单并使用了标签。
- 我从 display.cfm. 中删除了不相关的 HTML 代码
如有任何意见或指导,我们将不胜感激! :D
我将向您展示我将如何处理此类任务的示例。我的回答可能不是最好或最干净的解决方案:我过去的编码实践很糟糕(我仍然倾向于写意大利面条,而且我一直在努力反对这样做)。但是,我正在改变那些坏习惯,这很有趣。
我的解决方案是用 OOP 方法编写的。我真的建议每个人都尝试走这条路,因为很快就会开始感觉更自然:感觉不错,尤其是当您需要修复或扩展代码时。
那时我也会尝试使用 cfscript 而不是标签,因为使用组件和函数编写 OOP 更简单,特别是如果您有一些使用 JavaScript 的经验(这在某种程度上是相似的)。但是,我提供了标记方法,因为我认为这就是您想要的。
这个解决方案基本上由 4 个文件组成:
- display.cfm:条目template/page.
- components/CountiesDAO.cfc: 一个组件,作为您所在县的数据访问对象,具有相应的 getter。请注意,我正在使用 QoQ 模拟数据库请求。您应该能够使用您的数据源而不是那里的真实数据。
- countyForm.js: JavaScript文件用jQueryajax函数获取数据延迟对象并填充html 包含响应数据的容器(有关更多信息,请参阅我在代码中的注释)。
- ajaxAPI.cfm:模板echos/outputs所有数据为JSON为您jQueryajax请求。
主要问题是您需要为每个 ajax 请求检索更多 JavaScript 承诺。在 jQuery 中,延迟对象会发生这种情况。
文件如下:
1。 display.cfm:
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Page Title</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<body>
<cfset CountiesDAO= new components.CountiesDAO() />
<cfset queryWorkAreaCounties=CountiesDAO.getWorkAreaCounties()>
<cfoutput>
<select id="county">
<option value="0">Select</option>
<cfloop query="queryWorkAreaCounties">
<option value="#queryWorkAreaCounties.work_area_county_id#">
#queryWorkAreaCounties.work_area_county_name#
</option>
</cfloop>
</select>
<div id="cityContainer"></div>
<div id="streetContainer"></div>
</cfoutput>
<!-- embedded jquery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="countyForm.js"></script>
</body>
</html>
2。 components/CountiesDAO.cfc
<cfcomponent>
<cffunction name="init">
<cfset variables.queriesQoQ["work_area_counties"]=createWorkAreaCounties()>
<cfset variables.queriesQoQ["Work_area_cities"]=createWorkAreaCities()>
<cfset variables.queriesQoQ["Work_area_streets"]=createWorkAreaStreets()>
<cfreturn this>
</cffunction>
<!--- functions to create Data to emulate a DB with QoQ --->
<cffunction name="createWorkAreaCounties"
access="private"
returntype="query"
hint="create query to simulate a DB data table for QoQ">
<cfset work_area_countyTable= queryNew(
"work_area_county_id, work_area_county_name",
"integer,varchar",
[
{"work_area_county_id":1,"work_area_county_name":"Los Angeles County"},
{"work_area_county_id":2,"work_area_county_name":"Cook County"},
{"work_area_county_id":3,"work_area_county_name":"Harris County"},
{"work_area_county_id":4,"work_area_county_name":"Maricopa County"}
])/>
<cfreturn work_area_countyTable>
</cffunction>
<cffunction name="createWorkAreaCities"
access="private"
returntype="query"
hint="create query to simulate a DB data table for QoQ">
<cfset work_area_cityTable= queryNew(
"work_area_city_id, work_area_city_name, work_area_county_id",
"integer,varchar,integer",
[
{"work_area_city_id":1,"work_area_city_name":"Agoura Hills" , "work_area_county_id":1},
{"work_area_city_id":2,"work_area_city_name":"Alhambra" , "work_area_county_id":1},
{"work_area_city_id":3,"work_area_city_name":"Bradbury" , "work_area_county_id":1},
{"work_area_city_id":4,"work_area_city_name":"Arlington Heights" , "work_area_county_id":2},
{"work_area_city_id":5,"work_area_city_name":"Bellwood" , "work_area_county_id":2},
{"work_area_city_id":6,"work_area_city_name":"Bridgeview" , "work_area_county_id":2},
{"work_area_city_id":7,"work_area_city_name":"Baytown" , "work_area_county_id":3},
{"work_area_city_id":8,"work_area_city_name":"Cove" , "work_area_county_id":3},
{"work_area_city_id":9,"work_area_city_name":"The Woodlands" , "work_area_county_id":3},
{"work_area_city_id":10,"work_area_city_name":"Avondale" , "work_area_county_id":4},
{"work_area_city_id":11,"work_area_city_name":"Phoenix" , "work_area_county_id":4},
{"work_area_city_id":12,"work_area_city_name":"Glendale" , "work_area_county_id":4},
])/>
<cfreturn work_area_cityTable>
</cffunction>
<cffunction name="createWorkAreaStreets"
access="private"
returntype="query"
hint="create query to simulate a DB data table for QoQ">
<cfset work_area_streetTable= queryNew(
"work_area_street_id, work_area_street_name, work_area_city_id",
"integer,varchar,integer",
[
{"work_area_street_id":1,"work_area_street_name":"Street One Agoura Hills", "work_area_city_id": 1 },
{"work_area_street_id":2,"work_area_street_name":"Street Two Agoura Hills", "work_area_city_id": 1 },
{"work_area_street_id":3,"work_area_street_name":"Street Three Agoura Hills", "work_area_city_id": 1 },
{"work_area_street_id":4,"work_area_street_name":"Street One Alhambra", "work_area_city_id": 2 },
{"work_area_street_id":5,"work_area_street_name":"Street Two Alhambra", "work_area_city_id": 2 },
{"work_area_street_id":6,"work_area_street_name":"Street Three Alhambra", "work_area_city_id": 2 },
{"work_area_street_id":7,"work_area_street_name":"Street One Bradbury", "work_area_city_id": 3 },
{"work_area_street_id":8,"work_area_street_name":"Street Two Bradbury", "work_area_city_id": 3 },
{"work_area_street_id":9,"work_area_street_name":"Street One Arlington Heights", "work_area_city_id": 4 },
{"work_area_street_id":10,"work_area_street_name":"Street Two Arlington Heights", "work_area_city_id": 4 },
{"work_area_street_id":11,"work_area_street_name":"Street One Bellwood", "work_area_city_id": 5 },
{"work_area_street_id":12,"work_area_street_name":"Street Two Bellwood", "work_area_city_id": 5 },
{"work_area_street_id":13,"work_area_street_name":"Street One Bridgeview", "work_area_city_id": 6 },
{"work_area_street_id":14,"work_area_street_name":"Street Two Bridgeview", "work_area_city_id": 6 },
{"work_area_street_id":15,"work_area_street_name":"Street One Baytown", "work_area_city_id": 7 },
{"work_area_street_id":16,"work_area_street_name":"Street Two Baytown", "work_area_city_id": 7 },
{"work_area_street_id":17,"work_area_street_name":"Street One Cove", "work_area_city_id": 8 },
{"work_area_street_id":18,"work_area_street_name":"Street Two Cove", "work_area_city_id": 8 },
{"work_area_street_id":19,"work_area_street_name":"Street One The Woodlands", "work_area_city_id": 9 },
{"work_area_street_id":20,"work_area_street_name":"Street Two The Woodlands", "work_area_city_id": 9 },
{"work_area_street_id":21,"work_area_street_name":"Street One Avondale", "work_area_city_id": 10 },
{"work_area_street_id":22,"work_area_street_name":"Street Two Avondale", "work_area_city_id": 10 },
{"work_area_street_id":23,"work_area_street_name":"Street One Phoenix", "work_area_city_id": 11 },
{"work_area_street_id":24,"work_area_street_name":"Street Two Phoenix", "work_area_city_id": 11 },
{"work_area_street_id":25,"work_area_street_name":"Street One Glendale", "work_area_city_id": 12 },
{"work_area_street_id":26,"work_area_street_name":"Street Two Glendale", "work_area_city_id": 12 },
])/>
<cfreturn work_area_streetTable>
</cffunction>
<cffunction name="getWorkAreaCounties"
access="public"
returntype="query"
hint="function to return all counties">
<cfset work_area_county=queriesQoQ["work_area_counties"]>
<cfquery name="qCity" dbtype="query" >
SELECT * FROM work_area_county
</cfquery>
<cfreturn qCity>
</cffunction>
<cffunction name="getWorkAreaCitiesByCountyID"
access="public"
returntype="query"
hint="function to return all cities of a county">
<cfargument type="numeric" name="countyid" required="true">
<cfset work_area_city=queriesQoQ["work_area_cities"]>
<cfquery name="qCity" dbtype="query" >
SELECT work_area_city_id, work_area_city_name, work_area_county_id
FROM work_area_city
WHERE work_area_county_id = <cfqueryparam value="#arguments.countyid#" cfsqltype="cf_sql_int">
</cfquery>
<cfreturn qCity>
</cffunction>
<cffunction name="getWorkAreaStreetsByCityID"
access="public"
returntype="query"
hint="function to return all streets of a city">
<cfargument type="numeric" name="cityid" required="true">
<cfset work_area_street=queriesQoQ["work_area_streets"]>
<cfquery name="qStreet" dbtype="query" >
SELECT work_area_street_id, work_area_street_name, work_area_city_id
FROM work_area_street
WHERE work_area_city_id = <cfqueryparam value="#arguments.cityid#" cfsqltype="cf_sql_int">
</cfquery>
<cfreturn qStreet>
</cffunction>
</cfcomponent>
3。 countyForm.js
// ajax function
function sendAjaxAndUpdateForm(
url,
selectorForValue,
selectorForHTMLResponse ,
callbackFunction ){
let value = $( selectorForValue ).val();
/* return the ajax request as deferred object with done()/fail(). For more information, please see:
* https://api.jquery.com/jquery.ajax/
*
*/
return $.ajax({
method: "GET",
url: url + value,
}).done( function( result ) {
//populate HTML div with returned html
$( selectorForHTMLResponse ).html( result.contentHTML );
// invoke callback if a callback has been submitted
if ( callbackFunction && typeof( callbackFunction ) === "function") {
callbackFunction();
}
}).fail( function( e ) {
//log some info and alert about fail
console.dir( e.responseText );
alert('Ops! Something went wrong!');
});
}
$( document ).ready(function() {
// add listeners to HTML container and make use of callbacks
$('#county').change(
function() {
sendAjaxAndUpdateForm(
url='ajaxAPI.cfm?work_area_county_id=',
selectorForValue='#county',
selectorForHTMLResponse='#cityContainer',
callbackFunction= function(){ $('#city').change(
function() {
sendAjaxAndUpdateForm(
url='ajaxAPI.cfm?work_area_city_id=',
selectorForValue='#city',
selectorForHTMLResponse='#streetContainer',
callbackFunction=function(){ $('#street').change(
function(){ alert( 'Street ID:' + $('#street').val() + 'for \'' + $( '#street option:selected' ).text() + '\' selected.' )} )
}
);
})
}
);
});
});
4. ajaxAPI.cfm
<!--- Function to output content as JSON for a response of the ajax request --->
<cffunction name="outputJSON"
access="private"
returntype="void"
hint="function to output data as application/json">
<cfargument type="struct" name="contentStruct" required="true">
<cfcontent reset = "true">
<cfheader name="content-type" value="application/json">
<cfoutput>#serializeJSON( contentStruct )#</cfoutput>
<cfabort>
</cffunction>
<!--- instantiate Data Access Object Component--->
<cfset CountiesDAO = new components.CountiesDAO() />
<cfif structKeyExists(url, "work_area_county_id")
and len( work_area_county_id ) gt 0>
<cfset queryWorkAreaCities=CountiesDAO.getWorkAreaCitiesByCountyID( url.work_area_county_id )>
<cfsavecontent variable="result.contentHTML">
<cfoutput>
<select name="city" id="city" class="form-control">
<option value="">Select City</option>
<cfloop query="queryWorkAreaCities">
<option value="#queryWorkAreaCities.work_area_city_id#">#queryWorkAreaCities.work_area_city_name#</option>
</cfloop>
</select>
</cfoutput>
</cfsavecontent>
<!--- echo json --->
<cfset outputJSON( result )>
</cfif>
<cfif structKeyExists( url, "work_area_city_id" ) and len( work_area_city_id ) gt 0>
<cfset queryWorkAreaStreets=CountiesDAO.getWorkAreaStreetsByCityID( url.work_area_city_id )>
<cfsavecontent variable="result.contentHTML">
<cfoutput>
<select name="street" id="street" class="form-control">
<option value="">Select Street</option>
<cfloop query="queryWorkAreaStreets">
<option value="#queryWorkAreaStreets.work_area_street_id#">#queryWorkAreaStreets.work_area_street_name#</option>
</cfloop>
</select>
</cfoutput>
</cfsavecontent>
<!--- echo json --->
<cfset outputJSON( result )>
</cfif>
上述解决方案还远未完成,但它应该只是给您一个选择,让您可以开始尝试并找点乐子。
(之前开始写这个,后来被拉走了....)
老实说,county.cfm
脚本让我印象深刻,因为它过于努力地想要成为“每个人的一切”:)。它充当 ajax 的 cfinclude 和 端点,同时检索数据和生成 html。导致代码的可读性和复杂性比 IMO 所必需的要低。
更简洁的方法是将数据检索和 html/dom 操作分开。让 CF 服务器处理数据检索,让客户端操作 DOM。这样只需要两 (2) 个脚本。
创建一个只有 returns 数据的 cfc。然后在表单内,通过 ajax 调用 cfc 函数,并使用响应将 javascript.
填充到 select 列表中YourComponent.CFC
首先创建一个具有三个远程函数的组件:getCounties()
、getCities(selected_county_id)
、getStreets(selected_city_id)
。每个函数只运行一个查询,returns 结果作为结构数组,格式为 json 字符串。
<cfcomponent>
<cffunction name="getCounties" access="remote" returntype="string" returnFormat="plain">
<!--- query is a function local object, use "local" scope --->
<cfquery name="local.result">
SELECT work_area_county_id, work_area_county_name
FROM work_area_county
ORDER BY work_area_county_name
</cfquery>
<!--- convert query into workable format: array of structures --->
<cfreturn serializeJSON(local.result, "struct")>
</cffunction>
<cffunction name="getCities" access="remote" returntype="string" returnFormat="plain">
<cfargument name="work_area_county_id" type="numeric" required="true">
<cfquery name="local.result">
SELECT work_area_city_id, work_area_city_name
FROM work_area_city
<!--- correct sql type is "integer" or "cf_sql_intEGER" --->
WHERE work_area_county_id = <cfqueryparam value="#arguments.work_area_county_id#" cfsqltype="integer">
ORDER BY work_area_city_name
</cfquery>
<cfreturn serializeJSON(local.result, "struct")>
</cffunction>
<cffunction name="getStreets" access="remote" returntype="string" returnFormat="plain">
<cfargument name="work_area_city_id" type="numeric" required="true">
<cfquery name="local.result">
SELECT work_area_street_id, work_area_street_name
FROM work_area_street
WHERE work_area_city_id = <cfqueryparam value="#arguments.work_area_city_id#" cfsqltype="integer">
ORDER BY work_area_street_name
</cfquery>
<cfreturn serializeJSON(local.result, "struct")>
</cffunction>
</cfcomponent>
Display.cfm
在表单内,添加 ajax 调用以填充列表。在加载文档时填充“县”列表,并在适当的更改事件中填充“city/street”列表。还有改进的空间,但这里有一个小例子
<script type="text/javascript">
$(document).ready(function()
{
// On load, populate county list
$.getJSON(
"YourComponent.cfc?method=getCounties",{},
function(response){
fillList("#county", response, "work_area_county_id", "work_area_county_name");
// refresh city and state
$("#city").trigger("change");
});
// When county changes, re-populate cities
$("#county").on("change", function(evt) {
var county_id = $(this).val();
$.getJSON(
"YourComponent.cfc?method=getCities&work_area_county_id="+ county_id, {},
function(response){
fillList("#city", response, "work_area_city_id", "work_area_city_name")
// refresh city and state
$("#city").trigger("change");
});
});
// On city change, re-populate streets
$("#city").on("change", function(evt) {
$('#street').attr('disabled', true);
var city_id = $(this).val();
$.getJSON(
"YourComponent.cfc?method=getStreets&work_area_city_id="+ city_id, {},
function(response){
fillList("#street", response, "work_area_street_id", "work_area_street_name")
});
});
// populates select list with provided data
function fillList( id, rows, value, text) {
// reinitialize
$( id ).empty().append( $("<option>")
.text( "Select" )
.val( 0 )
);
// populate
$.each(rows, function(index, data) {
$(id).append( $("<option>")
.val( data[value] )
.text( data[text] )
);
});
// enable
$(id).attr('disabled', false);
}
});
</script>
<form name="state_populate">
<!--- select list must have an "id" --->
<select id="county" name="county">
<option value="0">Select</option>
</select>
<select id="city" name="city">
<option value="0">Select</option>
</select>
<select id="street" name="street">
<option value="0">Select</option>
</select>
</form>
对于未来的观众;我想 post 自己回答我的问题。在等待答案被 posted 时,我一直在尝试让代码正常工作。很多天过去了,我在下面粘贴的是结果。
由于 AndreasRu 和 SOS 的答案都更好,所以我最终没有使用我写的东西。也许有人可以用我的代码作为不该做什么的例子。 :D
我的 CFC:
component displayname="pull_locations" output="false" {
public function getCounties(returntype="query") {
getCounties = queryExecute(
sql = "SELECT work_area_county_id, work_area_county_name FROM work_area_county"
);
return getCounties;
}
remote function getCitiesByCounty(required numeric county_id) returnFormat="JSON" {
getCity = queryExecute(
sql = "SELECT work_area_county_id, work_area_city_id, work_area_city_name FROM work_area_city WHERE work_area_county_id = :need",
params = {
need: {
value: arguments.county_id,
type: "cf_sql_integer"
}
}
);
rData = {
"status" = "success",
"data" = queryToArray(getCity)
};
return serializeJSON(rData);
}
remote function getStreetsByCity(required numeric city_id) returnFormat="JSON" {
getStreet = queryExecute(
sql = "SELECT work_area_city_id, work_area_street_id, work_area_street_name FROM work_area_street WHERE work_area_city_id = :need",
params = {
need: {
value: arguments.city_id,
type: "cf_sql_integer"
}
}
);
rData = {
"status" = "success",
"data" = QueryToArray(getStreet)
};
return serializeJSON(rData);
}
// Thank you Ben Nadel! :D
public function queryToArray(required query Data) output=false {
var LOCAL = StructNew();
LOCAL.Columns = ListToArray( ARGUMENTS.Data.ColumnList );
LOCAL.QueryArray = ArrayNew( 1 );
for (LOCAL.RowIndex = 1 ; LOCAL.RowIndex LTE ARGUMENTS.Data.RecordCount ; LOCAL.RowIndex = (LOCAL.RowIndex + 1)){
LOCAL.Row = StructNew();
for (LOCAL.ColumnIndex = 1 ; LOCAL.ColumnIndex LTE ArrayLen( LOCAL.Columns ) ; LOCAL.ColumnIndex = (LOCAL.ColumnIndex + 1)){
LOCAL.ColumnName = LOCAL.Columns[ LOCAL.ColumnIndex ];
LOCAL.Row[ LOCAL.ColumnName ] = ARGUMENTS.Data[ LOCAL.ColumnName ][ LOCAL.RowIndex ];
}
ArrayAppend( LOCAL.QueryArray, LOCAL.Row );
}
return LOCAL.QueryArray;
}
}
我的JavaScript/jQuery:
function loadCity(county) {
if(county != '') {
$.ajax({
url: "cfc/data.cfc?method=getCitiesByCounty",
dataType: "json",
type: "get",
async: false,
cache: false,
data: {
county_id: county,
},
success: function (response) {
response = JSON.parse(response);
if(response.status == 'success') {
rData = response.data;
let html = '<option value="">Select City</option>';
rData.forEach(element => {
html += '<option value="'+element.WORK_AREA_CITY_ID+'">'+element.WORK_AREA_CITY_NAME+'</option>';
});
$('#city').html(html);
let html2 = '<option value="">Select Street</option>';
$('#street').html(html2);
}
else {
alert('Error occured while pulling City name.');
}
},
error: function(jqXHR, status, error) {
console.log(status + ": " + error);
}
})
}
}
function loadStreet(city) {
if(city != '') {
$.ajax({
url: "cfc/data.cfc?method=getStreetsByCity",
dataType: "json",
type: "get",
async: false,
cache: false,
data: {
city_id: city,
},
success : function(response) {
response = JSON.parse(response);
if(response.status == 'success') {
rData = response.data;
let html = '<option value="">Select Street</option>';
rData.forEach(element => {
html += '<option value="'+element.WORK_AREA_STREET_ID+'">'+element.WORK_AREA_STREET_NAME+'</option>';
});
$('#street').html(html);
}
else {
alert('Error occured while pulling Street name.');
}
},
error: function(jqXHR, status, error) {
console.log(status + ": " + error);
}
})
}
}