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

Text Fields Not Updating

Why isn't this working? HTML row in a grid that repeats four more times (save_1, save_2, etc.): < input type = 'number' min = '1' max = '20' value = '13' title = '@{save_1_base}' name = 'attr_save_1_base' /> < input type = 'number' min = '-20' max = '0' value = '0' title = '@{save_1_mod}' name = 'attr_save_1_mod' /> < input type = 'number' readonly title = '@{save_1}' name = 'attr_save_1' /> Sheet worker that is triggered by a change to a global save bonus modifier elsewhere on the sheet: // Save Bonus // Apply save bonus to all saving throw modifiers // Then, recalculate all saving throw targets on('change:class_save_bonus', function(eventInfo) {     const output = {};     getAttrs(['class_save_bonus', 'save_1_base', 'save_2_base', 'save_3_base', 'save_4_base', 'save_5_base'], function(values) {         const saveBonus = parseInt(values.class_save_bonus) || 0;         for (var i = 1; i < 6; i++) {             theBaseValue = parseInt(values['save_' + i + '_base']) || 0;             output['save_' + i + '_mod'] = -saveBonus;             output['save' + i] = Math.max(1, theBaseValue - saveBonus);             console.log('output: ' + output['save' + i]);         };     });     setAttrs(output); }); (Note that in this game system, everything is a "throw", meaning bonuses are subtracted from the target, then rolled against.) The function iterates through the five sets of fields to calculate and set values. I'm able to update these fields from a sheet worker, individually, if/when the player changes the Base or the Mod value. I've validated that all getAttrs values are being collected, as expected. I can see, via the console.log, that the output array contains the correct, calculated values. I've taken out the readonly attribute on the third <input> field just in case but same issue. Issue: Neither the 'save_X_mod' or 'save_X' input fields are updating in the UI. Is this some kind of UI bug or asynchronous issue?
1700266212
vÍnce
Pro
Sheet Author
Is this line correct? output['save' + i] = Math.max(1, theBaseValue - saveBonus); or should it include the underscore?  ie output['save_' + i]
1700267869
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Vince has the answer. Also, I would recommend using template literals for simple concatenation. It is much easier to read (at least in my opinion):             output[`save_${i}_mod`] = -saveBonus;             output[`save_${i}`] = Math.max(1, theBaseValue - saveBonus);
vÍnce said: Is this line correct? output['save' + i] = Math.max(1, theBaseValue - saveBonus); or should it include the underscore?  ie output['save_' + i] No, it isn't. Thank you. However, that doesn't address the issue, either - neither set of text fields are updating. So, I've reduced the sheet worker down to this... on('change:class_save_bonus', function(eventInfo) {     const output = {};     getAttrs(['class_save_bonus', 'save_1_base', 'save_2_base', 'save_3_base', 'save_4_base', 'save_5_base'], function(values) {         const saveBonus = parseInt(values.class_save_bonus) || 0;         for (var i = 1; i < 6; i++) {             output['save_' + i + '_mod'] = -saveBonus;         };     });     setAttrs(output); });
1700272911
GiGs
Pro
Sheet Author
API Scripter
I've noticed that text fields sometimes dont update properly, until you close the sheet and reopen it. Does that work for you?
1700281464
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Oh, I see the problem. Your setAttrs call is outside of the callback in getAttrs. The sheetworker functions are asynchronous and must be done in callbacks. It should be this: on('change:class_save_bonus', function(eventInfo) { const output = {}; getAttrs(['class_save_bonus', 'save_1_base', 'save_2_base', 'save_3_base', 'save_4_base', 'save_5_base'], function(values) { const saveBonus = parseInt(values.class_save_bonus) || 0; for (var i = 1; i < 6; i++) { output['save_' + i + '_mod'] = -saveBonus; };     setAttrs(output); }); });
Scott C. said: Oh, I see the problem. Your setAttrs call is outside of the callback in getAttrs. The sheetworker functions are asynchronous and must be done in callbacks.  Duh. That appears to have been the problem. That's what I get for slicing together multiple functions to get to this point (sloppy coding on my part). Early on, there were two, nested getAttrs functions in the code block. Obviously, that didn't work, but that's why it was structured the way it was. Here's the new function (using template literals ;) on('change:class_save_bonus', function(eventInfo) {     getAttrs(['class_save_bonus', 'save_1_base', 'save_2_base', 'save_3_base', 'save_4_base', 'save_5_base'], function(values) {         const saveBonus = parseInt(values.class_save_bonus) || 0;         const output = {};         for (var i = 1; i < 6; i++) {             theBaseValue = parseInt(values[`save_${i}_base`]) || 0;             output[`save_${i}_mod`] = -saveBonus;             output[`save_${i}`] = Math.max(1, theBaseValue - saveBonus);         };         setAttrs(output);     }); }); Thanks, all!