1

With JavaScript and jQuery I'm trying to replace a group element with a use element linking to another group element.

// Javascript
origgroup = $("#origgroup")[0];
repgroup = $("#referenceGroup1")[0];
origgroupParent = origgroup.parentNode;

use = document.createElementNS("http://www.w3.org/2000/svg", "use");
use.setAttribute("xlink:href", "#origgroup2");
use.setAttribute("id", "newuse");

tmp = origgroupParent.replaceChild(use, origgroup);

// After this snippet is run, "targetsvg" and "control" are identical. Except that targetsvg's use-tag has an unique ID.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- My "atlas". I want to put <use> elements in "targetsvg" below, linking to these groups. -->
Atlas <br>
<svg id="atlas" width="120" height="70" version="1.1">
  <g id="referenceGroup1">
    <rect x="10" y="10" width="90" height="20" fill="green"/>  
    <circle cx="20" cy="40" r="15" fill="blue"/>
  </g>
  <g id="referenceGroup2">
    <rect x="40" y="10" width="90" height="20" fill="red"/>  
    <circle cx="50" cy="40" r="15" fill="orange"/>
  </g>
</svg>
<br> Target <br>
<!-- My target -->
<svg id="targetsvg" width="120" height="70" version="1.1"
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <g id="origgroup">
    <rect x="40" y="10" width="90" height="20" fill="red"/>  
    <circle cx="50" cy="40" r="15" fill="orange"/>
  </g>
</svg>
<br>
Control
<br>
<!-- This is identical to the javascript modified version of "targetsvg" -->
<svg id="control" width="120" height="70" version="1.1" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <use xlink:href="#referenceGroup1"></use>
</svg>

What I expect to happen is for there to be a blue circle and a green rectangle under "Target". If I inspect the resulting svg of "targetsvg" it's identical to the svg under "Control". This leads me to believe that "targetsvg" is not redrawn for some reason, is this correct? Is there a way to force that?

I've spent the last five hours searching, but I can't find anything similar. The most relevant I've found is SVG <use> in Chrome doesn't work But that uses Angular, which I'm not. I think the cause is the same ("the relative hash link in the element would not correctly resolve."). But if this is the case, how do I resolve this without Angular?

Thanks!

[Background: I have a huge svg-file generated from illustrator. In this file there are a number of fairly complex elements (groups of groups et.c.) that I need to have different versions of. These elements will need to appear on multiple places in the final result, so I either need to have multiple copies of them (Showing/hiding depending on the situation) or some kind of 'atlas' where I pick and replace. My gut says the latter will be more maintainable since there are at least four places and seven "versions" (Think "green", "green with symbol x", "red with symbol y" et.c.). If there are other options, I welcome those.]

1 Answers1

1

Minutes after posting, I realized it was a namespace problem. Changing the JavaScript to:

origgroup = $("#origgroup")[0];
repgroup = $("#referenceGroup1")[0];
origgroupParent = origgroup.parentNode;

// Namespaces
var svgns = 'http://www.w3.org/2000/svg',
xlinkns = 'http://www.w3.org/1999/xlink'

use = document.createElementNS(svgns, "use");
// **setAttributeNS** instead of setAttribute as originally.
use.setAttributeNS(xlinkns, "xlink:href", "#referenceGroup1");
use.setAttribute("id", "newuse");

tmp = origgroupParent.replaceChild(use, origgroup);

Solved my problem.