问题
I wrote some JavaScript to intercept form data on a submit event, and to build an array of objects from the several <select>
fields, processing one field per iteration of a loop that grabs the field value and pushes it into an array. Each iteration should construct and push()
one object into the array unitl all form fields have been processed.
Instead, on this test page on my website, I get the complete array of all the objects from all the form fields on the first iteration prior to the first push. The array stays exactly like that on each subsequent iteration despite the recurring pushes.
The js is:
function buildClasses(formData) {
var timeslots = ['0830', '0900', '1030', '1245', '1415', '1545'];
var classrooms = ['chapel', 'A', 'B', 'C', 'D', 'E', 'F', 'I'];
var classes = [];
var ts = '';
var rm = '';
var startIndex = 3;
if(formData[startIndex].value == 'attend') {
formData[startIndex].value = 'chapel';
}
else {formData[startIndex].value = 'unsure';}
for(var i = startIndex; i < formData.length; i++) {
if(formData[i].value == 'unsure') {}
else {
ts = timeslots[i - startIndex];
rm = formDataArr[i].value;
classes.push(
{
timeslot: ts,
room: rm
}
);
} // end else/if
} // end for
return classSelections;
} // end def fn buildClasses
formData
is:
3: Object {name: "select-yui_3_nnn ... nnn-field", value: "unsure"}
4: Object {name: "select-yui_3_nnn ... nnn-field", value: "A"}
5: Object {name: "select-yui_3_nnn ... nnn-field", value: "B"}
6: Object {name: "select-yui_3_nnn ... nnn-field", value: "A"}
7: Object {name: "select-yui_3_nnn ... nnn-field", value: "unsure"}
8: Object {name: "select-yui_3_nnn ... nnn-field", value: "C"}
length: 9
The scheme in buildClasses()
is to cycle through the form fields beginning at index 3, to ignore the "unsure" values, and to build classes
using the non-unsure values, one each per iteration of the loop.
Investigating with console.log()
on the test page, I determined that, in the first iteration, prior to the first push()
, classes
is:
1: Object {timeslot: "0900", room: "A"}
2: Object {timesolt: "1030", room: "B"}
3: Object {timeslot: "1245", room: "A"}
5: Object {timeslot: "1545:, room: "C"}
length: 4
It's incredible, I know. But before composing this question, I tested it on the test page dozens of times, always with that result.
The whole thing is live at the page Test Conference Registration 2019. I littered the code with console logs, so that one can see what is produced on each iteration. Test it as you will. (It connects to and updates a live AWS table, so you will also get in the console the AWS return information.)
The function looks simple and straightforward. Yet it produces vexing results on my website. The site is built on the Squarespace platform using one of its 'form blocks' to construct the form.
I built the snippet below using the same code. It functions correctly, just as expected.
So, there must be something about the way the Squarespace form block works that is causing the entire array to appear even prior to the first push. I'm hoping that someone here may have experience with Squarespace and may be able to shed some light.
Thanks for reading this and for any effort toward answers.
Update:
Since first posting this question, I've come to understand the problem better and differently. I've completely revised it, changed the issue, and published it under a new title. I hope I've clarified things and posted a better question than originally.
Thanks to everyone who responded to the first version of this question.
/* new schema w/o comments */
$(document).ready(function() {
init();
}); // end doc.ready
function init() {
document.addEventListener("submit", processFormData);
} // end def fn init
function processFormData(event) {
event.preventDefault();
var formData = $('form').serializeArray();
classes = buildClasses(formData);
} // end def fn processFormData
function buildClasses(fd) {
var timeslots = ['0830', '0900', '1030', '1245', '1415', '1545'];
var classrooms = ['chapel', 'A', 'B', 'C', 'D', 'E', 'F', 'I'];
var ts = '';
var rm = '';
var startIndex = 3;
var classes = [];
console.log('classes post-initialization : ', classes);
if (fd[startIndex].value == 'attend') {
fd[startIndex].value = 'chapel';
} else {
fd[startIndex].value = 'unsure';
}
for (var i = startIndex; i < fd.length; i++) {
if (fd[i].value == 'unsure') {} else {
ts = timeslots[i - startIndex];
rm = fd[i].value;
console.log('fd[i].value : ', i, fd[i].value);
console.log('classes pre-push', classes);
classes.push({
timeslot: ts,
room: rm
});
console.log('classes post-push : ', classes);
} // end else/if
} // end for
return classes;
} // end def fn buildClassSelections
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="" method="post">
<div>
<label>First Name
<input type="text" name="fname" size="25">
</label>
</div>
<div>
<label>Last Name
<input type="text" name="lname" size="25">
</label>
</div>
<div>
<label>email address
<input type="email" name="email" size="25">
</label>
</div>
<div>
<label>08:30 Keynote Speaker
<select name="select">
<option value="" name="defaultOptionUnsure">unsure</option>
<option value="attend" name="">attend</option>
<option value="not attend">not attend</option>
</select>
</label>
<label>09:00 Classes
<select name="select">
<option value="">unsure</option>
<option value="class room A">room A</option>
<option value="class room B">room B</option>
</select>
</label>
<label>10:30 Classes
<select name="select">
<option value="">unsure</option>
<option value="class room A">room A</option>
<option value="class room B">room B</option>
</select>
</label>
</div>
<div>
<input type="submit" value="submit form">
</div>
</form>
回答1:
for a start
const myForm = document.querySelector("#My-Form")
, FormNames = Array.from(myForm.elements).reduce((a,n)=>{ if (n.name ) a.push(n.name); return a }, [])
;
var ResultArray = []
myForm.onsubmit = e =>{
e.preventDefault()
let info = {}
for (let elm of FormNames) {
info[elm] = myForm[elm].value
}
ResultArray.push(info)
myForm.reset()
console.clear()
console.log('ResultArray = ', ResultArray )
}
body { font-family: Arial, Helvetica, sans-serif; }
form { margin: 1em }
label,
button {
display: block;
float: left;
clear: both;
margin: .3em;
}
label { width:24em; line-height: 2em; }
input,
select { float: right; width: 15em;}
<form action="" method="post" id="My-Form">
<label>First Name <input type="text" name="fName"></label>
<label>Last Name <input type="text" name="lName"></label>
<label>email address <input thpe="email" name="email"></label>
<label>08:30 Keynote Speaker
<select name="Keynote_Speaker">
<option value="" >unsure </option>
<option value="attend" >attend </option>
<option value="not attend">not attend </option>
</select>
</label>
<label>09:00 Classes
<select name="Classes_09_00">
<option value="" >unsure </option>
<option value="class room A">room A </option>
<option value="class room B">room B </option>
<option value="class room C">room C </option>
</select>
</label>
<label>10:30 Classes
<select name="Classes_10_30">
<option value="" >unsure </option>
<option value="class room A">room A </option>
<option value="claww room B">room B </option>
<option value="class room C">room C </option>
</select>
</label>
<button type="submit">submit form</button>
</form>
回答2:
It is hard to tell, but I would bet that this line:
if(formDataArr[i] == 'unsure') {} // skip ‘unsure’
should read:
if(formDataArr[i].value == 'unsure') {} // skip ‘unsure’
Having said that, you should probably test a function like this in isolation, easily done in a node.js REPL. But nothing would beat a full blown mocha/chai test environment.
来源:https://stackoverflow.com/questions/56695981/what-causes-an-array-in-a-squarespace-site-initialized-as-to-be-populate