# JSON neue Objekte während der Laufzeit hinzufügen



## yeronimo (18. Januar 2010)

Hi, 

ich bin grad dabei zu veruschen, während der Laufzeit neue Elemente hinzufügen zu lassen.
Was ich gerade mache, ist ein "Einstellungs Formular" zu nehmen, in dem man zu bestimmten Felder im Kontaktformular Werte eintragen bzw. neue Felder anlegen kann. 

Dazu habe ich sowas hier: 

```
$.fn.serializeObject = function()
	{
	   var o = {};
	   var a = this.serializeArray();
	   $.each(a, function() {
		var nameSplit = this.name.split('.');
		console.log(nameSplit[0]);
		console.log(nameSplit[1]);
			if (o[nameSplit[0]]) {
				if(!o[nameSplit[0]].push) {
					o[nameSplit[0]] = [[nameSplit[0]]];
				}
				//o[nameSplit[0]].push({name: o[nameSplit[0]]});
				//o[nameSplit[0]].push({name: this.value || ''});
				o[nameSplit[0]][nameSplit[1]] = this.value || '';
		   } else {
			   o[nameSplit[0]] = this.value || '';
		   }
	   });
	   return o;
	};
	
	function formSubmit() {
		console.log($.toJSON($('form').serializeObject()));
		var settingsString = $.toJSON($('form').serializeObject());

		ConnBricksDialog.brickUpdate(settingsString);
		return false;
	};
```

wie oben erwähnt soll er das Formular umwandeln und dann eine Art "Einstellungsstring" erzeugen: 

Id: {name: "test",
       width: "bla",
       ...
      }

ichstrauche halt bei dem Punkt wo er dann das neue Objekt erstellt in dem die Atributte gespeichert werden, ich krieg dasnicht dynamisch hin, da er als ersten Wert einen STring v erlangt, ich aber den Namen dynamisch mit einer Variable setzen möchte....


Bitte um Hilfe, 

Besten Dank, Gruß
Ron


----------



## Sven Mintel (18. Januar 2010)

Moin Ron,

hast du mal ein Beispielformular parat, und was daraus werden soll?


----------



## yeronimo (18. Januar 2010)

Hi Sven, 
wiedermal der einzige, danke 


```
<script type="text/javascript" src="tiny_mce/tiny_mce_popup.js"></script>
	<script type="text/javascript" src="tiny_mce/utils/mctabs.js"></script>
	<script type="text/javascript" src="tiny_mce/utils/form_utils.js"></script>
	<script type="text/javascript" src="tiny_mce/utils/validate.js"></script>
	<script type="text/javascript" src="tiny_mce/utils/editable_selects.js"></script>
	
	<script type="text/javascript">

	//value, req, input, type [field1]
	
	$.fn.serializeObject = function()
	{
	   var o = {};
	   var a = this.serializeArray();
	   $.each(a, function() {
		var nameSplit = this.name.split('.');
		console.log(nameSplit[0]);
		console.log(nameSplit[1]);
			if (o[nameSplit[0]]) {
				if(!o[nameSplit[0]].push) {
					o[nameSplit[0]] = [o[nameSplit[0]]];
				}
				o[nameSplit[0]].push({attr: nameSplit[1] || '', value: this.value || ''});
				//o[nameSplit[0]].push({nameSplit[1] : this.value || ''});
				//o[nameSplit[0]][nameSplit[1]] = this.value || '';
		   } else {
			   o[nameSplit[0]] = this.value || '';
		   }
	   });
	   return o;
	};
	
	function formSubmit() {
		console.log($.toJSON($('form').serializeObject()));
		var settingsString = $.toJSON($('form').serializeObject());
		
		/*
		var settingsString = {};
		var count=1;
		for(var key in settingsStringCheck) {
			console.log('KEY: '+key);
			var keyPart = key.split('.');
			console.log(keyPart[0]+'.'+keyPart[1]);
			if(key[0] == 'id'+count && !settingsString[$('#id'+count+'.input')]) {
				//settingsString[$('#id'+count).attr('value')+'.input'] = settingsStringCheck['id'+count+'.input'];
				console.log(settingsString[$('#id'+count).attr('value')+'.input']);
				console.log(settingsStringCheck['id'+count+'.input']);
			}else{
				//in 2. array packen
			}
			
			//count++;
		}
		*/
		//feldernamen renamen
		/*
		var count = 1;
		var fields = $("[name^=id"+count+"]");
		
		while(fields.length>0) {
			for(var i=0; i<fields.length; i++){			
				console.log($(fields[i]));
				console.log($(fields[i]).attr('name'));
				var nName = $(fields[i]).attr('name').split('.');
				console.log(nName[0]+','+nName[1]);
				$(fields[i]).attr('name',this.value+'.'+nName[1]);
			}
			console.log(fields);
			//console.log($(field).attr('name'));
			//var nName = $(field).attr('name').split('.');
			//console.log(nName[0]+','+nName[1]);
			//$(this).attr('name',this.value+'.'+nName[1]);
			count++;
			fields = $("[name^=id"+count+"]");
		}
		*/
		
		ConnBricksDialog.brickUpdate(settingsString);
		return false;
	};
	
	var i = 0;
	function fieldCount() {
		i++;
		console.log(i);
		return i;
	}
		
	</script>	
</head>
<body id="table">
	<form id="contactForm" onsubmit="javascript:formSubmit();" action="" method="post">
		<div class="tabs">
			<ul>
				<li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">Allgemeine Einstellungen</a></span></li>
				<li id="advanced_tab"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">Erweiterte Einstellungen</a></span></li>
			</ul>
		</div>
		<div class="panel_wrapper" style="">
			<div id="general_panel" class="panel current" style="width:595px;">
				<fieldset>
					<legend>Allgemein</legend>
						<div id="divInfo">
							<table border="0" cellpadding="3" cellspacing="1" width="100%">
							  <tr>
								<td width="150"><b>Emailempf&auml;nger:<br>&nbsp;</b></td>
								<td colspan="3"><input id="mail_empf.value" name="mail_empf.value" value="" size="25" style="width: 99%;" type="text"><br>Mehrere Empf&auml;nger durch Semikolon trennen</td>
							  </tr>
							  <tr>
								<td><b>Betreff:</b></td>
								<td colspan="3"><input id="mail_reason.value" name="mail_reason.value" value="Kontaktanfrage" size="25" style="width: 99%;" type="text"></td>
							  </tr>
							  <tr>
								<td><b>Design:</b></td>
								<td colspan="3">
								<select id="design.value" name="design.value" style="width: 40%;">
										<option value="0">Textfeld oben</option>
										<option value="1" selected="selected">Textfeld unten</option>		                           
								</select>
								</td>
							  </tr>
							  <tr>
								<td><b>Breite:</b></td>
								<td colspan="3">
									<input id="contactForm.width" name="contactForm.width" value="100%" size="5" type="text">
								</td>
							  </tr>
							<tr>
								<td>	
								 <br>Felder im Formular
								</td>
							</tr>
							</table>
						</div>
						<div id="divFelder">
							<table id="divFelderTab" border="0" cellpadding="3" cellspacing="1" width="100%">
								<tr>	
									<td><b>Feldname</b></td>
									<td><b>Anzeigen?</b></td>
									<td><b>Pflichtfeld?</b></td>
									<td><b>Vorgabewerte</b>
									<font size="1"><br>(nur bei Auswahlfeld, durch Semikolon getrennt)</font></td>
								</tr>
								<tr>
									<td>
										<input id="FName.input" name="Fname.input" value="Vorname" type="text">
									</td>
									<td>
										<select id="FName.type" name="FName.type">
											<option value="0">Unsichtbar</option>
											<option value="1" selected="selected">Textfeld</option>
											<option value="2">Auswahlfeld</option>
										</select>
									</td>
									<td>
										<select id="FName.req" name="FName.req">
											<option value="0">Ja</option>
											<option value="1" selected="selected">Nein</option>
										</select>
									</td>
									<td>
										<input id="Fname.value" name="FName.value" value="" type="text">
									</td>
								</tr>
							</table>
						</div>
						<div>
							&nbsp;<input type="button" value="Feld hinzuf&uuml;gen" onclick="javascript:addField('contactFormField', fieldCount());">
							<input type="button" value="&uuml;berschrift hinzuf&uuml;gen" onclick="javascript:addField('header1FormField', fieldCount());">
						</div>
				</fieldset>
								<br style="clear:both" />
			</div>

			<div id="advanced_panel" class="panel">
				<fieldset>
					<legend>Erweitert</legend>
					<table border="0" cellpadding="3" cellspacing="4">
						<tr>
							<td><b>Hinweistext bei Pflichfeldern im Formular unterdr&uuml;cken:</b></td> 
							<td><input id="notice.visibility" name="notice.visibility" type="checkbox" value="hidden" /></td> 
						</tr>
						<tr>
							<td><b>Sicherheitsabfrage:</b></td> 
							<td><input id="captcha" name="captcha" type="checkbox" value="inactive" /></td> 
						</tr>
						<tr>
							<td><b>Text zur Sicherheitsabfrage:</b></td> 
							<td><input id="captchaTxt.value" name="captchaTxt.value" type="text" size="70" value="Bitte geben Sie den Sicherheitscode ein:" class="captchaTxt" /></td> 
						</tr>
					</table>
				</fieldset>
			</div>
		</div>
			<div class="mceActionPanel">
				<div style="float: left">
					<input type="submit" id="insert" name="insert" value="{#insert}" />
				</div>

				<div style="float: right">
					<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
				</div>

				<br style="clear:both" />
			</div>
	</form>
	</body>
	</html>
```

Das ist das Formular, musst halt nur jquery, json und so eingebunden haben. (s. o., und oben stehen noch die tabs von tinymce, einfach raushauen) dazu kommt noch diese methode die ich in einer lib habe: 

```
function addField(fieldType, tempId)
	{
		var fieldArray = [];
		
		fieldArray['contactFormField'] = "<tr><td><input name=\"field"+tempId+".input\" value=\"Vorname\" type=\"text\"></td><td><select name=\"field"+tempId+".type\"><option value=\"0\">Unsichtbar</option><option value=\"1\" selected=\"selected\">Textfeld</option><option value=\"2\">Auswahlfeld</option></select></td><td><select name=\"field"+tempId+".req\"><option value=\"0\">Ja</option><option value=\"1\" selected=\"selected\">Nein</option></select></td><td><input name=\"field"+tempId+".value\" value=\"\" type=\"text\"></td></tr>"; 
		
		fieldArray['header1FormField'] = "<tr><td colspan=\"2\"><b>Überschrift:</b>&nbsp;<input name=\"field"+tempId+".h4\" value=\"\" type=\"text\"></td></tr>"; 
		
		$('#divFelderTab').append(fieldArray[fieldType]);
	}
```

solltest du einfach mit oben rein packen können. 
Versuch mal obs klappt  

Besten Dank, Gruß 
Ron


----------



## Sven Mintel (18. Januar 2010)

Ok, und du möchtest daraus soetwas machen:

```
Id: {name: "test",
width: "bla",
...
}
```

Mal am Beispiel 
	
	
	



```
<input id="contactForm.width" name="contactForm.width" value="100%" size="5" type="text">
```

Verstehe ich das recht:
name sollte den Wert "contactForm" haben, den namen des 2.Members (width) das ist das, was im Namen des Feldes nach dem Punkt steht, und der Wert halt der value.

Aber woher soll Id kommen?


----------



## yeronimo (18. Januar 2010)

Moin, 

hab gerade selber gemerkt, das ich mich oben irgendwie komisch ausgedrückt habe 

ich möchte quasi ein Formular das ich habe serialisieren und bestimmte inhalte der Eingabefelder dann speichern. 
Als Beispiel, geht es um ein Kontaktformular, zu dem man Einstellugnen vornehmen kann, dazu wird ein popup aufgerufen, das die verschiedensten Werte anbietet die man ändern kann, dazu zählen einfache Felder : 


```
Formularbreite: <input type="text" name="formBreite" value="234px">
```

als auch eine Funktion die es Möglich machen soll beliebig viele Felder hinzuzufügen, dazu wird (s.o.) eine Javascriptfunktion aufgerufen, die eine Zeile von Inputfeldern zurückgibt, in diesen kann man dem Feld dann einen Namen geben,definieren was es für ein Feld sein soll, ob es ein Pflichtfeld ist, Vorgabewerte usw...
Meine Idee war nur das Formular so zu serialisieren, das ein JSON in dieser Form entsteht: 

"BausteinID(wird später hinzugefügt)":[
          "FeldName",{
		"attr":"pflichtfeld",
		"value":"feldinhaltBZW.Auswahl"
	 }],
          "FeldName",{
		"attr":"pflichtfeld",
		"value":"feldinhaltBZW.Auswahl"
	 }],  }........


und so weiter und so fort, so das ich durch meine spätere Methode(soweit fertig, falls du dich erinnerst ) einfach die Einstellungen aus dem String verarbeiten und die Werte abändern. Bei Feldernamen die nicht existieren wird er aus dem Type und den Attributen + name dann ein neues anlegen, vorhandene abändern.
Wie ich das mit Attributen wie Pflichtfeld mache weiß ich noch nicht genau, sobald das hier steht, sollte das aber nur noch eine Kinderkrankheit sein  

Falls noch Fragen sind, werde ich sie dir gleich nach Feierabend von zuhause beantworten, ich hoffe du weißt weiter, 

Besten Dank, Gruß
Ron


----------



## Sven Mintel (18. Januar 2010)

Sorry, jetzt bin ich weniger schlau als vorher 

Aus deiner Beschreibung eben geht bspw. nicht hervor, welche Rolle die beiden Teile des Namens (nameSplit) spielen sollen.

Poste doch einfach mal nen simples Beispiel-Formular zzgl. des Ergebnisses, welches du benötigen würdest.


----------



## yeronimo (19. Januar 2010)

Moin  
ok, kein Problem.

Also, nochmal eben als Auflistung: 

1. ich fülle das Formular aus
2. beim submit wird die methode im header aufgerufen, die das Form serialisiert
3. Werte der in die im Formular eingetragenen Felder werden zusammen mit dem dazugehörigen Feldnamen ausgelesen und in JSON gepackt

hier liegt auch der Knackpunkt, denn der String der hier erstellt wird muss auf folgende Dinge achten: 
       1. der Name der Felder besteht aus : Feldname.attr/type
       2. in der Funktion werden die namen gesplittet, so das wir attribut und Feldnamen einzeln haben
       3. sollte der Feldname noch nicht existieren, wird er angelegt und alle nachfolgenden gleichen Feldnamen (Feldname.width, Feldname.height....) innerhalb dieses Feldnamens platziert (Feldname: {attr1}, {attr2}......)


Beispielform: 
(sollte tun)

```
<html>
<head>
	<script type="text/javascript" src="tiny_mce/tiny_mce_popup.js"></script>
	<script type="text/javascript" src="tiny_mce/utils/mctabs.js"></script>
	<script type="text/javascript" src="tiny_mce/utils/form_utils.js"></script>
	<script type="text/javascript" src="tiny_mce/utils/validate.js"></script>
	<script type="text/javascript" src="/tiny_mce/utils/editable_selects.js"></script>
	
	 //<script type="text/javascript" src=tiny_mce/plugins/connBricks/js/connBricks.js"></script>
	<script type="text/javascript" src="scripts/jquery.js"></script>
	<script type="text/javascript" src="scripts/jquery.form.js"></script>
	<script type="text/javascript" src="scripts/jquery.json.js"></script>
	
	<script type="text/javascript">

        //wird unten aufgerufen um eine neue zeile hinzuzufügen
	function addField(fieldType, tempId)
	{
		var fieldArray = [];
		
		fieldArray['contactFormField'] = "<tr><td><input name=\"field"+tempId+".input\" value=\"Vorname\" type=\"text\"></td><td><select name=\"field"+tempId+".type\"><option value=\"0\">Unsichtbar</option><option value=\"1\" selected=\"selected\">Textfeld</option><option value=\"2\">Auswahlfeld</option></select></td><td><select name=\"field"+tempId+".req\"><option value=\"0\">Ja</option><option value=\"1\" selected=\"selected\">Nein</option></select></td><td><input name=\"field"+tempId+".value\" value=\"\" type=\"text\"></td></tr>"; 
		
		fieldArray['header1FormField'] = "<tr><td colspan=\"2\"><b>Überschrift:</b>&nbsp;<input name=\"field"+tempId+".h4\" value=\"\" type=\"text\"></td></tr>"; 
		
		$('#divFelderTab').append(fieldArray[fieldType]);
	}
	
	//Old function as backup
	/*
	$.fn.serializeObject = function()
	{
	   var o = {};
	   var a = this.serializeArray();
	   $.each(a, function() {
		   if (o[this.name]) {
			   if (!o[this.name].push) {
				   o[this.name] = [o[this.name]];
			   }
			   o[this.name].push(this.value || '');
		   } else {
			   o[this.name] = this.value || '';
		   }
	   });
	   return o;
	};
	*/
	
	$.fn.serializeObject = function()
	{
	   var o = {};
	   var a = this.serializeArray();
	   $.each(a, function() {
		var nameSplit = this.name.split('.');
		console.log(nameSplit[0]);
		console.log(nameSplit[1]);
			if (o[nameSplit[0]]) {
				if(!o[nameSplit[0]].push) {
					o[nameSplit[0]] = [o[nameSplit[0]]];
				}
				o[nameSplit[0]].push({attr: nameSplit[1] || '', value: this.value || ''});
				//o[nameSplit[0]].push({nameSplit[1] : this.value || ''});
				//o[nameSplit[0]][nameSplit[1]] = this.value || '';
		   } else {
			   o[nameSplit[0]] = this.value || '';
		   }
	   });
	   return o;
	};

	function formSubmit() {
		console.log($.toJSON($('form').serializeObject()));
		var settingsString = $.toJSON($('form').serializeObject());
		
		//ConnBricksDialog.brickUpdate(settingsString);
		return false;
	};
	
	var i = 0;
	function fieldCount() {
		i++;
		console.log(i);
		return i;
	}
		
	</script>	
</head>
<body id="table">
	<form id="contactForm" onsubmit="javascript:formSubmit();" action="" method="post">
						<div id="divInfo">
							<table border="0" cellpadding="3" cellspacing="1" width="100%">
							  <tr>
								<td width="150"><b>Emailempf&auml;nger:<br>&nbsp;</b></td>
								<td colspan="3"><input id="mail_empf.value" name="mail_empf.value" value="sdaf@asf.de" size="25" style="width: 99%;" type="text"><br>Mehrere Empf&auml;nger durch Semikolon trennen</td>
							  </tr>
							  <tr>
								<td><b>Betreff:</b></td>
								<td colspan="3"><input id="mail_reason.value" name="mail_reason.value" value="Kontaktanfrage" size="25" style="width: 99%;" type="text"></td>
							  </tr>
							  <tr>
								<td><b>Design:</b></td>
								<td colspan="3">
								<select id="design.value" name="design.value" style="width: 40%;">
										<option value="0">Textfeld oben</option>
										<option value="1" selected="selected">Textfeld unten</option>		                           
								</select>
								</td>
							  </tr>
							  <tr>
								<td><b>Breite:</b></td>
								<td colspan="3">
									<input id="contactForm.width" name="contactForm.width" value="100%" size="5" type="text">
								</td>
							  </tr>
							<tr>
								<td>	
								 <br>Felder im Formular
								</td>
							</tr>
							</table>
						</div>
						<div id="divFelder">
							<table id="divFelderTab" border="0" cellpadding="3" cellspacing="1" width="100%">
								<tr>	
									<td><b>Feldname</b></td>
									<td><b>Anzeigen?</b></td>
									<td><b>Pflichtfeld?</b></td>
									<td><b>Vorgabewerte</b>
									<font size="1"><br>(nur bei Auswahlfeld, durch Semikolon getrennt)</font></td>
								</tr>
								<tr>
									<td>
										<input id="FName.input" name="Fname.input" value="Vorname" type="text">
									</td>
									<td>
										<select id="FName.type" name="FName.type">
											<option value="0">Unsichtbar</option>
											<option value="1" selected="selected">Textfeld</option>
											<option value="2">Auswahlfeld</option>
										</select>
									</td>
									<td>
										<select id="FName.req" name="FName.req">
											<option value="0">Ja</option>
											<option value="1" selected="selected">Nein</option>
										</select>
									</td>
									<td>
										<input id="Fname.value" name="FName.value" value="" type="text">
									</td>
								</tr>
							</table>
						</div>
						<div>
							&nbsp;<input type="button" value="Feld hinzuf&uuml;gen" onclick="javascript:addField('contactFormField', fieldCount());">
							<input type="button" value="&uuml;berschrift hinzuf&uuml;gen" onclick="javascript:addField('header1FormField', fieldCount());">
						</div>
							<br style="clear:both" />
			</div>

					<table border="0" cellpadding="3" cellspacing="4">
						<tr>
							<td><b>Hinweistext bei Pflichfeldern im Formular unterdr&uuml;cken:</b></td> 
							<td><input id="notice.visibility" name="notice.visibility" type="checkbox" value="hidden" /></td> 
						</tr>
						<tr>
							<td><b>Sicherheitsabfrage:</b></td> 
							<td><input id="captcha" name="captcha" type="checkbox" value="inactive" /></td> 
						</tr>
						<tr>
							<td><b>Text zur Sicherheitsabfrage:</b></td> 
							<td><input id="captchaTxt.value" name="captchaTxt.value" type="text" size="70" value="Bitte geben Sie den Sicherheitscode ein:" class="captchaTxt" /></td> 
						</tr>
					</table>
			</div>
		</div>
			<div class="">
				<div style="float: left">
					<input type="submit" id="insert" name="insert" value="{#insert}" />
				</div>

				<div style="float: right">
					<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" />
				</div>

				<br style="clear:both" />
			</div>
	</form>
	</body>
	</html>
```

ok, so sollte das tun, methoden sind alle drin jquery und json pfade müssen noch geaendert werden 

Besten Dank, Gruß 
Ron


----------



## Sven Mintel (19. Januar 2010)

So sollte es gehen, wenn ich dich jetzt recht verstanden haben sollte:
	
	
	



```
$.fn.serializeObject = function()
	{
	   var o = {};
	   var a = this.serializeArray();
	   $.each(a, function() {
		var nameSplit = this.name.split('.');		
		if(typeof o[nameSplit[0]]=='undefined')
		{
		  o[nameSplit[0]]=[];
		}
		o[nameSplit[0]].push({'attr':nameSplit[1],'value':this.value});
	   });
	   return o;
	};
```


----------



## yeronimo (20. Januar 2010)

Moin Sven, 

danek, das sieht an sich recht vielversprechend aus und das ergebnis sieht auch nicht schlecht aus  

Eine Sache kann ich mir aber noch nicht erklären, das Feld "FName"  wird anders gespeichert als die anderen Reihen die ich per Button hinzufügen lasse.
"Fname":[{"attr":"input","value":"Vorname"}],"FName":[{"attr":"type","value":"1"},{"attr":"req","value":"1"},{"attr":"value","value":""}],

versteh ich nicht, da die attribute alle vorhanden sind, ich amche da nichts anders.


Besten Dank, Gruß
Ron


----------



## Sven Mintel (20. Januar 2010)

Schau dir mal den Namen des Feldes an...

F*n*ame!=FName


----------



## yeronimo (20. Januar 2010)

Danke, ich bin ein Idiot  Das passiert mir heute schon das Zweite mal.


----------

