• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Javascript that only targets groups that have a specific callout

Explorer ,
Jun 24, 2024 Jun 24, 2024

Copy link to clipboard

Copied

Hi there – I have a scripting problem outlined below but not sure if its even possible.

Is it possible use javascript to loop through all groups in a document and then target the group that contains the word “CALLOUT” with a find replace GREP to remove some pricing? And not touch the groups that don’t contain the  “CALLOUT” . The callout text box and the text box with the pricing are independent  of each other.

 

FIND was \$\d+(\.\d{2})? now \$\d+(\.\d{2})? & delete.

 

If possible what would that javascript look like

image.png

The group on the left does not contain the callout and the group items on the right does.
There could be many of these groups in a document.

 

Any help appreciated.

TOPICS
Scripting

Views

326

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Jun 26, 2024 Jun 26, 2024

Hey - I think this might fix it - sorry don't have time to test it properly

// Undo the script if needed
app.doScript(searchCallout, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Search Callout');

function searchCallout() {
    var res = getTextSearch("CALLOUT");
    var pg, tf;
    for (var i = 0; i < res.length; i++) {
        // Check if the result has parent text frames and if its parent is a group
        if (res[i].parentTextFrames.length > 0) {
            pg = res[i].p
...

Votes

Translate

Translate
Community Expert ,
Jun 24, 2024 Jun 24, 2024

Copy link to clipboard

Copied

Hey

 

Give this a go

// Main function
function main() {
    // Get the active document
    var doc = app.activeDocument;

    // Loop through all groups in the document
    for (var i = 0; i < doc.allPageItems.length; i++) {
        var group = doc.allPageItems[i];

        // Check if the item is a group
        if (group instanceof Group) {
            // Check if the group contains a text frame with the word "CALLOUT"
            if (groupContainsCallout(group)) {
                // Perform GREP find and replace to remove pricing
                removePricing(group);
            }
        }
    }

    alert("Pricing removal complete.");
}

// Function to check if a group contains a text frame with the word "CALLOUT"
function groupContainsCallout(group) {
    for (var j = 0; j < group.allPageItems.length; j++) {
        var item = group.allPageItems[j];

        // Check if the item is a text frame
        if (item instanceof TextFrame) {
            // Check if the text frame contains the word "CALLOUT"
            if (item.contents.indexOf("CALLOUT") !== -1) {
                return true;
            }
        }
    }
    return false;
}

// Function to remove pricing using GREP find and replace
function removePricing(group) {
    for (var j = 0; j < group.allPageItems.length; j++) {
        var item = group.allPageItems[j];

        // Check if the item is a text frame
        if (item instanceof TextFrame) {
            // Perform GREP find and replace to remove pricing
            var grepFind = "(was \\$\\d+(\\.\\d{2})? now \\$\\d+(\\.\\d{2})?)\\s";
            var grepReplace = "";
            app.findGrepPreferences.findWhat = grepFind;
            app.changeGrepPreferences.changeTo = grepReplace;

            item.changeGrep();
            
            // Clear GREP preferences
            app.findGrepPreferences = NothingEnum.nothing;
            app.changeGrepPreferences = NothingEnum.nothing;
        }
    }
}

// Run the main function
main();

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 25, 2024 Jun 25, 2024

Copy link to clipboard

Copied

Another approach to the one used by @Eugene Tyson is that instead of looping all the groups in the document we can run a find query to find "Callout" then for the results see if the result is part of a textframe whose parent is a group.

Another change that could be done is iterate just the textframes of the group instead of allPageItems. Both these suggestions could speed up the process.

-Manan

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 25, 2024 Jun 25, 2024

Copy link to clipboard

Copied

Thanks @Eugene Tyson your script works great.

I have added smoe fuctionality to either proces the current document or all open documents.

// Main function
function main() {
    var scope = userInput();
    var foundCALLOUT = false;

    // Loop through the selected scope
    if (scope instanceof Array) {
        for (var i = 0; i < scope.length; i++) {
            foundCALLOUT = processDocument(scope[i]) || foundCALLOUT;
        }
    } else {
        foundCALLOUT = processDocument(scope);
    }

    if (foundCALLOUT) {
        alert("CALLOUT product pricing updated.");
    } else {
        alert("No CALLOUT product groups found.");
    }
}

// Function to process a document
function processDocument(doc) {
    var foundCALLOUT = false;

    // Loop through all groups in the document
    for (var i = 0; i < doc.allPageItems.length; i++) {
        var group = doc.allPageItems[i];

        // Check if the item is a group
        if (group instanceof Group) {
            // Check if the group contains a text frame with the word "CALLOUT"
            if (groupContainsCallout(group)) {
                foundCALLOUT = true;
                // Perform GREP find and replace to remove pricing
                removePricing(group);
            }
        }
    }

    return foundCALLOUT;
}

// Function to check if a group contains a text frame with the word "CALLOUT"
function groupContainsCallout(group) {
    for (var j = 0; j < group.allPageItems.length; j++) {
        var item = group.allPageItems[j];

        // Check if the item is a text frame
        if (item instanceof TextFrame) {
            // Check if the text frame contains the word "CALLOUT"
            if (item.contents.indexOf("CALLOUT") !== -1) {
                return true;
            }
        }
    }
    return false;
}

// Function to remove pricing using GREP find and replace
function removePricing(group) {
    for (var j = 0; j < group.allPageItems.length; j++) {
        var item = group.allPageItems[j];

        // Check if the item is a text frame
        if (item instanceof TextFrame) {
            // Perform GREP find and replace to remove pricing
            var grepFind = "(was \\$\\d+(\\.\\d{2})? now \\$\\d+(\\.\\d{2})?)\\s";
            var grepReplace = "";
            app.findGrepPreferences.findWhat = grepFind;
            app.changeGrepPreferences.changeTo = grepReplace;

            item.changeGrep();

            // Clear GREP preferences
            app.findGrepPreferences = NothingEnum.nothing;
            app.changeGrepPreferences = NothingEnum.nothing;
        }
    }
}

// Function to get user input for the scope
function userInput() {
    var w = new Window('dialog', 'Select Scope', undefined, { closeButton: false });
    w.alignChildren = 'right';
    var p = w.add('panel {alignChildren: "left"}');
    p.add('radiobutton {text: "Active document"}');
    p.add('radiobutton {text: "All open documents"}');

    var b = w.add('group');
    b.add('button', undefined, 'Cancel');
    b.add('button', undefined, 'OK');

    // Set default selection
    p.children[0].value = true;

    if (w.show() == 1) {
        if (p.children[0].value) {
            w.close();
            return [app.activeDocument]; // Return an array with the active document
        } else {
            w.close();
            var allOpenDocs = [];
            for (var i = 0; i < app.documents.length; i++) {
                allOpenDocs.push(app.documents[i]);
            }
            return allOpenDocs; // Return all open documents
        }
    } else {
        w.close();
        exit(); // Close the script if Cancel is clicked
    }
}

// Run the main function
main();

 

 

@Manan Joshi Thanks for your input.
Is it possible to see a version of the script using your approach?

We will be processing  alot of documents at once sometimes so any speed efficiencies would be appreciated.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 26, 2024 Jun 26, 2024

Copy link to clipboard

Copied

Is it possible to see a version of the script using your approach?

 

Hi @rickt38612460, In case Manan doesn’t reply right away, here is an example:

 

//undo
app.doScript(searchCallout, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Search Callout');

function searchCallout(){
    var res = getTextSearch("CALLOUT")
    var pg, tf;
    for (var i = 0; i < res.length; i++){
        //gets the parent group—this assumes there are no nested groups
        pg = res[i].parentTextFrames[0].parent
        if (pg.constructor.name == "Group") {
            tf = pg.textFrames.everyItem().getElements()
            app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
            for (var j = 0; j < tf.length; j++){
                app.findGrepPreferences.findWhat = "(was \\$\\d+(\\.\\d{2})? now \\$\\d+(\\.\\d{2})?)\\s";
                app.changeGrepPreferences.changeTo = "";
                tf[j].parentStory.changeGrep()
            };  
        }    
    };
}

function getTextSearch(f){
    app.findTextPreferences = app.changeTextPreferences = app.findChangeTextOptions = null;
    app.findChangeTextOptions.properties = {includeHiddenLayers:true, includeLockedLayersForFind:true, includeLockedStoriesForFind:true, includeMasterPages:true} 
    app.findTextPreferences.findWhat = f;
    return app.activeDocument.findText()
}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jun 26, 2024 Jun 26, 2024

Copy link to clipboard

Copied

Thanks @rob day this works great and is alot faster but I am getting the error below – although the error didnt show up the first few time i ran it and the script still works?

 

JavaScript Error!

Error Number: 2

Error String: tf is undefined

Engine: main

File: Path to script

Callout findReplace.jsx

Line: 32

Source: tf[jl.parentStory.changeGrep;

 

Being able to undo the whole script in one go is a great addition.



 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 26, 2024 Jun 26, 2024

Copy link to clipboard

Copied

Hey - I think this might fix it - sorry don't have time to test it properly

// Undo the script if needed
app.doScript(searchCallout, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Search Callout');

function searchCallout() {
    var res = getTextSearch("CALLOUT");
    var pg, tf;
    for (var i = 0; i < res.length; i++) {
        // Check if the result has parent text frames and if its parent is a group
        if (res[i].parentTextFrames.length > 0) {
            pg = res[i].parentTextFrames[0].parent;
            if (pg.constructor.name == "Group") {
                tf = pg.textFrames.everyItem().getElements();
                if (tf.length > 0) {
                    app.findGrepPreferences = app.changeGrepPreferences = app.findChangeGrepOptions = null;
                    for (var j = 0; j < tf.length; j++) {
                        app.findGrepPreferences.findWhat = "(was \\$\\d+(\\.\\d{2})? now \\$\\d+(\\.\\d{2})?)\\s";
                        app.changeGrepPreferences.changeTo = "";
                        tf[j].parentStory.changeGrep();
                    }
                }
            }
        }
    }
}

function getTextSearch(f) {
    app.findTextPreferences = app.changeTextPreferences = app.findChangeTextOptions = null;
    app.findChangeTextOptions.properties = { includeHiddenLayers: true, includeLockedLayersForFind: true, includeLockedStoriesForFind: true, includeMasterPages: true };
    app.findTextPreferences.findWhat = f;
    return app.activeDocument.findText();
}

 

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jun 27, 2024 Jun 27, 2024

Copy link to clipboard

Copied

If Eugene’s fix doesn’t work, can you share the document that throws the error?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Jul 02, 2024 Jul 02, 2024

Copy link to clipboard

Copied

LATEST

Thanks @Eugene Tyson  @rob day  This works and I have marked it as the correct answer.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines