Wednesday, December 13, 2017

#1 2007-05-14 07:00:50 am

kai
Member
From:: Brighton, UK
Registered: 2005-05-28
Posts: 912

A Single Dialog to Handle Multiple Entries

A question that seems to crop up from time to time goes something like this: "Can I create a dialog to take more than one entry in the same panel?

Typical advice might range from building a custom dialog in AppleScript Studio/Xcode to using a third-party scripting addition (OSAX) - such as 24U Appearance. All worthy suggestions since, depending on exactly what's required, most of the proposed solutions offer a variety of benefits. But they could also involve an additional learning curve, cost or complication that the enquirer may prefer to avoid - especially if the immediate aim is not overly ambitious.

Often, the purpose is merely to produce a dialog that takes a list as input. Ideally, this would allow the user to enter the list in a single panel, review it in context, edit items as required - and then, finally, confirm the result. Such a feature might be useful as a front end for entering data into some kind of database, or simply as a means of jotting down a general-purpose list. What a pity it can't be achieved with vanilla AppleScript...

Or can it?

The script below shows a way to extend a regular dialog so that it accepts multiple line entries. It then goes on to output entries - formatted either as text or as a list. Of course, the trick here is not really in the script - but in Standard Additions, which accepts the insertion of return characters in a dialog's default answer. However, the script demonstrates how the input and output could be formatted - and the multi_dialog handler might be handy for creating a series of multiple-entry dialogs more easily.

The following notes may help:

Input error checking
Input error checking, which would normally depend on individual circumstances anyway, is minimal. (This is left as an exercise for the reader.) wink

Input formatting
Single or multiple prompts can be entered in a prompt list to appear in the dialog either as standard text, separate questions/items - or a combination of both.

The number of entry rows displayed in a dialog can be set either implicitly (according to the number of prompts listed), or explicitly (by an integer inserted at the beginning of the prompt list).

If a string or a single-item list (with no integer to define the number of entry rows) is passed to the multi_dialog handler, the resulting dialog will behave pretty much like a standard dialog.

Output formatting
The resulting lists can be configured so that they are of either fixed or variable length:

Fixed-length lists
A fixed-length list is useful for situations where output is intended to populate a defined target range of cells or fields - so the length of the resulting list will remain unaltered, regardless of user input. If the entries in the list fall short of the expected number, the list will be padded with an appropriate number of trailing, empty strings. If the expected number is exceeded, the list will be truncated accordingly.

Variable-length lists
The variable-length option could be handy for producing lists of indeterminate length (such as shopping or to do items). In this case, the length of the output is dictated by the user. Variable-length lists are defined by inserting a zero integer at the beginning of the prompt list.

User input
Use a separate line for each answer/item. To add a new line in a dialog, simply press the return key. To confirm a set of answers/items, either press the enter key - or click OK.


The script, which includes a few syntax examples, also demonstrates how the size of a dialog's entry panel is defined by the prompt list:

Applescript:


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


kai


Filed under: Dialog, Bell, MultiEntry, Kai

Offline

 

#2 2009-02-03 10:06:28 am

MacAnswerMan
Member
Registered: 2008-10-02
Posts: 1

Re: A Single Dialog to Handle Multiple Entries

I added the (option shift) line breaks mid-script to allow it to work...

Impressive script Kai!

Applescript:

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

Offline

 

#3 2014-09-19 09:33:38 am

rocketjam
Member
Registered: 2007-07-31
Posts: 8

Re: A Single Dialog to Handle Multiple Entries

When trying to run this I get "Can't get text item delimiters" with the second list in this line "set {d, text item delimiters} to {text item delimiters, return} highlighted. Suggestions?

Offline

 

#4 2014-10-11 01:29:42 pm

McUsrII
Member
Registered: 2012-11-21
Posts: 3046
Website

Re: A Single Dialog to Handle Multiple Entries

Hello.

I think that somehow, an illegal character has been incorporated in your script, because MacAnswerMan's script worked for me. I tried all options.

If the scipt compiles, then I'd try to

Applescript:

set AppleScript's text item delimiters to ""

at the  top of the script. HTH

Last edited by McUsrII (2014-10-11 01:31:16 pm)

Offline

 

#5 2014-10-11 01:47:41 pm

Adam Bell
Administrator
From:: Nova Scotia, Canada
Registered: 2005-10-04
Posts: 4660

Re: A Single Dialog to Handle Multiple Entries

If any script requiring text item delimiters you are testing fails persistently, McUsrII's solution should always be your first trial. It is easy to forget that text item delimiters are persistent which is why structures like this are always recommended:

Applescript:

set tid to AppleScript's text item delimiters
set applescript's text item delimiters to "search item here"
set tParts to text items of 'ref to text to be searched'
set AppleScript's text item delimiters to tid

Further when you're testing a complex parsing operation and it fails, the TID's are left where they were at the point of failure.


iMac running OS X 10.13.1

Offline

 

#6 2014-10-13 08:50:08 am

rocketjam
Member
Registered: 2007-07-31
Posts: 8

Re: A Single Dialog to Handle Multiple Entries

Thanks McUsril and Adam Bell for the tips. Turns out that wasn't the problem though. I was trying to run this in Smile and it won't run there without throwing that error about the text item delimiters. Copied the same script to the Script Editor and it runs fine there. No idea why Smile doesn't like it.

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)