I’ve been working on a dynamic form which uses .js to allow users to add field sets. my strategy is/ was to have a master object ( a field-set) that is cloned and appended or deleted from the DOM. the name all fields are given as an array, eg.: ‘fieldName’, upon submission that means i would be able to enter the information into the DB in the same order as the user had it on the form ; 'fieldName[0] would be the fist fieldset, 'fieldName[2] the second, 'fieldName[3] the third, and so forth. ALSO, this way data from all fieldsets would be coordinated relative to the fieldset, eg.: ‘otherFiled’ woudl also submit as 'fieldName[0] would be the fist fieldset, 'fieldName[2] the second, 'fieldName[3] the third, and so forth.
my javascript works, but I the strategy behind it has an unplanned side-effects.
Radio butons fields are linked though ALL field sets. I should have seen that one coming , since they all share the same name ( I really thought the ") was going to make a difference , but I was wrong
Checkboxes screw the count coordination , since checkboxes are not submitted when unchecked and I was counting on all my field names being an array of fried directly mapped to whichever field set they came from. so what I am saying is if I had 5 fieldsets and the checkbox on #3 is not checked my form submits an array containing 4 values; in this example because checkbox #3 is missing, #4 will come in as the 3rd array element, and #5 as the forth… see no longer synchronized. I understand that this the nature of checkboxes but I was hoping someone my know a trick around this.
I actually was pondering using a hidden field to send a dummy value, <input type=hidden name=“x” value=“blah” > <input checkbox=hidden name=“x” value=“1” > but since I am using an array that wont work as the hidden input would always be passed and increase the array pointer, rather than overriding the value for the checkbox field
I suppose this could be a gemeal HTML question as much as .js. But I thought that if there was no way to achieve this with plain HTML, i coudl use .js to do something to keep the fieldnames matched to the order that they are presented on screen. If that makes sense?
I fear I have painted myself into a corner here and would appreciate any suggestions.
temp=document.getElementById('master');
if (temp !== undefined ){
temp=document.getElementById('master');
baseAdd=document.getElementById('newW');
master=temp.cloneNode(true)
master.id='';
WA=document.getElementById('areas');
baseAdd.onclick=function(){master.addWidget();return false;}
master.addWidget=function(){ var rdy=prepWidg(master.cloneNode(true)); WA.appendChild(rdy); return false;}
master.delWidget=function(self){
var seg=self.parentNode.parentNode;
WA.removeChild(seg);}
master.newWidget=function(self){
var seg=self.parentNode.parentNode;
var rdy=prepWidg(master.cloneNode(true));
seg.parentNode.insertBefore(rdy, seg.nextSibling);
}
master.moveUp=function(self){
var seg=self.parentNode.parentNode;
seg.parentNode.insertBefore(seg, seg.previousSibling);
}
master.moveDwn=function(self){
var seg=self.parentNode.parentNode;
var last =seg.nextSibling;
var pos=(last===null) ? seg.parentNode.firstChild : seg.nextSibling.nextSibling;
seg.parentNode.insertBefore(seg, pos);
}
if (shoDef){master.addWidget() ;}
prepWidg(temp);
}
function makeHandler(fn){
return function (e){
e.preventDefault();
var self=this;
master[fn](self);
return false;
}
}
function prepWidg(fix){
var sel=new Array('.wDel', '.wUp','.wDwn', '.wAdd');
foo= new Array('delWidget', 'moveUp', 'moveDwn', 'newWidget');
for (k=0,ll=sel.length; k<ll; k++){
bType=fix.querySelectorAll(sel[k]);
for (i=0,l=bType.length;i<l; i++ ){
bType[i].onclick= makeHandler(foo[k]) ;
}
}
return fix;
I am not sure if i extracted the code ok … there are 1000s of lines and there may be a few dependencies I missed, BUT THATS NOT MY POINT… the JS does what I wanted it to do… the unexpected situation comes from the fact that i didn’t take into account how radio buttons and checkboxes work.
so for example if the (user) added 5 new fieldsets … but only checked the “ALL” check box in in two of those field sets… when the from is submitted… allout array will only have two values, and thus I wouldn’t be able to know which field set the values came from.
You could set up a ghost field, a hidden field, for each checkbox, acting like an index: value=“1”, …, value=“n”.
When you only get the index, you know that that box was not checked.
You can even set up such a ghost index field for every input in your form.
well I was thinking of that , but remember the field order can be shuffled by the user as well. so if I were to go for that technique i would need to figure out a way in .js or jquery to have a LIVE list of all the FIELD nodes. I would also have to update all element names in all fiends when the fields are shuffled no?
Keep a sequence to iterate the index with, no matter the fieldsets number. You’ll be looking at repetitive index ranges: 1…5, 16…20, 10…15 and spot in those ranges where there is only an index and not a value.
Something like null columns in a table.
The sequence could also have gaps, where a fieldset was deleted: 1…5, 15…20, 21…25. You will be looking at repetitive sequences, based on the number of fields in the template field to distinguish among fieldsets.
Something like this:
fieldset[1] will return:
1, “John”, 2, 3, “Doe”
fieldset[3] will return:
7, “Jane”, 8, checked, 9, “Doe”
The checkbox for “John” was not checked and fieldset[2] was deleted, hence there’s a gap in the sequence. It doesn’t matter, will be processing sets of three indexes: (1,2,3), (4,5,6), (7,8,9) and so on.
The form will return this: 1, “John”, 2, 3, “Doe”, 7, “Jane”, 8, checked, 9, “Doe”.
On server side you’ll check for sets of three indices: (1,2,3) then (4,5,6) then (7,8,9). Where you have two consecutive indices the field is an unchecked box.