0 votes
by (1.3k points)
Hi, I have another question while I'm here.

I have a situation where I have three buttons. Let's say "Edit", "Save" and "Confirm".

They're just normal buttons, using <<button>>. Does anyone know how I might disable the "Save" button until the user has used "Edit" to modify something? I'd like "Save" to start off disabled. Then, the user clicks "Edit" and does whatever. And then (since edit mode is enabled, the "Edit" button should be disabled), the "Save" button becomes enabled so they can save their changes.

Right now, I have all three buttons enabled, and it looks stupid. It works (apart from that confirm button), but I'd like them to function intelligently. So... help? Is there an easy way?

1 Answer

0 votes
by (159k points)
selected by
Best answer

Your problem can be broken down into two parts:

1. How to uniquely identify the button in such a way that you can modify it's enabled state programmatically as required.

One way you can do this is to wrap each of the buttons you need to identify in an HTML element with an ID, and you can use Custom Style markup like the following to do that.

@@#edit-button;<<button "Edit">><</button>>@@
@@#save-button;<<button "Save">><</button>>@@
<<button "Confirm">><</button>>

... which after processing generates HTML elements like the following.

<span id="edit-button">
	<button class="link-internal macro-button" type="button" tabindex="0">Edit</button>
<span id="save-button">
	<button class="link-internal macro-button" type="button" tabindex="0">Save</button>
<button class="link-internal macro-button" type="button" tabindex="0">Confirm</button>

... now the Edit button element can be identified via #edit-button button and the Save button element via #save-button button

2. How to modify the state of a button element so that it appears disabled.

In an ideal world you could simple use CSS to alter the the cursor property of button element to not-allowed which would not allow the user to click on it, unfortunately this does not work on mobile-based web-browsers.

So you will need to use Javascript to modify the element's disabled attribute instead, which the following example demonstrates.

@@#edit-button;<<button "Edit">>
	<<run $("#edit-button button").attr("disabled", true)>>
	<<run $("#save-button button").attr("disabled", false)>>
@@#save-button;<<button "Save">>
	<<run $("#save-button button").attr("disabled", true)>>
	<<run $("#edit-button button").attr("disabled", false)>>
<<button "Confirm">><</button>>

... and then uses some CSS like the following in your Story Stylesheet area so that you can tell when the button element is disabled or not.

.passage button:disabled {
	opacity: 0.65;

Now the only issue left is how to disable the Save button when it is first displayed to the end-user, and one way to do that is to use a single-use postrender task handler to disable the Save button element after it is created but before it is displayed to the end-user. Simple add the following to the end of the Passage that contains the Edit and Save <<button>> macro calls.

	postrender["Disable Save Button"] = function (content, taskName) {
		delete postrender[taskName];

		$(content).find("#save-button button").attr("disabled", true);


by (1.3k points)
Hey, this worked perfectly for me, with my real code. I couldn't have asked for more. Just perfect. So, thanks a lot, greyelf. I doubt I could have come up with all that. And it's saved me quite a bit of time. Big thanks!
by (68.6k points)

Strictly speaking, while jQuery will do the right thing here, you want to modify the disabled property, not the attribute.  In this case, the attribute is for use in tag literals, while the property is for changes to the element's status after the fact.

For example:

/* GOOD */
.prop('disabled', true)
.prop('disabled', false)

.attr('disabled', true)
.attr('disabled', false)