By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,453 Members | 961 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,453 IT Pros & Developers. It's quick & easy.

Iterate through JSON property list

RMWChaos
100+
P: 137
Any JSON experts out there? I'd like to know if it is possible, and if so how, to iterate through a JSON property list so that each iteration selects the next value for each object. Here is an example list:

Expand|Select|Wrap|Line Numbers
  1. function myFunction()
  2. {
  3.     createDOM({
  4.     'id'      :   ["formname", "inputname", "submitbutton"],
  5.     'dom'     :   ["form", "input", "input"],
  6.     'parent'  :   "content",
  7.     'form'    :   [null, "formname", "formname"],
  8.     'action'  :   [URI, null, null],
  9.     'method'  :   ["post", null, null],
  10.     'type'    :   [null, null, "submit"],
  11.     'size'    :   [null, 6, null],
  12.     'value'   :   [null, null, "Submit"],
  13.     )};
  14. };
  15.  
Now what I want to do is iterate through this list 3 times, in each case selecting the next value for each object. So through each iteration, it will go through all the objects (id, dom, parent, etc.). On the first run it will select the first set of values for each object (formname, form, content, null, URI, etc.). On the second run, it will select the second set (inputname, input, content, formlogin, etc.) and so on. In the case of the 'parent' object, it will select 'content' on each run.

I know one way to do this, but it involves creating an array for each object's value list, like so:

Expand|Select|Wrap|Line Numbers
  1. function myFunction()
  2. {
  3. var A = new Array ("formname", "inputname", "submitbutton");
  4. var B = new Array ("form", "input", "input");
  5. var C = new Array(null, "formname", "formname");
  6. var x = 0;
  7. var D = A.length + x;
  8. var E = B.length + x;
  9. var F = C.length + x;
  10.  
  11. for (x <= 3; x >= 0; x++)
  12.     {
  13.     createDOM({
  14.     'id'      :   D,
  15.     'dom'     :   E,
  16.     'parent'  :   F,
  17.     )};
  18. };
  19.  
That would result in a long list of arrays and "array.length + x" vars. So I am hoping there is an easier way by working with the first example.

Thanks!
Nov 13 '07 #1
Share this Question
Share on Google+
25 Replies


gits
Expert Mod 5K+
P: 5,390
hi ...

i hope i don't misunderstand your question ... have a look at the following example:

Expand|Select|Wrap|Line Numbers
  1. var data = {
  2.     'id'      :   ["formname", "inputname", "submitbutton"],
  3.     'dom'     :   ["form", "input", "input"],
  4.     'parent'  :   "content",
  5.     'form'    :   [null, "formname", "formname"],
  6.     'action'  :   ['URI', null, null],
  7.     'method'  :   ["post", null, null],
  8.     'type'    :   [null, null, "submit"],
  9.     'size'    :   [null, 6, null],
  10.     'value'   :   [null, null, "Submit"]
  11. };
  12.  
  13. for (var i = 0; i < 3; i++) {
  14.     // array for demonstrating the selection
  15.     var arr = [];
  16.  
  17.     for (var j in data) {
  18.         var prop = data[j];
  19.  
  20.         // the 'parent'-property case ... is handled for a
  21.         // property that is not an array or object
  22.         if (typeof prop != 'object') {
  23.             arr.push(prop);
  24.         } else {
  25.             arr.push(prop[i]);
  26.         }
  27.     }
  28.  
  29.     // alert the demo array
  30.     alert('[' + arr + '] :: length = ' + arr.length);
  31. }
  32.  
kind regards

ps: note that i made URI to a string (for testing purposes) and you had a syntax error in your original post in line 13 ... the brackets have to be switched :)
Nov 13 '07 #2

RMWChaos
100+
P: 137
Hey again, gits!

Ok, I am trying to understand your code here. Do you recall my post from a couple days ago, the one you replied to with that mass of code to go through (dom attributes vs. javascript attributes)?

Hover Scripts Work in FF & NN, but not IE

Well, createDOM is a function that creates a DOM element (or elements in this case) using the values from a JSON property list; so my goal is basically to take several property lists like this:

Expand|Select|Wrap|Line Numbers
  1. createDOM ({
  2.   'id'     :    "idname1",
  3.   'dom'    :    "domtype1",
  4.   'parent' :    "parentname"
  5.   });
  6.  
  7. createDOM ({
  8.   'id'     :    "idname2",
  9.   'dom'    :    "domtype2",
  10.   'parent' :    "parentname"
  11.   });
  12.  
...and turn it into a single list like this:

Expand|Select|Wrap|Line Numbers
  1. createDOM ({
  2.   'id'     :    ["idname", "idname2"],
  3.   'dom'    :    ["domtype", "domtype2"],
  4.   'parent' :    "parentname"
  5.   });
  6.  
So all I need to know at this point is how to iterate through the list using the next value for each object every loop. Does that clarify my original question?

My second example in my original post does accomplish this goal, but it's not very graceful. Maybe it's something like createDOM.id[0] and [1] in the example above, or perhaps attrib.id[0] access the first value of the first property using my createDOM script.

So if that is the case, I can modify my createDOM script to do a "while attrib.id has child nodes", or if that doesn't work a check for attrib.id[x] using for (x >= 0; x < attrib.index[0].length; x++). Hm, that might work.
Nov 14 '07 #3

gits
Expert Mod 5K+
P: 5,390
hi ...

lets have a closer look at my example and adapt it slightly to match your needs:

Expand|Select|Wrap|Line Numbers
  1. var your_data = {
  2.     'id'      :   ["formname", "inputname", "submitbutton"],
  3.     'dom'     :   ["form", "input", "input"],
  4.     'parent'  :   "content",
  5.     'form'    :   [null, "formname", "formname"],
  6.     'action'  :   ['URI', null, null],
  7.     'method'  :   ["post", null, null],
  8.     'type'    :   [null, null, "submit"],
  9.     'size'    :   [null, 6, null],
  10.     'value'   :   [null, null, "Submit"]
  11. };
  12.  
  13. function createDOMfromList(data) {
  14.     for (var i = 0; i < 3; i++) {
  15.         var obj = {};
  16.  
  17.         for (var j in data) {
  18.             var prop = data[j];
  19.  
  20.             obj[j] = prop instanceof Array ? prop[i] : prop;
  21.         }
  22.  
  23.         createDOM(obj);
  24.     }
  25. }
  26.  
  27. function createDOM(obj) {
  28.     alert(obj.toSource());
  29. }
  30.  
  31. createDOMfromList(your_data);
  32.  
as you can see ... its easy to use for your purpose, we create a new function that receives the list and calls you current method ... test it in FF because the toSource() won't work in IE ... but its only for demo of the createDOM() call :)

kind regards
Nov 14 '07 #4

RMWChaos
100+
P: 137
Ok, I think I got it now.

So to modify this a bit, I could recode my createDOM script to include this:

Expand|Select|Wrap|Line Numbers
  1. function createDOMfromList(data)
  2.     {
  3.     // because 'id' is required in my createDOM script, it determines
  4.     // the total number of values (DOM elements) to create; so instead
  5.     // of i < #, I can do this:
  6.     for (var i = 0; i < data[id].length; i++)
  7.         {
  8.         var obj = {};
  9.         for (var j in data)
  10.             {
  11.             var prop = data[j];
  12.             obj[j] = prop instanceof Array ? prop[i] : prop;
  13.             };
  14.             createDOM(obj);
  15.        };
  16.    };
  17.  
And then my property lists change to this:
Expand|Select|Wrap|Line Numbers
  1. createDOMfromList({
  2.     'id'      :   ["formname", "inputname", "submitbutton"],
  3.     'dom'     :   ["form", "input", "input"],
  4.     'parent'  :   "content",
  5.     etc...
  6.     });
  7.  
It adds an extra function, which is not really a problem, but I wonder if I can integrate the two into one? Anyway, I will try out what you have given me and work from there.

Thanks again!



[thinking out loud]
//no need to respond to this next part...just a reminder to myself

I also need to test to see what type of behavior to expect if there is a mismatch in the number of members in each value list. So if 'id' had 3 members, but 'parent' had only 2 members, what would be the result? In this case, my createDOM script has a default value for 'dom' and 'parent'; so I am pretty sure what the result would be there, but what if there were no default value, such as 'name' or 'type'. Would it error out, use the last value member repeatedly, use null?

And is it better to use null as a spaceholder for empty values, or "", or nothing at all, just back-to-back commas to separate empty values (i.e. [value1,,value3,,,value6]). Guess I will find out.

[/thinking out loud]
Nov 14 '07 #5

gits
Expert Mod 5K+
P: 5,390
good luck with it ... :)

btw: in case you refer to an nonexistent element in an array you will get it as 'undefined' ... so you could use the following check to set a default value in such a case:

Expand|Select|Wrap|Line Numbers
  1. if (typeof value == 'undefined') {
  2.     value = null;
  3. }
kind regards
Nov 14 '07 #6

RMWChaos
100+
P: 137
...you could use the following check to set a default value in such a case:
Expand|Select|Wrap|Line Numbers
  1. if (typeof value == 'undefined')
  2.     {
  3.     value = null;
  4.     };
  5.  
The problem with that is I already use this code:
Expand|Select|Wrap|Line Numbers
  1. for (var index in defaultAttribs)
  2.     {
  3.     if(typeof attrib[index] == 'undefined')
  4.         {
  5.         attrib[index] = defaultAttribs[index];
  6.         };
  7.     };
  8.  
And I set defaultAttribs in a seperate JSON property list. I would rather the code simply ignore 'undefined' values that do not have a default, and not even include them in the DOM creation process. I'll think on that a while. It shouldn't matter whether the attribute is 'undefined' or null should it? It won't affect the element in any way, I don't think. I guess I could just leave it alone; I haven't seen any issues with it so far.
Nov 14 '07 #7

gits
Expert Mod 5K+
P: 5,390
you are right in case i understand it right that you don't create an attribute when there is no value for it ... otherwise it could be a problem with attributes that are such ones that only have to be present like:

[HTML]<input type="text" name="test" readonly="whatever_value"/>[/HTML]
so in such a case it would matter when simply creating the readonly attribute (with null or undefined or even whatever_value) because the browser simply checks for its existence ... so make the element editable the attribute mustn't exist ... so in case you handle it the 'leave-it-out-way' you wouldn't encounter problems with that ... otherwise it could be a problem ... :)
Nov 14 '07 #8

RMWChaos
100+
P: 137
you are right in case i understand it right that you don't create an attribute when there is no value for it...
Correct, if the attribute does not exist in the either the attrib or defaultAttribs list, then it will not be created at all. So that is not an issue when I am working with a single value for each object. However, when I am setting multiple values for each object, many of them will be null or 'undefined' unless I am creating the same type of DOM element all the time (unlikely). That is where I want to make sure that null or 'undefined' values will not be a problem, and I believe that it is not.
...so make the element editable the attribute mustn't exist ... so in case you handle it the 'leave-it-out-way' you wouldn't encounter problems with that ... otherwise it could be a problem ... :)
Huh? :-\
If I understand you correctly, you mean that if the attribute does not exist, then I can modify the element on the fly, but if the attribute is null or 'undefined' I couldn't? Is that what you are saying?

I'm pretty sure that I can do "elemId.attribName = newValue" regardless of whether the attribute already exists or not, or whether it is set to null or 'undefined'. That's how my mouseHover() function works.

So how would it be a problem? And should I create a filter that removes/ignores objects when the value is null or 'undefined'. How would I say, "if ((value == null) || (typeof value == 'undefined')) skip it and go to the next value"? Oh, duh. It would actually be "if ((value != null) || (typeof value != 'undefined')) set the attib". Otherwise, it would ignore it and move on to the next value...I think.
Nov 14 '07 #9

RMWChaos
100+
P: 137
Woo-hoo! It works!

I ended up going with this code:
Expand|Select|Wrap|Line Numbers
  1. function createDOM(attribList) // Create DOM Elements Function //
  2.     {
  3.     for (var i = 0; i < attribList.id.length; i++) // iterate through multiple values //
  4.         {
  5.         var attrib = {};
  6.         for (var index in attribList) // assign attribList values to attrib //
  7.             {
  8.             if ((attribList[index] != null) && (typeof attribList[index] != 'undefined')) // filter out null & 'undefined' values //
  9.                 {
  10.                 var value = attribList[index];
  11.                 attrib[index] = value instanceof Array ? value[i] : value;
  12.                 };
  13.             };
  14.         };
  15.     var defaultAttribs =
  16.         {
  17.         'dom'        :    'div',
  18.         'parent'    :    'body'
  19.         };
  20.     for (index in defaultAttribs) // Assign default attribs to 'undefined' values//
  21.         {
  22.         if(typeof attrib[index] == 'undefined')
  23.             {
  24.             attrib[index] = defaultAttribs[index];
  25.             };
  26.         };
  27. etc...
  28.  
It remains a single function, I don't have to change any of the rest of my createDOM() function, and I don't have to make any changes to my other scripts which call createDOM(). In this particular order, the code iterates through multiple values, ignores null and 'undefined' values (shouldn't be a problem, right?), and then sets default values to required 'undefined' values.

Thank you very much for your help, once again, gits.
Nov 14 '07 #10

gits
Expert Mod 5K+
P: 5,390
Huh? :-\
If I understand you correctly, you mean that if the attribute does not exist, then I can modify the element on the fly, but if the attribute is null or 'undefined' I couldn't? Is that what you are saying?

I'm pretty sure that I can do "elemId.attribName = newValue" regardless of whether the attribute already exists or not, or whether it is set to null or 'undefined'. That's how my mouseHover() function works.
no ... it was an example for the input-box readonly-attrib locks the input and removing the attrib makes it editable (inputable) again. and with elemId.attribName = newValue you mix up two different things. you setting the javascript-property of an element with setAttribute('attribName', 'newValue'); you set the dom-attribute. setting the js-property effects the element directly ... and overwrites the setted attributes ... so sometimes it could be difficult to debug such things that mixes the two ways and it would be good practice to use only one-way the attibute OR the property way ...

kind regards
Nov 15 '07 #11

RMWChaos
100+
P: 137
...and with elemId.attribName = newValue you mix up two different things. you setting the javascript-property of an element with setAttribute('attribName', 'newValue'); you set the dom-attribute. setting the js-property effects the element directly ... and overwrites the setted attributes ... so sometimes it could be difficult to debug such things that mixes the two ways and it would be good practice to use only one-way the attibute OR the property way ...
Oh, right, you told me not to mix up the two variations before. So to clarify:

Expand|Select|Wrap|Line Numbers
  1. // This sets the javascript property
  2. element[attribute] = value;
  3. // or
  4. element.attribute = value;
  5.  
  6. // And this sets the DOM-node attribute
  7. element.setAttribute(attribute, "value");
  8.  
Have I got it right? Can you tell me is there any advantage to using one method over the other? I realize that they do not operate in exactly the same way; so perhaps the answer is, "It depends on what you want to do." I don't know enough about the differences between the two methods to understand if one method suites my needs over the other. That will be my research project for today.
Nov 15 '07 #12

gits
Expert Mod 5K+
P: 5,390
hmmm ... you gave the answer already :) ... personally i would always use the attribute way since i consider it a dom operation and i would like to use dom-methods for this purpose ... but in IE you cannot set the onclick handler with set attribute for example ... but i wouldnt do that anyway ... since i would use a generalized event-handling with addEventListener() and attachEvent() ... so as you can see one should make a choice ... and i think sometimes, when using some js-constructs (or not using them) you cannot avoid the mixing of the two ways ... but as i said ... in huge projects it could lead to strange things and then it could be difficult to debug by team-members that didn't know all the code ...

a solution for the mix-up-thing could be to create a util-method ... that centralizes the handling ... so that would be a typical framework-candidate :)

kind regards
Nov 15 '07 #13

RMWChaos
100+
P: 137
... but i wouldnt do that anyway ... since i would use a generalized event-handling with addEventListener() and attachEvent() ...
Ok, I use addEvent() as well, but I have no idea how you mean to use it in this case. I'll post my code below.

...a solution for the mix-up-thing could be to create a util-method ... that centralizes the handling ... so that would be a typical framework-candidate.
Wha-? Now you're just showing off. ;-D I have no idea what a util-method is.

Here's my addEvent() code. How would I use this as you suggested?
Expand|Select|Wrap|Line Numbers
  1. if(Array.prototype.push == null)
  2.  
  3.     {
  4.  
  5.     Array.prototype.push = function()
  6.  
  7.         {
  8.  
  9.         for(var i = 0; i < arguments.length; i++)
  10.  
  11.             {
  12.  
  13.             this[this.length] = arguments[i];
  14.  
  15.             };
  16.  
  17.         return this.length;
  18.  
  19.         };
  20.  
  21.     };
  22.  
  23. function addEvent(obj, type, fn)
  24.  
  25.     {
  26.  
  27.     if (obj.addEventListener) // FireFox, NN, Mozilla, etc.
  28.  
  29.         {
  30.  
  31.         obj.addEventListener(type, fn, false);
  32.  
  33.         // bugzilla bug #241518
  34.  
  35.         EventCache.add(obj, type, fn);
  36.  
  37.         }
  38.  
  39.     else if (obj.attachEvent) // MSIE
  40.  
  41.         {
  42.  
  43.         var func = function()
  44.  
  45.             {
  46.  
  47.             fn.apply(window.event.srcElement);
  48.  
  49.             };
  50.  
  51.         obj.attachEvent("on" + type, func);
  52.  
  53.         EventCache.add(obj, type, func);
  54.  
  55.         }
  56.  
  57.     else if (typeof obj['on' + type] != 'function') // old
  58.  
  59.         {
  60.  
  61.         obj['on' + type] = fn;
  62.  
  63.         }
  64.  
  65.     else // really old
  66.  
  67.         {
  68.  
  69.         var oldonload = obj['on' + type];
  70.  
  71.         obj['on' + type] = function()
  72.  
  73.             {
  74.  
  75.             oldonload();
  76.  
  77.             fn();
  78.  
  79.             };
  80.  
  81.         };
  82.  
  83.     };
  84.  
  85.  
  86. function removeEvent(obj, type, fn)
  87.  
  88.     {
  89.  
  90.     EventCache.remove(obj, type, fn);
  91.  
  92.     };
  93.  
  94.  
  95. var EventCache = function()
  96.  
  97.     {
  98.  
  99.     var listEvents = [];
  100.  
  101.     return {
  102.  
  103.         listEvents : listEvents,
  104.  
  105.         add : function(node, sEventName, fHandler)
  106.  
  107.             {
  108.  
  109.             listEvents.push(arguments);
  110.  
  111.             },
  112.  
  113.         remove : function(node, sEventName, fHandler)
  114.  
  115.             {
  116.  
  117.             var i, item;
  118.  
  119.             for(i = listEvents.length - 1; i >= 0; i = i - 1)
  120.  
  121.                 {
  122.  
  123.                 if(node == listEvents[i][0] && sEventName == listEvents[i][1] && fHandler == listEvents[i][2])
  124.  
  125.                     {
  126.  
  127.                     item = listEvents[i];
  128.  
  129.                     if(item[0].removeEventListener)
  130.  
  131.                         {
  132.  
  133.                         item[0].removeEventListener(item[1], item[2], item[3]);
  134.  
  135.                         };
  136.  
  137.                     if(item[1].substring(0, 2) != "on")
  138.  
  139.                         {
  140.  
  141.                         item[1] = "on" + item[1];
  142.  
  143.                         };
  144.  
  145.                     if(item[0].detachEvent)
  146.  
  147.                         {
  148.  
  149.                         item[0].detachEvent(item[1], item[0][sEventName+fHandler]);
  150.  
  151.                         };
  152.  
  153.                     item[0][item[1]] = null;
  154.  
  155.                     };
  156.  
  157.                 };
  158.  
  159.             },
  160.  
  161.         flush : function()
  162.  
  163.             {
  164.  
  165.             var i, item;
  166.  
  167.             for(i = listEvents.length - 1; i >= 0; i = i - 1)
  168.  
  169.                 {
  170.  
  171.                 item = listEvents[i];
  172.  
  173.                 if(item[0].removeEventListener)
  174.  
  175.                     {
  176.  
  177.                     item[0].removeEventListener(item[1], item[2], item[3]);
  178.  
  179.                     };
  180.  
  181.                 if(item[1].substring(0, 2) != "on")
  182.  
  183.                     {
  184.  
  185.                     item[1] = "on" + item[1];
  186.  
  187.                     };
  188.  
  189.                 if(item[0].detachEvent)
  190.  
  191.                     {
  192.  
  193.                     item[0].detachEvent(item[1], item[2]);
  194.  
  195.                     };
  196.  
  197.                 item[0][item[1]] = null;
  198.  
  199.                 };
  200.  
  201.             }
  202.  
  203.         };
  204.  
  205.     }();
  206.  
  207.  
  208. /* *******************************************
  209.    **           Initialize Events           **
  210.    ******************************************* */
  211.  
  212. function loadScripts()
  213.  
  214.     {
  215.  
  216.     loadScript('../scripts/DOMLoader.js');
  217.  
  218.     loadScript('../scripts/XHRLoader.js');
  219.  
  220.     loadScript('../scripts/FADELoader.js');
  221.  
  222.     loadScript('../scripts/LOGINLoader.js');
  223.  
  224.     loadScript('../scripts/NAVLoader.js');
  225.  
  226.     };
  227.  
  228. addEvent(window, 'load', loadScripts);
  229.  
  230. addEvent(window, 'reset', loadScripts);
  231.  
  232. addEvent(window, 'unload', EventCache.flush);
  233.  
  234. addEvent(window, 'reset', EventCache.flush);
  235.  
Nov 15 '07 #14

gits
Expert Mod 5K+
P: 5,390
hi ...

i'm sorry for confusing you ... was a little bit late yesterday :) ... let me explain it a little bit more clearly:

when you have to mix the property and attribute way for some reason ... you should centralize the handling of setting the value with a custom method like the following (and i use the onclick only for demonstration now ... you use the better attachEvent() - handling already ... but if you need to set a property because the attibute doesn't work as you expect then you may replace it or extend the exception list ... ok?) its only a general discussion ... and may be it is of some help for you or others that read the thread:

Expand|Select|Wrap|Line Numbers
  1. /** 
  2.  * the util-method is a simple method that encapsulates the
  3.  * setAttribute() and property-setting - i simply call it set_node_attrib 
  4.  * @param docroot the document
  5.  * @param id node-id
  6.  * @param attr_state true when we wnat to set the value
  7.  * explicitly, false when we want to remove it
  8.  * @param attr the attribute-name
  9.  * @param the value to set 
  10.  */
  11. function set_node_attr(docroot, id, attr_state, attr, value) {
  12.     var node = docroot.getElementById(id);
  13.     var exceptions = { onclick: 1 };
  14.  
  15.     if (attr in exceptions) {
  16.         _set_node_prop(node, attr, value);
  17.     } else  if (attr_state) {
  18.         node.setAttribute(attr, value);
  19.     } else {
  20.         node.removeAttribute(attr);
  21.     }
  22. }
  23.  
  24. /**
  25.  * @private
  26.  */
  27. function _set_node_prop(node, attr, value) {
  28.     node[attr] = value;
  29. }
and now we should always use the set_node_attr(); method and we always know where the attribs and properties are controlled ... ok?

kind regards
Nov 16 '07 #15

RMWChaos
100+
P: 137
Ok, took me a few times reading through your code to fully understand it, but I get it now. So basically, you create an exception list for attributes that are problematic or don't add the same in all browsers. If the attribute is in the exception list, it calls _set_node_prop(), which uses the javascript node[attr] = value method. If the attrib is not in the exception list, it uses the DOM node.setAttribute(attr, value) method. Makes sense now.

But why a separate function for exceptions rather than this:
Expand|Select|Wrap|Line Numbers
  1. function set_node_attr(docroot, id, attr_state, attr, value)
  2.     {
  3.     var node = docroot.getElementById(id);
  4.     var exceptions =
  5.         {
  6.         onclick: 1
  7.         };
  8.  
  9.     if (attr in exceptions)
  10.         {
  11.         node[attr] = value;
  12.         }
  13.     else  if (attr_state)
  14.         {
  15.         node.setAttribute(attr, value);
  16.         }
  17.     else
  18.         {
  19.         node.removeAttribute(attr);
  20.         };
  21.     };
  22.  
And how would you remove a attr in the exceptions list? Set value to null?

As for using attachEvent(), I think your example here helped me understand better the addEvent() code I posted (obviously, I didn't write it). I could, for instance, do this:
Expand|Select|Wrap|Line Numbers
  1. addEvent(document.getElementById('image"), "click", someFunction);
  2.  
Nov 16 '07 #16

gits
Expert Mod 5K+
P: 5,390
hi ...

yes ... that is what i thought :) ... two things:

first: i used a seperate function because it could be that we might have to use a much more complex handling of some properties ... so that the code would be more modular and we could handle the changes a bit better, or we later could have the need to call the property-setter seperatly from another function ... so i always prefer to use a seperate function for a seperate task ...

second: to remove a property from the exeption list we have to remove it ... a better way in huge projects would be to use a constant for the list that is defined in a seperate js-file ... so that we may find that very easy and could adapt the list ... setting the value to 0 wouldn't help, since we actually check with the in operator and that simply checks for the existence in the list ...

kind reagards
Nov 18 '07 #17

RMWChaos
100+
P: 137
Why this in your code?

/**
* @private
*/
Nov 23 '07 #18

RMWChaos
100+
P: 137
gits,

This is the code I ended up going with in my createDOM() function to address problems adding certain attributes in different browsers:

Expand|Select|Wrap|Line Numbers
  1. for (index in attrib)
  2.      {
  3.      var exceptions = ({
  4.           'onclick'     :   1,
  5.           'onmouseover' :   1,
  6.           'onmouseout'  :   1
  7.           });
  8.      if (index in exceptions)
  9.           {
  10.           createElem[index] = attrib[index];
  11.           }
  12.      else
  13.           {
  14.           createElem.setAttribute(index, attrib[index]);
  15.           };
  16.      };
  17.  
I understand why you suggested making the exception code a seperate function, but for my purposes, this will work fine.

I do have one other question, however. You have the exceptions in a JSON list, so I copied what you did, but is that necessary? Why not just:

Expand|Select|Wrap|Line Numbers
  1. var exceptions = new Array ("onclick", "onmouseover", "onmouseout");
  2.  
There is no data to hold here; so I guess I am missing the point of a JSON property list.

Thanks!
Nov 23 '07 #19

gits
Expert Mod 5K+
P: 5,390
Why this in your code?

/**
* @private
*/
that's for marking, that you shouldn't use that method seperatly ... only set_node_attr(); should be used in the code. the reason for that is, that you later on simply may change the functions without changing the code in different places, and so centralizes the attrib/property setting ion one place ...

kind regards
Nov 23 '07 #20

gits
Expert Mod 5K+
P: 5,390
I do have one other question, however. You have the exceptions in a JSON list, so I copied what you did, but is that necessary? Why not just:

Expand|Select|Wrap|Line Numbers
  1. var exceptions = new Array ("onclick", "onmouseover", "onmouseout");
  2.  
There is no data to hold here; so I guess I am missing the point of a JSON property list.

Thanks!
it's not really called a json-list ... its a simple javascript object. have a look at the following simple usage:

Expand|Select|Wrap|Line Numbers
  1. if (index in exceptions) {
  2.    // some code
  3. }
  4.  
that wouldn't be possible with an array :) where you would always have to loop through when checking a value. so the current code simply avoids that. and one more note ... simply to mention :) ...

Expand|Select|Wrap|Line Numbers
  1. // create an array-instance
  2. var arr = new Array();
  3.  
  4. // equivalent to this :: but js needn't to evaluate
  5. // the brackets
  6. var arr = new Array;
  7.  
  8. // equivalent to this :: more less to evaluate :) through
  9. // the use of literals
  10. var arr = [];
  11.  
kind regards
Nov 23 '07 #21

RMWChaos
100+
P: 137
Hey gits,

Yeah, I tried it out, and it didn't work. =\

Sometimes, it's the only way to learn.

Thanks!
Nov 23 '07 #22

RMWChaos
100+
P: 137
I asked why this:
Expand|Select|Wrap|Line Numbers
  1. /**
  2. * @private
  3. */ 
  4.  
You replied:
that's for marking, that you shouldn't use that method seperatly ... only set_node_attr(); should be used in the code. the reason for that is, that you later on simply may change the functions without changing the code in different places, and so centralizes the attrib/property setting in one place.
I'm not quite sure what you mean. Maybe it would be easier if I learned Deutsch. =D I think you mean by using that code snippet, it forces all functions that come after it to only be used in conjunction with the function before it, or is it just a reminder to the programmer?

As for util-method...Ok, ok, ok, you win! I will make these changes:

Expand|Select|Wrap|Line Numbers
  1. //in changeAttrib
  2. function changeAttrib(id, attr, value))
  3.      {
  4.      set_node_attrib(id, attr, value, false);
  5.      };
  6.  
  7. // in createDOM()
  8. for (index in attrib)
  9.      {
  10.      set_node_attrib(attrib.id, index, attrib[index], true);
  11.      };
  12.  
  13. // in set_node_attrib
  14. function set_node_attr(id, attr, value, state)
  15.      {
  16.      var node = docroot.getElementById(id);
  17.      var exceptions = 
  18.           {
  19.           'onclick'     :   1,
  20.           'onmouseover'    :   1,
  21.           'onmouseout'    :   1
  22.           };
  23.      if (attr in exceptions)
  24.           {
  25.           set_node_exceptions();
  26.           }
  27.      else if (state)
  28.         {
  29.         node.setAttribute(attr, value);
  30.         }
  31.      else
  32.           {
  33.           node.removeAttribute(attr);
  34.           };
  35.      };
  36.  
  37. /**
  38. * @private
  39. */
  40.  
  41. function set_node_exceptions(node, attr, value)
  42.      {
  43.      node[attr] = value;
  44.      };
  45.  
Nov 23 '07 #23

gits
Expert Mod 5K+
P: 5,390
it's a reminder as you said ... and the programmer should pay attention to it :) it's always a good idea to handle things that mix up different things like our attribute/property example in one place ... respectively with one single method-call ... so that everytime you have to build in more exeptions you have only one point where you have to maintain the code ;) ...

kind regards
Nov 23 '07 #24

RMWChaos
100+
P: 137
it's always a good idea to handle things that mix up different things like our attribute/property example in one place ... respectively with one single method-call ... so that every time you have to build in more exceptions you have only one point where you have to maintain the code
I understand exactly what you are saying, but I have a problem in using this code. The util-method assumes that the node-id already exists, but in the case of my createDOM script, it does not. The attribs are being set immediately before the node is actually created, so that the node is created with the attribs. Hm, let me see if I can create the node, then set the attribs. That might work...testing...

Nope, didn't work. Again, the problem is that no attribs have been set, including the node id, so that document.getElementById(id) has nothing to find. If I am going to use your util-method, I really need to give this some thought.
Nov 23 '07 #25

gits
Expert Mod 5K+
P: 5,390
simply change it to pass the node itself to it instead of the id :)

kind regards
Nov 23 '07 #26

Post your reply

Sign in to post your reply or Sign up for a free account.