Choose From List dialog with three buttons

I need a choose-from-list dialog with three buttons. My present intent is to use Shane’s Myriad Tables script library, but I wondered if there is an alternative (I need the third button and nothing else). Other options I’ve considered are writing a custom dialog with ASObjC and displaying a display-alert dialog which contains the options after displaying the choose-from-list dialog.

Thanks for the help.

Hi,

Here is one example written by @Takaaki Naganoya, and adapted by me right now. The script returns false when pressed button “Cancel”, last item of list when pressed button “Select last item”, index of selected item of list when pressed button “OK”. I think, @Peavine can improve this script further:


-- Created 2019-02-21 by Takaaki Naganoya
-- Adapted 2021-07-01 by Kniazidis Robert

use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSAlert : a reference to current application's NSAlert
property NSIndexSet : a reference to current application's NSIndexSet
property NSScrollView : a reference to current application's NSScrollView
property NSTableView : a reference to current application's NSTableView
property NSTableColumn : a reference to current application's NSTableColumn
property NSMutableArray : a reference to current application's NSMutableArray
property NSRunningApplication : a reference to current application's NSRunningApplication
property NSAlertSecondButtonReturn : a reference to current application's NSAlertSecondButtonReturn

property theResult : 0
property returnCode : 0
property theDataSource : {}
property theAlert : missing value


set paramObj to {myMessage:"項目の選択", mySubMessage:"適切なものを以下からえらんでください", aTableList:{"なし", "りんご", "ひよこ", "ぎょうざ", "すなぎも", "ぼんじり", "もも"}}
my chooseItemByTableView:paramObj



on initAlert:args
	set theAlert to NSAlert's alloc()'s init()
end initAlert:

on chooseItemByTableView:paramObj
	set aMainMes to myMessage of paramObj
	set aSubMes to mySubMessage of paramObj
	set aTList to (aTableList of paramObj) as list
	
	--define the matrix size where you'll put the radio buttons
	set aScrollWithTable to makeTableView(aTList, 300, 150) of me
	
	if my NSThread's isMainThread() as boolean then
		-- if we run in main thread
		my initAlert:paramObj
	else
		my performSelectorOnMainThread:"initAlert:" withObject:(missing value) waitUntilDone:true
	end if
	tell theAlert
		its setMessageText:aMainMes
		its setInformativeText:aSubMes
		its addButtonWithTitle:"OK"
		its addButtonWithTitle:"Cancel"
		its addButtonWithTitle:"Select last item"
		its setAccessoryView:aScrollWithTable
	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
		set aRes to false
	else if (my returnCode as number) = 1002 then
		set aRes to last item of aTList
	else
		set aRes to (aScrollWithTable's documentView's selectedRow()) + 1
	end if
end chooseItemByTableView:

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



on makeTableView(aList as list, aWidth as number, aHeight as number)
	set aOffset to 40
	
	set sourceList to {}
	repeat with i in aList
		set the end of sourceList to {dataItem:(contents of i)}
	end repeat
	
	set theDataSource to NSMutableArray's alloc()'s init()
	theDataSource's addObjectsFromArray:sourceList
	
	set aScroll to NSScrollView's alloc()'s initWithFrame:(current application's NSMakeRect(0, aOffset, aWidth, aHeight))
	set aView to NSTableView's alloc()'s initWithFrame:(current application's NSMakeRect(0, aOffset, aWidth, aHeight))
	
	
	set aColumn to (NSTableColumn's alloc()'s initWithIdentifier:"dataItem")
	(aColumn's setWidth:aWidth)
	(aColumn's headerCell()'s setStringValue:"dataItem")
	(aView's addTableColumn:aColumn)
	
	aView's setDelegate:me
	aView's setDataSource:me
	aView's reloadData()
	
	aScroll's setDocumentView:aView
	aView's enclosingScrollView()'s setHasVerticalScroller:true
	
	--1行目を選択
	set aIndexSet to NSIndexSet's indexSetWithIndex:0
	aView's selectRowIndexes:aIndexSet byExtendingSelection:false
	
	--強制的にトップにスクロール
	--set maxHeight to aScroll's documentView()'s |bounds|()'s |size|()'s height
	set aDBounds to aScroll's documentView()'s |bounds|()
	if class of aDBounds = list then
		--macOS 10.13 or later
		set maxHeight to item 2 of item 1 of aDBounds
	else
		--macOS 10.10....10.12
		set maxHeight to height of |size| of aDBounds
	end if
	
	set aPT to current application's NSMakePoint(0.0, -40.0) ------ (aScroll's documentView()'s |bounds|()'s |size|()'s height))
	aScroll's documentView()'s scrollPoint:aPT
	
	return aScroll
end makeTableView


--TableView Event Handlers
on numberOfRowsInTableView:aView
	return my theDataSource's |count|()
end numberOfRowsInTableView:

on tableView:aView objectValueForTableColumn:aColumn row:aRow
	set aRec to (my theDataSource)'s objectAtIndex:(aRow as number)
	set aTitle to (aColumn's headerCell()'s title()) as string
	set aRes to (aRec's valueForKey:aTitle)
	return aRes
end tableView:objectValueForTableColumn:row:

KniazidisR. Thanks for the suggestion. I’ll spend some time to incorporate that into my script.

@peavine
I cannot pretend to understand the complexities of the advanced coding I saw here for this problem.
But, once, when I wanted to have more choices from a choose-from-list dialog, I simply added a last item after the list. Choosing that instead of the list items was like having another button - not so elegant as another button but it got it done.

Sort of like this:

set answer to choose from list ((items 1 thru DisplayCount of ScriptFolders) & Reset) with title "Music Folders Information"

The string ‘Reset’ appears at the end of the list and can be used to trigger whatever logic was needed.

TheKrell. Thanks for the excellent suggestion–I appreciate the help.