Prompts

This is where things get interesting, but a bit more tricky; I hope some examples will simplify things.

As seen in the definition, the following types of AnyBox.InputTypes are allowed:

  • Text (default)
  • FileOpen
  • FileSave
  • FolderOpen
  • Checkbox
  • Password
  • Date
  • Link

The options provided to each prompt type include:

  • Name
  • InputType
  • Message
  • MessagePosition
  • DefaultValue
  • LineHeight
  • ReadOnly
  • ValidateNotEmpty
  • ValidateSet
  • ValidateScript

Similar to buttons, the hashtable returned by the AnyBox will contain key-value pairs for each prompt and the user input. If no Name is provided for the prompt, it will be auto-assigned with Input_#, where # is the index of the prompt, starting from zero.

Since v0.3.0, prompts are now even easier to create. Instead of using New-AnyBoxPrompt, you can just pass a string containing the prompt message, similar to how buttons are specified. Of course, New-AnyBoxPrompt opens you up to more options.

InputType.Text

Text is the default input type, so the simplest example is:

Show-AnyBox -Prompt '' -Buttons 'Submit'

Name		Value
----		-----
Input_0		Hello world
Submit		True

Here is an example use a DefaultValue and the LineHeight property set to 5

[string]$default_qry = @"
SELECT
  Name, COUNT(*) [Total]
FROM Table
WHERE Value < 10
GROUP BY Name
ORDER BY Timestamp
"@

[AnyBox.Prompt]$prompt = @{
  Message = 'Enter your query:'
  DefaultValue = $default_qry
  LineHeight = 5
  ValidateNotEmpty = $true
}

Show-AnyBox -Prompt $prompt -Buttons 'Cancel', 'Execute' -CancelButton 'Cancel' `
  -ContentAlignment 'Left' -MinWidth 300

Validate

Getting user input is not the only struggle. Often, a bigger struggle is validating the user input we get. AnyBox aims to make that simpler by use of any of three prompt options:

  • ValidateNotEmpty
  • ValidateSet
  • ValidateScript

-ValidateNotEmpty is the simplest; the AnyBox will not proceed until some input is entered (or the specified cancel button is selected).

-ValidateSet has some interesting behavior; it will replace the text box with a combo box to ensure whatever the user selects is in the given set.

$prompt = New-AnyBoxPrompt -Name 'fav_sport' `
  -Message 'What is your favorite sport?' `
  -ValidateSet @('Basketball', 'Football', 'Baseball', 'Soccer', 'Hockey', 'Other') `
  -DefaultValue 'Baseball'

Show-AnyBox -Icon 'Question' -Prompt $prompt -Buttons 'OK'

Name                           Value
----                           -----
OK                             True
fav_sport                      Baseball

By default, when options are provided to -ValidateSet, the options are presented as a dropdown box. Sets can now be presented as radio buttons using the -ShowSetAs parameter and specifying one of “Radio” or “Radio_Wide”.

$prompts = @(New-Prompt -Message 'Default Combo' -ValidateSet 'one', 'two', 'three' -ShowSeparator)
$prompts += @(New-Prompt -Message 'Radio' -ValidateSet 'one', 'two', 'three' -ShowSetAs 'Radio' -ShowSeparator)
$prompts += @(New-Prompt -Message 'Radio Wide' -ValidateSet 'one', 'two', 'three' -ShowSetAs 'Radio_Wide' -ShowSeparator)

Show-AnyBox -Prompts $prompts -Buttons 'one', 'two', 'three'

With -ValidateScript, the options are endless. If the script block you provide returns $true, the user input is considered valid.

$prompt = New-AnyBoxPrompt -Message 'Enter any number between 0 and 100:' `
  -ValidateScript { [int]$_ -ge 0 -and [int]$_ -le 100 }

Show-AnyBox -Prompt $prompt -Buttons 'Submit'

InputType.File[Open|Save]

The input types FileOpen and FileSave are similar to Text, with the addition of a button to the left of the textbox that opens either a OpenFileDialog or SaveFileDialog window, respectively.

Show-AnyBox -MinWidth 350 -Buttons 'Cancel', 'Submit' -Prompt @(
  (New-AnyBoxPrompt -InputType 'FileOpen' -Message 'Open File:' -ReadOnly),
  (New-AnyBoxPrompt -InputType 'FileSave' -Message 'Save File:' -ReadOnly),
  (New-AnyBoxPrompt -InputType 'FolderOpen' -Message 'Open Folder:' -ReadOnly)
)

InputType.Password

When the Password input type is specified, the user is presented a PasswordBox instead of a TextBox, so the password is masked and returned as a security string.

Show-AnyBox -Buttons 'Cancel', 'Login' -Prompt @(
  (New-AnyBoxPrompt -InputType 'Text' -Message 'User Name:' -ValidateNotEmpty),
  (New-AnyBoxPrompt -InputType 'Password' -Message 'Password:' -ValidateNotEmpty)
)

Name	Value
----	-----
Cancel	False
Input_0	donald
Input_1	System.Security.SecureString
Login	True

InputType.CheckBox

The Checkbox input is straightforward:

Show-AnyBox -Icon 'Question' -Buttons 'Cancel', 'Ignore' `
	-Message 'An error occurred. (Code=123)' `
	-Prompts (New-AnyBoxPrompt -InputType 'Checkbox' -Message "Don't ask again." -DefaultValue $true)

InputType.Date

The Date input is also fairly straightforward:

$p = New-AnyBoxPrompt -InputType 'Date' -Message 'Show all events after:' `
  -DefaultValue ((Get-Date).AddDays(-7)) -ValidateNotEmpty

Show-AnyBox -Buttons 'OK' -Prompt $p

The last of the available input types is Link. This type has some unique, useful behavior that is unlike the others. When specified, the user is presented with a link that, when clicked, can open a web url, a directory, or launch a program.

The provided Message is the link text. The provided DefaultValue is the link destination. The result of the AnyBox will show whether or not the link was clicked.

Show-AnyBox -Buttons 'OK' -MinWidth 200 -Prompt @(
    (New-AnyBoxPrompt -InputType 'Link' -Message 'My Files' -DefaultValue $env:USERPROFILE),
    (New-AnyBoxPrompt -InputType 'Link' -Message 'Reddit' -DefaultValue 'www.reddit.com' -ValidateNotEmpty),
    (New-AnyBoxPrompt -InputType 'Link' -Message 'Notepad' -DefaultValue 'notepad.exe')
)
Name      Value
----      -----
Input_2   False
OK        True
Input_0   False
Input_1   True

If -ValidateNotEmpty is specified, the user will be forced to click the link before proceeding.

Prompt Example

Prompts can be built dynamically. Here is a quick example:

$prompts = 1..7 | foreach {
  $type = [AnyBox.InputType]$_
  New-AnyBoxPrompt -InputType $type -Name "$type`_input" -Message "$type Input:"
}

$buttons = 1..6 | foreach {
  "Button $_"
}

$answer = Show-AnyBox -Prompt $prompts -Buttons $buttons -ButtonRows 2 -MinWidth 400

PS C:\> $answer

Name                           Value
----                           -----
Button 6                       False
Button 4                       True
FileOpen_input                 C:\Temp\Logs\old.log
Password_input                 System.Security.SecureString
Button 5                       False
Text_input                     hello world
Checkbox_input                 True
Date_input                     3/12/2018
Button 2                       False
Link_input                     False
Button 3                       False
Button 1                       False
FileSave_input                 C:\Temp\Logs\new.log
PS C:\> $prompts | select Name, Message, @{Name='UserInput';Expression={ $answer[$_.Name] }}

Name           Message         UserInput
----           -------         ---------
Text_input     Text Input:     hello world
FileOpen_input FileOpen Input: C:\Temp\Logs\old.log
FileSave_input FileSave Input: C:\Temp\Logs\new.log
Checkbox_input Checkbox Input: True
Password_input Password Input: System.Security.SecureString
Date_input     Date Input:     3/12/2018
Link_input     Link Input:     False

Prompt Grouping/Collapsing

Prompts are collapsible since v0.3.0.

$prompts = @(New-Prompt -Message 'This')
$prompts += @(New-Prompt -Message 'That' -Collapsible)
$prompts += @(New-Prompt -Message 'The other' -Collapsible)

Show-AnyBox -Prompts $prompts -Buttons 'OK'

AnyBox v0.3.0 introduces several ways to separate and/or group prompts. The most basic way is to specify the -ShowSeparator switch which, when specified, prints a horizontal line below the prompt. The -Group switch accepts a string and groups prompts that have the same group name. If the provided group name contains no word characters (e.g., only digits), the group name is not printed; otherwise, it will be printed. Similarly, -Tab accepts a string and shows prompts with the same tab name in the specified tab. Here’s an example showcasing each of these new options.

$prompts = @(New-Prompt -Message 'Prompt 1:' -ShowSeparator)
$prompts += @(New-Prompt -Group 1 -Message 'Prompt 2:' -ShowSeparator)
$prompts += @(New-Prompt -Group 1 -Message 'Prompt 3' -InputType 'Checkbox' -Alignment 'Center')
$prompts += @(New-Prompt -Group 'MyGroup' -Message 'Prompt 4:' -InputType 'Date' -ShowSeparator)
$prompts += @(New-Prompt -Group 'MyGroup' -Message 'Prompt 5:' -InputType 'FileOpen' -ReadOnly -ShowSeparator)
$prompts += @(New-Prompt -Group 'MyGroup' -Message 'Prompt 6:' -InputType 'FileSave' -ReadOnly -Collapsible)
$prompts += @(New-Prompt -Tab 'ThisTab' -Message 'Prompt 7:' -ShowSeparator)
$prompts += @(New-Prompt -Tab 'ThisTab' -Message 'Prompt 8:')
$prompts += @(New-Prompt -Tab 'ThatTab' -Message 'Prompt 9:' -ShowSeparator)
$prompts += @(New-Prompt -Tab 'ThatTab' -Message 'Prompt 10:')

Show-AnyBox -Prompts $prompts -Buttons 'Cancel', 'Continue' -AccentColor 'Gray'

Notice the use of -AccentColor in the call to Show-AnyBox. This parameter can be used to specify the color of the lines for the separator lines, group box lines, etc.

Similar to the -Collapsible switch for a prompt, an entire prompt group can be made collapsible by specifying -CollapsibleGroups to Show-AnyBox.

Show-AnyBox -Prompts $prompts -Buttons 'Cancel', 'Continue' -AccentColor 'CornflowerBlue' -CollapsibleGroups