Twine|Sugarcube - How to Disable Button if Text is ""

So, this is another kinda specific thing
Rather than have links set in passages, I’m having navigation be based upon a collection of 10 buttons set in a tray at the bottom of the screen. These buttons are technically displayed at all times, though the plan is to have them reduced to 0 opacity when disabled.
The options displayed upon the buttons is supposed to change depending on a string variable that can be altered in-passage as one navigates through the story.
I’d like to have it set to when the associated string in the passage is set to “”, then the button disables itself to prevent it from being clicked or otherwise interacted with.

Thus far, I’ve managed to do find this code,

@@#test;<<button "test">>
    <<run $("#test button").prop("disabled", true)>>
<</button>>@@

and I’ve tried to modify it to something like this;

<<set $bTest1 = "">>

@@#butt;<<button $bTest1>>
<</button>>@@
<<if $bTest1 == "">>@@<<run $("#butt button").prop("disabled", true)>>@@<</if>>

Maybe I’m not quite getting it, but I know if I attach the code within another button, then it works like so-

@@#butt;<<button $bTest1>>
<</button>>@@
@@#test;<<button "test">>
    <<run $("#butt button").prop("disabled", true)>>
<</button>>@@

So…
How be what do?

Will this work?

<<if $buttonText !== "">>
  <<button $buttonText>>
  <</button>>
<<else>>
  <button disabled></button>
<</if>>
1 Like

The problem you’re seeing is caused by the fact that, initially the passage is rendered to a “virtual” context, and then that is appended to the page. So, at the point where the code that looks for the buttons on the page is executed, the buttons aren’t actually on the page yet. They’re still “virtual”.

Normally to get around that, you’d add code like this to the bottom of a passage which needed access to its contents while it’s still “virtual”:

<<script>>
	$(document).one(":passagerender", function (event) {
		$(event.content).find("#butt button").prop("disabled", true);
	});
<</script>>

(See the :passagerender event for details.)

If you were doing this for the bottom bar though, then the code you can use instead is a bit simpler:

<<script>>
	setTimeout(function () {
		$("#butt button").prop("disabled", true);
	});
<</script>>

The setTimeout() method gives the code time to render the passage to the page before it tries to find the button.

However, in this case, because the buttons would initially be enabled and the bottom bar doesn’t use transitions, if you disabled them like that, then the buttons would “flash” due to their “transition” property. Rather than having to also fuss with the CSS to prevent that, then, assuming the buttons won’t be enabled at any time other than a passage transition, something like Gulumige’s solution is best, though I’d make a very minor change:

<<if $buttonText !== "">>\
	<<button $buttonText>>
		/* button code goes here */
	<</button>>\
<<else>>\
	<button disabled></button>\
<</if>>\

The “\” at the ends of lines are to prevent line breaks. Gulumige’s solution works because the HTML button there starts out disabled, so it won’t “flash” when displayed because it doesn’t have to transition to the disabled colors.

So, his solution is correct, I just wanted to also explain why your attempts weren’t working as you thought they should.

2 Likes

Alright, cool
Thank you so much for the help, and sorry for the super late reply

I’ve figured out how to make these work for what I want them to do, being navigating through my game to begin with. It works perfectly!

So, again, thank you so much for the help!