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???
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
@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.
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”, }”
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.
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
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.
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