I apologize in advance that this question isn’t associated with a notebook. While I’ve hacked around drawing from myriad internet examples, I still haven’t gotten to a happy place…
I’d like to create a button input for which both text and color changes on click, and clicks cycle through a few options. I’ve gotten this sort of thing working well for binary values, but haven’t managed to get color and text changes to line up for multiple values. For example, one button would cycle through three options:
select - grey
yes - red
no - green
I see that the ‘test passed’ / ‘test failed’ indicators in @mootari/mutable-forms adjust colors when values match parameters using a style.color = match ?
Before I starting hacking around with this notebook, I was hoping someone would tell me whether or not it’d be a relatively useful exercise.
Sure, I think it’d be useful! Certainly it’s a great learning exercise and it’s always good to have more importable inputs available!
One way to deal with more than two options is to store the possible states in an array and have an index that keeps track of the current state which cycles through 0, … , number of states using the % operator: see e.g. how I handle the options in the gridClick functions in my Grid inputs notebook for an example.
I see you’ve just posted an attempt. Here’s a little advice: it should be possible to do this in a single cell without having to use mutable cells. You might try filling in this skeleton:
viewof button = {
const form = html`<form><button name=button>Init`;
const states = [{}, {}, {}]; // <-- fill in data for the three state objects
let currentIndex = 0; // this variable keeps track of the state the form is in. It should cycle through 0, 1, 2 when the button is clicked
form.button.onclick = event => {
// <-- insert logic to cycle through currentIndex here
// <-- update the value of the form using states[currentIndex]
// <-- change button styling / text using states[currentIndex]
event.preventDefault(); // Don’t submit the form.
form.dispatchEvent(new CustomEvent("input"));
};
form.value = states[0]; // <-- set the initial value of this input (depending on the structure of the state objects, you might want this to use just a specific field e.g. states[0].value)
return form;
}
Thanks @mbostock! I see that you associate a color value to each of the button labels. I’ll see if I can’t find a way to have these values affect the color of the button itself.
… form.button.backgroundColor=state.value; not effecting change in button color
… form.style.backgroundColor=state.value; effects change, but not to the button itself
Just for completeness’ sake, you can also cycle the inputs themselves: I. e., create distinct buttons each with their own handler and cycle them by attaching / detaching.