List with checkboxes

Hello guys,

I would like to create a script that shows a list with different checkboxes but none of them preselected and only the selected ones to be pasted when triggered.

In more details, I would like to open a new Note or TextEdit document, trigger the above script, select only specific grocery items (my items list will be expanded) and have them pasted in my document.

So far I have created this:

Apple Script:

on run {}
    set theList1 to {“Fruits”, “Veggies”, “—“, “Bread”, “—“, “Milk”}
    return theList1
end run

However the pop-up window is so small and all the checkboxes are preselected and I have to click the “Select None” each time.

So I would like your help:

  1. Can I have the checkboxes unselected by default?
  2. Is it feasible to have the window resized? (the list has items with longer strings)
  3. Can I put separators between the lines?
  4. Can I have the text pasted directly after selection, without having to paste the Cmd+V button?

Thank you in advance!

It seems that it’s time to look at Shane Stanley’s Dialog Toolkit.

https://macosxautomation.com/applescript/apps/Script_Libs.html

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 16 novembre 2019 13:41:26

It sounds like Myriad Tables might be the answer, but the code you posted is missing any dialog. Anyway, Myriad Tables is available from the same place as Dialog Toolkit.

My checkboxLib seems fit your purpose.
Though the separator line does not exist…

You can try the sample scripts in library’s AppleScript dictionary.

http://piyocast.com/as/archives/8067

Model: MacBook Pro 2012
AppleScript: 2.7
Browser: Safari 13.0.1
Operating System: macOS 10.14

Thank you guys!

I will have a look asap!

Hello guys,

I would like your help on a slight alteration of Maro’s code at http://piyocast.com/as/archives/8067.

What I would like to have is a groceries list in four categories:

  • Basics
    • Bread
    • Milk
    • Eggs
    • Sugar
    • Item 1
  • Fruits
    • Apples
    • Oranges
    • Bananas
    • Item 2
  • Vegetables
    • Potatoes
    • Carrots
    • Onios
    • Item 3
  • Others
    • Item 4
    • Empty text box 5
    • Empty text box 6

and only the first two list checkboxes (for bread & milk) to be always selected and the rest of them to be unchecked. And then only all those selected items to be copied into clipboard.

Is that feassible?

You should add 1 reserved field (see the picture) to perform your task with this control. Other way, you need other (segmented control), which maro doesn’t provide with checkboxes yet. So:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use chkLib : script "checkboxLib"

set tList to {"Bread", "Apples", "Potatoes", "Item 4", "Milk", "Oranges", "Carrotos", "Empty text box 5", "Eggs", "Bananas", "Onios", "Empty text box 6", "Sugar", "Item 2", "Item 3", "(reserved box 1)", "Item 1"}

set cRes to choose checkbox main message "  Basics                           Fruits                           Vegetables                 Others" with columns 4 with titles tList checkbox type standard return type item number selection items {true, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false}
--> Result:  {1, 5} --    1 and 5 is selected

set the clipboard to cRes

NOTE: Don’t copy the text of my script, but open with button “Open This Scriplet in your Editor” of this site, to get it correctly!!! It contains invisible spaces, which are required.

Awesome! Lesson learned, so I used the “open in editor” in my personal computer as advised and got all the space characters!

Thank you!

However the clipboard seems to be empty. I cannot paste anything to notes or other apps. Is it working for you?

Moreover, I tried to copy the script to my work’s computer without success. Due to permissions, unfortunately I am unable of pasting the file checkboxLib to the appropriate folder. So can it be scripted without this library? Thanks in advance.

It isn’t empty. It contains list of integers. Manual pasting for some reason doesn’t work for me too.
But I was able to pass the clipboard contents to other application this simple way:

set aList to the clipboard as list  -- this tested in the other application

To put checkboxLib for all users in folder Library/Scripts Library/ of system domain, you should ask some administrator to do this. Other way, you can put it in the folder Library/Scripts Library/ of your user domain.

Exists way to not use checkboxLib at all, but you should write your own AsObjC source from begin. You can find such source examples on the same site of maro. See how he creates view and checkboxes in it. And how he adds the buttons to view. This will be an impressive piece of code to perform such a simple task.

Thanks for the advice!

So as I did not have permissions to paste checkboxLib or any other files, I found some source code on maro’s website and used part of it (removed the duplicates checker and the help button with its options).

And because the amount of items in every list is different (Basics: 5 items, Fruits: 3, Veggies: 4), I didn’t want to create empty boxes in multiple columns layout so I preferred to have all of them in one single list.

So the AppleScript that I have right now is this:

[format]
use AppleScript version “2.4”
use scripting additions
use framework “Foundation”
use framework “AppKit”

property NSView : a reference to current application’s NSView
property NSAlert : a reference to current application’s NSAlert
property NSButton : a reference to current application’s NSButton
property NSOnState : a reference to current application’s NSOnState
property NSOffState : a reference to current application’s NSOffState
property NSMutableArray : a reference to current application’s NSMutableArray
property NSButtonTypeOnOff : a reference to current application’s NSButtonTypeOnOff
property NSButtonTypeSwitch : a reference to current application’s NSButtonTypeSwitch
property NSRunningApplication : a reference to current application’s NSRunningApplication

property theResult : 0
property returnCode : 0
property bArray : {} --Checkbox button object array

set Basics to {“Bread”, “Milk”, “Eggs”, “Sugar”, “Honey”}
set Fruits to {“Apples”, “Oranges”, “Bananas”}
set Vegetables to {“Potatoes”, “Carrots”, “Onions”, “Tomatoes”}
set Others to {“”}

set cRes to «event LCCBCCKB» given «class CMMS»:“Please select:”, «class CSMS»:“Basics”, «class CSCS»:1, «class COLL»:Basics, «class COLC»:«constant enumcstd», «class COLR»:«constant enumdata»

set the clipboard to cRes
set aList to the clipboard as list – this tested in the other application

on run1(input, parameters)
set the text item delimiters to linefeed
set Storage to the input as text
end run1

on «event LCCBCCKB» given «class CMMS»:mainMes as string : “”, «class CSMS»:subMes as string : “”, «class CSCS»:cNum as integer : 1, «class COLL»:tList as list : {}, «class COLC»:eNum1 : «constant enumcstd», «class COLR»:eNum2 : «constant enumitmn»
if cNum < 1 then error “Wrong column number”

set en1Str to eNum1 as string
set en2Str to eNum2 as string

if en1Str = "standard" then
    set eN1 to 0
else if en1Str = "flat" then
    set eN1 to 1
else
    error "Checkbox type is wrong (standard or flat required)"
end if

if en2Str = "item number" then
    set eN2 to 0
else if en2Str = "data" then
    set eN2 to 1
else
    error "Return data type is wrong (item number or data)"
end if

set paramObj to {myMessage:mainMes, mySubMessage:subMes, mySuppression:"", myColNum:cNum, matrixTitleList:tList, chkType:eN1}
my performSelectorOnMainThread:"chooseItemByCheckBox:" withObject:(paramObj) waitUntilDone:true
set tmpList to (my sort1DNumList:theResult ascOrder:true) as list

if eN2 = 0 then return tmpList

set tmp2 to {}
repeat with i in tmpList
    set the end of tmp2 to contents of item i of tList
end repeat

return tmp2

end «event LCCBCCKB»

on chooseItemByCheckBox:(paramObj)
set aMainMes to myMessage of paramObj
set aSubMes to mySubMessage of paramObj
set aMatList to (matrixTitleList of paramObj)
set aLen to aMatList’s |count|()
set aSupMes to mySuppression of paramObj
set aCheckBoxType to (chkType of paramObj) as integer

set aMatList to aMatList as list

set colNum to (myColNum of paramObj) as integer
set rowNum to (aLen div colNum) + (aLen mod colNum)

set aButtonCellWidth to 240
set aButtonCellHeight to 24

set viewWidth to aButtonCellWidth * colNum
set viewHeight to aButtonCellHeight * rowNum

--define the matrix size where you'll put the radio buttons
set matrixRect to current application's NSMakeRect(0.0, 0.0, viewWidth, viewHeight)
set aView to NSView's alloc()'s initWithFrame:(matrixRect)

set aCount to 1
set bArray to current application's NSMutableArray's new()
repeat with y from 1 to rowNum
    repeat with x from 1 to colNum
        if aCount ≤ aLen then
            set j to contents of item aCount of aMatList
            set tmpB to (NSButton's alloc()'s initWithFrame:(current application's NSMakeRect(((x - 1) * aButtonCellWidth), ((aLen - aCount) div colNum) * aButtonCellHeight, aButtonCellWidth, aButtonCellHeight)))
            
            (tmpB's setTitle:j)
            (tmpB's setShowsBorderOnlyWhileMouseInside:true)
            (tmpB's setTag:(aCount))
            (tmpB's setTarget:me)
            (tmpB's setAction:("clicked:"))
            if aCheckBoxType = 0 then
                (tmpB's setButtonType:(NSButtonTypeSwitch))
            else
                (tmpB's setButtonType:(NSButtonTypeOnOff))
            end if
            (bArray's addObject:tmpB)
            
        end if
        
        set aCount to aCount + 1
    end repeat
end repeat

--Select the first radio button item
--(tmpArray's objectAtIndex:0)'s setState:(current application's NSOnState)
set theResult to {}

(aView's setSubviews:bArray)

-- set up alert    
set theAlert to NSAlert's alloc()'s init()
tell theAlert
    its setMessageText:aMainMes
    its setInformativeText:aSubMes
    its addButtonWithTitle:"OK"
    its addButtonWithTitle:"Cancel"
    its setAccessoryView:aView
    
    --for suppression check box ( No use for this case? )
    if (aSupMes as string) is not equal to "" then
        its setShowsSuppressionButton:(true) -- Show "Do not show this message again" checkbox
        set suppressionB to its suppressionButton
        suppressionB's setTitle:(aSupMes)
    else
        its setShowsSuppressionButton:(false)
    end if
end tell

-- show alert in modal loop
NSRunningApplication's currentApplication()'s activateWithOptions:0
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
if (my returnCode as number) = 1001 then error number -128

set theResult to (tmpArray's valueForKeyPath:"status") as list

end chooseItemByCheckBox:

on doModal:aParam
set (my returnCode) to aParam’s runModal()
end doModal:

on clicked:aParam
set aTag to (tag of aParam) as integer
if aTag is not in (theResult as list) then
set the end of theResult to aTag
else
set theResult to my deleteItem:aTag fromList:theResult
end if
end clicked:

on deleteItem:anItem fromList:theList
set theArray to NSMutableArray’s arrayWithArray:theList
theArray’s removeObject:anItem
return theArray as list
end deleteItem:fromList:

–1D List (numerical value) is sorted in ascending order when sort / ascOrder is true, and in descending order when it is false
on sort1DNumList:theList ascOrder:aBool
tell current application’s NSSet to set theSet to setWithArray_(theList)
tell current application’s NSSortDescriptor to set theDescriptor to sortDescriptorWithKey_ascending_(missing value, true)
set sortedList to theSet’s sortedArrayUsingDescriptors:{theDescriptor}
return (sortedList) as list
end sort1DNumList:ascOrder:
[/format]

Unfortunately still I cannot get the clipboard contents. What actually I would like is to have the selected items in plain text and different lines.

So the {“Milk”, “Honey”} selection to paste into clipboard this:
[format]Milk
Honey[/format]

Could you please help?

And also I am still trying to find a way of having the 3 lists all together, with their titles. Something like this:

https://imgur.com/a/YOF7a9A