[GastForen Programme Print/Bildbearbeitung Adobe InDesign Skriptwerkstatt Erstellen eines Script-Dialogs mit sich wiederholenden UI-Elementen

  • Suche
  • Hilfe
  • Lesezeichen
  • Benutzerliste
Print/Bildbearbeitung - Photos, Layout, Design
Themen
Beiträge
Moderatoren
Letzter Beitrag

Erstellen eines Script-Dialogs mit sich wiederholenden UI-Elementen

mdomino
Beiträge gesamt: 76

27. Sep 2014, 18:53
Beitrag # 1 von 6
Bewertung:
(2284 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Hallo zusammen,
ich bin neu hier und habe gleich eine etwas kompliziertere Frage.

Ich habe ein Script geschrieben, dessen UI-Dialog sehr viele sich wiederholende Elemente hat. Ich würde daher gerne (falls möglich) die sich gleichenden Unterdialoge mit einer Funktion erstellen. Mein Dialog sieht schematisch vereinfacht folgendermaßen aus:

Code
var myDialog = app.dialogs.add({name:"Do three different things with stuff"}); 

with(myDialog){
with(dialogColumns.add()){
var myFirstGroup = enablingGroups.add({staticLabel:"Do first thing", checkedState:true});
with (myFirstGroup){
with(borderPanels.add()){
with (dialogColumns.add()){
staticTexts.add({staticLabel:"Steps:"});
}
with (dialogColumns.add()){
var firstSteps = integerEditboxes.add({editValue:5});
}
}
}
var mySecondGroup = enablingGroups.add({staticLabel:"Do second thing", checkedState:false});
with (mySecondGroup){
with(borderPanels.add()){
with (dialogColumns.add()){
staticTexts.add({staticLabel:"Steps:"});
}
with (dialogColumns.add()){
var secondSteps = integerEditboxes.add({editValue:5});
}
}
}
var myThirdGroup = enablingGroups.add({staticLabel:"Do third thing", checkedState:false});
with (myThirdGroup){
with(borderPanels.add()){
with (dialogColumns.add()){
staticTexts.add({staticLabel:"Steps:"});
}
with (dialogColumns.add()){
var thirdSteps = integerEditboxes.add({editValue:5});
}
}
}
}
}


var myReturn = myDialog.show();

if (myReturn == true){
var myDoFirst = myFirstGroup.checkedState;
var myDoSecond = mySecondGroup.checkedState;
var myDoThird = myThirdGroup.checkedState;
var myFirstSteps = firstSteps.editValue;
var mySecondSteps = secondSteps.editValue;
var myThirdSteps = thirdSteps.editValue;

myDialog.destroy();
if(myDoFirst + myDoSecond + myDoThird != 0){
//execute main function
}
else{
alert("Nothing selected.");
}
}
else{
myDialog.destroy();
}


Wie man sieht wiederholt sich hier ein ganzer Block 3 mal (im echten Script wiederholt er sich noch öfter und hat noch mehr Unterpunkte).

Ich habe daher versucht diesen Block in eine Funktion zu packen, deren Übergabewert ein Objekt ist, in dem alle nötigen Informationen für den Block abgelegt sind. So sieht zum Beispiel eines dieser Objekte aus:

Code
var firstObject = { 
label: "Do first thing",
checkedState: true
}


Dann habe ich damit eine Funktion aufgerufen, in die ich den ganzen Code des zu ersetzenden Blocks reingepackt habe:

Code
function subDialog(object){ 
var myGroup = enablingGroups.add({staticLabel:object.label, checkedState:object.checkedState});

with (myGroup){
with(borderPanels.add()){
with (dialogColumns.add()){
staticTexts.add({staticLabel:"Steps:"});
}
with (dialogColumns.add()){
var steps = integerEditboxes.add({editValue:5});
}
}
}
}


Nun ist mir klar, dass ich das so nicht machen kann, da ich ja auch irgendwas aus der Funktion mittels return zurückgeben muss. Mir ist allerdings überhaupt nicht klar was das ist. Bei einem Testlauf scheitert das Script auch schon in der ersten Zeile der Funktion und bricht ab mit der Fehlermeldung:

Code
enablingGroups ist undefiniert 


Meine Fragen:

1. Warum ist enablingGroups hier undefiniert, funktioniert aber, wenn ich es normal im Block laufen lasse (ohne Funktion)?

2. Was muss ich aus der Funktion zurückgeben? Den ganzen Programmblock mit den eingesetzten Werten?

3. Wie könnte man denn hinterher die eingegebenen Werte auslesen?

Code
	var myFirstSteps = firstSteps.editValue; 


würde ja nicht mehr funktionieren, da alles generisch steps.editValue heißen würde, wenn es drei mal durch die Funktion erzeugt wird. Wie kann man hier in der Funktion eine Unterscheidung zwischen den drei Fällen herbeiführen?

Ist das Ganze überhaupt möglich? Oder muss man alles manuell eintippen?

Ich würde das ganze gerne dynamisch gestalten, da ein Fernziel ist, das Script so dynamisch zu programmieren, dass die Anzahl der Menüs sich automatisch aus der Länge eines Arrays mit Objekten generiert. Geht das?

Vielen Dank!

md

(Dieser Beitrag wurde von mdomino am 27. Sep 2014, 18:55 geändert)
X

Erstellen eines Script-Dialogs mit sich wiederholenden UI-Elementen

Dirk Becker
Beiträge gesamt: 174

27. Sep 2014, 20:43
Beitrag # 2 von 6
Beitrag ID: #532522
Bewertung:
(2251 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Moin,

das klingt nach einem gehobenen Einstieg in JavaScript.

Das "with" Schlüsselwort sorgt dafür, dass die Properties im übergebenen Objekt direkt in den Namensraum der lokalen Variablen eingeblendet werden.

Code
var myObject = { feld: 123 }; 
with( myObject ) $.writeln(feld);

gibt den Wert 123 aus.

Das ganze noch verschachtelt über mehrere "with", da kann man nur spekulieren oder mit dem Debugger nachsehen wo die Variable herkommt.
Ich vermute mal, die enablingGroups liegen in dem Objekt, das mit "dialogColumns.add()" erzeugt wird.

Dieser with Mechanismus funktioniert nur innerhalb des Code-Blocks (Scope), bei Aufruf einer Funktion wird ein neues Scope eröffnet.
Ein Ansatz wäre, das relevante Objekt mit in den Funktionsaufruf zu übergeben und dort mit einem neuen "with" bereitzustellen.

Code
var dialogColumn = dialogColumns.add(); 
with( dialogColumn ) {
subDialog(dialogColumn, {label: "Do first thing",checkedState: true});
}



Alternativ kann man auch die Funktion mitten im Code definieren, sie bekommt dann die lokalen Variablen der Umgebung mitgeliefert, als wären es globale Variable. Das Prinzip nennt sich "closure".

Code
with( dialogColumn ) { 
subDialog({label: "Do first thing",checkedState: true});
subDialog({label: "Do second thing",checkedState: true});
function subDialog(obj) {$.writeln(obj.label);}
}


Man sollte es damit aber nicht übertreiben, da der code sonst unübersichtlich wird. ExtendScript verliert bei closures auch gerne mal Speicher.

Btw, das "native" Dialog-System von InDesign ist ziemlich primitiv, es gibt da auch noch die Alternative ScriptUI und je nach InDesign Version noch andere.

Grüße,
Dirk


als Antwort auf: [#532520]

Erstellen eines Script-Dialogs mit sich wiederholenden UI-Elementen

Dirk Becker
Beiträge gesamt: 174

27. Sep 2014, 20:49
Beitrag # 3 von 6
Beitrag ID: #532523
Bewertung:
(2250 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Ach, da war noch eine Frage.

Für die Rückgabe aus der Funktion bietet sich die Variable myGroup an.
Also:

Code
with( dialogColumn ) { 
var myFirstGroup = subDialog(…);
var mySecondtGroup = subDialog(…);
function subDialog(obj) {
var myGroup = ...;
return myGroup;
} // function
} // with



als Antwort auf: [#532520]

Erstellen eines Script-Dialogs mit sich wiederholenden UI-Elementen

mdomino
Beiträge gesamt: 76

27. Sep 2014, 22:41
Beitrag # 4 von 6
Beitrag ID: #532524
Bewertung:
(2210 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Moin Dirk,

vielen Dank für deine Hilfe! Das funktioniert sehr gut. Das einzige, was ich nicht geschafft habe, ist meinen Eingabewert für Steps als neue Eigenschaft in das myGroup-Rückgabe-Objekt mit reinzuschreiben. Da gibt er mir eine Fehlermeldung, dass das Objekt die Eigenschaft oder Methode steps nicht unterstützt.

Ist das möglich, dass das "enablingGroups"-Objekt irgendwie "schreibgeschützt" ist?

Ich habe mir jetzt damit beholfen, dass ich am Ende der Funktion ein neues Objekt erstelle, das dann mein Rückgabe-Wert ist und aus dem ich die User-Eingabe abrufen kann. Sieht dann unten beim festlegen der Variabeln etwas seltsam aus, aber es funktioniert. Für alle, die es interessiert hier der Code:

Code
var firstObject = { 
label: "Do first thing",
checkedState: true
}
var secondObject = {
label: "Do second thing",
checkedState: false
}
var thirdObject = {
label: "Do third thing",
checkedState: false
}

var myDialog = app.dialogs.add({name:"Do three different things with stuff"});

with(myDialog){
var dialogColumn;
with(dialogColumn = dialogColumns.add()){

var myFirstGroup = subDialog(firstObject);
var mySecondGroup = subDialog(secondObject);
var myThirdGroup = subDialog(thirdObject);

function subDialog(object){

var myGroup = enablingGroups.add({staticLabel:object.label, checkedState:object.checkedState});

with (myGroup){
with(borderPanels.add()){
with (dialogColumns.add()){
staticTexts.add({staticLabel:"Steps:"});
}
with (dialogColumns.add()){
var steps = integerEditboxes.add({editValue:5});
}
}
}

var userInput = {
checked: myGroup,
steps: steps
}

return userInput;
}

}
}


var myReturn = myDialog.show();

if (myReturn == true){
var myDoFirst = myFirstGroup.checked.checkedState;
var myDoSecond = mySecondGroup.checked.checkedState;
var myDoThird = myThirdGroup.checked.checkedState;

var myFirstSteps = myFirstGroup.steps.editValue;
var mySecondSteps = mySecondGroup.steps.editValue;
var myThirdSteps = myThirdGroup.steps.editValue;

myDialog.destroy();
if(myDoFirst + myDoSecond + myDoThird != 0){
//execute main function
}
else{
alert("Nothing selected.");
}
}
else{
myDialog.destroy();
}


Vielen Dank noch einmal, Dirk!

Grüße,
md


als Antwort auf: [#532522]

Erstellen eines Script-Dialogs mit sich wiederholenden UI-Elementen

Dirk Becker
Beiträge gesamt: 174

28. Sep 2014, 11:13
Beitrag # 5 von 6
Beitrag ID: #532528
Bewertung:
(2089 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Die Vermutung stimmt, native InDesign Objekte sind gegen Erweiterungen geschützt.
Man kann auch einem Dokument nicht so einfach ein Feld "irgendwas" anhängen, das führt genauso zur Fehlermeldung.

Code
app.activeDocument.irgendwas = 47111; 


Noch ein paar Tips:
• wenn man auch die Haupt-Ausführungsebene in eine Funktion verpackt, ist das "Datenbrowser" Fenster im ESTK nicht so überfüllt.
• Klammer-Gebirge lassen sich etwas entschärfen, indem man die End-Klammern mit einem Kommentar versieht.
• ich würde im Rückgabe-Objekt die Bezeichner vereinheitlichen, also statt checked doit (do it). Die Steps benennst Du ja auch nicht "intedit" oder ähnlich.
• Noch besser kann man beide Ansätze kombinieren, also etwa doitCbx und stepsIEd.
• Die Boolean Werte myDoFirst etc. aufzusummieren funktioniert zwar, für das Verständnis besser wäre der logische "oder" Operator.

Code
if( myDoFirst || myDoSecond || myDoThird ) 


Happy programming,
Dirk


als Antwort auf: [#532524]

Erstellen eines Script-Dialogs mit sich wiederholenden UI-Elementen

mdomino
Beiträge gesamt: 76

28. Sep 2014, 21:47
Beitrag # 6 von 6
Beitrag ID: #532534
Bewertung:
(2026 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen
Vielen Dank für die Tips, erschließen sich mir alle und werde ich in mein finales Script auch so einbauen.

Schön, dass einem hier so schnell und kompetent geholfen wird und einem sogar geduldig darüber hinausgehende Verbesserungsvorschläge gemacht werden!


als Antwort auf: [#532528]
X

Aktuell

Veranstaltungskalender

Hier können Sie Ihre Anlässe eintragen, welche einen Zusammenhang mit den Angeboten von HilfDirSelbst.ch wie z.B. Adobe InDesign, Photoshop, Illustrator, PDF, Pitstop, Affinity, Marketing, SEO, Büro- und Rechtsthemen etc. haben. Die Einträge werden moderiert freigeschaltet. Dies wird werktags üblicherweise innert 24 Stunden erfolgen.

pdf-icon Hier eine kleine Anleitung hinsichtlich Bedeutung der auszufüllenden Formularfelder.

Veranstaltungen
26.01.2021 - 27.01.2021

Digicomp Academy AG, Zürich oder virtuell
Dienstag, 26. Jan. 2021, 08.30 Uhr - Mittwoch, 27. Jan. 2021, 17.00 Uhr

Kurs

In diesem Advanced-Kurs erlernen Sie weitergehende Methoden im Dokumentenaufbau, der Typografie und im Bereich Layouttechniken. Nach diesem Kurs können Sie strukturierte Dokumente erstellen oder bestehende effizienter anpassen.

Dauer: 2 Tage
Preis: CHF 1'400.–

Ja

Organisator: Digicomp Academy AG

Kontaktinformation: Kundenberater-Team, E-Mailkundenberatung AT digicomp DOT ch

digicomp.ch/d/INDEM2

Veranstaltungen
27.01.2021 - 28.01.2021

Digicomp Academy AG, Bern oder Basel
Mittwoch, 27. Jan. 2021, 08.30 Uhr - Donnerstag, 28. Jan. 2021, 17.00 Uhr

Kurs

Mit After Effects können Sie visuelle Effekte und Animationen für Video, Web, DVD und Blu-Ray erzeugen. In diesem Kurs lernen Sie die Grundlagen kennen und sehen inspirierende Anwendungsbeispiele, die Ihnen helfen, Ihre eigenen Ideen umzusetzen.

Preis: CHF 1'700.-
Dauer: 2 Tage

Ja

Organisator: Digicomp Academy AG

Kontaktinformation: Kundenberater-Team, E-Mailkundenberatung AT digicomp DOT ch

digicomp.ch/d/AFT

Neuste Foreneinträge


Absätze vor/nach AF suchen

Laser Drucker druckt schwarze Flecken Links und Rechts von Blatt

Gleich Große Icons erstellen

PSD CS6 (!) Mac: Dialog "Dateiinformationen" Fenster leer und Sackgasse

Langsamer MacMini

Illustrator Skript Übersatztext - Hilfe benötigt

ID CC 2019 und 2020: Crash beim Startvorgang - 2021

Inhalt Textrahmen verbinden

iPhone Farbprofil

Exel ohne leeres Tabellenblatt starten
medienjobs