11-14-2017 07:06
11-14-2017 07:06
I want to change the combo-button-icon and combo-button-icon-press on a combo-button via JavaScript. The icon in the button should reflect a state of something in my app, so I need to change it programmatically. How can I do this?
This seems like something that should be in the "Interacting with Elements" section of https://dev.fitbit.com/guides/user-interface/javascript/
Answered! Go to the Best Answer.
11-15-2017 11:03
Fitbit Developers oversee the SDK and API forums. We're here to answer questions about Fitbit developer tools, assist with projects, and make sure your voice is heard by the development team.
11-15-2017 11:03
I just tested it here, it's working.
<svg>
<!-- TOP LEFT -->
<use id="btn-tl" href="#combo-button-upper-left" fill="fb-cyan">
<set href="combo-button-icon" attributeName="href" to="cog.png"/>
<set href="combo-button-icon-press" attributeName="href" to="cog_press.png"/>
</use>
</svg>
import document from "document";
let btn = document.getElementById("btn-tl");
let icon = btn.getElementById("combo-button-icon");
let icon_press = btn.getElementById("combo-button-icon-press");
console.log(icon.image);
console.log(icon_press.image);
icon.image = "cog_press.png"
11-14-2017 12:37
Fitbit Developers oversee the SDK and API forums. We're here to answer questions about Fitbit developer tools, assist with projects, and make sure your voice is heard by the development team.
11-14-2017 12:37
You can get a handle on the button using getElementById, then use that to get a handle of each image.
Something like this: (untested).
let myButton = document.getElementById("myButton");
let press = myButton.getElementById("combo-button-icon-press");
press.image = "another.png";
Best Answer11-14-2017 13:08
11-14-2017 13:08
I tried two different approaches, but no luck.
<use id="btnPlayPause" href="#combo-button-lower-right" fill="fb-white">
<set id="btnPlayPause-icon" href="combo-button-icon" attributeName="href" to="play.png"/>
<set id="btnPlayPause-icon-press" href="combo-button-icon-press" attributeName="href" to="play-press.png"/>
<set href="combo-button-stroke" attributeName="display" to="inline"/>
</use>I tried:
let btnPlayPause = document.getElementById("btnPlayPause");
btnPlayPause.getElementById('btnPlayPause-icon').attributes.to = 'pause.png';and
document.getElementById('btnPlayPause-icon').attributes.to = 'pause.png';No luck. Error in the console:
Unhandled TypeError: Cannot read property 'attributes' of null
Best Answer11-15-2017 07:15
11-15-2017 07:15
Looks like JonFitbit code should work.
Alternative workaround:
I used two buttons in the same position, with different names. Displaying the one that I want. Unfortunately the “enabled” property does not work, but if you play with the display you can replicate it.
check this post:
11-15-2017 07:41
11-15-2017 07:41
@agsurf5 wrote:
Unfortunately the “enabled” property does not work,
I spent *hours* learning this the hard way. Hey Fitbit, if something is broken, don't document it as working.
11-15-2017 07:50
11-15-2017 07:50
@JonFitbit's example didn't seem like it would work, which is why I tried something similar but slightly different in my post above. Based on what @agsurf5 said, I figured I should try it explicitly anyway. The result:
Unhandled TypeError: Cannot set property 'image' of null
Here's the code:
index.gui:
<use id="btnPlayPause" href="#combo-button-lower-right" fill="fb-white">
<set id="btnPlayPause-icon" href="combo-button-icon" attributeName="href" to="play.png"/>
<set id="btnPlayPause-icon-press" href="combo-button-icon-press" attributeName="href" to="play-press.png"/>
<set href="combo-button-stroke" attributeName="display" to="inline"/>
</use>app/index.js:
let btnPlayPause = document.getElementById("btnPlayPause");
let innerButtonImage = btnPlayPause.getElementById('btnPlayPause-icon');
innerButtonImage.image = "pause.png";
Best Answer11-15-2017 08:09
11-15-2017 08:09
I should explain a little more why I didn't think Jon's approach would work: My understanding is that a <use> references a template symbol and the <set> child nodes are for modifying the attributes of the template symbol—they are not elements themselves within that template symbol. This is why I tried giving the <set> child nodes an id and trying to change their attributes, but changing their attributes does not seem to update the attributes of the template symbol instance after instantiation.
Best Answer11-15-2017 11:03
Fitbit Developers oversee the SDK and API forums. We're here to answer questions about Fitbit developer tools, assist with projects, and make sure your voice is heard by the development team.
11-15-2017 11:03
I just tested it here, it's working.
<svg>
<!-- TOP LEFT -->
<use id="btn-tl" href="#combo-button-upper-left" fill="fb-cyan">
<set href="combo-button-icon" attributeName="href" to="cog.png"/>
<set href="combo-button-icon-press" attributeName="href" to="cog_press.png"/>
</use>
</svg>
import document from "document";
let btn = document.getElementById("btn-tl");
let icon = btn.getElementById("combo-button-icon");
let icon_press = btn.getElementById("combo-button-icon-press");
console.log(icon.image);
console.log(icon_press.image);
icon.image = "cog_press.png"
11-16-2017 01:58
11-16-2017 01:58
Thank you, @JonFitbit! It worked. Clearly, I misunderstood how DOM selection differs in SVG from HTML and must have flubbed something when I tried what you originally posted.
Is the DOM of the components inspectable? I might have realized this sooner. If not, it might be useful to others to have the relevant parts documented.