Change New-UDButton Upon Click

Product: PowerShell Universal
Version: 1.5.14

I am building a page to allow helpdesk users retrieve various info and unlock accounts. I have the page working so far with one exception. I want the user to only be able to click the “unlock” button once. I am trying to remove it as being “clickable”–either greyed out, or ideally, refreshed with the results of the unlock script. I’ve been unsuccessful with trial and erroring through New-UDDynamic or Set/Sync-UDelement. I think my understanding of how to set/sync/refresh the field is plain flawed. Here is the full page code working, but requires the user re-submit the entire form to update the card/table:

$DynamicUserInfo = New-UDPage -Name 'Testing Dynamic User Info' -Content {
    New-UDTypography -Text 'Enter Active Directory username'
    New-UDForm -Content {
        New-UDTextbox -Id 'Username' -Placeholder 'AD Username'
        New-UDRadioGroup -Id 'RadioValue' -Content {
            New-UDRadio -Label 'Account Expiration Date' -Value 'AccountExpirationDate'
            New-UDRadio -Label 'Account Lockout Status' -Value 'LockedOut'
        } -Value 'LockedOut'
        
    } -OnSubmit {
        $InvokeParams = @{
            Script = (Get-UAScript -Name 'Get User Info.ps1')
            Identity = $EventData.UserName
            UserProperty = $EventData.RadioValue
        }
        Invoke-UAScript @InvokeParams | Tee-Object -Variable job | Wait-UAJob
        $Data = Get-UAJobPipelineOutput -Job $Job

        Set-UDElement -Id 'ElementJobOutput' -Content {
            New-UDCard -Id 'CardJobOutput' -Title "Results" -Content {
                $Columns = @(
                    New-UDTableColumn -Property SamAccountName -Title 'SamAccountName' -Width 10 -IncludeInExport
                    New-UDTableColumn -Property $EventData.RadioValue -Title $EventData.RadioValue -Width 25 -IncludeInExport
                )
                If($EventData.RadioValue -eq 'LockedOut'){
                    $Columns += New-UDTableColumn -Property Unlock -Title Unlock -Width 10 -Render {
                        $Item = $EventData
                        If($Item.LockedOut -eq $true){
                            New-UDButton -Id "btn$($Item.SamAccountName)" -Text "Unlock" -OnClick {
                                Show-UDToast -Message "Unlocking AD User [$($Item.SamAccountName)]" -Duration 2500

                                $InvokeParams = @{
                                    Script = (Get-UAScript -Name 'Unlock AD User.ps1')
                                    SamAccountName = $Item.SamAccountName
                                    Credential = $(Get-UAVariable -Name '<Redacted>')
                                }
                                Invoke-UAScript @InvokeParams | Tee-Object -Variable job | Wait-UAJob

                                $Job = Get-UAJob -Id $Job.Id
                                $Data = Get-UAJobPipelineOutput -Job $Job

                                If ($Job.Status -eq 'Completed' -and $Data -match 'Success'){
                                    $SuccessToastParams = @{
                                        Message = "Completed unlock for user $($Item.SamAccountName)"
                                        Duration = "5000"
                                        Position = 'center'
                                    }
                                    Show-UDToast @SuccessToastParams
                                } else {
                                    $Output = Get-UAJobOutput -JobId $Job.Id | Select-Object -Expand Message
                                    $FailedToastParams = @{
                                        Message = "Failed to unlock user. $($Output -join "`n")"
                                        BackgroundColor = 'red'
                                        MessageColor = 'white'
                                        Duration = "5000"
                                        Position = 'center'
                                    }
                                    Show-UDToast @FailedToastParams
                                }
                            }
                        } Else {
                            New-UDTypography -Text 'Not Locked'
                            New-UDIcon -Id "icon$($Item.SamAccountName)" -Icon CheckCircle
                        }
                    }
                }
                
                New-UDTable -Id 'TableUserInfo' -Data $Data -Columns $Columns -Export

            }
        }
    }
    New-UDElement -Id 'ElementJobOutput' -Tag 'div' # New empty element to be updated/displayed after user clicks 'Submit'

} -Url '/dynuserinfo'

Try adding
Set-UDElement -Id "btn$($Item.SamAccountName)" -Attributes @{disabled = $true}
before
Show-UDToast -Message "Unlocking AD User [$($Item.SamAccountName)]" -Duration 2500

That worked perfectly to disable the button. Thank you! Based on my original post, do you know if there is a way to replace that button based on success of the script? For example, if an account is not locked, I set the cell via:

New-UDTypography -Text 'Not Locked'
New-UDIcon -Id "icon$($Item.SamAccountName)" -Icon CheckCircle

However, I’m not sure how to change the cell data as opposed to initially setting it. If not, it’s not a huge ordeal, just disabling the staff from running multiples of the same script is helpful. Thank you for that!

I believe you not only want the button to show disabled while the account is being unlocked, but then update the cell to show the new status once complete.

This code worked for me:

New-UDTypography -Text 'Enter Active Directory username'
New-UDForm -Content {
    New-UDTextbox -Id 'Username' -Placeholder 'AD Username'
    New-UDRadioGroup -Id 'RadioValue' -Content {
        New-UDRadio -Label 'Account Expiration Date' -Value 'AccountExpirationDate'
        New-UDRadio -Label 'Account Lockout Status' -Value 'LockedOut'
    } -Value 'LockedOut'
        
} -OnSubmit {     
    #Get the user data
    $Data = Get-ADUser -Identity $EventData.Username -Properties *
    #Store the current Lockedout status in a session variable
    $Session:LockedOut = $Data.LockedOut

    Set-UDElement -Id 'ElementJobOutput' -Content {
        New-UDCard -Id 'CardJobOutput' -Title "Results" -Content {
            $Columns = @(
                New-UDTableColumn -Property SamAccountName -Title 'SamAccountName' -Width 10 -IncludeInExport
                New-UDTableColumn -Property $EventData.RadioValue -Title $EventData.RadioValue -Width 25 -IncludeInExport
            )
            If($EventData.RadioValue -eq 'LockedOut'){
                $Columns += New-UDTableColumn -Property Enable -Title "Unlock Account" -Width 10 -Render {
                    #Create New-UDDynamic element to update what gets displayed in Column 3.
                    New-UDDynamic -id 'colThree' -Content {
                        If($Session:LockedOut -eq $true){
                            New-UDButton -Id "btn$($Data.SamAccountName)" -Text "Unlock" -OnClick {
                                Set-UDElement -Id "btn$($Data.SamAccountName)" -Attributes @{disabled = $true}
                                Show-UDToast -Message "Enabling AD User [$($Data.SamAccountName)]" -Duration 2500
                                
                                #Unlock the user account
                                Unlock-ADAccount -Identity $Data.SamAccountName

                                #Removed error checking for this demo
                                $SuccessToastParams = @{
                                    Message = "Completed unlock for user $($Data.SamAccountName)"
                                    Duration = "5000"
                                    Position = 'center'
                                }
                                Show-UDToast @SuccessToastParams 

                                #On success, update our session variable and refresh the cell
                                $Session:LockedOut = $false
                                Sync-UDElement -id 'colThree'                                                                     
                            }                       
                        } Else {
                            New-UDTypography -Text 'Not Locked'
                            New-UDIcon -Id "icon$($Data.SamAccountName)" -Icon CheckCircle
                        }
                    }
                }
                New-UDTable -Id 'TableUserInfo' -Data $Data -Columns $Columns -Export
            }
        }
    }
}

New-UDElement -Id 'ElementJobOutput' -Tag 'div' # New empty element to be updated/displayed after user clicks 'Submit'

That worked. Thanks so much!

I’ve been taking the crawl-walk-run approach to UD. Eventually, I’d like to allow people to enter/select multiple usernames. The above code works for a single user, but if I capture output for two users (one locked, one unlocked) the UD Button never appears. Is there another way to iterate over an array for the column? For instance, the below code is fully functional if I pass only a single user (e.g. “user1”) but if I pass two users and get back an array (e.g. “user1,user2”), then the ‘Unlock’ button never appears, even though the ‘LockedOut’ column shows True:

New-UDPage -Name 'Get User Information' -Content {
    New-UDTypography -Text 'Enter usernames (comma separated) to retrieve information from Active Directory'
    New-UDForm -Content {
        New-UDTextbox -Id 'Username' -Placeholder 'AD Username'
        New-UDRadioGroup -Id 'RadioValue' -Content {
            New-UDRadio -Label 'Account Expiration Date' -Value 'AccountExpirationDate'
            New-UDRadio -Label 'Account Lockout Status' -Value 'LockedOut'
            New-UDRadio -Label 'Password Last Set' -Value 'PasswordLastSet'
        } -Value 'PasswordLastSet'
        
    } -OnSubmit {
        $UserList = $EventData.UserName -split ","
        $Script = Get-UAScript -Name '<Redacted>.ps1'
        $InvokeParams = @{
            Script = $Script
            Identity = $UserList
            UserProperty = $EventData.RadioValue
        }
        Invoke-UAScript @InvokeParams | Tee-Object -Variable job | Wait-UAJob
        $Data = Get-UAJobPipelineOutput -Job $Job
        #$Session:LockedOut = $Data.LockedOut
        Set-UDElement -Id 'ElementJobOutput' -Content {
            New-UDCard -Id 'CardJobOutput' -Title "Results" -Content {
                $Columns = @(
                    New-UDTableColumn -Property SamAccountName -Title 'SamAccountName' -Width 10 -IncludeInExport
                    New-UDTableColumn -Property $EventData.RadioValue -Title $EventData.RadioValue -Width 25 -IncludeInExport
                )
                If($EventData.RadioValue -eq 'LockedOut'){
                    $Columns += New-UDTableColumn -Property Unlock -Title Unlock -Width 10 -Render {
                        $Item = $EventData
                        New-UDDynamic -id 'colThree' -Content {
                            If($Item.LockedOut -eq $true){
                                New-UDButton -Id "btn$($Item.SamAccountName)" -Text "Unlock" -OnClick {
                                    Set-UDElement -Id "btn$($Item.SamAccountName)" -Attributes @{Disabled = $true}
                                    Show-UDToast -Message "Unlocking AD User [$($Item.SamAccountName)]" -Duration 2500
                                    ### Call 'Unlock AD User' script ###
                                    $Credential = Get-UAVariable -Name '<Redacted>'
                                    $Script = Get-UAScript -Name '<Redacted>.ps1'
                                    $InvokeParams = @{ # Parameters for Invoke-UAScript command
                                        Script = $Script
                                        SamAccountName = $Item.SamAccountName
                                        Credential = $Credential
                                    }
                                    Invoke-UAScript @InvokeParams | Tee-Object -Variable job | Wait-UAJob # Waits for completion and stores job info in '$Job' var
                                    $Job = Get-UAJob -Id $Job.Id
                                    $Data = Get-UAJobPipelineOutput -Job $Job
                                    If ($Job.Status -eq 'Completed' -and $Data -match 'Success'){
                                        $SuccessToastParams = @{
                                            Message = "Completed unlock for user [$($Item.SamAccountName)]"
                                            Duration = "5000"
                                            Position = 'center'
                                        }
                                        Show-UDToast @SuccessToastParams
                                        $Item.LockedOut = $false
                                        Sync-UDElement -id 'colThree'
                                    } else {
                                        $Output = Get-UAJobOutput -JobId $Job.Id | Select-Object -Expand Message
                                        $FailedToastParams = @{
                                            Message = "Failed to unlock user. $($Output -join "`n")"
                                            BackgroundColor = 'red'
                                            MessageColor = 'white'
                                            Duration = "5000"
                                            Position = 'center'
                                        }
                                        Show-UDToast @FailedToastParams
                                        Set-UDElement -Id "btn$($Item.SamAccountName)" -Attributes @{Disabled = $false}
                                    }
                                }
                            } Else {
                                New-UDTypography -Text 'Not Locked'
                                New-UDIcon -Id "icon$($Item.SamAccountName)" -Icon CheckCircle
                            }    
                        }
                    }
                }
                
                New-UDTable -Id 'TableUserInfo' -Data $Data -Columns $Columns -Export

            }
        }
    }
    New-UDElement -Id 'ElementJobOutput' -Tag 'div' # New empty element to be updated/displayed after user clicks 'Submit'

}

Table where the top user is locked out of AD and the bottom user is not: