(Optional) dynamic autocomplete in form not working as expected

So, I’ve built out this example to hopefully make it easy to test.

Essentially, what I’m trying to build is a dashboard to handle asset management.
The workflow should be…

  1. Assign to Location
  2. Choose Status
    • If it is deployed, show a radio group to then select who or what it is assigned to.
      • When option is selected in Radio Group, give a list of users or rooms (if user/room radio button was selected)

Currently in the dashboard if I choose a location, then choose “Deployed”, and then choose to deploy to the Location, it works.

If a User or Room is selected, the form doesn’t validate, despite the logic working outside of PSU.

If User or Room is selected, and then I select “location”, it keeps formdata from the autocomplete that is no longer there, which then causes form validation to fail.

New-UDDashboard -Title 'PowerShell Universal' -Content {
    $Locations = @("Detroit", "Chicago")
    $Rooms = @{
        Chicago = @("North Conference", "Hoteling 1")
        Detroit = @("Board Room", "Conference Room 1", "Conference Room 2")
    }
    New-UDForm -id 'frmTest' -Content {
        New-UDGrid -ExtraSmallSize 4 -Children {
            $LCHeader = New-UDCardHeader -Title "Location"
            $LCBody = New-UDCardBody -Content {
                New-UDRow -Columns {
                    New-UDAutocomplete -Id 'atcLocation' -Options $Locations -label 'Location' -OnChange {
                        ($Session:Location = Get-UDElement 'atcLocation' | Select-Object -ExpandProperty Value)
                        Sync-UDElement -id 'dynAssignedTo'
                    } -FullWidth
                }
            }
            New-UDCard -Body $LCBody -Header $LCHeader
        }
        New-UDGrid -Item -ExtraSmallSize 4 -Children {
            $ANHeader = New-UDCardHeader -Title "Assignment"
            $ANBody = New-UDCardBody -Content {
                New-UDRow -Columns {
                    New-UDGrid -Item -ExtraSmallSize 2 -Content {
                        New-UDAutocomplete -Id 'atcStatus' -Options @("In-Stock", "Deployed") -Label 'Status' -OnChange {
                            Show-UDToast $Body 
                            If ($Body -eq 'Deployed') {
                                Set-UDElement -id 'rdUser' -Properties @{ Disabled = $false }
                                Set-UDElement -id 'rdLocation' -Properties @{ Disabled = $false }
                                Set-UDElement -id 'rdRooms' -Properties @{ Disabled = $false }
                            }
                            else {
                                Sync-UDElement -id 'dynAssignment'
                                Test-UDForm -Id 'frmNewAsset'
                            }
                            If ($Body -eq 'Deployed') {
                                Set-UDElement -id 'rdAssignmentUser' -Properties @{ Disabled = $false }
                                Set-UDElement -id 'rdAssignmentLocation' -Properties @{ Disabled = $false }
                            }
                            else {
                                Set-UDElement -id 'rdAssignmentUser' -Properties @{ Disabled = $true }
                                Set-UDElement -id 'rdAssignmentLocation' -Properties @{ Disabled = $true }
                            }
                            Sync-UDElement -id 'dynAssignedTo'
                        }
                    }
                }
                New-UDDynamic -id 'dynAssignment' -Content {
                    $rdlayout = '{"lg":[{"w":1,"h":1,"x":0,"y":0,"i":"grid-element-rdUser","moved":false,"static":false},{"w":1,"h":1,"x":1,"y":0,"i":"grid-element-rdLocation","moved":false,"static":false},{"w":1,"h":1,"x":2,"y":0,"i":"grid-element-rdRooms","moved":false,"static":false}]}'
                    New-UDRadioGroup -Id 'rdgAssignment' -Children {
                        New-UDGrid -Container -Spacing 1 -Children {
                            New-UDGridLayout -Content {
                                New-UDRadio -Id 'rdUser' -Label 'User' -Value 'Users' -Disabled
                                New-UDRadio -Id 'rdLocation' -Label 'Location' -Value 'Locations' -Disabled
                                New-UDRadio -Id 'rdRooms' -Label 'Room' -Value 'Rooms' -Disabled
                            } -Layout $rdlayout
                        }
                    } -OnChange {
                        Sync-UDElement -id 'dynAssignedTo'
                        Invoke-UDForm -id 'frmTest'
                    }
                }
                New-UDDynamic -id 'dynAssignedTo' -Content {
                    if ((Get-UDElement -id 'rdgAssignment').value -eq 'Users') {
                        New-UDAutocomplete -id 'atcAssignedTo' -Label 'Assigned To' -Options @("John","Bob")
                    } elseif ((Get-UDElement -id 'rdgAssignment').value -eq 'Rooms') {
                        New-UDAutocomplete -id 'atcAssignedTo' -Label 'Assigned To' -Options ($Rooms[$Session:Location])
                    }
                }
            }
            New-UDCard -Header $ANHeader -Body $ANBody
            
        }
    } -OnValidate {
        Show-UDToast -message ($EventData | ConvertTo-Json) -Duration 50000
        if ($EventData.atcLocation -notmatch ($Locations -join '|')) {
            New-UDFormValidationResult -ValidationError "Please select a Location"
        }
        elseif ($EventData.atcStatus -eq 'Deployed') {
            If (($EventData.rdgAssignment -match 'Users|Rooms') -and ($EventData.atcAssignedTo -eq '')) {
                New-UDFormValidationResult -ValidationError "Please assign to $($matches[0].trimend("s"))"
            }
        }
        else {
            New-UDFormValidationResult -Valid
        }
    } -OnSubmit {
        Show-UDToast -Message ($EventData | ConvertTo-Json) -Duration 50000
    }
}
Product: PowerShell Universal
Version: 3.3.4

I had to change the validation logic a bit. What was happening was when it was valid, it wasn’t falling through to an else to return a valid validation result so it just stayed invalid.

-OnValidate {
        Show-UDToast -message ($EventData | ConvertTo-Json) -Duration 50000
        if ($EventData.atcLocation -notmatch ($Locations -join '|')) {
            New-UDFormValidationResult -ValidationError "Please select a Location"
        }
        elseif ($EventData.atcStatus -eq 'Deployed' -and ($EventData.rdgAssignment -Match "Users|Rooms")) {
            If ($EventData.atcAssignedTo -eq '') {
                New-UDFormValidationResult -ValidationError "Please assign to $($matches[0].trimend("s"))"
            } else {
                New-UDFormValidationResult -Valid
            }
        }
        else {
            New-UDFormValidationResult -Valid
        }
    }
1 Like

Ahhh, thanks! I swear, sometimes I just need a second set of eyes on things…

There is one other thing, which shouldn’t affect building the rest of the dashboard, but might be worth looking into for the sake of form cleanliness?

If you select deploy, then select a user or room and assign it, then click Location, $EventData.atcAssignedTo still returns data, despite the element no longer being there. I can get around it in my case because I need to run different scriptblocks on submit for User,Location, and Room. But if I was piping $EventData directly to a function things may fail.