Coordinating field names

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.

  1. 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
  2. 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. :confused: 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.

A sample to work with would be great.

I am going to admit that am looking at an abstract concept … i could copy paste the js/php on here without it being unwieldy. but here is the gist:


		 	   <div id="areas">
			 	   <fieldset id='master'><legend>Position:</legend>
				   <div class="widgetN">
					    <label for='widgetCh'>Widget:</label>
						<select  class='widgetCh' name='widgetCh[]'>
	 			 		<label>Condition <input type="text" class='cond' name='cond[]' value=""></label>
						<label>All<input name='allout[]' class='allout' type="checkbox" CHECKED ></label>
	 			    <!-- widgetN --></div>
	 		   		<div><button class="wDel">Delete</button> <button class="wUp">Move Up</button> <button class="wDwn">Move Down</button><button class="wAdd">Add Widget After</button></div>
				</fieldset>
			<!-- areas --></div>


	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.

I hope that makes my question more clear

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.

there is something about that that doesnt make sense, hwo would you have the from return teh field imputs as a range?

you would still need to use an array type name “” which is exactly why I CANT use the dummy hidden fields.

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.

That is, you will “range” it on server side.

yes, but you would need an array to have indexes, and having the array is what aused all this in the first place.

I mentioned the use of a sequence, a counter to increment really, to generate the index.