Repeating Section Function Library

The original Function Library showcases some functions and code snippets that are generally useful in sheet workers. This post will do the same for Repeating Sections, specifically.

Each function is listed with an accompanying explanation, explaining what is happening. Then at the end of the post, all the functions are listed together without the explanations, to make it easy to to copy abd past them into the start of your script block. You can then use them in any sheet worker after them. They don’t do anything unless they are called, so you can sdafely include them in any script block.

This is probably the most widely and easily used function. It has been used extensively in posts on this site.

const section_name = (section, id, field) => 
   `${section.startsWith('repeating_') ? section : 
       `repeating_${section}`}_${id}_${field}`;Code language: JavaScript (javascript)

This is a confusing looking function but it is used very easily. You often need to type an attribute name like:

const field = 'repeating_example_-fghw47gh5hw_field'

With this function, you can instead type:

const field = section_name('example', '-fghw47gh5hw', 'field');

That’s not a huge difference. The real advantage comes when you are working with variables. The row id is often variable, so that might be:

const field = section_name('example', id, 'field');

And it gets more potent. You might be filling all the sections with variables, like

const section = 'gear';
getSectionIDs(`repeating_${section}`, ids => {
   const fields = ['weight', 'quantity', 'container'];
   /* loop through each row id than each field and do something with them */
   ids.forEach(id => {
      const weight_properties = {};
      fields.forEach(field => {
          weight_properties[field] = values[section_name(section, id, field);
      });
   });Code language: JavaScript (javascript)

Obviously this is into a full or complete code block. It’s just to show the potential. Think things through for your need.


Combined Code Block

The functions listed here are examples of code. Copy this into your Script Block to use all the functions listed here. Just delete any you don’t need, or use this listing as inspiration for creating your own.

/* combine elements to create a full section attribute name *.
const section_name = (section, id, field) => 
   `${section.startsWith('repeating_') ? section : 
       `repeating_${section}`}_${id}_${field}`;

/* break a full repeating section attribute name into its parts */
const section_parts = (full_name, part='section') => {
   let [stub, section, row, ...field] = full_name.split('_');
   if(part === 'section'|| part === 1) return section;
   else if(part === 'row' || part === 'id' || part === 2) return row;
   else return field.join('_');
}

/* watch changes to build an event changes string */
const section_changes = section_object => {
   let output = '';
   Object.keys(section_object).forEach((key, index) => {
     if(index) section += ' ';
     section_object[key].forEach(field => {
       output += key === 'globals' ? field : `repeating_${key}:${field}`;
     });
   });
   return output;
};

/* add together the sum of multiple columns (can be just one) in section */
const sum_section = (section, ids, fields) => {
    if (!Array.isArray(fields)) fields = [fields.replace(/\s/g, '').split(',')];
    let total = 0;
    const getValue = (section, id, field) => v[`repeating_${section}_${id}_${field}`] === 'on' ? 1 : parseFloat(v[`repeating_${section}_${id}_${field}`]) || 0;
    ids.forEach(id => {
        let subtotal = 1;
        fields.forEach(field => subtotal *= getValue(section, id, field));
        total += subtotal;
    });
    return total;
};

/* operate on multiple repeating sections at a time, getting a data object
   which contains data.fields and data.each_section */
const getSectionObject = (sections, callback) => {
    const fields_object = {};
    fields_object.fields = [];
    let keys = Object.keys(sections);
    const burndown = () => {
        let section = keys.shift();
        getSectionIDs(`repeating_${section}`, ids => {
            ids.forEach(id => 
               sections[section].forEach(field => 
                  fields_object.fields.push(`repeating_${section}_${id}_${field}`)));
            fields_object[section] = ids;
            if(keys.length) {
                burndown();
            } else {
                callback(fields_object);
            }
        });
    };
    burndown();
};Code language: JavaScript (javascript)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.