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

Sheetworker on-change events not firing when changes are made within a routine called by sheet:opened event.

1551852383

Edited 1551856995
Chris D.
Pro
Sheet Author
API Scripter
Compendium Curator
If you have a sheetworker routine that does stuff in the on-opened event, and that routine changes stuff, on-changed events are NOT generated for those changed things! The problem is only seen when you have a function that runs calculations when the sheet is first opened.  <!DOCTYPE html> <meta charset="UTF-8"> <div class="user-root"> <input name="attr_a" type="number" value="1" style="width: 3em;" > <input name="attr_b" type="number" value="1" style="width: 3em;" > <input name="attr_c" type="number" value="1" style="width: 3em;" > <br> <input name="attr_r1" type="number" value="0" style="width: 3em;" > <input name="attr_r2" type="number" value="0" style="width: 3em;" > </div> <script type="text/worker"> var calculateR1 = function () { 'use strict'; getAttrs(["a", "b" ], function gar1(values) { 'use strict'; let vals = {}; vals[ "r1"] = parseInt(values[ "a"]) + parseInt( values[ "b"]); log( "R1: a = " + values["a"]);    log( "b = " + values["b"]);    log( "r1 = " + vals["r1"]); setAttrs( vals); }); }; var calculateR2 = function () { 'use strict'; getAttrs(["c", "r1" ], function gar1(values) { 'use strict'; let vals = {}; vals[ "r2"] = parseInt(values[ "c"]) + parseInt( values[ "r1"]); log( "r2: c = " + values["c"]);        log( "r1 = " + values["r1"]);        log( "r2 = " + vals["r2"]); setAttrs( vals); }); }; on("change:a change:b", function () { calculateR1(); }); on("change:c change:r1", function () { calculateR2(); }); on('sheet:opened',function fnOnSheetOpened(){ 'use strict'; log( "sheet opened."); calculateR1(); }); </script> When the sheet is opened for the first time, it is supposed to do all the calculations. Now I knew that because of asynchronous issues, R1 is not going to be correct if calculateR2 is run while calculateR1 is still being processed, so I can't just put calculateR1() and calculateR2() both in the sheet:opened  event. But I trusted that when R1 was actually written out, it would generate the event that would cause calculateR2 to run. It is not.  I don't want to have calculateR1 call calculateR2 directly, because then it would be called twice in every other circumstance! So I don't really know how to work around this. It seems like every solution I try ether has it sometimes not being called, or sometimes being called twice.  Using Windows 10 and latest version of chrome. 
We're sorry to hear that you are experiencing issues with this. Please carefully work through to the first three steps of our guide to Solving Technical Issues: Step 1: Make sure to use the right browser            - Please check if these issues persist when using both Chrome and Firefox. Step 2: Ensure that there are no extensions/addons interfering with Roll20            - Please disable all add-ons/extensions. Step 3: Clear your cache If steps 1-3 does not resolve your issue, please work through step 4 and provide us with that information.
1551865551

Edited 1551865789
Chris D.
Pro
Sheet Author
API Scripter
Compendium Curator
Using Windows 10 and version  Version 72.0.3626.121 (Official Build) (64-bit)  of chrome. I don't have firefox installed so have  not tested it on that.  I have very few extensions and have disabled them all for this test.  I have cleared my cash.  Javascript is installed. I am not running any API scripts in this test.  AntiVirus is Windows defender. I also usually run Avast online security and pop-up blocker pro but these extensions and all others have been disabled. The html is exactly like it is in my top post.  I cleared the console log and opened a character sheet.  sheet opened. sheetsandboxworker.js?1551864188123:120 R1: a = 1 sheetsandboxworker.js?1551864188123:120 b = 1 sheetsandboxworker.js?1551864188123:120 r1 = 2 app.js?1551283991:545 Do refresh link cache! app.js?1551283991:551 Really updating character sheet values app.js?1551283991:551 Setting up repeating sections took until 0ms app.js?1551283991:551 Updating ALL VALUES app.js?1551283991:551 Finding list of dirty attributes took until 1ms app.js?1551283991:551 Querytest took until 1ms app.js?1551283991:551 Attribute cache compliation took until 1ms app.js?1551283991:551 Set values (including auto-calcuating variables) took until 2ms app.js?1551283991:551 Appending to screen took until 2ms app.js?1551283991:551 Took 2ms app.js?1551283991:559 Refresh Journal List! app.js?1551283991:559 Search took 10ms As you can see from this console log,   calculateR1();  is run (it logs values for a, b, and r1), but on("change:c change:r1"  never fires to run calculateR2()  (we see no log entries from that routine); If I then change field 'a',  app.js?1551283991:551 Really updating character sheet values app.js?1551283991:551 Setting up repeating sections took until 0ms app.js?1551283991:551 Finding list of dirty attributes took until 1ms app.js?1551283991:551 Querytest took until 2ms app.js?1551283991:551 Attribute cache compliation took until 2ms app.js?1551283991:551 Set values (including auto-calcuating variables) took until 2ms app.js?1551283991:551 Took 3ms sheetsandboxworker.js?1551864188123:120 R1: a = 2 sheetsandboxworker.js?1551864188123:120 b = 1 sheetsandboxworker.js?1551864188123:120 r1 = 3 app.js?1551283991:551 Really updating character sheet values app.js?1551283991:551 Setting up repeating sections took until 1ms app.js?1551283991:551 Finding list of dirty attributes took until 1ms app.js?1551283991:551 Querytest took until 2ms app.js?1551283991:551 Attribute cache compliation took until 2ms app.js?1551283991:551 Set values (including auto-calcuating variables) took until 2ms app.js?1551283991:551 Took 3ms sheetsandboxworker.js?1551864188123:120 r2: c = 1 sheetsandboxworker.js?1551864188123:120 r1 = 3 sheetsandboxworker.js?1551864188123:120 r2 = 4 app.js?1551283991:551 Really updating character sheet values app.js?1551283991:551 Setting up repeating sections took until 0ms app.js?1551283991:551 Finding list of dirty attributes took until 0ms app.js?1551283991:551 Querytest took until 1ms app.js?1551283991:551 Attribute cache compliation took until 1ms app.js?1551283991:551 Set values (including auto-calcuating variables) took until 1ms app.js?1551283991:551 Took 2ms the on:change  event for a fires (we see the log entries it generates), r1 is updated, and this causes event on:change  r1 to fire which calculates r2 (and we see the log entries it generates). This is how it should be, but this is also how it should be if r1 is updated during the sheet:open event.  So once again, if event  sheet:open   causes value r1 to be set, the on:change  r1 event does not fire. Even though it does work if  on:change  a causes value r1 to be set. 
1551883071
The Aaron
Roll20 Production Team
API Scripter
As a work around, try deferring the calculate: on('sheet:opened',function fnOnSheetOpened(){ 'use strict'; log( "sheet opened."); setTimeout(calculateR1,100); }); Probably the event handling it’s set up properly when  sheet:opened  is issued. 
1551915101
Chris D.
Pro
Sheet Author
API Scripter
Compendium Curator
Very interesting.  That seemed like a very great idea, but I got an error  sheetsandboxworker.js?1551914506929:152 Character Sheet Error: Trying to do getAttrs when no character is active in sandbox. so I tried  on('sheet:opened',function fnOnSheetOpened(){ 'use strict'; log( "sheet opened."); calculateR1(); setTimeout( function () { log( "timeout."); calculateR1();}, 1000); }); and got.  sheet opened. sheetsandboxworker.js?1551914506929:120 R1: a = 1 sheetsandboxworker.js?1551914506929:120 b = 1 sheetsandboxworker.js?1551914506929:120 r1 = 2 app.js?1551283991:545 Do refresh link cache! app.js?1551283991:551 Really updating character sheet values app.js?1551283991:551 Setting up repeating sections took until 0ms app.js?1551283991:551 Updating ALL VALUES app.js?1551283991:551 Finding list of dirty attributes took until 1ms app.js?1551283991:551 Querytest took until 2ms app.js?1551283991:551 Attribute cache compliation took until 2ms app.js?1551283991:551 Set values (including auto-calcuating variables) took until 3ms app.js?1551283991:551 Appending to screen took until 4ms app.js?1551283991:551 Took 4ms app.js?1551283991:559 Refresh Journal List! app.js?1551283991:559 Search took 14ms sheetsandboxworker.js?1551914506929:120 timeout. sheetsandboxworker.js?1551914506929:152 Character Sheet Error: Trying to do getAttrs when no character is active in sandbox. So as you can see, while sheet:op en is actually running, calculateR1() can be run and works fine, excepting that no on:change  events fire. However if you set a timeout (and I tried this with several values from 100ms up to 5000ms), it always said no character is active in sandbox. Obviously I did not close the character or do anything at all between creating the character and the timeout expiring.  Also, this is not a function of the character being created for the first time. I get the exact same results when reopening a character.  So... bizarreness. But thanks for a very great idea Aaron.  
1551921606
The Aaron
Roll20 Production Team
API Scripter
Ah, that makes unfortunate sense. It looses the context of the character in the new callstack created when the timeout expires. :(
Hi Chris,  I went ahead and forwarded this over to our devs. Thanks!
Hi everyone, This issue has been submitted to the dev team for resolution. Thank you for catching this!
Javascript onChange events are not triggered by changes made programmatically. You may be able to achieve the desired result by using a .trigger to activate the event. More information on events can be found here:&nbsp;<a href="https://api.jquery.com/on/#on-events-selector-data-handler" rel="nofollow">https://api.jquery.com/on/#on-events-selector-data-handler</a>
1552348275
The Aaron
Roll20 Production Team
API Scripter
Can we use jQuery in sheet workers?
1552349004
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Nope, only javascript, just like the API. Sheetworkers have no direct interaction with the DOM; only through the defined sheetworker functions.
1552349512

Edited 1552349588
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Shawn C. said: Javascript onChange events are not triggered by changes made programmatically. You may be able to achieve the desired result by using a .trigger to activate the event. More information on events can be found here:&nbsp; <a href="https://api.jquery.com/on/#on-events-selector-data-handler" rel="nofollow">https://api.jquery.com/on/#on-events-selector-data-handler</a> This is not actually how the sheetworker environment works; I hadn't seen this response and Aaron's response makes more sense now that I have. setAttrs({someAttribute:'SomeValue'}); will trigger the following once the sheet is opened: on('change:someAttribute',(event)=&gt;{ &nbsp;&nbsp;&nbsp;&nbsp;console.log('look mah, programmatic change triggering'); }); The bug being reported here is that changes made during a sheet:opened &nbsp;event do not do this like they should.