Rundialog Issue

After getting unexpected behavior while working on a more complicated dialog window, I created a simple database with a simple dialog form with 3 objects: a text edit box, Cancel button, and OK button. The buttons have resume {} as their only code. When I present the form using Rundialog the code below should display my ‘in loop’ message when I hit the OK button but keep the dialog window open. Instead, the window closes and I only get my ‘after loop’ message. Rundialog seems not to be responding to the if info("trigger") contains "Button.OK" part of the code. What the heck am I missing??

[mac os monterey 12.2.1 Pan X 10.2.0.b25 (3901)]

fileglobal fgV01
fgV01=A

loop
    rundialog |||
        Form="DialogForm"
        sheet=true
        Menus=normal
        Height=780 Width=1060
    |||
    stoploopif info("trigger")="Dialog.Close"
    if info("trigger") contains "Button.OK" 
        message "in loop ok message"
        settrigger ""
    endif
endloop

if dlgResult="Cancel"
    message "afterloop cancel message"
endif

if dlgResult="Ok"
    message "afterloop ok message"
endif

Change this line to

if info("trigger") contains "Dialog.OK"

I made some charts for myself and posted them in the forum that helps explain what is happening.

That seems to have done the trick! Thanks! The Dialog Workshop provided the button.OK phrasing, so that might be a bit of a bug.

Thanks also for your graphics on what’s happening beneath the surface in the rundialog process! Very illuminating!

It did that because the standard spelling of that button (according to Apple) is Ok, not OK. Since you used a non-standard spelling, the Dialog Workshop did not recognize that it actually was the Ok button. You could have gotten it to generate the code you want by using the Ok Button popup menu in the Dialog Options section, as I’ve done here.

My dialog has three buttons, OK, Cancel and Go. The Cancel button is automatically recognized because I used the standard name for that button. If I had picked a non-standard name for the Cancel button I would have needed to specify that name in the Dialog Options panel of the Dialog Workshop.

Notice that there is no code for the Ok and Cancel buttons. These buttons are normally handled automatically, you don’t need to supply any code. You only need to supply code if you want to do some extra validation before Panorama actually performs the Ok or Cancel operation. If you do want that, you look for the triggers Dialog.OK or Dialog.Cancel – NO MATTER WHAT THE BUTTON TITLES ACTUALLY ARE. There are examples of this in the rundialog help page.

Tom suggested that you change Button.OK to Dialog.OK, as shown above, but that is wrong. The settrigger "" line will abort the action, leaving the dialog open. With this code in place, the only way to close this dialog will be pressing the Cancel button. At a minimum you should remove the settrigger line, and unless you absolutely need the message, you should remove all four lines of code.

I must have seen this chart last year because I had already liked this post, but I don’t remember. But having seen it again, bravo, this is a very cool chart.

I don’t see why you say I am wrong because:

  1. The code works as intended when you follow my suggestion. It’s true that this example given by Bill would be pointless and would disable the appropriate use of the ok button, but I think he wanted to understand why his code did not know that the OK button had been pressed and do something.

  2. The help page uses the same code to find out if the OK button has been pressed.
    It gives this example.

loop
rundialog {Form=“Find” Height=45 Width=346}
stoploopif info(“trigger”)=“Dialog.Close”
if info(“trigger”) contains “Dialog.OK” // has the ok button been pressed?
if findThis=“”
nsnotify “You must enter something to search for!”
settrigger “” // don’t close the dialog
else
select exportline() contains findThis // do the search
endif
endif
endloop

I sure hope you didn’t take my comment personally. If so, I am very sorry, that was the opposite of my intention.

I don’t think it does. The problem isn’t your suggestion, but the original code with the settrigger statement. I would thing the intention would be that pressing the OK button would close the dialog, and with this code, the dialog won’t close.

In that example the code is checking to make sure that pressing the OK button was really valid. If not, the dialog isn’t closed, but if everything is ready to go, the dialog will close. By taking Bill’s original code and simply changing Button.OK to Dialog.OK, clicking the OK button will not perform the task of closing the dialog. So that is what I meant by “wrong”.

Perhaps however, I am wrong, since @billashw says that the modified code did work! It seems to me that if it did work that would be a bug, so I kind of hope it doesn’t :upside_down_face:

No, I did not take it personally. Just wanted to have a discussion of the issue. Since I made my charts, I have made lots of use of rundialog and think it allows some very nice user interfaces.

1 Like

I appreciate the conversation! Just to clarify, trapping the user hitting the OK button and preventing the dialog from closing was the purpose of the simplified test routine I posted. The “real” intended use behind this test case was to have rundialog respond to the OK button by first performing a validation check on the user’s entries, and if there were problems to notify the user and keep the dialog window open so that the entries could be corrected, cleared, or Cancel chosen instead. Testing for Button.OK did not work even though that was the wording provided by the Dialog Workshop (and I did try different spellings of ‘OK’). Tom’s suggestion to use Dialog.OK did work. I’ve returned to my original working database (code not posted) and made the change and the validation check is now working as intended. Thanks again!

I will volunteer another strategy that I have used to validate data entered in a dialog before it closes. Upon opening the dialog (if info(“trigger”) contains “Dialog.Initialize”) , I disable the OK button with a changeobject statement. Then I have a validation procedure that checks whether the entries in the dialog meet the criteria, and if they do, the OK button is enabled. The validation procedure is triggered when the user presses return or tab to exit a text editor. This way, the user knows if they have entered valid data before pressing the ok button.

2 Likes

I like it!!

I can not find the above Dialog Workshop. Where is it hiding?

I have a ton of declarations to be made and it will be very helpful.

When you are editing a procedure, you can open the Dialog Workshop from the Program menu. I just made a dialog last night.

Sorry but perhaps I am a bit slow today.

The Help file for RunDialog says… “(If you set up your form correctly, the Dialog Workshop will write all of the declarations for you, completely automatically!)”

The link for ‘Dialog Workshop’ is a dead end. When I start with the current ‘non Dialog form’, and then open a procedure, it does recognize that that form is the one I want to turn into a Dialog. But no Declarations get created in the workshop procedure window.

Do I have start to over from scratch and re-create the form in some special manner for it to be done correctly? Is there perhaps any video from the early training of Pano X that I might find and use? I’ve looked but I’ve not found any real info on this Dialog Workshop.

I’m not sure why I wrote the word “declarations” there. It writes the code, which you can then paste into the procedure (and edit further if needed).

The link for ‘Dialog Workshop’ is a dead end.

Unfortunately true. There is no written documentation for this feature.

Is there perhaps any video from the early training

Not from the early training - I don’t think the Workshop existed then.

The title sheets for the videos Short Programming Topics Part 1 and Short Programming Topics Part 2 both claim that the Dialog workshop is part of the outline. But scrubbing through these videos, it seems to me that this topic was skipped over. I could swear that I remember covering it, but I cannot find it in any of the videos recorded during that period.

Anyway, it’s pretty easy.

First, you create your form. Be sure that your OK and Cancel buttons contain the code resume "". Resize the window to the size you want it to display as a dialog (you’ll have to adjust this later, but it will be faster if you get the size close).

Leave the form open, then create the procedure (or you can use an existing procedure). Open the Dialog Workshop. You’ll see that the code is already written. If your OK button is not named OK, then choose the button from the popup menu. You can also choose whether you want your dialog to be a sheet or a standalone dialog. When you make any changes in the Options are the code will immediately revise to reflect your choices. There is also a Write Code button, but it’s not needed.

Now you can copy the code into your procedure. Either press the Copy Code button, or simply select the text and copy it. Either way, paste it into the procedure window. It’s just code like any other code. You could also paste it straight into the code section of a graphic object, but I usually don’t do that.

Now you can simply run the dialog to test it. Note that you can leave the original form window open while you do that, and you can leave the Workshop open also.

If the dialog size is off such that the Cancel button isn’t visible, just press the ESC key to close the dialog. Usually you need to tweak the dimensions of the dialog in the code to get the size just right - it usually takes 3 or 4 iterations. Voila! Your dialog is ready.

As for the details of dialog code customization, that is all covered on the RunDialog help page.

So the bit about the Dialog Workshop writing all of my declarations was a typo?

I have over 100 variables that I am going to be needing so this is a worthy question to nail down. I’d rather work as smart as possible on this.

It doesn’t have anything to do with your 100 variables, sorry. It just writes the rundialog code.

Where would these be found? What would I search for?

If a user has a lot of fields that they need declarations for, the below code will quickly create the declarations. Run the code in a separate procedure, then do a paste into your RunDialog procedure.

Let LDeclarations = ""
Let AListOfFields = Info("Fields")
LoopArray AListOfFields,chr(13),FieldName
    LDeclarations = LDeclarations + 'Variable:"d'+FieldName+"="+FieldName+'"'+chr(13)
EndLoop
Clipboard() = LDeclarations

When you mentioned “declarations” earlier, I forgot that the rundialog documentation uses that terminology. So I had no idea what you were talking about.

Now that you’ve posted this code, it jogged my memory. Your code is fine, but you could just run this formula in the Formula Wizard.

arrayfilter(info("fields"),cr(),{'Variable:"d'+import()+"="+import()+'"'})

Here’s what it looks like in the wizard, you can copy the result out of the wizard.

Or you could use a separate procedure like you did:

clipboard() = arrayfilter(info("fields"),cr(),{'Variable:"d'+import()+"="+import()+'"'})

Now that you’ve mentioned this, it might be pretty easy to build this into the Dialog Workshop. I never thought of that before, but I will consider it.