Is there a way for a user to input multiple variables???

Hi everyone, and Christmas greetings to you all!!!

I have a quick query…using applescript…

It is fairly easy to get a response where the user inputs data into one text box. For example:


set theVariable to first item of text of (display dialog "Please input the date of the event:" default answer "DD/MM/YY")

My question is…can you get the user to input a number of variables at the same time. For example, if you wanted them to input the dates of a multiple number of events, or do you have to have a separate text boxes for each separate entry?? Obviously, each entry would require a new variable, but I am enquiring as to the ease of the user interface. If there was just one page where the different event dates could be entered, it might be easier???

Best wishes,

DDHawk

You should take a look at ApplescriptObjC (Xcode).

Once you’re there I like to help you further.

Thanks DJ!!

OK - I assume that you are going to suggest that the only sensible way of working this is to use xcode???

What are you suggesting that I take a look at??

DDHawk…

Hi,

if you want a bit easier: start play around with pashua: http://www.bluem.net/en/mac/pashua/

the documentation is pretty good …

it’s easy to create a record from response, add as much textfields for one sessions as you want and add a continue button to run it again …

this adaption from Pashua-example-code took 5 minutes:


set config to "
# Set transparency: 0 is transparent, 1 is opaque
*.transparency=0.95

# Set window title
*.title = Play around with Pashua

# some textfields
tf1.type = textfield
tf1.label = insert date
tf1.default = DD.MM.JJJJ
tf1.width = 100

tf2.type = textfield
tf2.label = insert date
tf2.default = 
tf2.width = 100

tf3.type = textfield
tf3.label = insert date
tf3.default = 
tf3.width = 100

tf4.type = textfield
tf4.label = insert date
tf4.default = 
tf4.width = 100

tf5.type = textfield
tf5.label = insert date
tf5.default = 
tf5.width = 100

# Add a cancel button with default label
cb.type=cancelbutton
"



-- Call Pashua and save the resulting record in pashuaResult
set pashuaResult to pashua_run(config, "", "")
activate
if cb of pashuaResult is not "1" then
	display dialog "AppleScript received this record: " & return & return & ¬
		"tf1: " & tf1 of pashuaResult & return & ¬
		"tf2: " & tf2 of pashuaResult & return & ¬
		"tf3: " & tf3 of pashuaResult & return & ¬
		"tf4: " & tf4 of pashuaResult & return & ¬
		"tf5: " & tf5 of pashuaResult & return
	
else
	-- The cancelbutton (named "cancel" in the config string) was pressed
	display dialog "The dialog was closed without submitting the values"
end if


-- Glue code for interfacing from AppleScript to Pashua. Written by
-- Carsten Blüm <carsten@bluem.net>, 10/2003-01/2006, with improvements
-- contributed by Eddy Roosnek and Hans Haesler. You can use or modify
-- this handler any way you like in your own scripts.
-- Argument 1: Configuration string / window description
-- Argument 2: Encoding to use; if empty, Pashua assumes "macroman"
-- Argument 3: Folder that contains Pashua.app; if empty, default locations are searched
on pashua_run(config, encoding, appdir)
	
	-- Create path for temporary file
	set AppleScript's text item delimiters to ""
	set tmpfile to ((path to temporary items folder as string) & "Pashua_" & (characters 3 thru end of ((random number) as string)) as string)
	
	-- Write temporary file and fill it with the configuration string
	set fhandle to open for access tmpfile with write permission
	write (config as string) to fhandle
	close access fhandle
	
	-- Get temporary file's POSIX path
	set posixtmpfile to POSIX path of tmpfile
	
	set diskPath to (path to startup disk as string)
	set userPath to path to "cusr" as string
	set myself to (path to me as string)
	tell application "Finder" to set myParentPath to (container of alias myself as string)
	
	-- Try to find Pashua application
	tell application "Finder"
		-- Try to find it in the directory supplied as argument to this handler
		if appdir is not "" then
			if last character of appdir = ":" then
				set dirsep to ""
			else
				set dirsep to ":"
			end if
			if item (appdir & dirsep & "Pashua.app") exists then
				set pashua to appdir & dirsep & "Pashua.app:"
			end if
			-- Try to find it in this script application bundle
		else if item (myself & "Contents:MacOS:Pashua") exists then
			set pashua to myself
			-- Try to find it in this script's parent's path
		else if item (myParentPath & "Pashua.app") exists then
			set pashua to (myParentPath & "Pashua.app:")
			-- Try to find it in global application folder
		else if item (diskPath & "Applications:Pashua.app") exists then
			set pashua to (diskPath & "Applications:Pashua.app:")
			-- Try to find it in user's application folder
		else if item (userPath & "Applications:Pashua.app") exists then
			set pashua to (userPath & "Applications:Pashua.app:")
		else
			display dialog "I can't find the Pashua application." & return & "It looks like Pashua is neither in one of the standard locations nor in the folder this AppleScript is in." buttons {"OK"} default button 1 with icon stop
			return -1
		end if
	end tell
	
	-- Append binary position inside app bundle to "regular" path
	-- and convert path from HFS to POSIX representation
	set pashuabinary to (POSIX path of pashua) & "Contents/MacOS/Pashua"
	
	-- Optionally, define the encoding as command-line argument
	if encoding = "" then
		set encodingArg to ""
	else
		set encodingArg to "-e " & encoding & " "
	end if
	
	-- Execute pashua and get the string returned
	set pashuaCall to "'" & pashuabinary & "' " & encodingArg & "'" & posixtmpfile & "'"
	set pashuaResult to do shell script (pashuaCall)
	
	-- Delete the temporary file
	tell application "Finder" to delete tmpfile
	
	-- Check whether the dialog was submitted at all.
	-- If this is not the case, return an empty list
	if pashuaResult = "" then
		return {}
	end if
	
	-- Parse the result
	set AppleScript's text item delimiters to return
	set resultLines to text items of pashuaResult
	set AppleScript's text item delimiters to ""
	set recordComponents to {}
	repeat with currentLine in resultLines
		set eqpos to offset of "=" in currentLine
		if eqpos is not 0 then
			set varKey to word 1 of currentLine
			try
				set varValue to (text (eqpos + 1) thru end of currentLine)
				-- Quote any quotation marks in varValue with a backslash.
				-- The proper way to do this would be a handler, but as
				-- all code for interfacing to Pashua should be as compact
				-- as possible, we rather do it inline
				set AppleScript's text item delimiters to "\""
				set textItems to every text item of varValue
				set AppleScript's text item delimiters to "\\\""
				set varValue to textItems as string
				set AppleScript's text item delimiters to ""
			on error
				set varValue to ""
			end try
			copy (varKey & ":\"" & varValue & "\"") to end of recordComponents
		end if
	end repeat
	
	-- Return the record we read from the tmpfile
	set AppleScript's text item delimiters to ", "
	set resultList to (run script "return {" & (recordComponents as string) & "}")
	set AppleScript's text item delimiters to {""}
	return resultList
	
end pashua_run

AppleScript Studio is deprecated as of Snow Leopard. AppleScriptObjC is a more future-proof path.

@stanley: I thought Applescript-Studio is just a term of making apps with applescript at the top level of the programm and that ApplescriptObjC is just the new way of doing this with the use of applescriptObjc framework. (I’ve changed my first post already)

OT: Anyway you can achieve your goal with xcode (creating a window with multiple input fields).

You don’t need anthing so fancy for a simple script. So if your script isn’t going to be too complex then something like this works well… of course you’ll need to add error checking but this will get you started.

Enter something like the following in the dialog box:
1, 2, 3

display dialog "Give me 3 variables separated by a comma and a space..." default answer "var1, var2, var3" with icon note buttons {"Cancel", "OK"} default button "OK"

set theAnswer to text returned of result
set text item delimiters to ", "
set {var1, var2, var3} to text items of theAnswer
set text item delimiters to ""
return {var1, var2, var3}

Yes and no. AppleScript Studio referred to a particular way of making AS apps, using a framework that provided AS terminology for the parts of Cocoa it made available to scripters. AppleScriptObjC involves more-or-less writing Objective-C in AppleScript, so it doesn’t come under the umbrella of AppleScript Studio.

I’d like to repeat that in AppleScript Studio it was quite easy to create powerful applications just with ordinary AppleScript skills.
In AppleScriptObjC you stab around in the dark without knowing the basics of Objective-C

That’s basically true, if a bit overstated – many Studio scripters end up relying heavily on “call method” to get stuff done. But I’m not sure I see the point in (re)making the comparison. It’s like pining for creator types or any other technology that’s been abandoned – at this stage it won’t change things, and it doesn’t make Studio any more viable.

Personally, I think Facespan 5.0 was shaping up as a much better alternative than either Studio or AppleScriptObjC, but it too was abandoned. I was bitterly disappointed, but stuff happens. Hopefully you mourn, then move on.

Hi,

just to play around and get “dynamic” variables in a Recordlist you may …

Result:

{var_1:"var1", var_2:"var1", var_3:"var1"}
display dialog "Give me 3 variables separated by a comma and a space..." default answer "var1, var2, var3" with icon note buttons {"Cancel", "OK"} default button "OK"

set theAnswer to text returned of result
set text item delimiters to ", "
set theList to text items of theAnswer
set text item delimiters to ""

set RecordList to {}
set counter to 0
set theString to ""
repeat with i from 1 to count of theList
	set theItem to item 1 of theList
	set counter to counter + 1
	
	if counter is equal to (count of theList) then
		set theRecord to ("var_" & counter as text) & ":" & "\"" & theItem & "\""
	else
		set theRecord to ("var_" & counter as text) & ":" & "\"" & theItem & "\", "
	end if
	
	set theString to theString & theRecord
end repeat

set theRecordList to run script "{" & theString & "}"

So, if “ for example “ you would read the string for the variable out of any source, you would be able to create a Record like “{MySpecialEvent_1:“var1”, }”

Hope this makes sense … :confused:

A variation on comma-space-delimited entries would be return-delimited ones. If there’s a return in the default answer, the return key inserts returns instead of working the default button. The size of the text window depends on the number of returns in the default answer, but any number of lines can be entered:

tell (current date) to set example to (short date string of (it - days)) & return & (its short date string) & return & (short date string of (it + days))
display dialog "Give me 3 dates separated by returns..." default answer example with icon note buttons {"Cancel", "Click here when done"} -- No default button, to lessen confusion!
paragraphs of text returned of result

Well it wasn’t powerfull but Applescript-Studio was powerfull in making prototypes. What I can achieve in one day with Applescript-Studio you couldn’t do this in the same time with Objective-C. Just like Mr. Stanley said I couldn’t work without call method if I had to populate an NSPopupButtonCell. Also accessing third party classes must be done with call method. Well I’m testing with ApplescriptObjC and must say that the applications feels more responsive than Applescript-Studio. Table views feels much more quicker filled now while the old ‘append’ command was also quick.

I hope not to be misunderstood.

Of course ASOC is much more effective than AppleScript Studio.
And it"s much quicker, because you’re actually writing native Objective-C code wrapped with a AppleScript language bridge.
In AppleScript Studio you’ve written AppleScript code with those expensive Apple Events wrapped with a Cocoa bridge.

I just wanted to say that it takes longer to learn ASOC because you need basic knowledge of object oriented programming.

It’s a bit like the difference between iMovie and Final Cut

Asking the user to enter a comma delimited string of dates may be pushing the envelope of their skill set.

Perhaps something like this would be easier for them.

set ListOfDates to {} -- list to choose from

set myDates to {"", "", ""} -- user's choices

-- rem build list of dates
repeat with i from 0 to 10
	copy (short date string of ((current date) + i * days)) to end of ListOfDates
end repeat

repeat with choosingNumber from 1 to 3
	set promptString to ""
	repeat with i from 1 to 3
		if i = choosingNumber then
			set promptString to promptString & "ENTER"
		else
			set promptString to promptString & tab
		end if
		
		set promptString to promptString & tab & "Date" & (i as text) & " " & (item i of myDates) & linefeed
	end repeat
	
	set promptString to text 1 thru -2 of promptString

	set usersChoice to (choose from list ListOfDates with prompt promptString)
	
	if usersChoice = false then
		return false
	else
		set item choosingNumber of myDates to (item 1 of usersChoice)
	end if
end repeat
return myDates

I think the MultiDialog method below is a way to enter multiple values in one pass.

set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {linefeed}}

set NamesOfRecords to {"Item ", "Count", "Cost"} -- input three items
set DefaultValues to {} -- no defaults

set uiValues to MultiDialog(NamesOfRecords, DefaultValues)

if uiValues = false then
	return "cancel pressed"
else
	display dialog "User entered:" & linefeed & uiValues as string
	-- {"banana", 3, 0.45}
end if

-- second example
set NamesOfRecords to {"Name ", "Address", "City", "State", "Zip"} -- input 5 items
set DefaultValues to {"Mike", "123 Main", "Davis", "CA"} -- with defaults

set uiValues to MultiDialog(NamesOfRecords, DefaultValues)

if uiValues = false then
	return "cancel pressed"
else
	display dialog "User entered:" & linefeed & uiValues as string
end if

set AppleScript's text item delimiters to tid

-- END DEMO

on MultiDialog(DataNames, DataValues)
	
	repeat until (count of DataNames) ≤ (count of DataValues)
		copy "" to end of DataValues
	end repeat
	-- find longest name
	set maxName to 0
	set nameCount to count of DataNames
	repeat with i from 1 to nameCount
		set tempLen to length of (item i of DataNames)
		if maxName < tempLen then set maxName to tempLen
	end repeat
	-- adjust for name lengths
	set PaddedNames to {}
	repeat with i from 1 to nameCount
		set countOfTabs to ((maxName - (length of item i of DataNames)) / 4)
		--if 0 < countOfTabs then set countOfTabs to countOfTabs + 1
		copy ((item i of DataNames) & my strRepeat(tab, countOfTabs)) to end of PaddedNames
	end repeat
	
	set titleString to "Enter indicated value"
	set workValue to 1
	set uiButton to ""
	
	repeat until (uiButton = "Enter")
		-- concatenate Names and Values for Display
		set promptString to ""
		
		repeat with i from 1 to nameCount
			if i = workValue then
				set promptString to promptString & "Enter ->" & tab
			else
				set promptString to promptString & tab & tab
			end if
			
			set promptString to promptString & (item i of PaddedNames) & tab & tab & (item i of DataValues) & linefeed
		end repeat
		
		set butDefault to "Enter"
		repeat with i from 1 to nameCount
			if (item i of DataValues) = "" then set butDefault to "Next"
		end repeat
		
		try
			set uiDialog to display dialog promptString buttons {"Cancel", "Next", "Enter"} default answer (item workValue of DataValues) default button butDefault with title titleString
			
			set {uiValue, uiButton} to {text returned, button returned} of uiDialog
		on error
			set {uiValue, uiButton} to {"", "Cancel"}
		end try
		
		set item workValue of DataValues to uiValue -- update user entered value
		
		if uiButton = "Cancel" then
			-- return cancel value
			set DataValues to false
			set uiButton to "Enter"
		end if
		
		if uiButton = "Next" then
			-- incriment what is being entered
			set workValue to (workValue mod nameCount) + 1
		end if
	end repeat
	
	return DataValues
	
end MultiDialog

on strRepeat(aString, rptNumber)
	log rptNumber
	set retVal to ""
	repeat with i from 1 to rptNumber
		set retVal to retVal & aString
	end repeat
	return retVal
end strRepeat

Dear All,

Thank you for your input, and I hope that you have had a very happy Xmas. Due to weather/travel issues, I have been unable to look at the site for the last ten days, and so I have returned to an extraordinary amount of replies. I will try to go through the various responses posted above, and see where they all lead.

All my best wishes for the new year,

DDHawk.

This Script by Kai (whom some of you will recall) does what you want in plain vanilla AppleScript. It returns a list of the answers. There are 4 examples to choose from embedded in the script.


on multi_dialog for q given listing:l
	tell q as list
		set {a, b, c} to {{}, beginning, count}
		set v to b's class is integer
		if v then set {c, v, q} to {b, b is 0, rest}
	end tell
	if v then set c to 30
	repeat c + 1 div (1 + (system attribute "sysv") div 4160) times
		set a's end to ""
	end repeat
	set {d, text item delimiters} to {text item delimiters, return}
	set {q, a, text item delimiters} to {q as string, a as string, d}
	set r to (display dialog q default answer a)'s text returned
	if not v then tell r & a
		if l then return items 1 thru c of paragraphs
		if c > 1 then return text 1 thru paragraph c
	end tell
	tell r to repeat with i from (count paragraphs) to 1 by -1
		if (count paragraph i) is not 0 then
			if l then return paragraphs 1 thru i
			return text 1 thru paragraph i
		end if
	end repeat
	if l then return {}
	""
end multi_dialog

------------------
-- demonstration --
------------------

property l : {"1]  Name: {items: 2, length: fixed, output: list}", ¬
	"2]  Address: {items: 3, length: fixed, output: list}", ¬
	"3]  Reasons: {items: 6, length: fixed, output: list}", ¬
	"4]  ToDo List: {items: ?, length: variable, output: text}", ¬
	"5]  Standard: {items: 1, length: variable, output: text}"}

property d : l's item 1

tell (choose from list l default items d with prompt "Choose a multi-dialog demonstration:")
	if it is false then error number -128
	set d to it
	set i to item 1's item 1 as integer
end tell

--------------------
-- syntax examples --
--------------------

if i is 1 then
	multi_dialog for {"¢ What is your first name?", "¢ And your last name?"} with listing
else if i is 2 then
	multi_dialog for {3, "Please enter your:", "", "1: house number & street name", "2: city/area", "3: zip code"} with listing
else if i is 3 then
	multi_dialog for {6, "List up to six reasons to be cheerful:"} with listing
else if i is 4 then
	multi_dialog for {0, "To Do list for " & (current date)'s weekday & ":"} with listing
else
	multi_dialog for "Did you *really* just want a standard dialog?" without listing
end if


Ah, of course I remember this. One of the first scripts that showed me the possibilities of AppleScript. A very ingenious script!