11-14-2017 07:06
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

11-14-2017 07:06
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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.
Accepted Solutions
11-15-2017 11:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


11-15-2017 11:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
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
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


11-14-2017 12:37
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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";

11-14-2017 13:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

11-14-2017 13:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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

11-15-2017 07:15
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

11-15-2017 07:15
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
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
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

11-15-2017 07:41
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
@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
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

11-15-2017 07:50
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@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";

11-15-2017 08:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

11-15-2017 08:09
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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.

11-15-2017 11:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


11-15-2017 11:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
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
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

11-16-2017 01:58
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
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.
