views:

34

answers:

2

Hi,

I'm using JavScript and jQuery to read an XML document and subsequently use the information from the XML to create HTML objects.

The main 'C' nodes in the XML document all have a type attribute, and depending on the type I want to run a function which will create a new html object using the other attributes assigned to that particular 'C' node node.

Currently, I have a for loop which extracts each 'C' node from the XML and also it's attributes (e.g. width, height, x, y).

Also inside the for loop, I have an if statement which checks the 'type' attribute of the current 'C' node being processed, and depending on the type it will run a different function which will then create a new HTML object with the attributes which have been drawn from the XML.

The problem is that there may be more than one 'C' node of the same type, so for example when I'm creating the function that will run when a 'C' node of 'type=1' is detected, I cannot use the 'var p = document.createElement('p')' because if a 'C' node of the same type comes up later in the loop it will clash and override that element with that variable that has just been created.

I'm not really sure how to approach this?

Here is my entire script. If you need me to elaborate on any parts please ask, I'm sure it's not written in the nicest possible way:

    var arrayIds = new Array();
$(document).ready(function(){
  $.ajax({
    type: "GET",
    url: "question.xml",
    dataType: "xml",
    success: function(xml)
    {
                  $(xml).find("C").each(function(){
                        arrayIds.push($(this).attr('ID'));
                  });


                  var svgTag = document.createElement('SVG');
                  // Create question type objects
                  function ctyp3(x,y,width,height,baC)
                  {
                      alert('test');
                      var r = document.createElement('rect');
                      r.x = x;
                      r.y = y;
                      r.width = width;
                      r.height = height;
                      r.fillcolor = baC;
                      svgTag.appendChild(r);
                  }

                  // Extract question data from XML
                  var questions = [];
                  for (j=0; j<arrayIds.length; j++)
                  { 
                    $(xml).find("C[ID='" + arrayIds[j] + "']").each(function(){
                        // pass values
                        questions[j] = {
                            typ: $(this).attr('typ'),
                            width: $(this).find("I").attr('wid'),
                            height: $(this).find("I").attr('hei'),
                            x: $(this).find("I").attr('x'),
                            y: $(this).find("I").attr('x'),
                            baC: $(this).find("I").attr('baC'),
                            boC: $(this).find("I").attr('boC'),
                            boW: $(this).find("I").attr('boW')
                        }

                        alert($(this).attr('typ'));

                        if ($(this).attr('typ') == '3')
                        {
                            ctyp3(x,y,width,height,baC);
                            // alert('pass');
                        } else {
                            // Add here
                            // alert('fail');
                        }
                    });
                  }
    }
  });
});
+2  A: 

My example uses the $.each() function in jQuery and adds the element to the <body> tag using a chained function so that you don't ever have to create a variable p.

Even though the author posted their code example after mine was written, I will leave it up here in case anyone else can benefit from it.

See it on jsFiddler: http://jsfiddle.net/gKN4V/

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
<title>Untitled Document</title>
<script type="text/javascript" 
  src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">
  var xmlString = '<root>'
  + '<C type="1" x="25" y="30" text="My cool div" />'
  + '<C type="2" x="50" y="75" text="My other div" />'
  + '<C type="1" x="100" y="10" text="My fun div" />'
  + '<C type="2" x="150" y="150" text="My awesome div" />'
  + '</root>';

$(function() {
  var xml = $(xmlString);
  $("C", xml).each(function(i,o) {
    var node = $(o);

    switch(node.attr("type")) {

      case "1" :
        $("<p />", { 
          "class" : "type1",
          css : {
            left :node.attr("x") + "px",
            top : node.attr("y") + "px"
          }
        }).text(node.attr("text")).appendTo("body");
        break;

        case "2":
          $("<div />", { 
            "class" : "type2",
            css : {
              left :node.attr("x") + "px",
              top : node.attr("y") + "px"
            }
          }).text(node.attr("text")).appendTo("body");
                            break;
      }

    });
  });

</script>
<style type="text/css">
  .type1 {
    position: absolute;
    border: solid 1px gray;
    font: normal 12px Arial, Helvetica, sans-serif;
  }
  .type2 {
    position: absolute;
    border: solid 1px green;
    font: bold 12px Arial, Helvetica, sans-serif;
    color: green;
  }
</style>
</head>
<body>
</body>
</html>
jessegavin
A: 

I cannot use the 'var p = document.createElement('p')' because if a 'C' node of the same type comes up later in the loop it will clash and override that element

Just don't use fixed variable names. Let your loop add elements to an array instead:

var elementList = [];
var Cs = xml.getElementByTagName("C");
for (var i=0; i<Cs.length; i++) {
  elementList.push( whateverYourFunctionIsThatCreatesHtmlNodes(Cs[i]) );
}

or add them right to the DOM in the loop body.

Tomalak