# JQUERY:  Einen bestimmten Bereich nach einer ID durchsuchen



## yeronimo (12. Januar 2010)

Hi, 

ich würde gerne mit Jquery einen bestimmtes DIV nach einer ID durchsuchen, ohne das die Suche dabei außerhalb des DIV's liegende elemente mit einbezieht.
Also: 


```
//hier außerhalb koennen noch elemente liegen die ids haben aber nicht durchsucht werden sollen
<div>
//hier liegen elemente die alle ids haben und die durchsucht werden sollen
</div>
//hier koennen auch elemente liegen die nicht durchsucht werden sollen
```

Ich möchte also gerne ID xyz im inneren eines vorher angegebenen DIV's finden.

Hoffe dabei kann mir jemand helfen 

Besten Dank, Gruß
Ron


----------



## chmee (12. Januar 2010)

Die Frage ist aber, warum? IDs dürfen auf der ganzen Seite nur 1x benutzt werden. Für mehrmaliges Benutzen werden Div-Classes eingesetzt. Also ist die Einschränkung unnötig.

mfg chmee


----------



## yeronimo (12. Januar 2010)

Muss nicht unbedingt die ID sein, ich baue gerade ein Plugin für TinyMce, mit dem man Bausteine einfügen, einstellugnen ändern usw kann.
Im Moment bin ich dabei, die Einstellungsgeschichet umzusetzen und dafür muss ich in einem Baustein nach einem bestimmten element suchen und da die attribute abändern.
Im Moment wird jeder baustein als DIV eingesetzt (div mit einer eindeutigen ID (fortlaufend, je nach anzahl der auf der Seite vorhandenen Bausteine), einer Klasse Brick und im Rel Tag die eigentliche BausteinID aus der Datenbank), jetzt kann es natürlich sein, das baustein xyz auf der Seite 2 x eingefügt wird -> d.h. gleicher Inhalt im DIV, aber das DIV ist eindeutig identifizierbar.
Um die einzelnen Einstellungen jetzt abzuändern, muss ich nach irgendwas suchen(z.B. einer Bildbreite oder einer TabellenHöhe), da die Elemente aber exakt gleich sind (Baustein 2x) muss ich den irgendwie eindeutig identifizieren und das geht aj irgendwie nur, wenn ich weiß wo ich suchen muss, denn innerhalb dieses Bereiches wird es nur einmal auftauchen.

Besten Dank, gruß
Ron


----------



## chmee (12. Januar 2010)

Such doch erstmal das bekannte Div und dann darin

Also wenn:

```
<div id="seiteEins">
  <div id="Remote> .. </div>
</div>
<div id="seiteZwei">
  <div id="Remote> .. </div>
</div>
```
dann eben:

```
$("#SeiteEins:contains('#Remote')").css("width", "200px");
oder
$("#SeiteEins:has(#Remote)").addClass("test");
```

sorry, das ist jetzt schnell hingeschlunzt (kann also fehlerhaft sein, aber sinngemäß sollte es so aussehen). Ich erkenne das eigentliche Problem nicht. Entweder man hangelt sich hin (erstmal das Hauptdiv finden und den Inhalt durchsuchen) oder eben gleich mit den Selektoren das Richtige ansprechen, im "schönsten-schlimmsten" Fall regex zu Rate ziehen.

http://docs.jquery.com/Selectors

mfg chmee


----------



## yeronimo (12. Januar 2010)

Ahoi, 

das sieht schonmal recht vielversprechend aus! Teste es gleich mal und meldm ich dann mit meinem Ergebnis 

Besten Dank, Gruß
Ron


----------



## CPoly (12. Januar 2010)

yeronimo hat gesagt.:


> Ich möchte also gerne ID xyz im inneren eines vorher angegebenen DIV's finden.


Der Vollständigkeit halber:

```
$("#outter #inner")
```
Gibt dir alle Elemente mit der ID "inner" innerhalb aller Elemente mit der id "outter".
Oder wenn dein outter-Div bekannt ist:

```
outter.find("#inner")
```
Ich denke aber das chmee das mit 





> oder eben gleich mit den Selektoren das Richtige ansprechen


 meinte.


----------



## yeronimo (12. Januar 2010)

Moin, 

danke erstmal zuer Ergänzung. 
Habe grad etwas damit rumgespielt, konnte es aber irgendwie noch nicht so ganz testen, da ich noch eine kkleine Frage zu JSON habe, bevor ich das anwenden kann.
ist es möglich, aus einem aus JSON heraus, die Keys zu bekommen ? 


```
var testSettings = {"t1":{
									"list":{
											"width":30,
											"height":20
											},
									"list2":{
											"width":10,
											"height":10
											}
									}
								};
```

in diesem Fall also "list2" und "list2", das muss mit in die Abfrage rein, als Vergleichswert um dann die einzelnen werte in diesem Objekt zu vergleichen und notfalls abzuändern.

das würde ich dann so versuchen: 

```
$("#"+brickId+" #"+testSettings.t1[0])
```

testSettings.t1[0] steht hierbei füer list.


Besten Dank, Gruß
Ron


----------



## Sven Mintel (12. Januar 2010)

Moin,



yeronimo hat gesagt.:


> ist es möglich, aus einem aus JSON heraus, die Keys zu bekommen ?



Dafür gibt es in JS folgendes Konstrukt:


```
for(var key in objekt)
```

Beispiel:

```
for(var key in testSettings.t1){alert(key);}
```


----------



## yeronimo (13. Januar 2010)

Edel, scheint alles zutun  !!
Besten Dank, Gruß
Ron


----------



## yeronimo (13. Januar 2010)

Eine Frage habe ich doch noch, da ich versuche das alles so dynamisch wie möglich zu lassen, hab ich das bisher so gemacht: 

```
for(var key in testSettings[brickId]) {
				console.log("KEY: "+key);
				var testCont = testSettings[brickId][key];
				console.log('KEYOBJECT: '+testCont);
				console.log('KEYINHALT: '+testCont[1]);
			
			}
```
edit chmee - kleinen Tippfehler nachgebessert

um halt einfach nur die Methode mit der ObjectID aufzurufen, dann holt er sich den passenden key, dann das erste object dazu und fängt an die Wert (s.o. width, height...) mit dem element auf der seite abzugleichen.

Ich komme bis zu dem Punkt (KeyObject) wo er das object kriegt, aber den Inhalt kriege ich nicht ohne explizit anzugeben das ich .width  z.b. möchte.
Kann ich da nicht irgendwie durchiterieren ? 

Besten Dank, Gruß
Ron




//edit
ok, habe es einfach mit 2 keyschleifen gelöst, wenn jemand eine bessere idee hat - ich bin für alles offen


----------



## Sven Mintel (13. Januar 2010)

yeronimo hat gesagt.:


> Kann ich da nicht irgendwie durchiterieren ?



Klar kannst du das, wieder über dasselbe Konstrukt(wenn du den Key nicht per Hand angeben willst).



```
for(var key in testSettings[brickId]) 
  {
    console.log("KEY: "+key);
    var testCont = testSettings[brickId][key];
    console.log('KEYOBJECT: '+testCont);
    for(var key2 in testCont)
    {
      console.log(key2+':'+testCont[key2]);
    }
  }
```

*<edit> hast es ja selbst herausgefunden </edit>*
Du umgehst Probleme, wenn du dir generell klarmachst, dass ein Objekt nicht automatisch ein Array ist(es kann einer sein, weil Arrays immer auch Objekte sind, muss aber nicht).
Dies Objekt, was du dort hast, ist kein Array, soetwas wie assoziative Arrays gibt es in JS nicht... du kannst auch keinerlei Array-Methoden auf ein Objekt anwenden, welches kein Array ist.


----------



## yeronimo (13. Januar 2010)

Hi, 

klappt soweit wunderbar, hatte mir aus der Keygeschichte aber etwas mehr dynamik erhofft.
nämlich so: 

 ich hol mir in meiner testgeschichte oben mein objekt: 
                 var keyObject = testSettings[brickId][outerKey];

und dann dynamisch halt die innereKeys und damit die werte:
                 keyObject.innerKey;

das obere Funktioniert, das untere nicht. Die Keys gehen auch alle und der richtige Key steckt auch in "innerKey" drin, wenn ich anstelle von innerKey "width" benutze, dann tut es, in allen anderen Fällen ist es "undefined". 

Meine Idee dahinter war, das ich nur den SettingsString in form von JSON übergebe und die Methode den rest alleine macht, sich also den Baustein sucht, die Atribute checkt- Notfalls ergänzt und abändert.

Irgendeine Idee wie ich das obige Problem lösen könnte?

besten Dank, Gruß
Ron


EDIT: Vergiss meine Frage bitte, ich bin ein IDIOT  !


----------



## chmee (13. Januar 2010)

Auch wenn Du jetzt sagst, vergiss die Frage, ich schreib meine Idee trotzdem hin 

Wie wär's, wenn Du den Ansatz umdrehst? Nicht schauen, was in der div schon drinsteckt, definiert ist, sondern einfach Deine Daten reinschreiben,ersetzen?

mfg chmee


----------



## yeronimo (13. Januar 2010)

nicht schlimm, aber dazu muss ich sagen, das ich darüber schon nachgedacht habe.
Macht aber deshalb weniger Sinn, da es passieren kann das nur 5 / 100 möglichen Einstellungen im Einstellungsstring stehen und nur die dann auch effektiv geprüft und geändert werden sollen. Würde ich anderherum vorgehen würde alles im String stehen und er auch alles prüfen und ersetzen müssen.

Habe eh schon wieder eine neue Sache, habe jetzt ind er Funktion diese Suche integriert, aber irgendwie gibts Fehlerlos kein Ergebnis  

```
if($('#'+brickId)){
				for(var outerKey in testSettings[brickId]) {
					var keyObject = testSettings[brickId][outerKey];
					console.log("KEY: "+outerKey);
					console.log('KEYOBJECT: '+keyObject);
					//if e.g. 'list' exists in a div with id = brickId
					var elem = $('#'+brickId).find('#'+outerKey);
					if(elem) {
						for(var innerKey in keyObject) {
							console.log('ELEM: '+elem);
							$(elem).attr(innerKey, keyObject[innerKey]);
							console.log('INNER KEY-ATTR-: '+innerKey+' VALUE: '+keyObject[innerKey]);
						}
					}else{
						console.log('Dieser Baustein enthält kein Element mit dieser ID.');
					}
				}
			}else{
				console.log('Dieser baustein existiert nicht.');
			}
```

es stecken überall werte drin, hab alles x -mal ausgegeben und nachgeprüft. ich denke der Fehler steckt in der Zeile wo ich versuche das Attribut entweder zu erstellen oder zu ändern ($(elem).attr(innerKey, keyObject[innerKey]) denn in den divs befindet sich anschließend kein neues oder abgeändertes attribut. Fehler werden auch nicht angezeigt. Irgendeine Idee warum ? 


Besten Dank, Gruß
Ron


----------



## Sven Mintel (13. Januar 2010)

Mmmh, funktioniert bei mir problemlos 

```
<<html>
<head>
<title>test</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<div id="t1">
  <img id="list"  src="http://www.tutorials.de/forum/customavatars/avatar23393_2.gif">
  <img id="list2" src="http://www.tutorials.de/forum/customavatars/avatar23393_2.gif">
</div>

<script type="text/javascript">
<!--
if(typeof console=='undefined')console={log:function(s){alert(s);}}
brickId='t1';
var testSettings = 
{"t1":{"list":{"width":30,"height":20},"list2":{"width":10,"height":10}}};

if($('#'+brickId)){
				for(var outerKey in testSettings[brickId]) {
					var keyObject = testSettings[brickId][outerKey];
					console.log("KEY: "+outerKey);
					console.log('KEYOBJECT: '+keyObject);
					//if e.g. 'list' exists in a div with id = brickId
					var elem = $('#'+brickId).find('#'+outerKey);
					if(elem) {
						for(var innerKey in keyObject) {
							console.log('ELEM: '+elem);
							$(elem).attr(innerKey, keyObject[innerKey]);
							console.log('INNER KEY-ATTR-: '+innerKey+' VALUE: '+keyObject[innerKey]);
						}
					}else{
						console.log('Dieser Baustein existiert nicht.');
					}
				}
			}
//-->
</script>
</body>
</html>
```


----------



## yeronimo (13. Januar 2010)

ich bin baff, das verstehe ich nicht, habs grad getestet und es tut tatsächlich bei dir...
Irgendeine Idee warum das bei mir nicht geht  Bin gerade echt sprachlos  ich hab den Fehler die ganze zeit in der Abänderung gesucht und nicht gefunden. 

Besten Dank, Gruß
Ron


----------



## Sven Mintel (14. Januar 2010)

yeronimo hat gesagt.:


> Irgendeine Idee warum das bei mir nicht geht



Die Idee könnte ich haben, wenn du den gesamten Code deines HTML-Dokumentes postest...am JS-Teil alleine liegt es ja offensichtlich nicht.


----------



## yeronimo (14. Januar 2010)

Das könnte etwas schwierig werden, da es ein TinyMCE plugin ist. Aber ich schicke dir mal den code des plugins.
Als Anmerkung, die ganze Geschichte befindet sich irgendwie innerhalb eines iFrames und ich vermute, das er zwar ein object zurückgibt, aber in wirklichkeit gar keins gefunden hat ?


```
(function() {
	var each = tinymce.each;

	tinymce.create('tinymce.plugins.connBricksPlugin', {
		init : function(ed, url) {
			var t = this;
			t.editor = ed;			
			
			// Register commands
			ed.addCommand('mceConnBricks', function(ui) {
				ed.windowManager.open({
					file : url + '/bricks.htm',
					width : ed.getParam('connBricks_popup_width', 650),
					height : ed.getParam('connBricks_popup_height', 500),
					inline : 1
				}, {
					plugin_url : url
				});
			});
			
			ed.addCommand('mceConnBricksSettings', t._brickSettings, t);
			ed.addCommand('mceInsertConnBricks', t._insertConnBricks, t);
			ed.addCommand('mceConnBricksDelete', t._deleteConnBricks, t);
			ed.addCommand('mceConnBricksUpdate', t._updateConnBricks, t);
			
			// Register buttons
			ed.addButton('connBricks',{
				title:'Bausteine',
				image: url+'/img/brick.gif',
				cmd: 'mceConnBricks'
			});
			
			
			//Bricks Contextmenu setup
			if (ed && ed.plugins.contextmenu) {
				ed.plugins.contextmenu.onContextMenu.add(function(th, m, e) {
					//console.log('test:'+ed.selection.getNode().getAttribute('class'));
					var brickCheck = t._getParent(ed.selection.getNode(), 'getBool');
					
					//console.log(brickCheck);
					m.removeAll();

					if(brickCheck) {
						//removes the old contextMenu & adds the new menu items
						m.removeAll();

						//m.add({title : 'advanced.link_desc', icon : 'link', cmd : ed.plugins.advlink ? 'mceAdvLink' : 'mceLink', ui : true});
						m.add({
								title : 'Bausteineigenschaften', 
								icon : 'brickSettings', 
								cmd : 'mceConnBricksSettings'
							});

						m.add({
								title : 'Baustein l&ouml;schen', 
								icon : 'brickDelete', 
								cmd : 'mceConnBricksDelete'
							});

						//m.addSeparator();
						return false;
					}
				});
			};
						
		ed.onPreProcess.add(function(ed, o) {
				var dom = ed.dom;
				each(dom.select('div', o.node), function(e) {
					if (dom.hasClass(e, 'mceBrck')) {
						each(dom.select('*', e), function(e) {
							if (dom.hasClass(e, ed.getParam('connBricks_mdate_classes', 'mdate').replace(/\s+/g, '|')))
								e.innerHTML = t._getDateTime(new Date(), ed.getParam("connBricks_mdate_format", ed.getLang("connBricks.mdate_format")));
						});
						t._replaceVals(e);
					}
				});
			});
		},
	
		_getParent : function(el, mode) {		
				//console.log('übergabeEL mit jquery: '+$(el));				
				//returns the parents of the selected element which contain class "brick"
				var filterElemTags = $(el).parents('div')
							   .filter('.brick')
							   .map(function () { 
										return this.tagName; 
								})
							   .get();
				
				var filterElem = $(el).parents('div')
									.filter('.brick');
									
				var ele = el.getAttribute('class');
				var brickCheck = false;
				
				//checks if the selected elements or one of the parent"DIVs" contain class "brick"
				if(ele!=null && ele.indexOf('brick') > -1)
				{
					 brickCheck = true;
				}else{
					if(filterElemTags == 'DIV')  {
						brickCheck = true;
					}
				}

				switch(mode) {
					case 'getBool':
						return brickCheck;
					case 'getElem':
						return filterElem;
				}
				
				return false;
		},
		
		_updateConnBricks : function(ui, v, t) {
			var t=this, ed = t.editor;
			var brickId = 1;
			
			var testSettings = {"1":{
									"list":{
											"width":30,
											"height":20
											},
									"list2":{
											"width":10,
											"height":10
											}
									}
								};
								
			//console.log("JSONTEST: "+testSettings.t1['list'].width);
			//nach den einstellungen suchen und mit dem string abgleichen und ändern
			if($('#'+brickId).length>0){
				for(var outerKey in testSettings[brickId]) {
					var keyObject = testSettings[brickId][outerKey];
					console.log("KEY: "+outerKey);
					console.log('KEYOBJECT: '+keyObject);
					//if e.g. 'list' exists in a div with id = brickId
					var elem = $('#'+brickId).find('#'+outerKey);
					if(elem) {
						for(var innerKey in keyObject) {
							console.log(elem);
							$(elem).attr(innerKey, keyObject[innerKey]);
							console.log('INNER KEY-ATTR-: '+innerKey+' VALUE: '+keyObject[innerKey]);
						}
					}else{
						console.log('Dieser Baustein enthält kein Element mit dieser ID.');
					}
				}
			}else{
				console.log('Dieser baustein existiert nicht.');
			}
			//console.log($("#"+brickId+" #"+testSettings.1[0]));
		},
		
		_deleteConnBricks : function(ui, v, t) {
			var t= this, ed = t.editor;
			var brickCheck = t._getParent(ed.selection.getNode(), 'getElem');
			
			if(brickCheck) {
				if($(brickCheck).attr('rel')!='undefined' )
				{
					$(brickCheck).remove();
				}
			}		
		},
		
		_brickSettings : function(ui, t) {
			var t= this, ed = t.editor;
			var selectedBrickId = t._getParent(ed.selection.getNode(), 'getElem').attr('rel');
			var baseUrl = ed.getParam('baseUrl');	

			ed.windowManager.open({
				file : baseUrl+'/admin/default/bricks/form/id/'+selectedBrickId,
				width : ed.getParam('connBricks_popup_width', 650),
				height : ed.getParam('connBricks_popup_height', 500),
				inline : 1
			}, {
				plugin_url : baseUrl
			});
		},		
		
		_insertConnBricks : function(ui, v) {
			var t = this, ed = t.editor, h, el, dom = ed.dom, sel = (v.selection) ? v.selection:ed.selection.getContent();
			h = v.content;
			console.log("SELECTION: "+sel);
			each(t.editor.getParam('connBricks_replace_values'), function(v, k) {
				if (typeof(v) != 'function')
					h = h.replace(new RegExp('\\{\\$' + k + '\\}', 'g'), v);
			});

			el = dom.create('div', null, h);
			
			// Find ConnBricks element within div
			n = dom.select('.mceBrck', el);
			if (n && n.length > 0) {
				el = dom.create('div', null);
				el.appendChild(n[0].cloneNode(true));
			}

			function hasClass(n, c) {
				return new RegExp('\\b' + c + '\\b', 'g').test(n.className);
			};

			each(dom.select('*', el), function(n) {
				// Replace cdate
				if (hasClass(n, ed.getParam('connBricks_cdate_classes', 'cdate').replace(/\s+/g, '|')))
					n.innerHTML = t._getDateTime(new Date(), ed.getParam("connBricks_cdate_format", ed.getLang("connBricks.cdate_format")));

				// Replace mdate
				if (hasClass(n, ed.getParam('connBricks_mdate_classes', 'mdate').replace(/\s+/g, '|')))
					n.innerHTML = t._getDateTime(new Date(), ed.getParam("connBricks_mdate_format", ed.getLang("connBricks.mdate_format")));

				// Replace selection
				if (hasClass(n, ed.getParam('connBricks_selected_content_classes', 'selcontent').replace(/\s+/g, '|')))
					n.innerHTML = sel;
			});

			t._replaceVals(el);

			ed.execCommand('mceInsertContent', false, el.innerHTML);
			ed.addVisual();
		},
		
		_replaceVals : function(e) {
			var dom = this.editor.dom, vl = this.editor.getParam('connBricks_replace_values');
			each(dom.select('*', e), function(e) {
				each(vl, function(v, k) {
					if (dom.hasClass(e, k)) {
						if (typeof(vl[k]) == 'function')
							vl[k](e);
					}
				});
			});
		}
		
		/*
		,
		_getDateTime : function(d, fmt) {
				if (!fmt)
					return "";

				function addZeros(value, len) {
					var i;

					value = "" + value;

					if (value.length < len) {
						for (i=0; i<(len-value.length); i++)
							value = "0" + value;
					}

					return value;
				}

				fmt = fmt.replace("%D", "%m/%d/%y");
				fmt = fmt.replace("%r", "%I:%M:%S %p");
				fmt = fmt.replace("%Y", "" + d.getFullYear());
				fmt = fmt.replace("%y", "" + d.getYear());
				fmt = fmt.replace("%m", addZeros(d.getMonth()+1, 2));
				fmt = fmt.replace("%d", addZeros(d.getDate(), 2));
				fmt = fmt.replace("%H", "" + addZeros(d.getHours(), 2));
				fmt = fmt.replace("%M", "" + addZeros(d.getMinutes(), 2));
				fmt = fmt.replace("%S", "" + addZeros(d.getSeconds(), 2));
				fmt = fmt.replace("%I", "" + ((d.getHours() + 11) % 12 + 1));
				fmt = fmt.replace("%p", "" + (d.getHours() < 12 ? "AM" : "PM"));
				fmt = fmt.replace("%B", "" + this.editor.getLang("connBricks_months_long").split(',')[d.getMonth()]);
				fmt = fmt.replace("%b", "" + this.editor.getLang("connBricks_months_short").split(',')[d.getMonth()]);
				fmt = fmt.replace("%A", "" + this.editor.getLang("connBricks_day_long").split(',')[d.getDay()]);
				fmt = fmt.replace("%a", "" + this.editor.getLang("connBricks_day_short").split(',')[d.getDay()]);
				fmt = fmt.replace("%%", "%");

				return fmt;
		}
		*/	
	});

	// Register plugin
	tinymce.PluginManager.add('connBricks', tinymce.plugins.connBricksPlugin);
})();
```


EDIT : 

Alles klar, var brickElem = document.getElementById('text[de]_ifr').contentWindow.document.getElementById('1');
liegt am iFrame


----------

