Copy link to clipboard
Copied
I am trying to write a script that opens a dialog so the user can choose if colums and gutter should be adjusted. This is ment for tesing. I want to take this further later on but at the moment I am stuck with this simple task. The dialog works fine and the columns part works fine but I can’t merge it together successully. Where is my mistake?
3 Correct answers
quick troubleshooting help. try using a try/catch alert to help identify where some problems might be happening. here's what I did.
i took the mp.columnGutter=4 line and changed it to
button2.onClick = function () {
// Set gutter
alert(mp.columnGutter)
try{
//mp.columnGutter = 2;
} catch (e){alert(e.message)}
alert(mp.columnGutter)
// Set column count
//mp.columnCount = 12;
dialog.close();
}
This alerts back that the column gutter cant be interacted with because "a modal dialog is still active
...Hi @Daniel268281559oj9 , For simple dialogs like this I use InDesign’s built-in dialog object—less code. This creates integer only edit boxes:
//variables for columns and gutter
var cn, g;
var theDialog = app.dialogs.add({name:"Edit Columns", canCancel:true});
with(theDialog.dialogColumns.add()){
//dialog labels
staticTexts.add({staticLabel:"Number of Columns:"});
staticTexts.add({staticLabel:"Gutter:"});
}
with(theDialog.dialogColumns.add()){
//integer boxes
cn = integerE
Daniel -- The problem with your script is that it moans about a modal dialog or alert that's open. That's the alert that your script shows. You can get around that by using RobOctopus's approach, but in general the solution is to use a palette-style window instead of a dialog window. That's all, so change
var dialog = new Window("dialog");
to
var dialog = new Window("palette");
And you may have to define a target engine, which you do by adding this line at the top of your script:
#targetengine s
...
Copy link to clipboard
Copied
quick troubleshooting help. try using a try/catch alert to help identify where some problems might be happening. here's what I did.
i took the mp.columnGutter=4 line and changed it to
button2.onClick = function () {
// Set gutter
alert(mp.columnGutter)
try{
//mp.columnGutter = 2;
} catch (e){alert(e.message)}
alert(mp.columnGutter)
// Set column count
//mp.columnCount = 12;
dialog.close();
}
This alerts back that the column gutter cant be interacted with because "a modal dialog is still active" so I moved the dialog.close to be at the top of the onclick function. despite the dialog being "closed" it still wasnt functioning and so i rewrote how the buttons are working and wrapped it into a function to close the dialog before interacting with indesign. in this instance the buttons are only returning whether you hit ok or cancel. you can rewrite the entire onclick functions to be instead.
var button1 = group2.add("button", undefined, undefined, {name: "Cancel"});
button1.text = "Cancel";
var button2 = group2.add("button", undefined, undefined, {name: "Ok"});
button2.text = "OK";
if(dialog.show()==1){
dialog.close()
return true
} else {
dialog.close()
return false
}
by default scriptUI will return 1 on a button assigned to the OK name. this allows you to have the dialog.show() code return back as 1 which == 1 and then return true out of the function. So the entire script looked like this at the end
var doc = app.activeDocument;
var selectedPage = doc.pages.item(0);
var mp = selectedPage.marginPreferences;
var temp = getColumnGutterDialog()
if(temp){
mp.columnGutter = 4;
mp.columnCount = 12;
}
function getColumnGutterDialog(){
var dialog = new Window("dialog");
dialog.text = "Columns and Gutter";
dialog.preferredSize.width = 400;
dialog.orientation = "column";
dialog.alignChildren = ["left","top"];
dialog.spacing = 10;
dialog.margins = 16;
// GROUP1
// ======
var group1 = dialog.add("group", undefined, {name: "group1"});
group1.orientation = "row";
group1.alignChildren = ["left","top"];
group1.spacing = 30;
group1.margins = 0;
var statictext1 = group1.add("statictext", undefined, undefined, {name: "statictext1"});
statictext1.text = "Adjust to 12 Columns, Gutter 4?";
// GROUP2
// ======
var group2 = dialog.add("group", undefined, {name: "group2"});
group2.orientation = "row";
group2.alignChildren = ["left","center"];
group2.spacing = 10;
group2.margins = [0,20,0,0];
group2.alignment = ["right","top"];
var button1 = group2.add("button", undefined, undefined, {name: "Cancel"});
button1.text = "Cancel";
var button2 = group2.add("button", undefined, undefined, {name: "Ok"});
button2.text = "OK";
if(dialog.show()==1){
dialog.close()
return true
} else {
dialog.close()
return false
}
} /* end of dialog function */
Alternative approach, you can probably change the dialog window type to a palette and interact with indesign and not notice this interaction at all.
Hope this helps!
Copy link to clipboard
Copied
Thnak you very much. Very good approach and testing idea! I keep it in mind as my script evolves.
Copy link to clipboard
Copied
Hi @Daniel268281559oj9 , For simple dialogs like this I use InDesign’s built-in dialog object—less code. This creates integer only edit boxes:
//variables for columns and gutter
var cn, g;
var theDialog = app.dialogs.add({name:"Edit Columns", canCancel:true});
with(theDialog.dialogColumns.add()){
//dialog labels
staticTexts.add({staticLabel:"Number of Columns:"});
staticTexts.add({staticLabel:"Gutter:"});
}
with(theDialog.dialogColumns.add()){
//integer boxes
cn = integerEditboxes.add({editValue:12, maximumValue:100, minimumValue:2, minWidth:100});
g = integerEditboxes.add({editValue:4, maximumValue:100, minimumValue:0, minWidth:100});
}
if(theDialog.show() == true){
//the returned dialog values
cn = cn.editValue;
g = g.editValue;
//the function to run
setColumns()
theDialog.destroy();
}
function setColumns(){
//using Points for the gutter dimension
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
var doc = app.activeDocument;
var selectedPage = doc.pages.item(0);
var mp = selectedPage.marginPreferences;
mp.columnCount = cn;
mp.columnGutter = g;
app.scriptPreferences.measurementUnit = AutoEnum.AUTO_VALUE;
}
Copy link to clipboard
Copied
Thank you, it works perfectly. In my case units are mixed. Gutter 4 produces 4pt Gutter = 1,411 mm. I´ll find an adjustment for that 🙂
Copy link to clipboard
Copied
I´ll find an adjustment for that 🙂
Another reason I prefer the InDesign dialog class is, it is easy to enforce dialog data types. So here I’ve set g to a measurementEditbox, which lets the user enter any kind of unit—4mm, 4in, 4px, etc. The returned units are automatically converted to Points:
//variables for columns and gutter
var cn, g;
var theDialog = app.dialogs.add({name:"Edit Columns", canCancel:true});
with(theDialog.dialogColumns.add()){
//dialog labels
staticTexts.add({staticLabel:"Number of Columns:"});
staticTexts.add({staticLabel:"Gutter:"});
}
with(theDialog.dialogColumns.add()){
//integer box
cn = integerEditboxes.add({editValue:12, maximumValue:100, minimumValue:2, minWidth:100});
//measurement box. Here the default unit is from the document’s horizontal ruler setting
g = measurementEditboxes.add({editUnits:app.activeDocument.viewPreferences.horizontalMeasurementUnits, editValue:0, minWidth:100});
}
if(theDialog.show() == true){
//the returned dialog values
cn = cn.editValue;
g = g.editValue;
//the function to run
setColumns()
theDialog.destroy();
}
function setColumns(){
//the returned value for a measurementEditbox is converted to Points,
//so use Points for the script
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
var doc = app.activeDocument;
var selectedPage = doc.pages.item(0);
var mp = selectedPage.marginPreferences;
mp.columnCount = cn;
mp.columnGutter = g;
app.scriptPreferences.measurementUnit = AutoEnum.AUTO_VALUE;
}
Copy link to clipboard
Copied
Ive never used the indesign dialog class, and frankly the look of the code is more confusing than scriptUI's. I use scriptUI since it has been more universal across Ai/Indd/Ps. Something I have started to use in some of my scripts is the UnitValue conversion function that's built in.
UnitValue(100,"mm").as("pt")
This allows you to convert any number into other values.
https://extendscript.docsforadobe.dev/extendscript-tools-features/specifying-measurement-values.html
So a handful of my windows have been set up like so. any value can be entered and any unit can be used and on the return it'll just grab the value and the dropdown selection to convert them to whatever needs to be used. This was mostly an illustrator thing since you're forced to used pts.
Copy link to clipboard
Copied
Hi @RobOctopus , I didn‘t mean to imply one shouldn’t use ScriptUI—both have pros and cons. With the measurementEditbox you don’t need the added dropdown, all of InDesign‘s ruler unit abbreviations work.
Copy link to clipboard
Copied
Daniel -- The problem with your script is that it moans about a modal dialog or alert that's open. That's the alert that your script shows. You can get around that by using RobOctopus's approach, but in general the solution is to use a palette-style window instead of a dialog window. That's all, so change
var dialog = new Window("dialog");
to
var dialog = new Window("palette");
And you may have to define a target engine, which you do by adding this line at the top of your script:
#targetengine session;
Rob Day's solution is correct but uses InDesign's own dialog system, which is entirely different but may suit your purpose better.
Copy link to clipboard
Copied
> all of InDesign‘s ruler unit abbreviations work.
That can be handled in ScriptUI as well, see e.g. in this script:
https://creativepro.com/files/kahrel/indesign/page_set-up.html
Copy link to clipboard
Copied
Thanks Peter, you certainly can do more with scriptUI—it’s the measurementEditbox one liner that I prefer when building simple dialogs.
Not that it matters much now that newspapers are dead, but for some reason UnitValue doesn’t work with Agates and Ciceros—ag and c return errors.

