Change color of UI Bar button to show it's new

If you are requesting technical assistance with Twine, please specify:
Twine Version: 2.3.16
Story Format: 2.36.1

So I’m trying to make it so when a new button is added to the side bar, the color is purple or something, to showcase it’s new. Once the player has clicked on it and gone to the page, the color goes back to the normal grey. The buttons in question are added via the StoryMenu special name.

I looked up how to change the color, and all I could find was how to change all of the colors of the buttons. I just want the color to change for one of the buttons. How would I go about doing that? I imagine it involves creating new classes in CSS, but I’m not sure how.

I’ve gotten as far as learning the buttons all fall under < li > < /li >, but I don’t know how to make each button use their own version, like < li1 > < /li1 >, < li2 > < /li2 >.

There are limits to what macro’s you can use in the StoryMenu special Passage.

You’ve described a button that has two states (new and normal) when it’s added to the menu area:

  1. what controls when this button is added to that area?
  2. Can multiple of these two state buttons be added to the menu area at the same time?
  3. Can a two state button get removed from the menu at some later point? And if so, what controls when it gets removed?

You can use the Special Attribute feature of HTML Attribute mark-up to add HTML anchor <a> element to the menu area, which will be displayed like a ‘button’. Which would allow you to selectively add a CSS class to that ‘button’ as needed…

<a class="new" data-passage="Phone">Phone</a>

…and you could use a CSS rule like the following in your project’s Story Stylesheet area to style this ‘new’ state button…

#menu-story a.new {
    color: green;
}

…however how exactly you use the above knowledge depends on the answers to the questions I asked earlier in this post.

Fun question.

The following JavaScript and CSS should do the trick. First, add this to your game’s JavaScript section:

State.variables.knownButtons = [];  /* Initialize $knownButtons */
$(document).on(":passageend", function (event) {
	var i, menuButtons = $("#menu-story a");
	if (State.variables.knownButtons.length === 0) {
		/* Get list of existing buttons. */
		for (i = 0; i < menuButtons.length; i++) {
			State.variables.knownButtons.push(menuButtons[i].text);
		}
	} else {
		/* Tag new buttons. */
		for (i = 0; i < menuButtons.length; i++) {
			if (!State.variables.knownButtons.includes(menuButtons[i].text)) {
				setTimeout(function (btn) {
					if (!State.variables.knownButtons.includes(btn.text)) {
						$(btn).addClass("newbutton");
					}
				}, 20, menuButtons[i]);
				$(menuButtons[i]).one("click", function (ev) {
					/* Unmark clicked new buttons. */
					State.variables.knownButtons.push($(this).text());
					$(this).removeClass("newbutton");
				});
			}
		}
	}
});
Save.onSave.add(function (save) {
	/* Make sure that $knownButtons is properly saved. */
	save.state.history[save.state.index].variables.knownButtons = State.variables.knownButtons;
});

and then add something like this to your game’s Stylesheet section in order to style the “new” buttons:

.newbutton {
	background-color: darkslateblue;
}

You can change the CSS within that newbutton class to whatever you want in order to style the new button highlighting.

The above code will automatically track the buttons by their text on the $knownButtons variable. If a new button is displayed in the StoryMenu passage, then it will be highlighted using the newbutton class’ styling. Once it’s clicked, then it will add the text of that button to the $knownButtons variable so that it won’t be highlighted again. I even added some code to make sure that it will be tracked properly in any saves, since normally the click tracking code would update the value of $knownButtons too late to be recorded if you saved immediately after it changes.

If you want to make it so that a currently known button is able to be highlighted again, you can do something this in your passage:

<<run $knownButtons.delete("button text")>>

Where “button text” is the text shown on the button you want to be able to be highlighted again.

If, after first looking at the relevant SugarCube, jQuery, or setTimeout() documentation, you still have any questions about the above code, please feel free to ask and I’m happy to explain how it all works. (Note: All of the $(...).etc stuff is jQuery code.)

Enjoy! :slight_smile:

[EDIT: Clarified what I meant about changing the CSS.]

So the way I have it written, is the button shows up once you get to a certain passage using the << if >> macro. I added all of what you wrote into my CSS and Javascript, but I’m unsure how to make it apply to the button.

I changed the “newbutton” to the text of the button, but that didn’t change the color of the button. I also tried using < span class=“powers” > since you mentioned class styling, but that just made it so the button doesn’t appear at all. Sorry if this is basic, I’m very new with this, and am mostly a writer, not a coder. I appreciate the help!

Also, it should be noted that I’m making the buttons through StoryMenu by just making a link using [[This]]. If I should be using a different command or macro in order to make this work, I can do that.

  1. what controls when this button is added to that area?
    I’m using an <<if>> macro, and making it so when they get to a certain passage, a variable is set to 1, and the <<if>> is completed.
  2. Can multiple of these two state buttons be added to the menu area at the same time?
    Ideally, as I plan to have multiple tabs that update as the player progresses
  3. Can a two state button get removed from the menu at some later point? And if so, what controls when it gets removed?
    I would imagine just turning the variable I mentioned in the answer to 1 to 0 would remove it.

I should have mentioned this in the original post, as I think it’s an issue. I’m making buttons on the UI bar using StoryMenu, and all i’m doing is adding a link to a passage like this. [[NewButton]]

If I need to add buttons in a different way to make this functional, I can do that, you’ll just have to point me in the right way, as I’m still new to this.

StoryMenu filters out everything that’s not a link, so you’ll need to style the element itself. Since that’s the case, you’ll need to use an anchor (<a>) element directly. E.g.,

<a class="new-btn" data-passage="Some Passage">Some Passage</a>

Alright, so the button alternative that TheMaxExile wrote did work, and I substituted everything, and now the button is a different color. However, the color remains, no matter how many times I navigate to the passage it leads to. I copied the text exactly as HiEv wrote it.

If you’re not applying a separate class for some other reason, which I thought you asking for, you shouldn’t need to do anything. While not exactly how I’d have done it, HiEv’s code shouldn’t need any changes from you—other than maybe changing the color used in the style.

It keeps track of the text of buttons it’s seen before and automatically adds the newbutton class to any whose text it hasn’t. Once the user clicks on such a link, it automatically removes the class and records the text so it won’t flag it again.

I didn’t look at the code too closely, so I guess there might be a bug in it, but I’d try it as-is before since the basic idea is sound.

TL;DR: You shouldn’t have to do anything manually, just add your [[Muh Button]] links and it should just work.

Ok, thats weird, it’s working fine now. Alright, I’ll mark HiEv’s post as solution, although honorable mention to Exile, who managed to figure out I fucked it up somehow.

Just a question, and I feel kind of like an asshole just for asking, but I figured I’d shoot my shot. With this code, would it be possible to control the color depending on the notification that would pop up?

So if a new magic power appears, the button would turn blue, and if a new physical ability appeared, the button would turn red.

Again, if it can’t that’s absolutely fine, this has been more than enough, but I figured I’d ask.

Yup, because doing that breaks the code. :stuck_out_tongue_closed_eyes:

The class you add to the button has to have a corresponding class set up in the Stylesheet section in order to modify anything. Additionally, there are limitations on class names, such as the fact that you can’t have class names with spaces in them. So, if the button text has any spaces in it, that method could never work.

I assume by “notification” you mean the button itself?

You’d have to first create classes for each color you want to use in your Stylesheet section, and then modify the code to apply the appropriate class based on the button’s text.

For example, you could add something like this to your Stylesheet:

.newbutton.btngreen {
	background-color: darkgreen;
}

That would add that styling to any element which has both the “newbutton” and “btngreen” classes.

Then, in the JavaScript section, you’d want to set up an object which translates button text into those class names. Something like:

var buttonclass = {
	"Button text 1": "btngreen",
	"Button text 2": "btnblue",
	"Button text 3": "btnpurple"
};

Now, after the $(btn).addClass("newbutton"); line, you could do this:

if (buttonclass[btn.text]) {
	$(btn).addClass(buttonclass[btn.text]);
}

Which says, if the button’s text is a property of the buttonclass object, then add that property’s value as a class on that button. Any buttons with text that isn’t set up on the buttonclass object will just use the default newbutton class styling.

Enjoy! :slight_smile:

You could also use an anchor tag with an existing class for this purpose, which would obviate the need to edit the original code and add a new object.

For example, the markup:

<a class="magic" data-passage="Magic">Magic</a>

And the styles:

.newbutton {
	background-color: darkslateblue;
}
.newbutton.magic {
	background-color: darkgreen;
}

That’s correct if they’re only using <a> (anchor) elements for these links. However, my intent was to provide code which would work in all cases, including for [[X]] and <<link "X">><</link>> style links, so that people don’t have to rewrite their StoryMenu passage if they just want to add this feature.

I’m also a bit curious about your earlier comment:

How would you have done it? I’m curious to learn any new tricks you could teach.

Alright, that worked, thanks!

Does adding a .modifier work on any type of variable like that?

I’m assuming you’re talking about the CSS stuff, right? If so, then I should clarify that they aren’t variables, they’re selectors. “Selectors” are what you use in CSS to “select” what HTML elements on the page that the styling in the next { ... } block affects.

The “.” in front of selectors is just shorthand for “class”. You’ll also see “#” in front of some selectors, and that’s shorthand for “ID”. Selectors without either of those characters in front usually refer to HTML element types.

Let’s give a quick example. Say you have this HTML on a page:

<a class="classname" id="idname" href="https://www.google.com/">Google</a>

In CSS you can target all <a> links, including that one, like this:

a {
	color: red;
}

That would make all links red.

But if you only want to target elements with that “classname” class, you could do this instead:

.classname {
	color: green;
}

That would make the text in all elements with the “classname” class green.

Or, if you want to target that specific element, you could use its “idname” ID like this:

#idname {
	color: blue;
}

That would make text in the element with the ID of “idname” blue.

Note that IDs should be unique on the page, so if you’re giving more than one element the same ID then that’s not valid HTML. On the other hand, the same class can be used on multiple elements at the same time.

Now, let’s say that you added all of those bits of CSS to your game at once. Which one would affect the line of HTML I gave above? Well, CSS prefers the more specific selectors over the more general selectors. So the “a” selector would be the most general, the “.classname” selector would be next, and then “#idname” would be the most specific selector, so that last one would be the one that’s applied to that line of HTML. Other links would still be colored red, since the “a” styling would still be applied to them, unless some other, more specific, styling overrode that. (See the “SpeciFISHity” chart, which shows a list of least-to-most specific CSS selectors using cute “fish”.)

What if there’s a tie for specificity? Then the last one listed will win. That’s part of what the “cascading” in “Cascading Style Sheets” (CSS) means.

There are a lot more selector tricks you can use, so I’d recommend bookmarking and using this page on “CSS Selectors” if you’re having trouble targeting specific elements in your HTML with CSS styling.

Hope that helps! :slight_smile:

Hey, sorry for responding so long after, but I had a question regarding this code.

So since then, I’ve made my sidebar collapsable, in the sense that when the sidebar is stowed, small buttons show up, the size of the arrow at the top that opens the sidebar. Using just HTML, and changing classes, I made it so the new buttons glow like you helped me here. And when using the buttons, it sends you to a new passage, which has a <<set>> which changes a variable, making the minibutton glow.

However, the issue is that the way this code was made, the only way to get the full button to stop glowing is to press the button. However, if the player uses the minibutton, I want the full button to stop glowing as well. Is there a way to do that?