Modifier Keys with Checkboxes and Buttons

I have a database with multiple checkboxes. Is there a method where I would have to hold a modifier key (control, option, or command) to be able to check or uncheck a box? This would help prevent unintended changes.

How about the same question but for buttons?

if info(“modifiers”) notcontains “option”
if data=“” data=“x” else data=“” endif
showvariables data
endif

1 Like

Thank you for the prompt response.

I tried this with a checkbox. It still allows me to check/uncheck a box without holding down option key. I assume there something else I have to set.

I just pasted the above into the Procedure properties of a checkbox. I also added the following to the form event procedure. (letfileglobal data = “”) and (showVariables data).

@epansoft is on track in the right direction, but didn’t quite get there.

First, for push buttons, this is very simple. Just add a check for the option key at the top of the code:

if info(“modifiers”) notcontains “option”
    beep // optional, or you could use nsnotify
    return // no option key, so do nothing
endif
// rest of your code here

For data buttons (for example checkboxes), this won’t work, because the data button handles the click itself. By the time your code runs, the checkbox has already flipped.

However, there is a way to do this - you simply have to use the Formula Mode option. This gives you full control over the operation of the button. You’ll find full documentation for this mode here:

Suppose you wanted the checkbox to toggle a variable called boxIsChecked with a boolean value (true/false). Create the data button, and enable Formula mode. Then set the formula to:

catcherror(false(),boxIsChecked)

The catcherror( function means that your button will work even before the variable has been initialized.

Then, set the code of the button to:

if info(“modifiers”) notcontains “option”
    beep // optional, or you could use nsnotify
    return // no option key, so do nothing
endif
letfileglobal boxIsChecked = not catcherror(false(),boxIsChecked)
showvariables boxIsChecked
1 Like

‘data’ here is the name of the Data in Data Button Options and 'x" is the value, so change those with the actual name and value you used.

1 Like

I made a 1-field DB; the field is called A. I made a form with a checkbox and a text display object. The formula for the TDO is A. The checkbox is a data button associated with field A and its default value is “Clicked”

This procedure in the checkbox’s procedure panel does exactly what you want:

if info(“modifiers”) notcontains “option” and A="" A="Clicked" elseif info(“modifiers”) notcontains “option” and A="Clicked" A="" endif

So there’s your solution, but I find it puzzling. It seems to me as if the not contains ought to be a contains, but that’s not the case. If I write it the way it makes sense to me, it doesn’t work in several ways. Maybe wiser heads among our colleagues can explain.
PS this is almost identical to @epansoft’s suggestion


At this point Jim posted his reply which thoroughly explains everything.

1 Like

Oops. I followed these instructions, changing showvariable (not a statement) to showvariables. It works but the checkbox turns on and off whether or not the variable is changed. That is, with option, the checkbox turns on and off and the variable is changed. Without option the checkbox turns on and off but the variable is not changed. I looked around to try to find a control for the checkbox, but couldn’t find one.

BTW, using my previously posted solution, the checkbox behaves as expected.
But I couldn’t find a way to get a beep in there. I tried putting it in the beginning in an if info("modifiers") contains "option" beep return statement, but that gives a beep when the option key is down.

1 Like

Thank you Jim, @epansoft and @billconable - I appreciate your help. I’m way over my head when it comes to coding.

Sorry to ask so many questions. However, Please know that I do try to work it out on my own before posting. :grinning:

Oops, sorry, my code didn’t quite actually work - I should have tested it before I posted but I was in a rush. Here’s a slightly modified version that definitely does work.

if info(“modifiers”) notcontains “option”
    beep
else
    letfileglobal boxIsChecked = not catcherror(false(),boxIsChecked)
endif
showvariables boxIsChecked
1 Like

Yes- this works. Thanks.

I think I should have explained this better. I have 18 checkboxes (representing 18 gardens) associated with one field (Garden). When I check a box for a specific garden, it adds that garden to the Garden field. Unchecking a box removes it. The simplicity of doing this is one of the beautiful features of PanX. Since the solution to my request requires that I leave the Data field blank on the Data Button Options, the checkboxes will be disassociated from the Garden field. It seems that I will have to add code to make the checkboxes behave like they did before. Can you point me in the right direction to accomplish this?

Right from the start, what you are asking for is super non-standard. Who ever heard of a checkbox that only works if the option key is pressed? I’ve never seen any Mac application that behaved that way.

Of course if you want something non-standard, that’s your choice. But you can’t expect implementing something completely non-standard to be easy, if it’s possible at all.

I believe that what you want is possible, but it’s going to take a lot of work to set up. As you have pointed out, creating a group of checkboxes is easy in Panorama - if you want them to behave in a standard way. Since you don’t, you’ll essentially have to do all the work yourself, and it’s a bunch of extra work for each button.

Here’s what I think you’ll have to do (but note that I am NOT taking the time to test this). Each button will have to be set up in Formula mode. Suppose you want a button for a garden named “Bushard”. The formula will need to be:

Garden contains "Bushard"

The procedure will need to be:

if info(“modifiers”) notcontains “option”
    showfields Garden
else
    arraytoggle Garden,",","Bushard"
endif

The code above will put a comma between each garden name (if there are multiple names). If you want something other than a comma, you’ll need to change that.

Each button will need a customized version of the formula and the code, each with a different garden name.

In fact, I would set it up as a subroutine. Let’s say you created a procedure named ToggleGarden, with this code.

if info(“modifiers”) notcontains “option”
    showfields Garden
else
    arraytoggle Garden,",",parameter(1)
endif

Then each button would only need one line of code, like this:

call ToggleGarden,"Bushard"

In my personal opinion, I don’t think you should do any of this. It’s a lot of work, and does it really solve a problem? If you accidentally check a box, then un-check it, what’s the big deal? You can also use Undo (command-Z). If you’re really worried about accidentally clicking on a checkbox, then only make the checkboxes available when you’re planning to click. For example, put the checkboxes in a tab panel, so you can only click on them when you switch to that panel. Or put them in a dialog form.

I agree.

I agree.

I don’t expect you to, but I appreciate it when you do.

Noted. At your suggestion, I’ll move on to explore the alternatives you’ve described.

My thanks to you and the others who have helped me with this.

Update: I moved the checkboxes into a tab panel as you suggested. Works fantastic. Also is a much cleaner look. Thank you.

1 Like