Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Add new skill to repeating attributes

1485993073
GiGs
Pro
Sheet Author
API Scripter
I have created a script to populate a character sheet with random and preset stats. But there are a couple of repeating sections, that I dont know how to add new values to. For example, one of the Repeating sections is pretty simply defined as follows (with irrelevant css and other stuff removed) <fieldset class="repeating_Skill" >         <input name="attr_SkillName" type='text' value="skill name">         <input  type="number" name="attr_SkillValue" value="0" /> </fieldset> This script will only be run on for new character, where I can guarantee each repeating section will be empty when the script is run. What script process do i need to add one or more new entries (skillname and skillvalue, in this example) to this repeating set?  
1485993698
The Aaron
Pro
API Scripter
You need to generate a rowid (I've got the code for that somewhere), then create two attributes of the form: repeating_Skill_ROWID_skillname repeating_Skill_ROWID_skillvalue Having the same RowID will make them part of the same row. 
1485998027

Edited 1485998112
Kryx
Pro
Sheet Author
API Scripter
With fear of adding confusion I'll provide my generate skills function for 5e. It's built with es6 and some wrapper functions around roll20's getters and setters, but it should give you the idea: EDIT: This is sheet workers, but you could use a similar process for API, just replace the calls. const SKILLS = { ACROBATICS: 'dexterity', ANIMALHANDLING: 'wisdom', ARCANA: 'intelligence', ATHLETICS: 'strength', DECEPTION: 'charisma', HISTORY: 'intelligence', INSIGHT: 'wisdom', INTIMIDATION: 'charisma', INVESTIGATION: 'intelligence', MEDICINE: 'wisdom', NATURE: 'intelligence', PERCEPTION: 'wisdom', PERFORMANCE: 'charisma', PERSUASION: 'charisma', RELIGION: 'intelligence', SLEIGHTOFHAND: 'dexterity', STEALTH: 'dexterity', SURVIVAL: 'wisdom', }; const getIdOfRepeatingString = repString => repString.substring(repString.lastIndexOf('_') + 1); const getSkillIdByStorageName = (data, repStrings, prop) => { let returnId; for (const repString of repStrings) { if (data[`${repString}_storage_name`] === prop || data[`${repString}_storage_name`] === camelize(prop)) { returnId = getIdOfRepeatingString(repString); break; } } return returnId; }; generateSkills() { getSetRepeatingItems('initialize.generateSkills', { repeatingItems: ['repeating_skill'], collectionArrayAddItems: ['storage_name', 'name', 'ability'], callback: (data, repStrings) => { Object.keys(SKILLS).forEach((skill) => { let skillId = getSkillIdByStorageName(data, repStrings, skill); if (!skillId) { skillId = generateRowID(); } const repString = `repeating_skill_${skillId}`; data[`${repString}_storage_name`] = skill; data[`${repString}_name`] = getTranslationByKey(skill); data[`${repString}_ability`] = getFormattedAbility(SKILLS[skill]); abilityChecks.updateSkill(skillId); }); }, setFinalAttrsCallback: () => { abilityChecks.updateMacro(); }, }); } on('sheet:opened', () => { this.generateSkills(); });
1486005576
GiGs
Pro
Sheet Author
API Scripter
The Aaron said: You need to generate a rowid (I've got the code for that somewhere), then create two attributes of the form: repeating_Skill_ROWID_skillname repeating_Skill_ROWID_skillvalue Having the same RowID will make them part of the same row.  I just stumbled across an older, simpler way of doing it. With an empty repeating set, you can apparently use 0 for the first ROWID, 1 for the second row, 2 for the 3rd, etc.  Are there problems doing it this way that I'm setting myself up for down the line? It has the advantage of not needing code to build a UUID for the rowID.
1486005755
GiGs
Pro
Sheet Author
API Scripter
I'm storing that code for later study, Kryx. I am wondering why its in the Sheet:Opened event, wouldn't that run every time someone opens the sheet?
1486009710
The Aaron
Pro
API Scripter
Using a 0 causes problems. It needs an id that is unique across all characters or weird things happen. They changed the way they were doing it a year or so ago, so the older code may have issues.  The reason the code is in open:sheet is that it's the earliest event available. 
1486011612
The Aaron
Pro
API Scripter
Here is where I posted the generateRowID() function for API:&nbsp; <a href="https://app.roll20.net/forum/permalink/3037403/" rel="nofollow">https://app.roll20.net/forum/permalink/3037403/</a>
1486014505
GiGs
Pro
Sheet Author
API Scripter
about the sheet:open - i just wondered why you'd want a routine that builds a skill list running every time the sheet opens, rather than just once. I must be missing something about the function's purpose.
1486015405
GiGs
Pro
Sheet Author
API Scripter
The Aaron said: Using a 0 causes problems. It needs an id that is unique across all characters or weird things happen. They changed the way they were doing it a year or so ago, so the older code may have issues.&nbsp; The reason the code is in open:sheet is that it's the earliest event available.&nbsp; Can you be more specific about what strange things happen? In your linked thread Kevin mentioned something about not being able to sort or delete repeating items from the character sheet, but I'm not seeing that issue. Did he mean in using the API, or manually? If it just causes a problem with API manipulating the items after creation, I'm fine with that. For this campaign, there'll be no need to do any of that once the character sheets are created.
1486018233
GiGs
Pro
Sheet Author
API Scripter
Interesting. I've found that names in the form repeating_skills_$0_SkillName cause the problem described in the linked thread, but names in the form repeating_skills_0_SkillName do not, in my limited testing. I'm not really clear what the $ does in the first format.
1486019307
Jakob
Sheet Author
API Scripter
G G said: Interesting. I've found that names in the form repeating_skills_$0_SkillName cause the problem described in the linked thread, but names in the form repeating_skills_0_SkillName do not, in my limited testing. I'm not really clear what the $ does in the first format. $0 always refers to the top row even after reordering, whereas 0 is treated like a rowid. But you can't use $0 directly in the API (except in getAttrByName). Trying to create a repeating attribute with id &nbsp;$0 leads to a broken repeating row :). I think rows with a 0 can't be reordered, at least.
1486022350

Edited 1486022939
GiGs
Pro
Sheet Author
API Scripter
Thanks for the explanation of $0. You do seem to be able to reorder attributes created by the other method. I created a repeating set with 4 entries, using _0_ to _3_ and was able to reorder them. I refreshed the page and reopened the sheet, and the new ordering remained. My suspicion is that the simple rowID (0, 1, 2 3,) is every bit as functional as the UUID, and that there is no difference between them at all. I think the UUID method was introduced to solve the problem of conflicting IDs: when you add new rows, then delete some, then add more, it gets very hard to avoid duplicating a previous rowID without extensive error checking code. Creating a guaranteed unique ID upfront avoids all that, and its simpler for roll20 when their backend can automate it easily. But for a user who is creating a completely new sheet, and knows every field is empty, is there any drawbcak to using the simple 0, 1, 2, 3 method? It avoids the need to add extra code for the UUID generation, which seems to be unnecessary in this use case.
1486039014

Edited 1486039130
The Aaron
Pro
API Scripter
Sheet:open -- There is no event for "character created" and you can't prepopulate repeating rows. &nbsp;The earliest point you can create the rows so that the sheet doesn't come up "broken" is in Sheet:open. &nbsp;Sheet:open only happens the first time a sheet is opened in a session, so it's not going to be firing THAT often. &nbsp;Also, he's probably got a check in that functionality to short circuit if it doesn't need to run. RowID 0 -- The issue is that there is a flat namespace for repeating rows. &nbsp;Open a second character and start adding rows in each where the row ids are not unique. &nbsp;You will likely see the values being changed in ways you don't intend. &nbsp;At a minimum, you will see the wrong values being returned for getAttr calls.
1486043627
GiGs
Pro
Sheet Author
API Scripter
Sheet:open - makes sense. RowID - interesting, thanks for being patient. I'll do some testing about that when I have time later. I only checked one character at a time.
1486047471
Kryx
Pro
Sheet Author
API Scripter
The Aaron said: Also, he's probably got a check in that functionality to short circuit if it doesn't need to run. I do indeed have such a check. Sorry for the misdirection in that regard. It's hard to share just a small bit of code and give the full picture of what I'm doing.
1486117747

Edited 1486117926
GiGs
Pro
Sheet Author
API Scripter
Aaron, I've hit a snag with that UUID generating code. I have noticed sometimes it fails to set values, and the only thing i can see, is that in every case the UUID generated has an underscore in it. For instance, this UUID:&nbsp;-Kc2SMYFpyoBWPBMbg_8 and this one:&nbsp;-Kc2TndlP_QKF7OEqSrU I've run my script dozens of times now to test, and I'm gettign those underscores reasonably often, and every time there is one, the set command fails. I see this in your code "return generateUUID().replace(/_/g, "Z");" that looks like it should be replacing the underscores, though i dont understand regex. If that is what its for, any idea why it wouldnt be working for me? Also, side question: if that is meant to replace the underscores, why not just remove them from that big source string in the main body first?&nbsp;
1486127298
The Aaron
Pro
API Scripter
Are you calling generateRowID() or generateUUID() ? And to be clear, that's not MY code, that's the actual functions in the sheet worker code for Roll20, I just dug it out. If it were my code, I would fix the off-by-one error that causes it to always start with a -, as well as the _ to Z and make it only lowercase (since all attribute names are case insensitive and the RowID is part of the repeating attribute's name). That said, it shouldn't cause a problem.&nbsp;
1486129073
GiGs
Pro
Sheet Author
API Scripter
ahhh, I'm calling&nbsp;generateUUID(), I see now I should be calling the other one. I wondered why it always started with a "-".