Modifying the content of a listbox when changing the value of another one

Hello everyone.

A couple years ago, thanks to your answers, I was able to change dynamically a text block according to the value of a listbox.

This time, I have another, more complex use case that requires your advice.

I am working on a battle system. As currently designed, the system would use two listboxes in order to select the action (listbox1) and the target (listbox2).

Something that would look roughly like that:

<<set _warriorActions to ["Attack", "Heal", "Guard"]>>
<<set _enemyTargets to ["Slime", "Goblin"]>>
<<set _allyTargets to ["Mage", "Rogue"]>>

''Warrior': '<<listbox "_warriorAction">><<optionsfrom _warriorActions>><</listbox>> - <<listbox "_warriorTarget">><<optionsfrom _enemyTargets>><</listbox>>

I want to change the content of the _warriorTarget listbox, according to the current value of _warriorAction:

  • If “Attack” is selected, then the targets are from _enemyTargets
  • If “Heal” is selected, then the targets are from _allyTargets
  • If “Guard” is selected, then the target is “self”

Is this technically doable through a <<script>> and some JQuery ?

So you can’t have conditional statements inside a listbox, but it is doable, with some custom code. The way of doing it is having a listening event, to check for any change in the first listbox, and then tell the code to change the source of options for the second listbox. Something like this custom macro:

<<listen>>

  <<listbox 1>> <span id="other-action"></span>

<<when>>
    <<if _warrioraction is "Attack">>
          <<replace "#other-action">>
                 <<listbox 2 with the correct source>>
          <</replace>>
     <<elseif [other condition]>>
          [repeat code above but with the wanted source]
    <<else>>
         [for the third condition]
    <</if>>
<</listen>>

Note: you will need to add the custom macro to your JavaScript for it to work!

After some search, I managed to do something using my first intent (script and JQuery).

$(document).one(
    ":passagerender", 
    function (event) {
		  $(event.content).find("select#listbox--warrioraction").on("change", function (event) {
        switch(State.getVar("_warriorAction")) {
          case "Attack":
            $("#warriorTarget").empty().wiki('<<listbox "_warriorTarget">><<optionsfrom _enemyTargets>><</listbox>>');
            break;
          case "Heal":
            $("#warriorTarget").empty().wiki('<<listbox "_warriorTarget">><<optionsfrom _allyTargets>><</listbox>>');
            break;
          default:
            $("#warriorTarget").empty().wiki('<<listbox "_warriorTarget">><<optionsfrom _selfTarget>><</listbox>>');
            break;
        };
		  });
	  }
  );

However, I’ll gladly take a macro that would do a similar job, but with cleaner. Thanks for the link. I’ll check it out.

Not directly answering the question, but I’d strongly suggest some interaction mechanism that isn’t a listbox.

Listboxes are fiddly to use, especially on mobile. They slow down interaction, and they conceal the choices available until clicked. Using them for something requiring repetitive input, like a combat system, will only magnify those issues.

My suggestion is a series of icons (or words, if icons don’t suit) in a grid. Have them set up so that clicking one in a group highlights it and dims the others … basically like a series of radio buttons. I think that is conceptually the same as a listbox, but a lot more accessible.

Of course, if there’s a dozen choices per step, that might not work.