Find and replace script with content of other fields

Hello,

@Joris_Grouillet made me this script to search for {tag} and replace by the tag column.
Am in urgent need of some changes but don’t want to be too much of a burden so I ask here.

Could someone please help me modify the script so that:

  • It replaces every occurence of a match in a cell
    (e.g. if there is {name} twice in a cell, it replaces both and not just the first it finds)

  • It searches for tags in […] rather than {…}

  • it searches and replace in place rather than in an additional field.
    (i.e. it uses the same field for template and destination)

  • If possible, it is dynamic and uses regex to find any tag in […] and replace it with the matching column.

I urgently need the first enhancement, the rest are more for the convenience of my workflow.

Here is the script:

(async ({ record_id }) => {

    
    async function getClientById(recordId, clientsTable){
        const queryResult = await clientsTable.selectRecordsAsync({
            fields: ['nom', 'code', 'ville', 'template_message']        
        }); // get all records in Clients table
        return queryResult.getRecord(recordId)   
    }

    function makeMessageFromTemplate(template, client){
        const mapTagsAndValues = {
            'nom' : { value: client.getCellValueAsString("nom") },
            'code' : { value: client.getCellValueAsString('code') },
            'ville' : {value: client.getCellValueAsString('ville'), options: { uppercase: true } }
        }

        function applyOptions(value, options){
            if ((options ?? {})?.uppercase === true) {
                return value.toUpperCase();
            }
            return value;
        }
        return Object.entries(mapTagsAndValues).reduce((messageToWrite, [tag, { value, options }]) => {
            return messageToWrite.replace(`{${tag}}`, applyOptions(value, options));        
        }, template);
    }
        
    const clientsTable = base.getTable("CEDT");
    const clientFound = await getClientById(record_id, clientsTable);
    console.log('clientFound : ', clientFound);
    // ci-dessous : ne pas passer par getCellValueAsString() : il supprime le formattage markdown
    const template = clientFound.getCellValue('template_message');
    console.log('template : ', template)

    const message = makeMessageFromTemplate(template, clientFound);
    console.log('message final : ', message);

    await clientsTable.updateRecordAsync(clientFound, { message })    
})(input.config())

Thank you very much for your help :innocent:

[quote=“Joachim_Brindeau, post:1, topic:50729”]

        return Object.entries(mapTagsAndValues).reduce((messageToWrite, [tag, { value, options }]) => {
            return messageToWrite.replace(`{${tag}}`, applyOptions(value, options));        
        }, template);

   return Object.entries(mapTagsAndValues).reduce((messageToWrite, [tag, { value, options }]) => {
   const replaceAll=(x,y,z)=>x.split(y).join(z)       
  return replaceAll( messageToWrite, `[${tag}]`, applyOptions(value, options) );        
        }, template);

Just a quick fix for 1 and 2, but I have no time to dig into code (and I don’t like ‘reduce’ operator) , so I can’t guarantee it will work

1 Like

Thank you so much for your help!
Here is an improved version solving 1 and 2:

(async ({ record_id }) => {
   
    async function getClientById(recordId, clientsTable){
        const queryResult = await clientsTable.selectRecordsAsync({
            fields: ['nom', 'code', 'ville', 'medecin', 'template_message']        
        }); // get all records in Clients table
        return queryResult.getRecord(recordId)   
    }

    function makeMessageFromTemplate(template, client){
        const mapTagsAndValues = {
            'nom' : { value: client.getCellValueAsString("nom") },
            'code' : { value: client.getCellValueAsString('code') },
            'ville' : {value: client.getCellValueAsString('ville') },
            'medecin' : {value: client.getCellValueAsString('medecin') },
        }

        function applyOptions(value, options){
            if ((options ?? {})?.uppercase === true) {
                return value.toUpperCase();
            }
            return value;
        }
        return Object.entries(mapTagsAndValues).reduce((messageToWrite, [label, { value, options }]) => {
            return messageToWrite.replaceAll(getLabelAsTag(label), applyOptions(value, options));        
        }, template);
    }

    function getLabelAsTag(value, leftDelimiter ='{', rightDelimiter = '}'){
        return [leftDelimiter, value, rightDelimiter].map(elm => elm.trim()).join('');
    }
        
    const clientsTable = base.getTable("CEDT");
    const clientFound = await getClientById(record_id, clientsTable);
    console.log('clientFound : ', clientFound);
    // ci-dessous : ne pas passer par getCellValueAsString() : il supprime le formattage markdown
    const template = clientFound.getCellValue('template_message');
    console.log('template : ', template)

    const message = makeMessageFromTemplate(template, clientFound);
    console.log('message final : ', message);

    await clientsTable.updateRecordAsync(clientFound, { message })    

})(input.config())```

I’m a bit curious. does it really have native replaceAll function?

Well it works so yes apparently :sweat_smile:

1 Like