我有一个<select>
列表,通过AJAX在页面加载时动态填充。我试图在加载页面时以及在用户实际选择默认选择之外的其他内容时找出初始选择的值。
获取值后,我尝试将其传递给名为PopulateCustomerAlertDIV()
的自定义函数。以下是我到目前为止的情况:
HTML:
<cfselect name="company_name" id="company_name" tabindex="0"
onchange="PopulateCustomerAlertDIV();" >
<option>#customers.company_name#</option>
</cfselect>
Javascript(填充列表)
<!--- Retrieves list of customers --->
<script>
$(document).ready(function () {
//populate the vehicle select list
$.ajax({
url: 'cfcs/get_customers.cfc?method=getData&returnformat=json',
dataType: 'json',
success: function(response){
console.log('Success');
$.each(response.DATA, function(i, row){
// get value in first column ie "description"
var company_name = row[0];
// append new option to list
$("##company_name").append($('<option/>', {
value: company_name,
text : company_name
}));
});
},
error: function(msg){
console.log(msg);
}
})
populateSalesTax();
console.log('Sales Tax Function Ran from Customer Query Function');
});
</script>
Javascript(填充DIV):
<script>
function PopulateCustomerAlertDIV(){
// Populate the customer alert DIV based on the customer selection
console.log( $("##company_name2>option:selected").attr("Value") );
$.ajax({
url:'cfcs/customerAlertDIV.cfc?method=getAlert&returnformat=json',
dataType: 'json',
data: { company_name: $("##company_name>option:selected").attr("Value") },
success: function(obj) {
JSON.stringify(obj);//to string
console.log(obj.alert);
$("##CustomerAlertDIV").html( '<div style="width:80%" align="center"> <br /> <br />' + obj.alert + ' <br /> <br /> </div>' );
if(obj.alert_priority == 'high' ) {
$('##CustomerAlertDIV').removeClass().addClass('alert_error');
}
else if (obj.alert_priority == 'medium' ){
$('##CustomerAlertDIV').removeClass().addClass('alert_warning');
}
else if(obj.alert_priority == 'low' ){
$('##CustomerAlertDIV').removeClass().addClass('alert_info');
}
},
error: function(req, err){
$("##CustomerAlertDIV").html("");
$('##CustomerAlertDIV').removeClass().addClass('');
console.log('error'); }
});
}
$(document).ready(function() {
console.log('My Var: ' + x);
PopulateCustomerAlertDIV();
console.log('Customer DIV Function Ran');
populateSalesTax();
console.log('Sales Tax Function Ran from Document Ready');
});
</script>
Get_Customers.cfc
<cfcomponent>
<cffunction name="getData" access="remote" returntype="query">
<!---Get Customers --->
<cfquery name="data" datasource="#datasource#">
select company_name
from customer_table
order by company_name ASC
</cfquery>
<!--- Return results --->
<cfreturn data>
</cffunction>
<!---Get Customer Sales Tax Info --->
<cffunction name="getSalesTax" access="remote" returntype="query">
<cfargument name="company_name" type="any" required="true">
<!--- localize function variables --->
<cfset var dataDetail = "">
<cfoutput>
<cfquery name="dataDetail" datasource="#datasource#">
SELECT tax_rate
FROM customer_table
<!--- adjust cfsqltype if needed --->
WHERE company_name = <cfqueryparam value="#ARGUMENTS.company_name#" cfsqltype="cf_sql_varchar">
</cfquery>
</cfoutput>
<cfreturn getSalesTax.tax_rate>
</cffunction>
</cfcomponent>
CustomerAlertDIV.cfc
<cfcomponent>
<cffunction name="getAlert" access="remote" returntype="any">
<cfargument name="company_name" type="any" required="true">
<!--- localize function variables --->
<cfset var dataDetail = "">
<cfquery name="getID" datasource="#datasource#" >
select customer_id
from customer_table
where company_name = <cfqueryparam value="#ARGUMENTS.company_name#"
cfsqltype="cf_sql_varchar">
</cfquery>
<cfquery name="dataDetail" datasource="#datasource#">
SELECT ID, alert, alert_priority
FROM customer_alerts
WHERE customer_id = <cfqueryparam value="#getID.customer_id#" cfsqltype="cf_sql_varchar"> AND alert_status = 'on'
</cfquery>
<cfoutput query="dataDetail">
<cfset obj = {
"alert" = alert,
"alert_priority" = alert_priority
} />
<cfprocessingdirective suppresswhitespace="Yes">
<cfoutput>
#serializeJSON(obj)#
</cfoutput>
</cfprocessingdirective>
</cfoutput>
</cffunction>
</cfcomponent>
答案 0 :(得分:1)
我想将此作为评论添加,但我仍然对评论要点有点简短,所以在此处发表评论。我认为有两种方法可以使这更容易。两个选项都需要在PopulateCustomerAlertDIV()中进行此更改。
// Change to accept passed var
function PopulateCustomerAlertDIV(selected){
// Populate the customer alert DIV based on the customer selection
$.ajax({
url:'cfcs/customerAlertDIV.cfc?method=getAlert&returnformat=json',
dataType: 'json',
data: { company_name: selected }, // Change to use passed var
选项一是使用JS而不是CF填充选择列表。通过AJAX调用获取列表。成功函数看起来像这样:
var sel = $('#company_name');
$.each(obj, function(i,j){
sel.append($('<option>').attr('value', j.Id).text(j.Name));
});
PopulateCustomerAlertDIV(obj[1].company_name);
使用这样的html:
<select name="company_name" id="company_name" onchange="PopulateCustomerAlertDIV(this.value);" />
所以现在填充了select,并且第一次调用了PopulateCustomerAlertDIV()。
选项二是将值传递给函数。从body标签调用onload允许你将cf var传递给JS,并且看起来比文档准备好更可靠。
<body onload="PopulateCustomerAlertDIV(#customers[1].company_name#)">
无论你走哪条路,我建议不要使用cfinput。
编辑:过早提交。
答案 1 :(得分:1)
(聊天摘要)
简答:
只是为了澄清原始问题:它是由计时问题引起的。该代码使用了几个ajax调用,它们是异步。因此,刷新DIV的功能是在公司列表甚至填充之前尝试获取所选公司。显然,解决方案是等到它填充后。然后刷新DIV。
更长的回答:
原始代码使用的是<cfselect bind...>
或ExtJS,使用的是与jQuery不同的事件模型。在ExtJS加载选择列表之前,JQuery的document.ready
事件实际上是在触发。因此,当PopulateCustomerAlertDIV()
试图抓住“选定的”公司时:
$.ajax({ url:'cfcs/customerAlertDIV.cfc?method=getAlert&returnformat=json', data: { company_name: $("##company_name>option:selected").attr("Value") }, .. });
...结果为null / undefined。因此它实际上并没有将有效的company_name传递给CFC。这就是<div>
未正确填充的原因。
<script> $(document).ready(function() { //... // 1st: $.ajax() call to populate select list PopulateList(); // 2nd: populate div with selected company PopulateCustomerAlertDIV(); //... }); </script>
后面的代码使用jQuery来填充列表而不是“绑定”。这是更好的IMO,因为它不会混合事件模型。但是,它仍然存在轻微的计时问题。
第一个函数使用$.ajax()
调用来填充公司列表。 $.ajax()
调用默认是异步的。即使第二次调用PopulateCustomerAlertDIV()
函数,也不能保证第一个函数在启动时完成执行。因此,PopulateCustomerAlertDIV()
最终仍然试图在公司列表填充之前访问所选公司。
解决方案是在填充公司列表后调用PopulateCustomerAlertDIV()
:正如Mike建议的那样,在ajax调用的success()
方法中。 (虽然无需修改函数参数)。
请记住,您也可以通过使用同步ajax调用来解决问题,或者完全放弃ajax并使用基本的cfoutput循环填充列表。那么时间不是问题。但是,这些选项有不同的优缺点。
答案 2 :(得分:-1)
你可以随时轻松地做到这一点。我刚刚运行了这段代码:
<cfset abc = "hello">
<cfoutput>
<script>
alert("#abc#");
</script>
并得到我的警觉。这意味着你可以做到这一点。
<cfif you have the selected value identified>
<cfset javascriptVar = that value>
<cfelse>
<cfset javascriptVar = the first value that will appear in your select>
</cfif>
<cfoutput>
<script>
var varFromColdFusion = #javascriptVar#;
etc
</script>