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

Dynamic Editing of Handout Tables

Hi Folks, I am currently trying to set up my item database for our The Witcher TRPG group. I am struggeling with editing my handouts according to a user specific Input. In the end I want to achieve something like the following: I can successfully click on "Weapons". This will open a command prompt asking me for additional filters, e.g rarity. After this I know how to make an API call with the selected filter option. Something like this "!displayWeapons --filter someFilterArgument". Within my API I defined my state object to hold my item database as a JSON struct e.g.: state.Weapons = {        'Iron Long Sword': {skill: 'swordsmanship', type: 'S/P', accuracy: 0, availability: 'E', damage: "2d6+2", reliability: 10, hands: 2, range: "N/A", effect: "", concealment: "L", encumbrance: 0, weight: 1.5, cost:160, info: "Some info"}     //Some other stuff } No I want to sort in every entry from my filter query into the table of the handout. I had a look through the forums for the last 3 hours and I was not able to find a hint on how to edit tables in a handout. So let me summarize my Questions: My Goal 1) My Goal is the creation of a internal compendium for my players where they are able to have a quick look at the items available. My Questions 1) How do I create and edit a table in a handout via the API? 2) Is holding item information a correct intend to use of the struct? 3) Is there any way to get a real button inside of a handout? Thanks for your advice and if you need more information please ask and I will provide everything you need ;-) Best regards and happy gaming! Julian
1619185483
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
1 is totally possible, however, you can't edit the existing table. You need to essentially rebuild the table each time. You can get the current handout contents and use that to build from. I'll try and post some example code when I'm not on mobile. 2. I would not recommend storing your item database in the state. The state has a max size of ~2mb shared between all scripts. Is your database dynamic? Or static? 3. Depends what you mean by a real button. You can do journal command buttons, although keep in mind these will not work if the handout is popped out into its own window.
1619185930
The Aaron
Roll20 Production Team
API Scripter
The content of a Handout, from the API's point of view, is just HTML.  To make a table, you simply create the right HTML elements to make it. While you can put that in the state, it might be better to store it somewhere else.  The state is specific to that game, so if you create a new game, you'll have to recreate that information, or find some way to export it and import it.  If you store it in a Roll20 Object (say as a Base64 encoded JSON string in the GM Notes of your handout), then it will naturally move to other games when you copy this one, or use the Transmogrifiier.  The State is also limited in size (I think it's 2Mb total), so you can end up filling it up and then you get some weird behavior (truncation).  Another option is to store the information as attributes on a special character, or possibly abilities. I'm not completely sure what you mean by "real button", but you can certainly style an anchor tag to look like a button in a handout.
1619188955
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
And, simple demo code: //Assuming you have a handout assigned to a variable known as helpObj helpObj.set({ notes: `<table> <tr> <th>Table header</th> </tr> </table` }); Note that you would probably want to assemble the handout text outside of the set, and if there is other content of the handout that you want to preserve, you'll need to get the notes value first and then replace as needed.
1619191053

Edited 1619191111
timmaugh
Pro
API Scripter
As a database guy, I have lamented the lack of a serializable data structure at the game level. For instance, you could have an "Inventory" character Mule using attributes as your item entries, but that only gives you 2 data points to track (current and max), and you have to maintain the mapping of what they represent (current is the color, and max is the value... no... current is the time it takes a goat to digest it, and max is the minimum size of said goat... no... wait...). What you would need is the ability to create ad hoc repeating sections on a sheet, where you can designate the fields of a row. And that's what we lack. Sooooo... you know... if you're inclined... you might think about giving this a "configuration" front-end to set up field names for a custom application, and a query structure for your filters that isn't specific to any particular field names (but take what the user provides). Just, you know... if you might ever want to... I don't know... share it. ;-)
Hey folks! Thanks for your fast replies and sorry I am coming back so late :-) Holiday even in times of Corona is quite busy :-/ @Scott and Aaron: Thank you for the reply. A very helpfull hint is the fact, that I have to rebuild the table from scrath but that is fine. I already have an idea on how to solve this issue. Also I did not know, that html code parsed via the set method will automatically translate to the corresponding visual front-end behavior e.g. displaying a table. This will also be helpfull. Regarding the state... the 2MB limit is also a very nice hint :-D @timmaugh Sooooo... you know... if you're inclined... you might think about giving this a "configuration" front-end to set up field names for a custom application, and a query structure for your filters that isn't specific to any particular field names (but take what the user provides). This one is a little bit hard for me to understand. What do you mean by "configuration front-end". I have a lot of programming experience in C++ and Python but I am lacking the ability to create UI elements in Roll20 apart from the prompts you can open using macros. If I want to create a filter query do I need to use a really annoying combination of different macros opening single prompts and storing the return value? Or is there any other more ... elegant way... on fetching some user inputs? Another way i could think of for filter options is a single prompt saying something like: Enter filter options and seperate them by semicolon. Possible options are:     Rarity(E/C/P/R)     CostLess(xxx)     CostMore(xxx)     Weapons     ... The user then may enter a written command Rarity(P);CostLess(300);Weapons The internal query will seperate the string and filter the objects accordingly. I would love to jsut have checkboxes and value fields ... I don't know if the thoughts are going in your direction but I think this might be the most suitable solution right now without access to custom UI elements. According to filling the database: I thought about Aarons suggestion and just create handouts for the different sections e.g. "database_Weapons" and "database_General Goods". Each row in the handout is a JSON string corresponding to one item. The Buttons in the public database handout may then be fetched by iterating over all handouts in the game getting those with the prefix "database_". The table created on button click without any filters will then be filled according to the union of different keys in all of the JSON strings. This way anyone should be able to use the script and only needs to fill their database_Handouts with the content. Feel free to leave any ideas comments and critics on my thoughts before I dive into the development. Best regards and happy gaming! Julian
1619705902
timmaugh
Pro
API Scripter
Opening caveat : this is just to explain where my brain went... not saying anything about what you should/shouldn't do, nor that you hadn't already thought of these things... You probably have! Just trying to present the whole picture of what I saw as the potential. Do with this as you will. =D Creating Imagining a table structure in a handout, you could get it there a few different ways.  You could construct it elsewhere and paste it. You could construct it elsewhere and import it (though a parser you write). You could create in manually in the handout. You could create it through wizard-y queries where the API creates it. And then there are the hybrids. Obviously any solution where the data is preconstructed and then pasted/imported sort of renders this portion of the process moot, provided that everything gets into the handout properly formatted (ie, you can't have 3 header rows, Aaron. You just can't. So stop trying. It doesn't work like that. Because Julian said so!) To handle the ad hoc, in-game creation and maintenance of a new table, I'd some sort of brief wizard of interrogatives. API Command 1 =>     What is the name of your new table?     How many fields do you want to start with? Based on the answer to the second question, the API would then construct a new command line and assign it to a button in the chat interface, full of that many interrogatives for field names. The command line would also store the table name, so the script could pick that back up when the user clicked the button and answered the queries... API Command 2 =>     What is the name for field 1?     What is the name for field 2?     ...etc... If you wanted to get even funkier, you could allow for certain schema data to be associated with the fields -- either in a sibling table or in the first row of the primary table. For instance, the fields "Rarity" and "Realm" (below) have a limited list of entries they will accept: Item    | Type | Rarity    | Material | Cost | Realm -------------------|------------------|------------------|-----------|---------------------------------------    | | VR, R, N, C, VC | | | Destiny, Gardening, Astral, Elemental -------------------|------------------|------------------|-----------|--------------------------------------- The Odetch | Hairpin | VR | Jade | 200 | Destiny Secateurs of Might | Pruning Shears | R | Alloy | 50 | Gardening Once you had all of that, you can create the table. Presentation and Buttons You could have a handout button in the header row, to the right of the last column name, for "New Column"... which would ask for the name of the new field (and any associated schema data, if you were implementing that). Each row could have a "Delete" button in the same location in their row (at the end) to remove that item from the table... and/or one for "Edit" (if you needed to manage user interaction). At the top and bottom you could have an "Add Item" button, which would present the queries for the various field entries, reading the schema as necessary to turn a standard input into a drop-down of choices ("Rarity" would be read to have 5 options, "Realm" to have 4). In fact, the "Edit" line button is really the same thing, just prefilled with the data from the associated line. Querying/Reporting Let the user input their query, as you said, but then I would suggest a recursive descent parser to extract the field names and their comparison. I use something very analogous in APILogic... allowing for these comparisons: a = b // equals a != b // does not equal a > b // is greater than a >= b // is greater than or equal a < b // is less than a <= b // is less than or equal a ~ b // includes a !~ b // does not include ... and logical sugar... (...)   //  grouping &&    // logical AND ||      // logical OR That lets the user do things like: Material = Jade && Realm = Destiny && Cost <=300 The resulting entries could be output to chat in a nice interface with buttons that allow for actions on that item... you could have some pre-built button functionality the table-owner could choose to implement with this table... like "Acquire" (copy to the Speaker's character sheet) or "Edit" or "Delete" (if you're on the handout's access list). Meta Application Once you know the rules of architecture around how you'd store data (the rules that are behind all such tables derived from your script), you could write an access scriptlet as a meta-script to return a particular data point from the table based on a user's query input. If the script sees a particular syntax in the command line, it triggers a search to return the requested datapoint, and replaces all of that inline syntax with the data before the message is handed off to the intended-recipient script: !somescript --price|{& askjulian [Market Bazarre].[Price] Material=Jade && Realm=Destiny} Your meta-script would take everything in the {& askjulian ...} construction, and return the Price of the first item made from Jade that deals with Destiny magic from the table "Market Bazarre". By the time the recipient script (somescript) saw the message, the command line (contents) would read: !somescript --price|200 ... ...Not that I've thought about this a bunch, or anything. =D Like I said, old database guy, irked that there isn't a customizable, serializable data construct at the game level... specifically for things like inventories, treasure hordes, or whatever.