问题描述
我正在其中一种表单中使用导入的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>
表单运行正常,如果我转储表单变量,我可以看到表单变量名称及其数据:
我的问题是,我似乎无法访问该代码部分的表单值。例如,此可行:<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>