Select
With label
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let basicSelect =
Select.create "updateFrequency" "Update frequency" id [
Select.option "daily" "Daily"
Select.option "weekly" "Weekly"
Select.option "monthly" "Monthly" ]
|> Select.withSelected "weekly"
|> Select.renderWith help text
Choose how often to receive a summary.
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let selectWithHelp =
Select.create "digestFrequency" "Digest frequency" id [
Select.option "daily" "Daily"
Select.option "weekly" "Weekly"
Select.option "monthly" "Monthly" ]
|> Select.withDescription "Choose how often to receive a summary."
|> Select.withPlaceholder "Choose a frequency"
|> Select.renderRequired selection with validation
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
type AccountStatus =
| Active
| Pending
| Suspended
| Scheduled
let private statusValue = function
| Active -> "active"
| Pending -> "pending"
| Suspended -> "suspended"
| Scheduled -> "scheduled"
let private selectStatusOptions =
[ Select.option Active "Active"
Select.option Pending "Pending"
Select.option Suspended "Suspended" |> Select.disable
Select.option Scheduled "Scheduled" ]
let private choiceSubmitButton id (label:string) =
Button.create label
|> Button.withVariant ButtonVariant.Primary
|> Button.asSubmit
|> Button.withAttributes [ _id id ]
|> Button.render
let private choiceResult id result =
output {
_id id
_role "status"
_class "block min-h-5 text-sm text-[var(--fve-muted-text)]"
defaultArg result "Submit this ordinary form to see the server-owned result."
}
let selectFormRegion selected validation result =
let config =
Select.create "status" "Status" statusValue selectStatusOptions
|> Select.withId "components-status"
|> Select.withDescription "Controls whether the account can receive entries."
|> Select.withPlaceholder "Choose a status"
|> Select.required
|> (match selected with Some value -> Select.withSelected value | None -> id)
|> (match validation with Some message -> Select.withValidation message | None -> id)
div {
_id "components-select-form-region"
_class "grid max-w-sm gap-3"
form {
_dataOn ("submit", "@post('/components/choices/select')")
_class "grid gap-3"
config |> Select.render
choiceSubmitButton "components-select-submit" "Validate status"
}
choiceResult "components-select-result" result
}
let statusSelect = selectFormRegion None None NoneDisabled
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
type AccountStatus =
| Active
| Pending
| Suspended
| Scheduled
let private statusValue = function
| Active -> "active"
| Pending -> "pending"
| Suspended -> "suspended"
| Scheduled -> "scheduled"
let private selectStatusOptions =
[ Select.option Active "Active"
Select.option Pending "Pending"
Select.option Suspended "Suspended" |> Select.disable
Select.option Scheduled "Scheduled" ]
let disabledStatusSelect =
Select.create "status" "Disabled status" statusValue selectStatusOptions
|> Select.withId "components-disabled-status"
|> Select.withSelected Active
|> Select.disabled
|> Select.renderPending
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
type AccountStatus =
| Active
| Pending
| Suspended
| Scheduled
let private statusValue = function
| Active -> "active"
| Pending -> "pending"
| Suspended -> "suspended"
| Scheduled -> "scheduled"
let private selectStatusOptions =
[ Select.option Active "Active"
Select.option Pending "Pending"
Select.option Suspended "Suspended" |> Select.disable
Select.option Scheduled "Scheduled" ]
let pendingStatusSelect =
Select.create "status" "Updating status" statusValue selectStatusOptions
|> Select.withId "components-pending-status"
|> Select.withSelected Pending
|> Select.pending
|> Select.renderMultiple selection
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let multipleMembersSelect =
Select.create "memberIds" "Team members" id memberOptions
|> Select.multiple
|> Select.withPlaceholder "Choose members"
|> Select.renderWith several selected
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let selectedMembersSelect =
Select.create "assignedIds" "Assigned members" id memberOptions
|> Select.multiple
|> Select.withSelectedMany [ "alex"; "jamie"; "riley" ]
|> Select.renderMultiple selection with validation
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let private choiceSubmitButton id (label:string) =
Button.create label
|> Button.withVariant ButtonVariant.Primary
|> Button.asSubmit
|> Button.withAttributes [ _id id ]
|> Button.render
let private choiceResult id result =
output {
_id id
_role "status"
_class "block min-h-5 text-sm text-[var(--fve-muted-text)]"
defaultArg result "Submit this ordinary form to see the server-owned result."
}
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let multipleSelectForm selected validation result =
div {
_id "components-multiple-select-form-region"
_class "grid gap-3"
form {
_ariaLabel "Project reviewers"
_novalidate true
_dataOn ("submit", "@post('/components/choices/multiple-select', {contentType: 'form'})")
_class "grid gap-3"
Select.create "reviewerIds" "Reviewers" id memberOptions
|> Select.withId "components-reviewers"
|> Select.multiple
|> Select.withSelectedMany selected
|> Select.withDescription "Choose one to three reviewers."
|> Select.required
|> (match validation with Some message -> Select.withValidation message | None -> id)
|> Select.render
choiceSubmitButton "components-reviewers-submit" "Validate reviewers"
}
choiceResult "components-reviewers-result" result
}Submit to check the selection. This example does not save your data.
Multiple selection, disabled
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let disabledMembersSelect =
Select.create "disabledMemberIds" "Disabled members" id memberOptions
|> Select.multiple
|> Select.withSelectedMany [ "alex"; "jamie" ]
|> Select.disabled
|> Select.renderMultiple selection, pending
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let pendingMembersSelect =
Select.create "pendingMemberIds" "Updating members" id memberOptions
|> Select.multiple
|> Select.withSelectedMany [ "alex"; "jamie" ]
|> Select.pending
|> Select.renderSearchable
Loading options
No matching options
Filter locally supplied typed options.
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let private accounts = [ 101, "Operating"; 102, "Tax reserve"; 103, "Payroll clearing" ]
let private accountOptions values =
values
|> List.map (fun (value, label) ->
Select.option value label
|> (if value = 103 then Select.disable else id))
let staticAccountCombobox =
Select.create "staticAccount" "Static account" string (accountOptions accounts)
|> Select.withId "components-static-account"
|> Select.withSearch SelectSearch.Static
|> Select.withSelected 101
|> Select.withDescription "Filter locally supplied typed options."
|> Select.renderSearchable with remote results
Loading accounts
No matching accounts
Results remain authoritative on the server.
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let private accounts = [ 101, "Operating"; 102, "Tax reserve"; 103, "Payroll clearing" ]
let private accountOptions values =
values
|> List.map (fun (value, label) ->
Select.option value label
|> (if value = 103 then Select.disable else id))
let private accountComboboxConfig =
Select.create "account" "Parent account" string (accountOptions accounts)
|> Select.withPlaceholder "Search accounts"
|> Select.withDescription "Results remain authoritative on the server."
|> Select.withEmptyMessage "No matching accounts"
|> Select.withLoadingMessage "Loading accounts"
|> Select.withSearch (SelectSearch.Remote "/components/accounts/search")
let accountCombobox = accountComboboxConfig |> Select.render
let accountComboboxOptions query retry =
if String.Equals(query, "error", StringComparison.OrdinalIgnoreCase) && retry |> not then
accountComboboxConfig
|> Select.withSearch (SelectSearch.Remote "/components/accounts/search?retry=true")
|> Select.withError "Accounts could not be loaded."
|> Select.renderOptions
else
accounts
|> List.filter (fun (_, label) -> String.IsNullOrWhiteSpace query || label.Contains(query, StringComparison.OrdinalIgnoreCase))
|> accountOptions
|> fun options -> accountComboboxConfig |> Select.withOptions options |> Select.renderOptionsSearch Operating for a result, an unknown name for no matches, or error to try failure and retry.
Searchable with validation
Loading options
No matching options
Choose an account before continuing.
Choose an available account.
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let private accounts = [ 101, "Operating"; 102, "Tax reserve"; 103, "Payroll clearing" ]
let private accountOptions values =
values
|> List.map (fun (value, label) ->
Select.option value label
|> (if value = 103 then Select.disable else id))
let validationAccountCombobox =
Select.create "validatedAccount" "Account with validation" string (accountOptions accounts)
|> Select.withId "components-validated-account"
|> Select.withSearch SelectSearch.Static
|> Select.withDescription "Choose an account before continuing."
|> Select.withValidation "Choose an available account."
|> Select.renderSearchable, loading
Loading accounts
No matching options
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let loadingAccountCombobox =
Select.create "loadingAccount" "Loading account" string []
|> Select.withId "components-loading-account"
|> Select.withSearch (SelectSearch.Remote "/components/accounts/search")
|> Select.withLoadingMessage "Loading accounts"
|> Select.loading
|> Select.renderSearchable, disabled
Loading options
No matching options
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let private accounts = [ 101, "Operating"; 102, "Tax reserve"; 103, "Payroll clearing" ]
let private accountOptions values =
values
|> List.map (fun (value, label) ->
Select.option value label
|> (if value = 103 then Select.disable else id))
let disabledAccountCombobox =
Select.create "disabledAccount" "Disabled account" string (accountOptions accounts)
|> Select.withId "components-disabled-account"
|> Select.withSearch SelectSearch.Static
|> Select.withSelected 101
|> Select.disabled
|> Select.renderSearchable, pending
Loading options
No matching options
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let private accounts = [ 101, "Operating"; 102, "Tax reserve"; 103, "Payroll clearing" ]
let private accountOptions values =
values
|> List.map (fun (value, label) ->
Select.option value label
|> (if value = 103 then Select.disable else id))
let pendingAccountCombobox =
Select.create "pendingAccount" "Updating account" string (accountOptions accounts)
|> Select.withId "components-pending-account"
|> Select.withSearch SelectSearch.Static
|> Select.withSelected 102
|> Select.pending
|> Select.renderSearchable multiple selection
Loading options
No matching options
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let multipleMembersCombobox =
Select.create "searchMemberIds" "Search members" id memberOptions
|> Select.withSearch SelectSearch.Static
|> Select.multiple
|> Select.withSelectedMany [ "alex"; "jamie" ]
|> Select.renderSearchable multiple selection with remote results
Loading options
No matching options
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let remoteMembersConfig =
Select.create "remoteMemberIds" "Remote members" id memberOptions
|> Select.withId "components-remote-members"
|> Select.multiple
|> Select.withSelectedMany [ "alex" ]
|> Select.withPlaceholder "Search members"
|> Select.withSearch (SelectSearch.Remote "/components/members/search")
let remoteMembersCombobox =
div {
_class "grid gap-3"
remoteMembersConfig |> Select.render
button {
_type "button"
_dataOn ("click", "@get('/components/members/field')")
_class "min-h-8 text-sm text-[var(--fve-brand-text)] underline underline-offset-2"
"Refresh members"
}
}
let searchMemberOptions (query:string) =
[ "alex", "Alex Morgan"; "jamie", "Jamie Lee"; "riley", "Riley Chen"; "taylor", "Taylor Brooks" ]
|> List.filter (fun (_, label) -> label.Contains(query, StringComparison.OrdinalIgnoreCase))
|> List.map (fun (value, label) -> Select.option value label)
let remoteMembersField query =
remoteMembersConfig
|> Select.withQuery query
|> Select.withOptions (searchMemberOptions query)
|> Select.render
let remoteMembersOptions query retry =
let config = remoteMembersConfig |> Select.withQuery query
if String.Equals(query, "error", StringComparison.OrdinalIgnoreCase) then
if retry then config |> Select.renderOptions
else
config
|> Select.withSearch (SelectSearch.Remote "/components/members/search?retry=true")
|> Select.withError "Members could not be loaded."
|> Select.renderOptions
else
config |> Select.withOptions (searchMemberOptions query) |> Select.renderOptionsSearch for Jamie or Riley, an unknown name for no matches, or error to try recovery.
Searchable multiple selection with validation
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let private choiceSubmitButton id (label:string) =
Button.create label
|> Button.withVariant ButtonVariant.Primary
|> Button.asSubmit
|> Button.withAttributes [ _id id ]
|> Button.render
let private choiceResult id result =
output {
_id id
_role "status"
_class "block min-h-5 text-sm text-[var(--fve-muted-text)]"
defaultArg result "Submit this ordinary form to see the server-owned result."
}
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let multipleComboboxForm selected validation result =
div {
_id "components-multiple-combobox-form-region"
_class "grid gap-3"
form {
_ariaLabel "Project assignees"
_novalidate true
_dataOn ("submit", "@post('/components/choices/multiple-combobox', {contentType: 'form'})")
_class "grid gap-3"
Select.create "assigneeIds" "Assignees" id memberOptions
|> Select.withId "components-assignees"
|> Select.withSearch SelectSearch.Static
|> Select.multiple
|> Select.withSelectedMany selected
|> Select.withDescription "Choose one to three assignees."
|> Select.required
|> (match validation with Some message -> Select.withValidation message | None -> id)
|> Select.render
choiceSubmitButton "components-assignees-submit" "Validate assignees"
}
choiceResult "components-assignees-result" result
}Submit to check the selection. This example does not save your data.
Searchable multiple selection, loading
Loading options
No matching options
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let loadingMembersCombobox =
Select.create "loadingSearchIds" "Loading members" id memberOptions
|> Select.withSearch SelectSearch.Static
|> Select.multiple
|> Select.withSelectedMany [ "alex" ]
|> Select.loading
|> Select.renderSearchable multiple selection, disabled
Loading options
No matching options
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let disabledMembersCombobox =
Select.create "disabledSearchIds" "Disabled search members" id memberOptions
|> Select.withSearch SelectSearch.Static
|> Select.multiple
|> Select.withSelectedMany [ "alex"; "jamie" ]
|> Select.disabled
|> Select.renderSearchable multiple selection, pending
Loading options
No matching options
open System
open FSharp.ViewEngine
open Acme.Components.Primitives
open Acme.Components.Application
open type Html
open type Svg
open type Datastar
let memberOptions =
[ Select.option "alex" "Alex Morgan"
Select.option "jamie" "Jamie Lee"
Select.option "riley" "Riley Chen"
Select.option "taylor" "Taylor Brooks"
Select.option "sam" "Sam Rivera" |> Select.disable ]
let pendingMembersCombobox =
Select.create "pendingSearchIds" "Updating search members" id memberOptions
|> Select.withSearch SelectSearch.Static
|> Select.multiple
|> Select.withSelectedMany [ "alex"; "jamie" ]
|> Select.pending
|> Select.render