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 Question] Copying old attributes to new attributes from a repeating section

October 06 (7 years ago)
Nicolaj G.
Sheet Author
Hello, everyone!

I am updating a sheet and need help regarding the Sheet Worker. I have manged to copy all old attributes to new attributes, except for the attributes in repeating sections. I've tried looking for inspiration in almost every character sheet that gets attribute data from a repeating section, but to no avail. It simply does not create or copy of the rows with data in it.

What I want to do:
Copy attribute data from a repeating section with old attribute names to a repeating section with new attribute names for backwards-compatability.

How I test it:
In the sheet with the old code I have added two rows of simple text to a repeating-section (by clicking "Add" on the character sheet). I then update with new code and open the character sheet to see if the two rows with text have been added. If I return to old code, I still see the added rows.

I tried doing different things, and I simply don't know how to proceed, and hopefully someone here can help.

The old code is not done by me, so also let me know if there are any problems there that prevents me from doing what I want.
Snippet of fieldset/repeating-class from the Old sheet:
<fieldset class="repeating_krits">
	<table>
		<tr class="sheet-bb">
			<td>
				<input type="text" name="attr_krit-skador" value="0">
			</td>
		</tr>
	</table>
</fieldset>
Snippet of fieldset/repeating-class from New sheet:
<fieldset class="repeating_crits">
	<table>
		<tr class="bb">
			<td>
				<input type="text" name="attr_crit-injury">
			</td>
		</tr>
	</table>
</fieldset>
Snippet of Sheet Worker script:
<script type="text/worker">
	on('sheet:opened', function() {
	 	//crit-injury
        	getAttrs(["repeating_crits_crit-injury", "repeating_krits_krit-skador"], function(v) {
			setAttrs({
				repeating_crits_crit-injury: v.repeating_krits_krit-skador
			});
        	});
	});
</script>
This is just how it looks right now, I've tried a ton of different formats.
In the script there are of course also all the other attributes, which works fine, except for the repeating-sections.
October 06 (7 years ago)

Edited October 06 (7 years ago)
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
When working with repeating sections, you must pass the row id to getAttrs. Your problem is that there is no attribute called repeating_crits_crit-injury or repeating_krits_krit-skador, there is an attribute called something like repeating_crits_-Sfwet-56123tyquuq_crit-injury.

You'll want to use the getSectionIDs function to get these.

Something like this:
<script type="text/worker">
	on('sheet:opened', function() {
	 	//crit-injury
		var repeatRows=[],
			setObj={},
			itemIDArr;
		getSectionIDs('repeating_crits',(critsIDArr)=>{
			getSectionIDs('repeating_krits',(kritsIDArr)=>{
				itemIDArr = critsIDArr.concat(kritsIDArr);
				itemIDArr = _.uniq(itemIDArr);
				_.each(itemIDArr,(id)=>{
					repeatRows.push('repeating_crits_'+id+'_crit-injury');
					repeatRows.push('repeating_krits_'+id+'_krit-skador');
				}
				getAttrs(repeatRows, function(v) {
					_.each(itemIDArr,(id)=>{
						if(!v['repeating_crits_'+id+'_crit-injury']){
							setObj['repeating_crits_'+id+'_crit-injury']=v['repeating_krits_'+id+'_krit-skador'];
						}
					}
					setAttrs(setObj);
		        	});
			});
		});
        	
	});
</script>

Note this is untested, but is very similar to what I am using in my Starfinder HUD sheet.

Edited to properly get IDs for multiple repeating sections. Note that you may need to utilize the generateRowID function to create a new rowID since you are essentially creating a new repeating section.

I would also question why you are transitioning this if the only difference is the language that the attributes are in, I haven't gotten to this stage of my own sheet, but I believe that the translation system can handle what you are trying to do.
October 06 (7 years ago)

Edited October 06 (7 years ago)
Nicolaj G.
Sheet Author
Thank you! I will have a look at that, I was thinking it was something along those lines, but didn't know how to work with the IDs.

It's a sheet that I plan to do a great overhaul of (since all the layout is done through tables), and all the attributes were in Swedish and some were simply confusing (and the past author forgot to differentiate similar skills, so multiple attributes are updated at the same time where they shouldn't, e.g. there is a skill called "Pilot" but also a text-field called "Pilot", sharing the same attribute, where they shouldn't.).

The translation system only passes information to be translated for what is "Shown" to the players, and not for the underlying code, thus I had to translate the code to English to get an understanding of where all the attributes originate from, and to make it easier for someone in the future to continue working on it.
October 06 (7 years ago)

Edited October 06 (7 years ago)
Lithl
Pro
Sheet Author
API Scripter
Here's a snippet from the Exalted 3rd Edition sheet, where I'm converting from version 1 to version 2 of the sheet. Version 1 had 3 static "specialty" fields and a repeating section called "repspecialty". The code below moves all of them to a repeating section called "specialty":
function cleanAttrs(attrs) { return _.mapObject(attrs, function(e) { return e === undefined ? '' : e; }); }

function upgradeV1toV2() {
// TAS is TheAaronSheet:
// https://github.com/shdwjk/TheAaronSheet
TAS.debug('Upgrading from version 1');

getAttrs(['specialty1', 'specialty2', 'specialty3'], TAS._fn(function upgrade(values) {
var attrs = {},
// indexes is an array of 3 ids suitable to be used for creating new items in a repeating section
indexes = _.times(3, generateRowID);

TAS.debug('Copying specialties');
// for each generated index, if "specialtyN" has a value, move that to the "specialty" repeating section
_.each(indexes, function(id, k) {
var old = values['specialty' + (k + 1)];
if (old && old.length > 0) {
attrs['repeating_specialty_' + id + '_repspecialty'] = old;
attrs['specialty' + (k + 1)] = '';
}
});
// for each "repspecialty" item, move that value to the "specialty" repeating section
TAS.repeating('speciality')
.fields('repspecialty')
.each(TAS._fn(function copyRepeatingSpecialties(row) {
var id = generateRowID(), attrs = {};
TAS.debug(row);
attrs['repeating_specialty_' + id + '_repspecialty'] = row.repspecialty;
row.repspecialty = '';
setAttrs(cleanAttrs(attrs));
})).execute();
}));
}
October 06 (7 years ago)

Edited October 06 (7 years ago)
Nicolaj G.
Sheet Author
I will see if I can get it working. IT's all very daunting and confusing when I don't know scripting :p
October 06 (7 years ago)

Edited October 06 (7 years ago)
Nicolaj G.
Sheet Author
I got it working! I don't know if this code is spaghetti (I have never touched HTML or CSS or Javascripting before this week), but it works. I got a version-checker for it too, so it won't launch the migration all the time. Snippet of the migration for repeating_krits to repeating_crits.

 	//crit-injury
	getSectionIDs("repeating_krits", function(idarray) { //Get oldSectionID
		var setOps={};
		_.each(idarray, function(currentID, i) {
			getAttrs(['repeating_krits_' + currentID + '_krit-skador'], function(v) { //Get oldAttribute from FieldID
				var newrowid = generateRowID(); //Create object for newFieldID
				setOps['repeating_crits_' + newrowid + '_crit-injury'] = v['repeating_krits_' + currentID + '_krit-skador'];
				setAttrs(setOps); //Update
			});
		});
	});