在页面加载时通过 JQUERY 获取 SelectList 值

Get SelectList Value Via JQUERY on Page Load

我有一个 <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>

我想把这个加到评论里,但是我的评论点还不够,所以把我的评论放在这里。我看到有两种方法可以使此 easier.Both 选项需要在 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 填充 select 列表。使用 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,并且似乎比 document ready 更可靠。

<body onload="PopulateCustomerAlertDIV(#customers[1].company_name#)">

无论哪种方式,我都建议不要使用 cfinput。

编辑:过早提交。

你总能以简单的方式做到这一点。我只是 运行 这个代码:

<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>

(聊天摘要)

简答:

澄清一下原来的问题:是时序问题引起的。该代码使用多个 ajax 调用,它们是 异步的 。因此,刷新 DIV 的函数试图在 公司列表被填充之前获取 selected 公司 。显然,解决方案是等到它被填充之后。然后刷新DIV。

更长的答案:

原始代码使用 <cfselect bind...> 或 ExtJS,使用与 jQuery 不同的事件模型。 JQuery 的 document.ready 事件实际上是在 ExtJS 加载 select 列表之前触发的。因此,当 PopulateCustomerAlertDIV() 试图收购 "selected" 公司时:

   $.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 代替 "bind" 来填充列表。这是更好的 IMO,因为它不混合事件模型。但是,它仍然存在轻微的时间问题。

第一个函数使用 $.ajax() 调用来填充公司列表。 $.ajax() 调用默认是异步的。即使 PopulateCustomerAlertDIV() 函数被第二次调用,也不能保证第一个函数在启动时会完成执行。所以最终,PopulateCustomerAlertDIV() 仍在尝试在公司列表被填充之前访问 selected 公司。

解决方案是在填充公司列表后调用 PopulateCustomerAlertDIV():正如 Mike 所建议的,在 ajax 调用的 success() 方法中。 (虽然不需要修改函数参数)

请记住,您也可以通过使用同步 ajax 调用来解决问题,或者完全放弃 ajax 并使用基本的 cfoutput 循环填充列表。那么时机就不是问题了。但是,这些选项各有利弊。