views:

163

answers:

3

Hello, I have the following SVG code in a XHTML page

<svg:svg>
<svg:svg width="450" heigth="450" viewBox="0 0 500 500">  
    <svg:defs>
        <svg:g id='mygroup'>
            <svg:circle id='a' cx="15" cy="15" r='15' fill="green" fill-opacity="0.3"/>
            <svg:line id='b' x1="15" y1="15" x2="15" y2="0" style="stroke: black;" />
        </svg:g>
</svg:defs>

<svg:rect width="400" height="400" fill="white" stroke="black" />
<svg:use id="g1" xlink:href="#mygroup" x="100" y="100" onclick="moveMe()" />
<svg:use id="g2" xlink:href="#mygroup" x="100" y="200" />
</svg:svg>

and I would like to modify it with the following javascript code

<script><![CDATA[
    function moveMe(){
    obj = document.getElementById("g1");
    obj.setAttributeNS(null, "x", "200"); //Ok it works

    //How can I change the color of the a circle in g1? 
    obj = document.getElementById("g1.a");
    obj.setAttributeNS(null, "fill", "red"); //It doesn't work
    }
 ]]></script>

How can I change the color of the 'a' circle in 'g1'? How can I access it from my javascript code?

EDIT: If I have a 2nd mygroup item called g2, I don't want to change its color.

+1  A: 

Replace

obj = document.getElementById("g1.a");

with

obj = document.getElementById("a");

since the id of the circle element is a and not g1.a.

iN document.getElementById(id)

id is a case-sensitive string representing the unique ID of the element 
being sought.
rahul
Thnaks for this answer. That works in the original example but see my edit.
luc
I think you are calling the moveme function on g1's click only. Then what is the issue for g2.
rahul
In fact, the problem is that the color is changing on g1 and g2. I would like to change it only for g1. Is that possible?
luc
Are you calling the function on both g1 and g2?
rahul
No only on g1. What I want to do is to change the color of the circle in g1 without modifying the circle in g2.
luc
A: 

You can achieve the desired behaviour by using css.

Add this to your html-head:

<style type="text/css">
   .g1red #a {fill:red}
</style>

use this script code:

<script><![CDATA[
function moveMe(){
obj = document.getElementById("g1");
obj.setAttributeNS(null, "x", "200");
obj.setAttributeNS(null, "class", "g1red");  
}
]]></script>
räph
+1  A: 

A simple solution is to pass in a color using the 'currentColor' keyword like this:

<svg:svg>
<svg:svg width="450" heigth="450" viewBox="0 0 500 500">  
<svg:defs>
    <svg:g id='mygroup'>
        <svg:circle id='a' cx="15" cy="15" r='15' fill="currentColor" fill-opacity="0.3"/>
        <svg:line id='b' x1="15" y1="15" x2="15" y2="0" style="stroke: black;" />
    </svg:g>
</svg:defs>

<svg:rect width="400" height="400" fill="white" stroke="black" />
<svg:use id="g1" xlink:href="#mygroup" x="100" y="100" onclick="moveMe()" color="green"/>
<svg:use id="g2" xlink:href="#mygroup" x="100" y="200" color="blue"/>
</svg:svg>

If you want to change the colors you can now just change the 'color' attribute on the 'use' elements. Or simply use CSS to do it, e.g:

<style>
#g1:hover { color: lime }
</style>
Erik Dahlström
nice! I didn't knew that one. But one thing: in your example you cannot define a default color for the circles. E.g. you want to have all #a green, and only by clicking #g1 it should turn red. Is this possible?
räph
It works perfectly. Thank you so much for this elegant solution
luc
@räph: It's possible to apply the default color with CSS, so that all use-elements that has a particular classname gets the default 'color' set, e.g: .myInstances { color: fuchsia; /* the default color */ }This way you only need to set the color once, instead of on each 'use' element.As for the clicking, well, maybe if the state-change is non-static you could use an :active pseudoclass to set it, but it might be better to assign an additional classname instead when clicked.
Erik Dahlström