Advanced Action Buttons

Action buttons are a great innovation, and have already been covered: Action Buttons. But there are some special considerations when action buttons are used in a repeating section.

Action Button Naming

You cannot use an underscore in the name of an action button, when in a repeating dsection.

Recall that all action button names begin act_ – that part must always be there and is notpart of the name. it is a prefix that signals to Roll20 that this is an action button.

You might be used to naming things like strength_macro (like say attr_strength_macro, or act_strength_macro). And outside of a repeating section that is fine. But inside a repeating section, that name will never trigger the button. You need to use act_strength-macro, act_strengthMacro, act_strength, or whatever – anything that gets ride of the underscore in the ability name,

This only applies to action buttons. Roll buttons and attributes can use underscores perfectly fine.

Action Buttons and Positioning

Another thing that only apples to action buttons inside of a repeating section: if you set the CSS position on an button, or container including the button, that button probably won’t work.

It’s common to use position:relative or position:absolute in more complex layouts. Dont do this with action buttons in a repeating section.

One theory put forward by Scott C is that position moves an element out of the normal CSS sequence used to layout the sheet, and roll20 fieldsets already manipulate this sequence and they don’t interact well. I find this theory persuasive. Whatever te truth, we cant use position with action buttons in a repeating section. Remember this only applies while in a repeating section.

The Macro Bar

In the last post on action buttons, we found that action buttons cannot be dragged to the macro bar. This is a feature that some players rely heavily on, and it’s irritating that you can’t do it with action buttons. Unlike many action button bugs, this isn’t limited to repeating sections – it applies to all action buttons/

But there is a way around this!

You can drag roll buttons to the macro bar, and roll buttons can launch action buttons (they are, after all just abilities). So you can create the action button, hide it, and create a roll button that includes a call to the action button.

One problem with this approach is that roll buttons post their text to chat, and all abilities in chat need to know which character they apply to. Your roll button must include the currect character name – and plays can change their name.

So this becomes a multi-step procedure:

  1. create the ability that does the work, and hide it (class=”hidden”)
  2. Create a hidden attribute, whose value will be created by a sheet worker.
  3. Create a roll button, which has a set value – the name of the above attribute.
  4. Create a sheet macro that runs whenever the character name changes, and updates all relevant attributes, to point to the correct action button.

This can be a bit complex to keep in your head, but is required by some quirks of roll20. First the roll button text cannot be changed by a sheet worker, but can call an attribute, and attribyte values can be changed.

So, first you need to create the buttons and we name them to make it easier to understand what is going on:

<button type="action" name="act_example-action" class="hidden"></button>
<input type="hidden" name="example_attribute" value ="">
<button type="roll" name="roll_example" value="@{example_attribute}"></button>Code language: HTML, XML (xml)

Notice that the attribute value is empty.

You’ll have a sheet worker that does whatever the action button does, which starts normally:

on('clicked:example-action', () => {
   //rest of sheet worker
});Code language: JavaScript (javascript)

The we create the sheet worker that creates the roll button attributes. You need an array of names of all such buttons, and can then update them.

const array_of_buttons = ['example'];
on('change:character_name', () => {
    getAttrs(['character_name'], v => {
       const character = v.character_name;
       const output = {};
       array_of_buttons.forEach(button => {
          output[`${button}_attribute`] = `%{${character}}|${button}-action}`;
       });
       setAttrs(output);
    });
});Code language: JavaScript (javascript)

This sheet worker runs whenever the character name changes (which includes when the character is first created and assigned a name), and updates all named attributes to call the correct action button.

One thing very important to realise: you can create this wheet worker once, and then forget about it. You just need to add the names of new buttons to the array at the start, and it just works on its own.

Action Buttons in a Repeating Section

This process is a bit more complicated for repeating sections, because you need to define the full name of each attribute, including the repeating section name and row id. Here’s a sheet worker that accounts for that.

This assumes you put any attributes not in a repeating section inside a global array, and each section ater that actually exists, and has an array of button names. You need the getSectionObject function install before this.

const buttons_object = {
   global: ['example'],
   section1: ['example1','example2'],
   section2: ['example3']
};
on('change:character_name', () => {
  getSectionObject(buttons_object, data => {
     getAttrs(['character_name'], v => {
       const character = v.character_name;
       const output = {};
       [...data.fields,...buttons_object.global].forEach(button => {
          output[`${button}_attribute`] = `%{${character}}|${button}-action}`;
       });
       setAttrs(output);
     });
  });
});Code language: JavaScript (javascript)

The only thing you need to change here is the buttons_object. Add your sections, attributes, and global attribute names here, and the action button calls will be created automatically.

Now players can drag their buttons to the macro bar and it just works.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.