How to dynamically get and set the ID of SVG elements using javascript

Viewed 1928

So I want to set and get the ID of the SVG elements I created. The way I did it is not working when I try to get the SVG element by using document.getElementByID(). My main goal is to eventually implement a way in which I can see which element is being dragged on top of another element so that I can change the colors of the shapes accordingly. Any help is appreciated, thanks.

const SVG_NS = 'http://www.w3.org/2000/svg';

let Y = 1450;



// create bottom left row
for(let i = 1; i< 12; i++){
  let x = 21 + i*49;
  drawCircle({cx:x, cy:Y,r:20},circle_seats,i);
  drawText({props:{x:x, y:Y},txtContent:i}, circle_seats);
  
}


// create bottom right row
for(i = 12; i < 23; i++) {
  let x = 21 + i*49;
  drawCircle({cx:(x+49*5), cy:Y,r:20},circle_seats,i);
  drawText({props:{x:(x+49*5), y:Y},txtContent:i}, circle_seats);
}
Y = 1400;

//create top left row
for(let i = 1,j = 23; i< 15; i++,j++){
  let x = 21 + i*49;
  drawCircle({cx:x, cy:Y,r:20},circle_seats,i);
  drawText({props:{x:x, y:Y},txtContent:j}, circle_seats);
  
}

//create top right row
for(i = 12,j = 37; i < 27; i++,j++) {
  let x = 21 + i*49;
  drawCircle({cx:(x+49*5), cy:Y,r:20},circle_seats,i);
  drawText({props:{x:(x+49*5), y:Y},txtContent:j}, circle_seats);
}

function drawCircle(o, parent, a) {

  var circle = document.createElementNS(SVG_NS, 'circle');
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      circle.setAttributeNS(null, name, o[name]);
      circle.id = "seat"+ a;
    }
  }
  parent.appendChild(circle);
  return circle;
}

function drawText(o, parent) {
  var text = document.createElementNS(SVG_NS, "text");
  for (var name in o.props) {
    if (o.props.hasOwnProperty(name)) {
      text.setAttributeNS(null, name, o.props[name]);
    }
  }
  text.textContent = o.txtContent;
  parent.appendChild(text);
  return text;
}
//rectangle plate functions

function drawText_plate(o, parent) {
  var text = document.createElementNS(SVG_NS, "text");
  for (var name in o.props) {
    if (o.props.hasOwnProperty(name)) {
      text.setAttributeNS(null, name, o.props[name]);
    }
  }
  text.textContent = o.txtContent;
  text.style.fontSize = "17px";
  parent.appendChild(text);
  return text;
}




var svgns = "http://www.w3.org/2000/svg";
function drawRectangle(o, parent, a) {
  var rectangle = document.createElementNS(svgns, 'rect');
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      rectangle.setAttributeNS(null, name, o[name]);
      rectangle.setAttribute("id", "seat"+ a);
    }
  }
  parent.appendChild(rectangle);
  return rectangle;
}



Y = 100;
let X = 25;
  drawRectangle({x:X, y:Y,width:100,height:50},name_plates,i);
  drawText_plate({props:{x:X+90, y:Y+25},txtContent:1}, name_plates);
  drawCircle({cx:X+10,cy:Y+25,r:5},name_plates,1);
  
  
for(let i = 2; i< 51; i++){
  X = X + 100 + 10
  if(i % 13 == 0) {
    X = 25;
    Y = Y + 55;
  }
  drawRectangle({x:X, y:Y,width:100,height:50},name_plates,i);
  drawText_plate({props:{x:X+90, y:Y+25},txtContent:i}, name_plates);
  drawCircle({cx:X+10,cy:Y+25,r:5},name_plates,i);
  
  
}


//NameTag Functions

function drawText_name_tag(o, parent) {
  var text = document.createElementNS(SVG_NS, "text");
  for (var name in o.props) {
    if (o.props.hasOwnProperty(name)) {
      text.setAttributeNS(null, name, o.props[name]);
    }
  }
  text.textContent = o.txtContent;
  text.style.fontSize = "10px";
  parent.appendChild(text);
  return text;
}

//create name tags
Y = 400;
X = 25;
  drawRectangle({x:X, y:Y,width:100,height:50},name_tags,i);
  drawText_name_tag({props:{x:X+50, y:Y+25},txtContent:"BLANK"}, name_tags);

for(let i = 2; i< 2; i++){
  X = X + 100 + 10
  if(i % 13 == 0) {
    X = 25;
    Y = Y + 55;
  }
  drawRectangle({x:X, y:Y,width:100,height:50},name_tags,i);
  drawText_name_tag({props:{x:X+50, y:Y+25},txtContent:"BLANK"}, name_tags);
  
  
  
}


function change_name(event) {
 var name = prompt("Enter a New Name (Max 20 characters):");
 while(name.length > 20) {
    name = prompt("Enter a New Name (Previous Over 20 Characters)");
  }
  if (name != null && name != "") {
event.target.textContent = name;
 }
}
text {
  fill: black;
  font-family: Verdana;
  font-size: 28px;
  stroke: black;
  dominant-baseline:middle;
  text-anchor:middle;
}

circle {
  fill: url(#gradGreen);
  stroke: black;
}

rect {
  fill: url(#gradGrey);
  stroke: black;
}
<svg id="svg" height="1500" width="1500">
 <defs>
  <lineargradient id="gradGreen" x1="0%" x2="100%" y1="0%" y2="0%">
   <stop offset="0%" style="stop-color:rgb(152, 251, 152);stop-opacity:1"></stop>
   <stop offset="100%" style="stop-color:rgb(0, 128, 0);stop-opacity:1"></stop>
  </lineargradient>
  <lineargradient id="gradYellow" x1="0%" x2="100%" y1="0%" y2="0%">
   <stop offset="0%" style="stop-color:rgb(255, 140, 0);stop-opacity:1"></stop>
   <stop offset="100%" style="stop-color:rgb(218, 165, 32);stop-opacity:1"></stop>
  </lineargradient>
  <lineargradient id="gradRed" x1="0%" x2="100%" y1="0%" y2="0%">
   <stop offset="0%" style="stop-color:rgb(255, 0, 0);stop-opacity:1"></stop>
   <stop offset="100%" style="stop-color:rgb(178, 34, 34);stop-opacity:1"></stop>
  </lineargradient>
 <lineargradient id="gradGrey" x1="0%" x2="100%" y1="0%" y2="0%">
   <stop offset="0%" style="stop-color:rgb(220, 220, 220);stop-opacity:1"></stop>
   <stop offset="100%" style="stop-color:rgb(105, 105, 105);stop-opacity:1"></stop>
  </lineargradient>
  
  </defs>
  
  
 <g class="circle_seat" id="circle_seats">
    
  </g>
  
  <g class ="name_plate" id= "name_plates">
  
  </g>
 
  
  
  
  <g class="name_tag" id="name_tags" ondblclick="change_name(event)">

 </g>

  
  </svg>

1 Answers

In order to draw a circle you are using this function:

function drawCircle(o, parent) {

  var circle = document.createElementNS(SVG_NS, 'circle');
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      circle.setAttributeNS(null, name, o[name]);
      //circle.id = "seat"+ a;
    }
  }
  parent.appendChild(circle);
  return circle;
}

As you may see I've commented out one line of code, the one where you try to set the id. You don't need this line. When you create a new circle you can do:

drawCircle({cx:(x+49*5), 
            cy:Y,
            r:20,
            id:"seat"+i},circle_seats); 

Now that your id is set you can use document.getElementByID().

UPDATE

This is your code but I've removed some functions you didn't need. Since you can't have repeated ids I've named them by adding tr for top left bl for bottom left... instead of seat.

This is important: the presentation attributes have a very low specificity and are overwritten by css declarations. To change a fill that is set in css you need to add a css rule:

document.getElementById("bl1").setAttribute("style", "fill:red");

const SVG_NS = "http://www.w3.org/2000/svg";

let Y = 1450;

// create bottom left row
for (let i = 1; i < 12; i++) {
  let x = 21 + i * 49;
  drawCircle({ cx: x, cy: Y, r: 20, id: "bl" + i }, circle_seats);
  drawText({ props: { x: x, y: Y }, txtContent: i }, circle_seats);
}

// create bottom right row
for (i = 12; i < 23; i++) {
  let x = 21 + i * 49;
  drawCircle({ cx: x + 49 * 5, cy: Y, r: 20, id: "br" + i }, circle_seats);
  drawText({ props: { x: x + 49 * 5, y: Y }, txtContent: i }, circle_seats);
}
Y = 1400;

//create top left row
for (let i = 1, j = 23; i < 15; i++, j++) {
  let x = 21 + i * 49;
  drawCircle({ cx: x, cy: Y, r: 20, id: "tl" + i }, circle_seats);
  drawText({ props: { x: x, y: Y }, txtContent: j }, circle_seats);
}

//create top right row
for (i = 12, j = 37; i < 27; i++, j++) {
  let x = 21 + i * 49;
  drawCircle({ cx: x + 49 * 5, cy: Y, r: 20, id: "tr" + i }, circle_seats);
  drawText({ props: { x: x + 49 * 5, y: Y }, txtContent: j }, circle_seats);
}

function drawCircle(o, parent) {
  var circle = document.createElementNS(SVG_NS, "circle");
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      circle.setAttributeNS(null, name, o[name]);
      //circle.id = "seat"+ a;
    }
  }
  parent.appendChild(circle);
  return circle;
}

function drawText(o, parent) {
  var text = document.createElementNS(SVG_NS, "text");
  for (var name in o.props) {
    if (o.props.hasOwnProperty(name)) {
      text.setAttributeNS(null, name, o.props[name]);
    }
  }
  text.textContent = o.txtContent;
  parent.appendChild(text);
  return text;
}

function drawRectangle(o, parent) {
  var rectangle = document.createElementNS(SVG_NS, "rect");
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      rectangle.setAttributeNS(null, name, o[name]);
      //rectangle.setAttribute("id", "seat"+ a);
    }
  }
  parent.appendChild(rectangle);
  return rectangle;
}

Y = 100;
let X = 25;
drawRectangle({ x: X, y: Y, width: 100, height: 50 }, name_plates, 1);
drawText({ props: { x: X + 90, y: Y + 25 }, txtContent: 1 }, name_plates);
drawCircle({ cx: X + 10, cy: Y + 25, r: 5 }, name_plates, 1);

for (let i = 2; i < 51; i++) {
  X = X + 100 + 10;
  if (i % 13 == 0) {
    X = 25;
    Y = Y + 55;
  }
  drawRectangle({ x: X, y: Y, width: 100, height: 50 }, name_plates, i);
  drawText({ props: { x: X + 90, y: Y + 25 }, txtContent: i }, name_plates);
  drawCircle({ cx: X + 10, cy: Y + 25, r: 5 }, name_plates, i);
}

//create name tags
Y = 400;
X = 25;
drawRectangle({ x: X, y: Y, width: 100, height: 50 }, name_tags);
drawText(
  { props: { x: X + 50, y: Y + 25, class: "blank" }, txtContent: "BLANK" },
  name_tags
);

document.getElementById("bl1").setAttribute("style", "fill:red");

function change_name(event) {
  var name = prompt("Enter a New Name (Max 20 characters):");
  while (name.length > 20) {
    name = prompt("Enter a New Name (Previous Over 20 Characters)");
  }
  if (name != null && name != "") {
    event.target.textContent = name;
  }
}
text {
  fill: black;
  font-family: Verdana;
  font-size: 28px;
  stroke: black;
  dominant-baseline:middle;
  text-anchor:middle;
}

#name_plates text{font-size:17px}
text.blank{font-size:10px}
circle {
  fill: url(#gradGreen);
  stroke: black;
}

rect {
  fill: url(#gradGrey);
  stroke: black;
}
<svg id="svg" viewBox="0 0 1500 1500">
 <defs>
  <lineargradient id="gradGreen" x1="0%" x2="100%" y1="0%" y2="0%">
   <stop offset="0%" style="stop-color:rgb(152, 251, 152);stop-opacity:1"></stop>
   <stop offset="100%" style="stop-color:rgb(0, 128, 0);stop-opacity:1"></stop>
  </lineargradient>
  <lineargradient id="gradYellow" x1="0%" x2="100%" y1="0%" y2="0%">
   <stop offset="0%" style="stop-color:rgb(255, 140, 0);stop-opacity:1"></stop>
   <stop offset="100%" style="stop-color:rgb(218, 165, 32);stop-opacity:1"></stop>
  </lineargradient>
  <lineargradient id="gradRed" x1="0%" x2="100%" y1="0%" y2="0%">
   <stop offset="0%" style="stop-color:rgb(255, 0, 0);stop-opacity:1"></stop>
   <stop offset="100%" style="stop-color:rgb(178, 34, 34);stop-opacity:1"></stop>
  </lineargradient>
 <lineargradient id="gradGrey" x1="0%" x2="100%" y1="0%" y2="0%">
   <stop offset="0%" style="stop-color:rgb(220, 220, 220);stop-opacity:1"></stop>
   <stop offset="100%" style="stop-color:rgb(105, 105, 105);stop-opacity:1"></stop>
  </lineargradient>
  
  </defs>
  
  
 <g class="circle_seat" id="circle_seats">
    
  </g>
  
  <g class ="name_plate" id= "name_plates">
  
  </g>
  <g class="name_tag" id="name_tags" onclick="change_name(event)">

 </g>

  
  </svg>

Related