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

[sheet worker] getAttr and SetAttrs

1534205548

Edited 1534205665
Mike W.
Pro
Sheet Author
I am having some trouble coding the following when a character sheet is opened (I am brand new to HTML and CSS and JavaScript) I have an attribute named attr_modifier It can have one of two values; Either it  equals: ?{Modifier|0} Or it equals: ?{Modifier|0} +?{Shock|0} +?{Reeling or Staggered|0} + ?{Off-Hand|0} + ?{Familiarity|0} If it equals: ?{Modifier|0}, I need to change it to: [[?{Modifier|0}]] If it equals: ?{Modifier|0} +?{Shock|0} +?{Reeling or Staggered|0} + ?{Off-Hand|0} + ?{Familiarity|0}, I need to change it to: [[?{Modifier|0}]] +[[?{Shock|0}]] +[[?{Reeling or Staggered|0}]] + [[?{Off-Hand|0}]] + [[?{Familiarity|0}]] I know the code starts as; on('sheet:opened', function() { I started the rest of the code (but I know it is all wrong) getAttr([‘attr_modifier’], function(v){ if(v. attr_modifier)== ?{Modifier|0} { setAttrs({attr_modifier})== [[?{Modifier|0}]]; } if(v. attr_modifier)==?{Modifier|0} +?{Shock|0} +?{Reeling or Staggered|0} + ?{Off-Hand|0} + ?{Familiarity|0}{ setAttrs({attr_modifier})== [[?{Modifier|0}]] +[[?{Shock|0}]] + [[?{Reeling or Staggered|0}]] + [[?{Off-Hand|0}]] + [[?{Familiarity|0}]]; } } I really need some help here- Thanks.
1534208186
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Well, doesn't help with your actual question, but why do you need this? It sounds like this attribute is either a select or radio. If you set the attribute like that, you're going to deselect whatever the user has selected. Why not just set the possible values of the attribute to be in inline roll format to begin with?
1534208415

Edited 1534208497
Mike W.
Pro
Sheet Author
It is a radio. The reason I need this is I am changing the value in the selection. For those people who already have a value chosen, the new values do not match and thus their macro will not function properly unless they reelect. I am trying to do this for them automatically..
1534209380

Edited 1534209412
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Ah, gotcha. I'm back on my computer, so now I can actually show some code :). There's several issues with your code getAttr([‘attr_modifier’], function(v){ if(v. attr_modifier)== ?{Modifier|0} {//Not sure if this is just copy paste error, but you've got a space between "v." and attr_modifier                                               //also, the "attr_" is not used when working with attributes, it simply tells the tabletop to make an attribute with the appropriate name                                               //and finally, your comparison is outside of your if declaration, should be "if(v.modifier==='?{Modifier|0}'){"                                               //You'll also note that I used === instead of ==. This is to avoid erroneous positives when the type of the variable is different. setAttrs({attr_modifier})== [[?{Modifier|0}]];//setAttrs expects an object with key:value pairs where the key is the attribute name and the value is the attribute value. You're also attempting to do a comparison between the setAttrs and the value you want. } if(v. attr_modifier)==?{Modifier|0} +?{Shock|0} +?{Reeling or Staggered|0} + ?{Off-Hand|0} + ?{Familiarity|0}{ setAttrs({attr_modifier})== [[?{Modifier|0}]] +[[?{Shock|0}]] + [[?{Reeling or Staggered|0}]] + [[?{Off-Hand|0}]] + [[?{Familiarity|0}]]; } } You can also do this without needing the if statements. Here's how I'd do it, taking the corrections above into account: getAttrs(['modifier'], function(v){ const setObj = {}; setObj.modifier = v.modifier.replace(/(^|[^\[])\?/g,'$1[[?').replace(/}([^\]]|$)/g,'}]]$1'); setAttrs(setObj,{silent:true}); });
1534209816
Mike W.
Pro
Sheet Author
Scott C. said: Ah, gotcha. I'm back on my computer, so now I can actually show some code :). There's several issues with your code getAttr([‘attr_modifier’], function(v){ if(v. attr_modifier)== ?{Modifier|0} {//Not sure if this is just copy paste error, but you've got a space between "v." and attr_modifier                                               //also, the "attr_" is not used when working with attributes, it simply tells the tabletop to make an attribute with the appropriate name                                               //and finally, your comparison is outside of your if declaration, should be "if(v.modifier==='?{Modifier|0}'){"                                               //You'll also note that I used === instead of ==. This is to avoid erroneous positives when the type of the variable is different. setAttrs({attr_modifier})== [[?{Modifier|0}]];//setAttrs expects an object with key:value pairs where the key is the attribute name and the value is the attribute value. You're also attempting to do a comparison between the setAttrs and the value you want. } if(v. attr_modifier)==?{Modifier|0} +?{Shock|0} +?{Reeling or Staggered|0} + ?{Off-Hand|0} + ?{Familiarity|0}{ setAttrs({attr_modifier})== [[?{Modifier|0}]] +[[?{Shock|0}]] + [[?{Reeling or Staggered|0}]] + [[?{Off-Hand|0}]] + [[?{Familiarity|0}]]; } } You can also do this without needing the if statements. Here's how I'd do it, taking the corrections above into account: getAttrs(['modifier'], function(v){ const setObj = {}; setObj.modifier = v.modifier.replace(/(^|[^\[])\?/g,'$1[[?').replace(/}([^\]]|$)/g,'}]]$1'); setAttrs(setObj,{silent:true}); }); Yeah mostly pasting errors and forgetting things, old age, life interruptions, etc, so I realize my code is terrible. Yours is so much simpler and way above my pay grade and I do nto understand it at all but will try it out.
1534210611

Edited 1534210623
Mike W.
Pro
Sheet Author
OK worked partially for the ?{Modifier|0} to [[?{Modifier|0}]]  alone it worked fine but for the ?{Modifier|0} +?{Shock|0} + ?{Reeling or Staggered|0} + ?{Off-Hand|0} + ?{Familiarity|0} to [[?{Modifier|0}]] +[[?{Shock|0}]] + [[?{Reeling or Staggered|0}]] + [[?{Off-Hand|0}]] + [[?{Familiarity|0}]] it did not work (note sure what value it placed there as I cannot figure out your code)
1534213507

Edited 1534214746
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Hmm, ok, what did it set the value to? You could try this instead (this is actually a better way to do it anyways): getAttrs(['modifier'], function(v){ const setObj = {}; //make an empty object. I prefer making an object that will then be used for the setAttrs rather than manually assembling it. setObj.modifier = v.modifier.replace(/(^|[^\[])(\?{.+?})($|[^\]])/g,'$1[[$2]]$3'); //set the "modifier" property of the setObj to be equal to the value of modifier replacing the non inline roll version with the inline roll version setAttrs(setObj,{silent:true}); //Set the attributes and don't trigger sheetworker on('change:...') events from this change.                                         //This is the same thing as doing setAttrs({modifier:'correct string'}); }); As for what this is, don't let the strange syntax between the forward slashes fool or scare you. This is just using regular expressions to match and replace specific strings. I like to use regexr.com  to test regex patterns and learn more about them.
1534214262
Mike W.
Pro
Sheet Author
Scott C. said: Hmm, ok, what did it set the value to? You could try this instead (this is actually a better way to do it anyways): getAttrs(['modifier'], function(v){ const setObj = {}; //make an empty object. I prefer making an object that will then be used for the setAttrs rather than manually assembling it. setObj.modifier = v.modifier.replace(/(^|[^\[])(?{.+?})($|[^\]])/g,'$1[[$2]]$3'); //set the "modifier" property of the setObj to be equal to the value of modifier replacing the non inline roll version with the inline roll version setAttrs(setObj,{silent:true}); //Set the attributes and don't trigger sheetworker on('change:...') events from this change.                                         //This is the same thing as doing setAttrs({modifier:'correct string'}); }); As for what this is, don't let the strange syntax between the forward slashes fool or scare you. This is just using regular expressions to match and replace specific strings. I like to use regexr.com  to test regex patterns and learn more about them. I do not know what value it set from your first code. Your second really has me confused but I will trust you on this.
1534214851

Edited 1534214970
Mike W.
Pro
Sheet Author
Scott I really appreciate your help but I am afraid that has made matter worse. Whatever the value it is setting the Modifier to, it does not match any of the Radio selections. I realize your code is much more sophisticated then I can ever do but is there a way to to make t  more simpler and exact values that I can just type in? This also would help that if in he future I may have to change some of these names because of other modification in the pipe. Opening  the console log I see this; SyntaxError: Invalid regular expression: /(^|[^\[])(?{.+?})($|[^\]])/: Invalid group     at Object.eval [as -LI9j5Bx0fp0Lmvc1UKH//false//0.010372578532258814] (eval at messageHandler (sheetsandboxworker.js?1534214581435:548), <anonymous>:21:33)     at _fullfillAttrReq (sheetsandboxworker.js?1534214581435:523)     at messageHandler (sheetsandboxworker.js?1534214581435:555) sheetsandboxworker.js?1534214581435:581 SyntaxError: Invalid regular expression: /(^|[^\[])(?{.+?})($|[^\]])/: Invalid group     at Object.eval [as -LI9j5Bx0fp0Lmvc1UKH//false//0.010372578532258814] (eval at messageHandler (sheetsandboxworker.js?1534214581435:548), <anonymous>:21:33)     at _fullfillAttrReq (sheetsandboxworker.js?1534214581435:523)     at messageHandler (sheetsandboxworker.js?1534214581435:555)
1534215334

Edited 1534215829
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Just realized, I had an invalid pattern in that regex. Edited the code in the post to be correct. So, let's break down what the regular expression is looking for. There are three capturing groups in the regex expression. A capturing group is just a subset of the pattern that will be returned as an individual result in the array of results and are denoted by parentheses wrapping. The groups are: (^|[^\[]) This group looks for the beginning of the string (the ^ before the bar), or a character that is not an opening square bracket (the [^\[] ) (\?{.+?}) This group looks for a question mark (the \?, question marks have to be escaped like this because they have special meaning in regex), followed by an opening curly brace followed by 1 or more characters, ending at the first closing curly brace encountered (the question mark here tells the regex to match as few characters as possible) ($|[^\]]) This group looks for the end of the string (the $) or a non closing square bracket (the [^\]] ). Taken altogether these will look for a roll query that is not wrapped in inline brackets. Then there is the second argument of the replace function: "$1[[$2]]$3". This is a string that tells the replace function to take capturing group 1 and put it at the start of the string followed by two opening square brackets. Then follow this with capture group 2 and two closing square brackets. Finally put capture group 3 at the end. It may be easier to see how this all works by seeing the pattern in action .
1534215378

Edited 1534215667
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Mike W. said: Scott I really appreciate your help but I am afraid that has made matter worse. Whatever the value it is setting the Modifier to, it does not match any of the Radio selections. I realize your code is much more sophisticated then I can ever do but is there a way to to make t  more simpler and exact values that I can just type in? This also would help that if in he future I may have to change some of these names because of other modification in the pipe. Opening  the console log I see this; SyntaxError: Invalid regular expression: /(^|[^\[])(?{.+?})($|[^\]])/: Invalid group     at Object.eval [as -LI9j5Bx0fp0Lmvc1UKH//false//0.010372578532258814] (eval at messageHandler (sheetsandboxworker.js?1534214581435:548), <anonymous>:21:33)     at _fullfillAttrReq (sheetsandboxworker.js?1534214581435:523)     at messageHandler (sheetsandboxworker.js?1534214581435:555) sheetsandboxworker.js?1534214581435:581 SyntaxError: Invalid regular expression: /(^|[^\[])(?{.+?})($|[^\]])/: Invalid group     at Object.eval [as -LI9j5Bx0fp0Lmvc1UKH//false//0.010372578532258814] (eval at messageHandler (sheetsandboxworker.js?1534214581435:548), <anonymous>:21:33)     at _fullfillAttrReq (sheetsandboxworker.js?1534214581435:523)     at messageHandler (sheetsandboxworker.js?1534214581435:555) Sorry, didn't get my post done soon enough. I had made an error in the regex pattern in the code. See my post right above this. Edit: You could certainly do this with if's: getAttrs(['modifier'], function(v){ const setObj = {};         if(v.modifier===' ?{Modifier|0}'){             setObj.modifier = '[[?{Modifier|0}]]'         }else if(v.modifier===' ?{Modifier|0} +?{Shock|0} + ?{Reeling or Staggered|0} + ?{Off-Hand|0} + ?{Familiarity|0} '){             setObj.modifier = '[[?{Modifier|0}]] +[[?{Shock|0}]] + [[?{Reeling or Staggered|0}]] + [[?{Off-Hand|0}]] + [[?{Familiarity|0}]]'         } setAttrs(setObj,{silent:true}); });
1534216906
Mike W.
Pro
Sheet Author
I figures out why the multiple inline entries we not working there was a space missing from  +? {Shock|0}, should have been  + ? {Shock|0}, that was why the strings were not matching. Of all things. Scott again thank you so very very much for your time. All is working now as intended. Mike
1534219746
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Excellent to hear, and you're welcome. Just passing on what the community has taught me. Pay it forward!