Product: PowerShell Universal Version: 5.5.2
New-UDPage -Url '/EditRoomDefaults' -Name 'Edit Room Mailbox Config' -Content {
New-UDTypography -Text 'Edit Room Mailbox Config' -Variant 'h4' -Id 'pageTitle'
Import-Module ActiveDirectory
# Setup basic form
New-UDForm -Id 'roomConfigForm' -Content {
New-UDRow -Columns {
New-UDColumn -Size 2 -Content {
# create a single textbox with verifcations to AD, update UI 'on the fly'
New-UDTextbox -Id 'txtMailboxEmailAddress' -Label 'mailbox address' -Placeholder 'yaya@domain.com ' -Value 'toure@domain.com' -FullWidth -OnValidate {
$FoundMailbox = $null
$Mail = (Get-UDElement -Id 'txtMailboxEmailAddress').value
if (-not [string]::IsNullOrEmpty($Mail))
{
try
{
# $FoundMailbox = Get-ADUser -LDAPFilter "(mail=$($Mail.ToLower()))" -ErrorAction Stop
$FoundMailbox = $true
}
catch
{
Set-UDElement -Id 'errorEmail' -Properties @{ Content = "Error checking email: $($_.Exception.Message)" }
}
if ($FoundMailbox)
{
Set-UDElement -Id 'txtMailboxEmailAddress' -Properties @{ Value = "$Mail" } # Or $FoundMailbox.mail if you want the AD value
Set-UDElement -Id 'errorEmail' -Properties @{ Content = '' }
Set-UDElement -Id 'txtMailboxEmailAddress' -Properties @{ Icon = (New-UDIcon -Icon Check -Style @{ color = 'green' }) }
New-UDFormValidationResult -Valid # Email is valid
}
else
{
Set-UDElement -Id 'txtMailboxEmailAddress' -Properties @{ Value = "$Mail" }
Set-UDElement -Id 'errorEmail' -Properties @{ Content = "Email address '$mail' doesn't exist." }
Set-UDElement -Id 'txtMailboxEmailAddress' -Properties @{ Icon = (New-UDIcon -Icon Xmark -Style @{ color = 'red' }) }
}
}
elseif ([string]::IsNullOrEmpty($Mail))
{
Set-UDElement -Id 'errorEmail' -Properties @{ Content = 'Mail is required.' }
Set-UDElement -Id 'txtMailboxEmailAddress' -Properties @{ Icon = (New-UDIcon -Icon Xmark -Style @{ color = 'red' }) }
}
}
New-UDElement -Tag 'div' -Id 'errorEmail' -Attributes @{
style = @{
color = 'red'
}
}
}
}
# Empty container (div) to display errors concerning mailaddress validation.
New-UDDynamic -Id 'dynamicContent' -Content {
New-UDElement -Tag 'div' -Id 'errorMailboxEmailAddress' -Attributes @{
style = @{
color = 'red'
}
}
}
} -OnSubmit {
# Create custom object to create our new UI elements with.
$Properties = [PSCustomObject]@{
Capacity = '1'
Floor = '1'
IsWheelChairAccessible = $True
AudioDevice = $True
VideoDevice = $True
DisplayDevice = $true
AllBookInPolicy = $false
AllRequestInPolicy = $true
AutomateProcessing = $true
DeleteSubject = $true
BookingWindowInDays = '428'
Tags = 'wifi'
}
# Debug code to console
$Properties | Write-Host
# Dynamic section to 're'-create UI form.
New-UDDynamic -Id 'dynamicSettings' -Content {
New-UDRow -Columns {
New-UDColumn -Size 6 -Content {
New-UDTextbox -Id 'txtCapacity' -Label 'Capacity' -Value $properties.Capacity
}
New-UDColumn -Size 6 -Content {
New-UDTextbox -Id 'txtFloor' -Label 'Floor' -Value $Properties.Floor
}
New-UDColumn -Size 6 -Content {
New-UDCheckBox -Id 'checkboxIsWheelChairAccessible' -Label 'Is WheelChair Accessible' -Checked $Properties.IsWheelChairAccessible
}
New-UDColumn -Size 6 -Content {
New-UDCheckBox -Id 'checkboxAudioDevice' -Label 'Audio Device' -Checked $Properties.AudioDevice
}
New-UDColumn -Size 6 -Content {
New-UDCheckBox -Id 'checkboxVideoDevice' -Label 'Video Device' -Checked $Properties.VideoDevice
}
New-UDColumn -Size 6 -Content {
New-UDCheckBox -Id 'checkboxDisplayDevice' -Label 'Display Device' -Checked $Properties.DisplayDevice
}
New-UDColumn -Size 6 -Content {
New-UDTextbox -Id 'txtTags' -Label 'Tags' -Value $Properties.Tags
}
New-UDColumn -Size 6 -Content {
New-UDCheckBox -Id 'checkboxDeleteSubject' -Label 'Delete Subject' -Checked $Properties.DeleteSubject
}
New-UDColumn -Size 6 -Content {
New-UDTextbox -Id 'txtBookingWindowInDay' -Label 'Booking Window In Days' -Value $Properties.BookingWindowInDays
}
New-UDColumn -Size 6 -Content {
New-UDCheckBox -Label 'AllBookInPolicy' -Id 'checkboxAllBookInPolicy' -Checked $Properties.AllBookInPolicy -OnChange {
Sync-UDElement -Id 'dynamicAllBookInPolicyCheckboxContainer'
Sync-UDElement -Id 'dynamicAllRequestInPolicyInputContainer'
}
}
}
}
New-UDColumn -Size 6 -Content {
New-UDDynamic -Id 'dynamicAllBookInPolicyCheckboxContainer' -Content {
$AllBookInPolicy = (Get-UDElement -Id 'checkboxAllBookInPolicy').checked
if ($AllBookInPolicy -eq $false)
{
New-UDCheckBox -Id 'checkboxAllRequestInPolicy' -Checked $Properties.AllRequestInPolicy -Style @{
marginRight = '-16px' #For some reason, the checkbox gets a margin of 16px, this is to reverse that undesired margin.
} -OnChange {
Sync-UDElement -Id 'dynamicAllRequestInPolicyInputContainer'
}
New-UDTooltip -TooltipContent {
New-UDTypography -Text 'When you want AllBookinPolicy to be limited this needs to be set to $false. Otherwise the booking will go to a ''tentative'' state. Waiting for approval by a delegate.'
} -Content {
New-UDTypography -Text 'Disable AllRequestInPolicy'
}
}
else
{
#If AllBookingPolicy is true, we don't want AllRequestInPolicy to be available or selected.
Set-UDElement -Id 'AllRequestInPolicy' -Properties @{ Checked = $false } #Clear upon deselect, just to be sure.
}
}# end dynamic
New-UDDynamic -Id 'dynamicAllRequestInPolicyInputContainer' -Content {
$AllBookInPolicy = (Get-UDElement -Id 'checkboxAllBookInPolicy').checked #Remember to re-add, with dynamic, the scope gets lost!
$AllRequestInPolicy = (Get-UDElement -Id 'checkboxAllRequestInPolicy').checked
if ($AllRequestInPolicy -eq $true -and $AllBookInPolicy -eq $false)
{
New-UDColumn -Size 2 -Content {
# later we need to fill this with the people that are allowed to book
New-UDTextbox -Id 'txtAllBookinPolicyList' -Label 'List of people allowed to book.' -Placeholder 'Provide a list of user mail addressess separated by ;' -FullWidth
}
}
else
{
Set-UDElement -Id 'txtAllBookinPolicyList' -Properties @{ Value = '' } #Clear upon deselect, just to be sure.
}
}
}
} # end of submit.
} -Title 'Room Mailbox Config'
This used mocked data to simplify the code.
The problem I have is with the checkboxes.
When i retrieve the data and `AllBookInPolicy` is `$false` then
if `AllRequestInPolicy` is `true` it should be selected and show the textbox `txtAllBookinPolicyList`.
The problem is that these dynamic containers, only update when I have an onChange event. These happen after the page is loaded.
Is there any way around this?
This used mocked data to simplify the code.
The problem I have is with the checkboxes on pageload.
When i retrieve the data and AllBookInPolicy is $false then
if AllRequestInPolicy is true it should be selected and show the textbox txtAllBookinPolicyList.
The problem is that these dynamic containers, only update when I have an onChange event. These happen after the page is loaded. The dynamic containers work when the page is loaded.
Perhaps I am doing it all wrong. Is there any way to get around this?
So after a lot of reading and struggle, i came up with the following solution.
This seems to work 98% of the time. The 2% is when you do a reload of the page too soon after the previous one. Somehow , the submit button doesn’t work, no clue why.
<#
.SYNOPSIS
The goal of the UI should be:
If AllBookinPolicy is checked --> Don't show anything else.
If AllBookinPolicy if NOT checked --> Show AllRequestInPolicy checkbox.
If AllRequestInPolicy is checked --> Show Textbox txtAllBookinPolicyList.
If AllRequestInPolicy is NOT checked --> Don't show textbox txtAllBookinPolicyList.
.DESCRIPTION
The problem is that by using Get-UDElement & Set-UDElement, we encouter the issue that
- When the page is loading,
- I address DOM-objects, that are not ready loading yet.
This means that if I use Get-UDElement 'checkboxAllBookInPolicy' and the object in the browser isn't ready yet at the time that I call it
it breaks the entire code.
In my use case, we can retrieve our desired INITIAL state of the UI object, by using Get-mailbox .... , and store those in $Cache:variables.
When we then change the state of the object, we use the -onChange event and $Eventdata (which holds true/false), to adjust the $Cache:variable.
This way, the variables are always up to date and the UI should have the correct state.
#>
New-UDPage -Url "/DynamicChecks" -Name "Test" -Content {
New-UDTypography -Text 'Test dynamic checkboxes in UI' -Variant 'h4' -Id 'pageTitle'
New-UDForm -Id 'roomConfigForm' -Content {
New-UDRow -Columns {
New-UDColumn -Size 2 -Content {
# create a single textbox with verifcations to AD, update UI 'on the fly'
New-UDTextbox -Id 'txtMailboxEmailAddress' -Label 'mailbox address' -Placeholder 'yaya@domain.com ' -Value 'toure@domain.com' -FullWidth
}
}
# Empty container (div) to display errors concerning mailaddress validation.
New-UDDynamic -Id 'dynamicContent' -Content {
New-UDElement -Tag 'div' -Id 'errorMailboxEmailAddress' -Attributes @{
style = @{
color = 'red'
}
}
}
} -OnSubmit {
Start-sleep 5
# Mock the initiale session state for checkbox values.
# These should normally come from Exchange by using Get-Mailbox ....
$Cache:AllBookInPolicy = $false
$Cache:AllRequestInPolicy = $true
# Create custom object to build our new UI elements with.
$Properties = [PSCustomObject]@{
AllBookInPolicy = $Cache:AllBookInPolicy
AllRequestInPolicy = $Cache:AllRequestInPolicy
AutomateProcessing = $true
BookingWindowInDays = '428'
Tags = 'wifi'
}
# Debug code to console
$Properties | Write-Host
# Dynamic section to 're'-create UI form.
# New-UDDynamic -Id 'dynamicSettings' -Content {
New-UDRow -Columns {
New-UDColumn -Size 6 -Content {
New-UDCheckBox -Label 'AllBookInPolicy' -Id 'checkboxAllBookInPolicy' -Checked $Cache:AllBookInPolicy -OnChange {
# Update cache state when checkbox changes --> basically replaces Get-UDElement, which was not reliable.
$Cache:AllBookInPolicy = $EventData
Sync-UDElement -Id 'dynamicAllBookInPolicyCheckboxContainer'
Sync-UDElement -Id 'dynamicAllRequestInPolicyInputContainer'
}
}
}
# }
New-UDColumn -Size 6 -Content {
New-UDDynamic -Id 'dynamicAllBookInPolicyCheckboxContainer' -Content {
# Use cache state instead of reading the DOM with Get-UDElement.
$AllBookInPolicy = $Cache:AllBookInPolicy
# Only show "Disable AllRequestInPolicy" checkbox when AllBookInPolicy is FALSE
if ($AllBookInPolicy -eq $false)
{
New-UDCheckBox -Id 'checkboxAllRequestInPolicy' -Checked $Cache:AllRequestInPolicy -Style @{
marginRight = '-16px' #For some reason, the checkbox gets a margin of 16px, this is to reverse that undesired margin.
} -OnChange {
# Update cache state when checkbox changes --> basically replaces Get-UDElement, which was not reliable.
$Cache:AllRequestInPolicy = $EventData
Sync-UDElement -Id 'dynamicAllRequestInPolicyInputContainer'
}
New-UDTooltip -TooltipContent {
New-UDTypography -Text 'When you want AllBookinPolicy to be limited this needs to be set to $false. Otherwise the booking will go to a ''tentative'' state. Waiting for approval by a delegate.'
} -Content {
New-UDTypography -Text 'Disable AllRequestInPolicy'
}
}
# If AllBookInPolicy is true, don't show the AllRequestInPolicy checkbox at all
} # end dynamic
New-UDDynamic -Id 'dynamicAllRequestInPolicyInputContainer' -Content {
# Use cache state instead of reading the DOM with Get-UDElement.
$AllBookInPolicy = $Cache:AllBookInPolicy
$AllRequestInPolicy = $Cache:AllRequestInPolicy
# Only show textbox when AllBookInPolicy is FALSE
if ($AllBookInPolicy -eq $false)
{
# Show textbox when AllRequestInPolicy is TRUE AND AllBookInPolicy is FALSE
if ($AllRequestInPolicy -eq $true)
{
New-UDColumn -Size 2 -Content {
# later we need to fill this with the people that are allowed to book
New-UDTextbox -Id 'txtAllBookinPolicyList' -Label 'List of people allowed to book.' -Placeholder 'Provide a list of user mail addressess separated by ;' -FullWidth
}
}
}
# If AllBookInPolicy is true, don't show anything in this container!
}
}
# Stuck here :
# Stuck here :
# Stuck here :
# Add a separate form for final submission that will hide after submit
}-OnProcessing {
New-UDCard -Title 'Processing' -Content {
New-UDProgress
}
}
} -Title 'Learning PSU'```Hi KST
You could take advantage of dynamic content, so that the bulk of your code is not triggered by the onsubmit and more importantly not being redirect to a different “page”.
Here is an example where a textbox will only appear when AllRequestInPolicy is checked (manually). Any other combination will not show that textbox/checkbox. You could apply the same logic to any other component.
New-UDPage -Name "AnotherOption" -Content {
New-UDCard -Content {
New-UDStack -Children {
New-UDCheckBox -Label 'AllBookInPolicy' -OnChange {
$Page:AllBookInPolicy = $EventData
}
New-UDCheckBox -Label 'AllRequestInPolicy' -OnChange {
$Page:AllRequestInPolicy = $EventData
}
} -Direction row
New-UDButton -Text "Submit" -OnClick {
Sync-UDElement -id "MyDynamicContent"
}
}
New-UDDynamic -Id "MyDynamicContent" -Content {
New-UDCard -Content {
If ($Page:AllBookInPolicy -eq $false -or [string]::IsNullOrEmpty($Page:AllBookInPolicy)) {
Show-UDSnackbar -Message "AllBookInPolicy is False"
If ($Page:AllRequestInPolicy -eq $true) {
Show-UDSnackbar -Message "AllRequestInPolicy is True"
# Only visible when RequestInPolicy is set to true when submitting
New-UDStack -Children {
New-UDCheckBox -Label "AllRequestInPolicy" -Checked $true
New-UDCheckBox -Label "AllBookInPolicy" -Checked $false
} -Direction row
New-UDTextbox -Label "mytextbox"
}
}
}
}
}