在Coldfusion中访问Javascript创建的结构表单字段

问题描述

我正在其中一种表单中使用导入的Javascript代码段来创建动态输入部分(您可以按+按钮添加行,而-按钮以删除行),其中办公室可能有多个不同的地方联络人。如果您需要的话,这是适用的代码(但这确实可以正常工作,所以这不是问题):

<script type="text/javascript">
var ROWCOUNT = 0;
function add_contact_fields(contactData) {
    if (typeof contactData === 'object') {} else {
    
        ROWCOUNT = ROWCOUNT+1;
        
        contactData = {
                    id: 'A'+ROWCOUNT,cFirstName: '',cLastName: '',cTitle: '',cPhone: '',cEmail: ''
        }
    }

    var contactRow = document.createElement("div");
    contactRow.setAttribute("class","form-group row contact-field-wrapper");
    contactRow.innerHTML = ''+
    '<div class="col-xs-2">'+
    '   <div class="form-group required">'+
    '       <input type="text" class="form-control" id="cFirstName'+contactData.id+'" name="contact['+contactData.id+'][cFirstName]" value="'+contactData.cFirstName+'" placeholder="First Name" data-rule-required="true" required="true">'+
    '   </div>'+
    '</div>'+
    '<div class="col-xs-2">'+
    '   <div class="form-group required">'+
    '       <input type="text" class="form-control" id="cLastName'+contactData.id+'" name="contact['+contactData.id+'][cLastName]" value="'+contactData.cLastName+'" placeholder="Last Name" data-rule-required="true" required="true">'+
    '   </div>'+
    '</div>'+
    '<div class="col-xs-2">'+
    '   <div class="form-group required">'+
    '       <input type="text" class="form-control" id="cTitle'+contactData.id+'" name="contact['+contactData.id+'][cTitle]" value="'+contactData.cTitle+'" placeholder="Title/Role" data-rule-required="true" required="true">'+
    '   </div>'+
    '</div>'+
    '<div class="col-xs-2">'+
    '   <div class="form-group required">'+
    '       <input type="tel" class="form-control" id="cPhone'+contactData.id+'" name="contact['+contactData.id+'][cPhone]" value="'+contactData.cPhone+'" placeholder="Phone Number" maxlength="12" required="true" data-rule-pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}" data-msg-pattern="Please Enter your Phone Number in xxx-xxx-xxxx Format" data-rule-maxlength="12" data-rule-required="true">'+
    '   </div>'+
    '</div>'+
    '<div class="col-xs-2">'+
    '   <div class="form-group required">'+
    '       <input type="email" class="form-control" id="cEmail'+contactData.id+'" name="contact['+contactData.id+'][cEmail]" value="'+contactData.cEmail+'" placeholder="Email" data-rule-email="true" data-rule-required="true" required="true">'+
    '   </div>'+
    '</div>'+
    '<div class="col-xs-2">'+
    '   <div class="input-group-btn">'+
    '       <button class="btn btn-danger" type="button" onclick="remove_contact_fields(this);">'+
    '           <span class="glyphicon glyphicon-minus" aria-hidden="true"></span>'+
    '       </button>'+
    '   </div>'+
    '</div>'+
    '<div class="clear"></div>';
    
    document.getElementById('contact_fields').appendChild(contactRow);

}

function remove_contact_fields(el) {
    el.closest(".contact-field-wrapper").remove();
}
</script>

表单运行正常,如果我转储表单变量,我可以看到表单变量名称及其数据:

Form data dump

我的问题是,我似乎无法访问该代码部分的表单值。例如,此可行<cfoutput>#form.address#</cfoutput>但是不起作用(未定义元素联系人):<cfoutput>#form.CONTACT[1][CEMAIL]#</cfoutput>

我认为这可能与ColdFusion将其视为某种结构或数组这一事实有关,但是,我承认我对这些结构或数组相当虚弱。我也尝试使用此代码段,但是,它也不起作用(抛出错误):

<cfloop index="i" list="#FORM['cFirstName[]']#">    
    <cfset ArrayAppend(aFirstName,"#i#")>
</cfloop>
 <cfloop index="i" list="#FORM['cLastName[]']#">    
    <cfset ArrayAppend(aLastName,"#i#")>
</cfloop>
  <cfloop index="i" list="#FORM['cTitle[]']#">    
    <cfset ArrayAppend(aTitle,"#i#")>
</cfloop>
  <cfloop index="i" list="#FORM['cPhone[]']#">    
    <cfset ArrayAppend(aPhone,"#i#")>
</cfloop>
  <cfloop index="i" list="#FORM['cEmail[]']#">    
    <cfset ArrayAppend(aEmail,"#i#")>
</cfloop>
  
 </cfoutput>

<cfloop index="i" from="1" to="#ArrayLen(aFirstName)#" >

    <cfoutput>#aFirstName[i]# - #aLastName[i]# - #aTitle[i]# - #aPhone[i]# - #aEmail[i]#</cfoutput><br>

</cfloop>

所以我有点卡住了。我显然需要能够访问这些变量以便对其进行处理(即将它们保存在表中),但是目前还不确定如何执行这些操作。有没有人可以尝试的建议或代码段?

解决方法

由于这个问题的作者(@Paul B)向我提供了一个示例,该示例说明如何将序列化的javascript数据传递给表单提交中的Coldfusion,然后对其进行迭代,因此下面提供了一个示例。

首先,这是我在ColdFusion中输出表单字段的方法:

<cfset arr = [
    {
        firstName: "Brian",lastName: "Kelly"
    },{
        firstName: "Billy",lastName: "Short"
    }
];

<form id="myform" action="myhandler.cfm" method="post" enctype="multipart/form-data">
    <input type="hidden" name="mydata" id="myhiddenfield" />
    <cfloop from="1" to="#ArrayLen(arr)#" index="ix">
        <div class="myform-item">
            <!---
            Group each element into a div,and the name of 
            each input are the same! This makes it easier to get
            their values on submit.
            --->
            <div class="form-group">
                <label>First Name:</label>
                <input type="text" name="firstName" value="#arr[ix].firstName#" />
            </div>
            <div class="form-group" data-index="#ix#">
                <label>Last Name:</label>
                <input type="text" name="lastName" value="#arr[ix].lastName#" />
            </div>
            <div class="clearfix"></div>
        </div>
    </cfloop>
</form>

接下来,这是javascript ...我正在使用jQuery,但是有多种方法可以完成同一件事:

<script>
$(document).ready(function () {

    var form = $('#myForm');

    $(form).on('submit',function () {
        var items = [];
        $('div.myform-item',form).each(function (ix,item) {
            items.push({
                firstName: $('input[name="firstName"]',item).val(),lastName: $('input[name="firstName"]',item).val()
            });
        });
        $('#myhiddenfield').val(JSON.stringify(items));
    });

});
</script>

最后,这是ColdFusion处理程序,它将JavaScript数组反序列化为本地ColdFusion数组:

<cfscript>
// myhandler.cfm

try {

    param name="form.mydata"; // there will be other fields,but we don't care about them

    // do some basic validation... obviously this can be enhanced quite a bit
    if (!IsJSON(form.myData)) {
        throw();
    }

    myArray = DeserializeJSON(form.myData);
    
    if (!IsValid("array",myArray)) {
        throw();
    }

    // here's your array,now you can iterate over the array and do what you need to do
    dump(var=myArray);

} catch (any e) {
    dump(var=e);
}
</cfscript>