Using a Modal Form to edit SQL Data and Refresh Server Side table

I created a dashboard that hosts a server side table. I am querying SQL and populating and then adding an edit and delete button on each row for editing the record. When I use the edit button I have created, I have it opening a Modal Form with the current values pre-populated. Then the user can edit any field and submit or cancel. This then runs an UPDATE sql command to update the table in the source. I am trying to find a way that it will also update the table with the new values. I have tried adding it to a New-UDDynamic element, but when I do that and then sync the element, it refreshes and them limits the records that it returns and starts over from where I edited the record and I can’t go back to it. Does anyone know the best way to reset the data in the server side table to reflect the new values. My edit button works and I haven’t built out my delete button yet, but with either one, I still need it to refresh the data in the table.

Here is my code for my dashboard:

    $Pages += New-UDPage -Name "Hardware Devices" -Title "Univeristy of Alaska Provisioning Portal" -Logo '/images/ua_logo.png' -Content {
    New-UDElement -tag 'p' # This adds a blank line
    New-UDTypography -Text "This page will house the new Hardware Listing." -Variant "h5"
    New-UDElement -tag 'p' # This adds a blank line
    New-UDTable -Title 'Computer Hardware' -Id 'HardwareDevices' -ShowSelection -LoadData {
    $TableData = ConvertFrom-Json $Body

    $OrderBy = $TableData.orderBy.field
    If ($OrderBy -eq $null){
        $OrderBy = 'HostName'
    }
    $OrderDirection = $TableData.OrderDirection
    If ($OrderDirection -eq $null){
        $OrderDirection = "asc"
    }

    $Where = ""
    If ($TableData.Filters){
        $Where = "WHERE "
        ForEach($filter in $TableData.Filters){
            $Where += $filter.id + " LIKE '%" + $filter.value + "%' AND "
        }
        $Where += " 1 = 1"
    }
    $PageSize = $TableData.PageSize
    # Calculate the number of rows to skip
    $Offset = $TableData.Page * $PageSize
    $Count = Invoke-Sqlcmd -ServerInstance anc-vsql.apps.ad.alaska.edu\general -Database CallCenterDashboard -Credential $Credential -Query "Select COUNT(*) as count from dbo.Hardware $WHERE"
    
    $TaskSequences = Invoke-RestMethod https://sccm-gateway.uaa.alaska.edu:5000/TaskSequences
    $ApplicationProfiles = Invoke-RestMethod https://sccm-gateway.uaa.alaska.edu:5000/ApplicationProfile
    $HardwareData = Invoke-Sqlcmd -ServerInstance {Servername} -Database {DatabaseName} -Credential $Credential -Query "Select a.Id,SerialNumber,TargetOU,HostName,TaskSequenceID,ApplicationProfileName,a.applicationProfileID from dbo.Hardware as a left join dbo.ApplicationProfile as b on b.Id = a.ApplicationProfileID $WHERE ORDER BY $OrderBy $OrderDirection OFFSET $Offset ROWS FETCH NEXT $PageSize ROWS ONLY" | ForEach-Object {
        $TempID = $_.TaskSequenceID
        $TempAppID = $_.ApplicationProfileID
        @{
            HostName = $_.HostName
            SerialNumber = $_.SerialNumber
            TaskSequenceName = $($TaskSequences | Where-Object {$_.AdvertisementID -eq $TempID}).PackageName
            ApplicationProfileName = $($ApplicationProfiles | Where-Object {$_.ID -eq $TempAppID}).ApplicationProfileName
            TaskSequenceID = $TempID
            ApplicationProfileID = $TempAppID
            HardwareID = $_.Id
            TargetOU = $_.TargetOU
        }
    }

    $HardwareData | Out-UDTableData -Page $TableData.page -TotalCount $Count.count -Properties $TableData.properties
    } -Columns @(
        New-UDTableColumn -Property 'HostName' -Title 'Computer Name' -Sort -Filter
        New-UDTableColumn -Property 'SerialNumber' -Title 'Serial Number' -Sort -Filter
        New-UDTableColumn -Property 'TargetOU' -Title 'Destination OU' -Sort -Filter
        New-UDTableColumn -Property 'TaskSequenceName' -Title 'Task Sequence' -Sort -Filter
        New-UDTableColumn -Property 'ApplicationProfileName' -Title 'Application Profile' -Sort -Filter
        New-UDTableColumn -Property 'HardwareID' -Title 'Action' -Render {
            New-UDButton -Icon (New-UDIcon -Icon edit) -OnClick {
                Show-UDModal -Persistent -FullWidth -MaxWidth 'md' -Content {
                    New-UDForm -Content {
                        New-UDTypography -Text "Edit Hardware Entry" -variant 'h4'
                        New-UDTextBox -Id 'txtHardwareID' -Disabled -Value $Eventdata.HardwareID
                        New-UDTextBox -Id 'txtHostName' -Label 'Computer Name' -Value $Eventdata.HostName
                        New-UDTextBox -Id 'txtSerialNumber' -Label 'Serial Number' -Value $EventData.SerialNumber
                        New-UDTextBox -Id 'txtOU' -Label 'Destination OU' -FulLWidth -Value $EventData.TargetOU
                        New-UDSelect -Id 'comboTaskSequences' -Label 'Task Sequence' -DefaultValue $EventData.TaskSequenceID -Option {
                            $AvailableTaskSequences = $TaskSequences | Sort-Object -Property PackageName
                            ForEach ($TaskSequence in $AvailableTaskSequences){
                                New-UDSelectOption -Name $TaskSequence.PackageName -Value $TaskSequence.AdvertisementID
                            }
                        }
                        
                        New-UDSelect -Id 'comboApplicationProfile' -Label 'Application Profile' -DefaultValue $EventData.ApplicationProfileID -Option {
                            $AllApplicationProfiles = $ApplicationProfiles | Sort-Object -Property ApplicationProfileName
                            ForEach ($Profile in $AllApplicationProfiles) {
                                New-UDSelectOption -Name $Profile.ApplicationProfileName -Value $Profile.ID
                            }
                        }
                    } -OnSubmit {
                        $NewHardwareID = (Get-UDElement -Id 'txtHardwareID').Value
                        $NewHostName = (Get-UDElement -Id 'txtHostName').Value
                        $NewTargetOU = (Get-UDElement -Id 'txtOU').Value
                        $NewSerialNumber = (Get-UDElement -Id 'txtSerialNumber').Value
                        $NewTaskSequence = (Get-UDElement -Id 'comboTaskSequences').Value
                        $NewApplicationProfile = (Get-UDElement -Id 'comboApplicationProfile').Value
                        Show-UDToast -Message "$NewHostName   $NewTargetOU   $NewSerialNumber   $NewTaskSequence   $NewApplicationProfile" -Duration 30000
                        Try {
                            Invoke-Sqlcmd -ServerInstance {ServerName} -Database {DatabaseName} -Credential $Credential -Query "UPDATE dbo.Hardware SET SerialNumber = '$NewSerialNumber', HostName = '$NewHostName', TargetOU = '$NewTargetOU', TaskSequenceID = '$NewTaskSequence', ApplicationProfileID = $NewApplicationProfile WHERE Id = $NewHardwareID"
                            Sync-UDElement -Id 'HardwareDevices'
                            Hide-UDModal
                        } catch {
                            Show-UDToast -Message "Failed to update Record"
                        }
                        
                        
                    } -OnCancel {
                        Hide-UDModal
                    }
                }
            }
            New-UDButton -Icon (New-UDIcon -Icon trash) -OnClick {
                Show-UDModal -Content { $EventData.HostName }
            }
        }
    ) -Sort -Paging -Filter -Export -OnRowSelection {
        $Item = $EventData
        Show-UDToast -Message "$($Item.HostName | Out-String)"
    }

    } -NavigationLayout permanent -Navigation $Navigation

Any help would be gratefully appreciated.

FYI, i think you put this in the wrong category which might be why it took a while for anyone to notice. Universal Automation references that section of the PSU product from admin console, where you setup scripts to run. This problem is still within the area of Universal Dashboard, so it would have been better in that section. Hope this helps :smiley:

I’m doing the data pull and table setup a bit differently, but this is how I do it. Looking at your code, I think you simply just need to wrap the entirety of your New-UDTable setup in a New-UDDynamic with an -ID setup.

Then your button does sync-udelement on that id instead of your ‘hardwaredevices’ tied to the new-udtable element. I also tossed a refresh button at the top of my table so that you can always just refresh to make sure the data is current.

Here is my code

New-UDDynamic -id 'dynBuildQueueTable' -content {
  New-UDButton "Refresh Table Data" -onclick {
      $queryTxt = "SELECT Status, StatusMessage, SystemName, ID FROM DBTable"
      $Cache:ServerBuildQueue = Invoke-Sqlcmd -ServerInstance $SqlServer -Database $SqlDBName -MaxCharLength 10000 -Query $queryTxt | Select-Object ID,SystemName,Status,StatusMessage
      Sync-UDElement -id 'dynBuildQueueTable'
  }
  $queryTxt = "SELECT Status, StatusMessage, SystemName, ID FROM DBTable"
  $Cache:ServerBuildQueue = Invoke-Sqlcmd -ServerInstance $SqlServer -Database $SqlDBName -MaxCharLength 10000 -Query $queryTxt | Select-Object ID,SystemName,Status,StatusMessage
  $Columns = @(
      New-UDTableColumn -Property 'retrystatus' -Title 'Retry' -Render { 
          New-UDButton -Id "btnRetry$($eventdata.id)" -Text "Flag to Retry Build"  -OnClick {
              Show-UDToast -message ("System " + $eventdata.systemname + " is flagged for build retry.")
              $GambitVMID = $eventdata.id
              $Status = "Retry"
              $StatusMessage = "Flagged for retry on build."
              $retryTxt = "UPDATE DBTable SET Status = `'$status`', StatusMessage = `'$StatusMessage`' WHERE ID = `'$GambitVMID`'"
              Invoke-sqlcmd -ServerInstance $SqlServer `
              -database $SqlDBName `
              -query $retryTxt
              $Cache:ServerBuildQueue = Invoke-Sqlcmd -ServerInstance $SqlServer -Database $SqlDBName -MaxCharLength 10000 -Query $queryTxt | Select-Object ID,SystemName,Status,StatusMessage
              Sync-UDElement -id 'dynBuildQueueTable'
          } 
      }
      New-UDTableColumn -Property ID -Title 'ID' -IncludeInSearch
      New-UDTableColumn -Property SystemName -Title 'System Name' -IncludeInSearch
      New-UDTableColumn -Property Status -Title "Status" -IncludeInSearch
      New-UDTableColumn -Property StatusMessage -Title 'Status Message' -IncludeInSearch
  )
  New-UDTable -Data $Cache:ServerBuildQueue -Columns $Columns -Dense -filter -sort -ShowPagination -pagesize 20 -export -search
}

This was a Universal Dashboard issue, but I think that the issue is related to the issue posted here:

They just had a better way of explaining it and getting to the root cause. Adam says that it is a bug… When I wrapped it in a New-UDDyanmic, and had an ID on both the Dynamic and the Table, it failed, but if I removed the ID from the table, then it would refresh…

Thank you for this.