0 votes
by (210 points)
closed by

Hi everyone,

I am trying to let users report bugs or suggestions while reading the story. In each passage, readers may click a link to prompt a window that let them write their comment. However, I am struggling in how to store these comments during the story (note that I am quite a newbie in programming).

I am using Harlowe 2.1.0.

Right now, I have a footer passage with this code:

(set: $currentpassage to (passage:)'s name)

(link: "Report a bug")[(set: $ncomment to it + 1)(set: $usercomment to (prompt: "Your comment", ""))(set: $comment to ("$currentpassage") + ("$ncomment") + ("$usercomment"))]

This allows me to precisely trace the comment. However, my issue is that each comment is erased with each new one. 

Is there a way to change the last (set: $comment) to call a different variable with each call? For instance, is there a way to set a variable name with something like: (set: ("$comment+$ncomment") to ...)?

Or do you have another idea that would work?

Thanks!

Lou

closed with the note: Resolved

1 Answer

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

You could use an Array story variable to store the comments the user enters.

1. Initialise the Array in your project's startup tagged special Passage using the (a:) macro.

(set: $userComments to (a:))


2. Use TwineScript like the following to obtain the comment from the user and to add it to the Array.

warning: The (prompt:) macro will return an empty String value if the user either selects the 'Cancel' option or selects the 'OK' option without entering a value into the field. You can use the (unless:) macro to make sure you are only adding actual comments to the Array.

(link-repeat: "Report a bug")[{
	(set: _userComment to (prompt: "Your comment", ""))
	(unless: _userComment is "")[
		(set: $userComments to it + (a: _userComment))
	]
}]


3. Displaying the comments (elements) contained within the Array using the (for:) macro.

warning: The (for:) macro will show an error if it is passed an empty Array, you can use an (unless:) macro to check the Array's length value to make sure it contains elements.

{
	(unless: $userComments's length is 0)[
		(set: $counter to 0)
		(for: each _comment, ...$userComments)[
			(set: $counter to it + 1)
			<br>$counter: _comment
		]
	]
}


4. Combining the asking for a comment and the displaying of the contents of the Array in the same Passage.

The following example consists of two passages:

a. The first passage (named whatever you like) displays the "Report a bug" link and the contents of the Array.

(link-repeat: "Report a bug")[{
	(set: _userComment to (prompt: "Your comment", ""))
	(unless: _userComment is "")[
		(set: $userComments to it + (a: _userComment))
	]
	(replace: ?comments)[(display: "List User Commments")]
}]

{
User Comments: ((link-repeat: "Refresh")[(replace: ?comments)[(display: "List User Commments")]])
|comments>[(display: "List User Commments")]
}

b. The second passage (named List User Commments in this example) contains the TwineScript from the above Point 3.

note: You will notice that I added a (replace:) macro within the associated hook of the the "Report a bug" link, this causes the User Comments list to be automatically updated each it a new comment is added to the Array. If you don't want that to happen then simply remove that (replace:) macro.

by (210 points)
Sorry for the delay in my answer and thanks you for your help. Your answer was very complete and precise. Your code works perfectly and I managed to also add the passage's name information by following the same logic.

Thanks again!
...