Copy link to clipboard
Copied
Hi all, I have several indesign projects of 8 pages that have been previously created, each project has around 100 checkboxes. I need to change the appearance of all the checkboxes, I there an easy way to do this - Change them all at the same time? or do I have to manually copy and paste the new checkbox (With the changed appearance) for each one?
Thanks in advance.
Copy link to clipboard
Copied
Hi @Deefadog, try this script I wrote. But there's a little preparation first:
1. Open all your eight documents.
2. Create an object style that styles a checkbox they way you want.
3. Copy that object style into all your documents (eg. paste and then delete a checkbox into each.)
4. Edit my script, this line:
var objectStyleName = 'Put the name of your style here!'
5. Run my script (listed below).
Let me know how you go.
- Mark
/**
* Apply object style to all checkBoxes of all open documents.
* @author m1b
* @discussion https://community.adobe.com/t5/indesign-discussions/scripting-find-all-form-fields-and-remove/m-p/14000885
*/
function main() {
// you must specify the name of your object style:
var objectStyleName = 'My Style';
var thingPlural = 'checkBoxes',
docs = app.documents,
counter = 0;
for (var i = docs.length - 1; i >= 0; i--) {
if (!docs[i].saved)
continue;
var doc = docs[i],
things = doc[thingPlural].everyItem().getElements(),
objectStyle = getThing(doc.allObjectStyles, 'name', objectStyleName);
if (undefined == objectStyle) {
alert('Sorry no object style "' + objectStyleName + '" found in document "' + doc.name + '".');
continue;
}
if (doc.groups.length > 0)
// also collect things in groups
things = things.concat(doc.groups.everyItem()[thingPlural].everyItem().getElements());
if (doc.stories.length > 0) {
// also collect any anchored things
things = things.concat(doc.stories.everyItem()[thingPlural].everyItem().getElements());
if (doc.stories.everyItem().tables.length > 0)
// also collect any thing in tables
things = things.concat(doc.stories.everyItem().tables.everyItem().cells.everyItem()[thingPlural].everyItem().getElements());
}
// apply the object style
for (var j = things.length - 1; j >= 0; j--) {
if (things[j].isValid) {
things[j].applyObjectStyle(objectStyle, true, false);
counter++;
}
}
}
alert('Applied object style to ' + counter + ' checkboxes.');
} // end main
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Apply Object Style to CheckBoxes');
/**
* Returns a thing with matching property.
* @param {Array|collection} things - the things to look through, eg. PageItems.
* @param {String} key - the property name, eg. 'name'.
* @param {*} value - the value to match.
*/
function getThing(things, key, value) {
for (var i = 0; i < things.length; i++)
if (things[i][key] == value)
return things[i];
};
Copy link to clipboard
Copied
m1b, you're a genius! If you attending Adobe Max later this year, i will buy you a drink or several for sure!
It does work with the styles perfectly! But it does not bring across the appearance settings of that check box, which are: Normal On - Normal off - Click On - Click Off.
I guess as these are not a style more an interactive function?
I am not sure if they can be implemented into the script?
Copy link to clipboard
Copied
CheckBox have few a collection o States - but I dont see there what you've listed?
StateTypes.DOWN
StateTypes.DOWN_OFF
StateTypes.DOWN_ON
StateTypes.ROLLOVER
StateTypes.ROLLOVER_OFF
StateTypes.ROLLOVER_ON
StateTypes.UP
StateTypes.UP_OFF
StateTypes.UP_ON
Or Normal would be UP and Click would be DOWN?
If those are correct ones - then it can be scripted.
Copy link to clipboard
Copied
Thanks, Robert, Yes,"Or Normal would be UP and Click would be DOWN?" I think that would be correct.
Copy link to clipboard
Copied
Hi @Deefadog, unfortunately I won't be at Max this year, but I do appreciate the thought! 😁
Okay it was simplistic of me to think that a single object style could work on a multi-state checkbox! It is still fairly easy to do—but the tricky part is knowing what to target for the object style.
I've re-written the script above (for my own benefit—the effect is the same) so that it is easier to re-purpose and fiddle with. I've also, *as an example* targeted the first rectangle in both the "Normal On" and "Normal Off" states. You can think of states as basically separate groups, that each hold some number of further page items. So it depends on the page items that your checkboxes actually contain as to how we target them and which need object styles applied to them.
To try the new script, do this:
1. Create objects styles on the checkbox square for "on" and "off" style called "CheckBox On" and "CheckBox Off"
2. Run script.
And have a look at the doToThing function to see how I targetted the checkbox square.
- Mark
Here's the revised script:
/**
* Apply object style to all checkBoxes of all open documents.
*
* To use, first configure the parameters given to `doSomethingToThings`.
* See function documentation below.
* @author m1b
* @discussion https://community.adobe.com/t5/indesign-discussions/can-you-change-the-appearance-of-multiple-checkboxes-the-same-time-in-an-indesign-document/m-p/14453805
*/
function main() {
// you must specify the name of your object style:
var counter = 0,
onStyle,
offStyle;
doSomethingToThings({
target: app.documents,
thingPlural: 'checkBoxes',
doToDocument: function (doc) {
onStyle = getThing(doc.allObjectStyles, 'name', 'CheckBox On');
offStyle = getThing(doc.allObjectStyles, 'name', 'CheckBox Off');
if (!onStyle || !offStyle)
return alert('Missing object style in document "' + doc.name + '".');
return true;
},
doToThing: function (thing, doc) {
var target1 = thing.states.itemByName('Normal On').pageItems[0].rectangles[0],
target2 = thing.states.itemByName('Normal Off').pageItems[0].rectangles[0];
if (
!target1.isValid
|| !target2.isValid
)
return;
target1.applyObjectStyle(onStyle, true, false);
target2.applyObjectStyle(offStyle, true, false);
counter++;
},
});
alert('Applied object style to ' + counter + ' checkboxes.');
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Apply Object Style To CheckBoxes');
/**
* Executes a function for every thing
* in the document or documents.
* `thingPlural` is a Document property name,
* for example 'formFields' or 'swatches'.
* @author m1b
* @version 2024-02-29
* @param {Object} options
* @param {String} options.thingPlural - collective property of Document eg. 'checkBoxes'.
* @param {Document|Documents} [options.target] - an Indesign Document or Documents (default: active document).
* @param {Function} [options.doToDocument] - a function to be executed for each document (default: do nothing).
* @param {Function} [options.doToThing] - a function to be executed for each thing (default: do nothing).
*/
function doSomethingToThings(options) {
options = options || {};
var doc = options.target || app.activeDocument,
thingPlural = options.thingPlural,
doToDocument = options.doToDocument,
doToThing = options.doToThing;
if ('Documents' === doc.constructor.name) {
for (var i = 0; i < doc.length; i++) {
options.target = doc[i];
doSomethingToThings(options);
}
return;
}
// do something to document
if (undefined != doToDocument)
if (!doToDocument(doc))
return;
var things = getThingsFromDocument(doc, thingPlural) || [];
// do something to things
for (var i = things.length - 1; i >= 0; i--)
if (undefined != doToThing)
doToThing(things[i], doc);
};
/**
* Returns array of things found in `doc`.
* `thingPlural` is a Document property name,
* for example 'formFields' or 'swatches'.
* @author m1b
* @version 2024-02-29
* @param {Document} doc - an Indesign Document.
* @param {String} thingPlural - collective property of Document eg. 'checkBoxes'.
* @returns {?Array<*>} - the things.
*/
function getThingsFromDocument(doc, thingPlural) {
if (
!doc.hasOwnProperty(thingPlural)
|| 'function' !== typeof doc[thingPlural].everyItem
)
return;
var things = doc[thingPlural].everyItem().getElements();
if (doc.groups.length > 0)
// also collect things in groups
things = things.concat(doc.groups.everyItem()[thingPlural].everyItem().getElements());
if (doc.stories.length > 0) {
// also collect any anchored things
things = things.concat(doc.stories.everyItem()[thingPlural].everyItem().getElements());
if (doc.stories.everyItem().tables.length > 0)
// also collect any thing in tables
things = things.concat(doc.stories.everyItem().tables.everyItem().cells.everyItem()[thingPlural].everyItem().getElements());
}
return things;
};
/**
* Returns a thing with matching property.
* @param {Array|collection} things - the things to look through, eg. PageItems.
* @param {String} key - the property name, eg. 'name'.
* @param {*} value - the value to match.
* @returns {*} - the thing.
*/
function getThing(things, key, value) {
for (var i = 0; i < things.length; i++)
if (things[i][key] == value)
return things[i];
};
Copy link to clipboard
Copied
Thank you so much (Sorry for the late reply on this).
Have a good rest of your day!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now