Copy link to clipboard
Copied
Am I right with my observations?
Ordinary (not named) callback functions are all listed as (for example) onClick() in the Functions pane of ESTK. In addition local variables in these functions are not listed in the Data Browser. Hence IMHO debugging is not possible.
So I tried the method with named callback functions which avoids both drawbacks:
Unnamed callback functions | Named callback functions |
---|---|
myDlg.btn2.onClick = function() { | myDlg.btn2.onClick = ActButton2; |
variable aLocal is not listed in Data Browser | variable aLocal is listed in Data Browser |
All functions are named onClick in the Functions pane | Functions have distinct names in the Functions pane |
callback functions are within the window function | callback functions (are) / (may be) outside the window function |
Of course the names for the named callback functions must be unique for the whole script.
Which FrameMaker version do you use?
Now I see your problem:
You can't do something like this:
wPnlN.p0.b1.onClick = Button1p (whatIsThis, outerParm) ;
Means: you can't pass parameters to this function here. Otherwise the function is executed immediately.
wPnlN.p0.b1.onClick = Button1p; // no brackets!!!!!!
Copy link to clipboard
Copied
I fell into the trap of a working simple example - in real life aka my long script) it does not work:
The named fallback functions are entered even during creation of the diaglog/palette - and not only on a click on the buttons. Hence they are entered before the dialouge is really set up and visible...
The sekeleton of my dialog routine is this:
function PaletteCalcMarkers(){
var gsMarkerName= "#calc";
var indexOfMarker = RefreshGlobalsC (); // if null => inactivatemost buttonsuff
var palC = new Window('palette',"Handle #Calc Markers",undefined); // dialog or palette
palC.p0 = palC.add('panel',undefined,undefined);// outmost panel
// -- lot of stuff// --- behaviour of the buttons====================================================================
palC.p0.g2.btnInsert.onClick = ButtonInsertC (palC);
// -- more of these (one for each button)palC.p0.g4.Cancel.onClick = function () { // the only unname one i left
palC.close();
}
if (indexOfMarker === null) HideButtonsC(palC);
palC.show();
} // end of PaletteCalcMarkers --------------------------------------------------------------------function ButtonInsertC (palC) {
indexOfMarker = InsertMarker (goCurrentDoc.TextSelection, gsMarkerName, gsMarkerText)
goCurrentMarker = goaCalcMarkers[indexOfMarker];
DisplayMarker (goCurrentDoc, goCurrentMarker);
palC.p0.sMarkerContent.text ="";
gsMarkerText = goCurrentMarker.MarkerText;
palC.p0.sMarkerContent.textselection = gsMarkerText;
}
// -- More of these functions (one for each button)
So I'm back to square one with not being able to check local variables in the unnamed fallback functions.
Copy link to clipboard
Copied
Hello Klaus,
I don't know the answer (yet).
But I can give you one hint:
I read somewhere(???) that a "Window" MUST be defined globally (outside the function).
I don't know, if this could solve your problem.
So just try it.
Copy link to clipboard
Copied
Klaus, this has no influence on the behaviour.
I have set up a simpler example with both cases: internal callback functions and external (named) ones.
While the transfer of parameters works they can not be inspected in the Data Browser - the theme of this thread.
/* NamedCallbackFunctions.jsx
Call back functions defined within the dialog function work as intended
Named (externalised) dialog function doe not work correctly
*/var globalValue = 17;
var wPnl = new Window ("dialog", "Paneled Dialog OK", undefined);
var wPnlN = new Window ("dialog", "Paneled Dialog NOK", undefined);PaneledDialog (globalValue); // callback functions run before dialog is visible
alert ("Now the demonstration of the named callback functions");
PaneledDialogNOK (globalValue); // this is OK/* Callback functions defined and invoked inside the dialogue fucntion work as intended
It is, however, not possible to transfer local parameters to them
The setup of the windows does'nt need to be outside the dialogue function
(as suggested by Klaus Göbel)
*/
function PaneledDialog (outerParm) {
var innerParm = 19;
var whatIsThis = 99;
wPnl.p0 = wPnl.add ("panel", undefined, "a panel");
wPnl.p0.b1 = wPnl.p0.add ("button", undefined, "Outer");
wPnl.p0.b2 = wPnl.p0.add ("button", undefined, "Inner");
wPnl.p0.st = wPnl.p0.add ("statictext", undefined, "st= " + innerParm); // initially 19wPnl.p0.b1.onClick = function () {
alert ("Outer argument outerParm is " + outerParm, "PaneledDialog OK", false); // = 17
alert ("whatIsThis is " + whatIsThis, "PaneledDialog OK", false); // undefined
}
wPnl.p0.b2.onClick = function Button2P () {
alert ("Inner argument innerParm is " + innerParm, "PaneledDialog OK", false); // = 19
wPnl.p0.st.text = "st= 13"; // this changes the display
}
wPnl.show ();
}/* Externalised named callback functions - probaly misunderstood from
javascript Tools Guide > Defining event-handler callback functions
This does not work: the callback functions are invoked during buildup of the dialog
even before the dialogue becomes visible.
The setup of the windows does'nt need to be outside the dialogue function
(as suggested by Klaus Göbel)
*/
function PaneledDialogNOK (outerParm) {
var innerParm = 19;
var whatIsThis = 99;
wPnlN.p0 = wPnlN.add ("panel", undefined, "a panel");
wPnlN.p0.b1 = wPnlN.p0.add ("button", undefined, "Outer");
wPnlN.p0.b2 = wPnlN.p0.add ("button", undefined, "Inner");
wPnlN.p0.st = wPnlN.p0.add ("statictext", undefined, "st= " + innerParm); // initially 19wPnlN.p0.b1.onClick = Button1p (whatIsThis, outerParm) ;
wPnlN.p0.b2.onClick = Button2P (innerParm);wPnlN.show ();
}function Button1p (whatIsThis, outerParm) {
alert ("Outer argument outerParm is " + outerParm, "PaneledDialog NOK", false); // = 17
alert ("whatIsThis is " + whatIsThis, "PaneledDialog NOK", false); // = 99
}
function Button2P (innerParm) {
alert ("Inner argument innerParm is " + innerParm, "PaneledDialog NOK", false); // = 19
wPnlN.p0.st.text = "st= 13"; // this changes the display
}
Setting a breakpoint with $.bp(true); - for example after line 27 - works only if
#target framemaker
is present.
Copy link to clipboard
Copied
Hi Klaus D.,
Two thoughts, neither are very deep...
- I've seen variables fail to appear in the Data Browser if they simply lacked "var" in the declaration, like "var myVar = "Hi Klaus". Your original post shows this. While JavaScript doesn't care, the Data Browser sometimes seems to.
- In general, I've found the Data Browser and debug tools to have bad moods and just act strange sometimes.
Russ
Copy link to clipboard
Copied
Wait a minute... Does the variable even exist before the callback is called? I get confused by closure and life cycle in javascript...
Copy link to clipboard
Copied
Hi Russ,
The DataBrowser does not show any local variables from a callback function - independently of they are really declared locally to that function by var ... or that they are global (that is declared in the window setup function).
And yes, the behaviour is sometimes erratic and I just close everything (FM, ESTK) and start afresh.
CudSpan,
When using the 'named callback functions" I need to call the real functions (which are outside the scope of the window function) with parameters to get some values into them. See lines 53 and 54 above. If i just use
wPnlN.p0.b1.onClick = Button1p;
wPnlN.p0.b2.onClick = Button2P;
as it is describe in the Javascript Tools Guide > Defining event-handler callback functions, then of course all varirables are undefined in the external functions.
So, IMHO named callback functions either work completely differt than I can deduct from the documentation - or this is a dead end anyway.
I have resorted back to the unnamed method of doing it and need lots of alerts in the functions to know what's going on - thanks a very helpless Data Browser.
Copy link to clipboard
Copied
Hi Klaus,
I've tested your script several times and for me it works!
I'm using FM 2015 with the new update 3.1 (from today)
I'm gonna test it now with FM12.
Copy link to clipboard
Copied
Klaus, in my tests,
As soon as I execute line 12 containing
PaneledDialogNOK (globalValue); // this is ot OK
the external callback routines are run and all alerts happen. Only after that the dialog is displayed and the buttons don't work.
Copy link to clipboard
Copied
Which FrameMaker version do you use?
Copy link to clipboard
Copied
Klaus, I did the tests with FM-12.0.2.433 and just now again with FM-13.0.3.495 (13.0.3.1)
=> Same behaviour: As soon as I execute line 12 containing
PaneledDialogNOK (globalValue);
the external callback routines are run and all alerts happen. Only after that the dialog is displayed and the buttons don't work.
Please note that in the posted script the comments are exchanged. Lines 10 - 12 shoul read
PaneledDialog (globalValue); // this is OK
alert ("Now the demonstration of the named callback functions");
PaneledDialogNOK (globalValue); // callback functions run before dialog is visible
Copy link to clipboard
Copied
Which FrameMaker version do you use?
Now I see your problem:
You can't do something like this:
wPnlN.p0.b1.onClick = Button1p (whatIsThis, outerParm) ;
Means: you can't pass parameters to this function here. Otherwise the function is executed immediately.
wPnlN.p0.b1.onClick = Button1p; // no brackets!!!!!!
Copy link to clipboard
Copied
Thanks Klaus - I think the behaviour is now demystified:
// argumentsInNamedCallbackFunction2.jsx
#target framemakervar globalValue = 17;
var wPnlN = new Window ("dialog", "Paneled Dialog NOK", undefined);PaneledDialog (globalValue);
function PaneledDialog (outerParm) {
var innerParm = 19;
var whatIsThis = 99;
wPnlN.p0 = wPnlN.add ("panel", undefined, "a panel");
wPnlN.p0.b1 = wPnlN.p0.add ("button", undefined, "Outer");
wPnlN.p0.b2 = wPnlN.p0.add ("button", undefined, "Inner");
wPnlN.p0.st = wPnlN.p0.add ("statictext", undefined, "st= " + innerParm); // initially 19wPnlN.p0.b1.onClick = buttonOuter; // there must not be parameters!
wPnlN.p0.b2.onClick = buttonInner; // or the functions are executed immediatelywPnlN.show ();
}function buttonOuter () {
$.bp(true);
var whatIsThis = "local to buttonOuter"; // visible in Data Browser
alert ("Outer argument outerParm is: " + wPnlN.outerParm); // = 17 not visible in DB
alert ("whatIsThis is " + whatIsThis);
}
function buttonInner () {
$.bp(true);
alert ("Inner argument innerParm is: " + wPnlN.innerParm);
wPnlN.p0.st.text = "st= 13"; // this changes the display
}
Thnak You all for this discussion and solution.
Klaus