Output Window with Scrollbar

I had a user request a control that would allow for the output of messages from a UDInput so they could see progress. This uses the Stack class so it writes new messages to the top, outputs them into a collection and then adds a scrollbar after it reaches 200px.



$Dashboard = New-UDDashboard -Title 'hey' -Content {

   New-UDElement -Tag 'div' -Endpoint {
      $Session:Elements = New-Object System.Collections.Stack
   }

   New-UDButton -Text "Add Item" -OnClick {
      $Session:Elements.Push("[$(Get-Date)]")
      Sync-UDElement -Id 'output'
   }

   New-UDButton -Text "Clear Items" -OnClick {
      $Session:Elements.Clear()
      Sync-UDElement -Id 'output'
   }

   New-UDElement -Id 'output' -Tag 'div' -Attributes @{
      style = @{
         height = "200px"
         overflowY = "scroll"
      }
   } -Endpoint {
      New-UDCollection -Content {
         $Session:Elements | ForEach-Object {
            New-UDCollectionItem -Content { $_ }
         }
      }
   }
}

Start-UDDashboard -Dashboard $Dashboard -Port 10000 -FOrce
5 Likes

Hello Adam,

I am in the process of making a terminal window but have run into an issue where I am having difficulty making the scroll bar auto scroll to the newest element at the bottom of the window.

$Navigation = @(
    New-UDListItem -Label "Home" -OnClick { Invoke-UDRedirect "/Home" }
    New-UDListItem -Label "Terminal" -OnClick { Invoke-UDRedirect "/Terminal" }
)

$pages = @()

$Pages += New-UDPage -Name 'Terminal Window' -Content {
    New-UDCard -Title 'Select from left menu bar the type of user account you wish to manage.' -Content {
        "Created by someone."
    } 
} -url '/Home' -NavigationLayout permanent -Navigation $Navigation

$Pages += New-UDPage -Name 'Terminal Window' -Content {
   New-UDElement -Tag 'div' -Endpoint {
      #$Session:Elements = New-Object System.Collections.Stack
      $Session:Elements = New-Object System.Collections.ArrayList
      1..100 | % {$session:Elements.add("[$_]")} | Out-Null
   }

   New-UDButton -Text "Add Item" -OnClick {
      #$Session:Elements.Push("[$(Get-Date)]")
      $Session:Elements.Add("[$(Get-Date)]")
      Sync-UDElement -Id 'output'
   }

   New-UDButton -Text "Clear Items" -OnClick {
      $Session:Elements.Clear()
      Sync-UDElement -Id 'output'
   }

   New-UDElement -Id 'output' -Tag 'div' -Attributes @{
      style = @{
         height = "400px"
         overflowY = "scroll"
         'scroll-behavior' = "auto"
      }
   } -Endpoint {
      #New-UDCollection -Content {
         New-UDElement -id 'wordlist' -Tag 'div'
         $Session:Elements | ForEach-Object {
            #New-UDCollectionItem -Content { $_ }
            New-UDelement -Tag 'div' -ClassName 'word' -Endpoint {$_}
         }
         New-UDElement -Tag 'div'
      #}
   }   
} -url '/Terminal' -NavigationLayout permanent -Navigation $Navigation

As you can see I have taken your demo code above and swapped to an ArrayList, also the New-UDCollection I guess has been depreciated so I have removed it. The example code at the bottom of this page is the desired affect I am trying to accomplish CSS scrolling with top overflow

This mentions calling a method called scrolltop like the example here.
$(“#wordlist”).scrollTop($(‘#wordlist’).height())

I’m not sure how to add the style attributes needed to my code to get this to work also I don’t know how to go about calling the scrollTop method from PowerShell universal. Any help would be appreciated and if also this is the right way to go about it.

Cheers Carl.

Hello Adam,

So I have made progress in that I have a changed the button to scroll to bottom when clicked. But is there a way to make it do so automatically after its finished listing the elements? here is my new code below with the button click “Scroll to Bottom”.

New-UDElement -Tag 'div' -Endpoint {
      #$Session:Elements = New-Object System.Collections.Stack
      $Session:Elements = New-Object System.Collections.ArrayList
      1..100 | % {$session:Elements.add("[$_]")} | Out-Null
   }

   New-UDButton -Text "Add Item" -OnClick {
      #$Session:Elements.Push("[$(Get-Date)]")
      $Session:Elements.Add("[$(Get-Date)]")
      Sync-UDElement -Id 'output55'
      Invoke-UDJavaScript -JavaScript 'document.getElementById("output55").scrollTop = 50000;'
   }

   New-UDButton -Text "Scroll Bottom" -OnClick {
      #$Session:Elements.Clear()
      #Sync-UDElement -Id 'output'
      Invoke-UDJavaScript -JavaScript 'document.getElementById("output55").scrollTop = 50000;'
   }

   New-UDElement -Id 'output55' -Tag 'div' -Attributes @{
      style = @{
         height = "400px"
         overflowY = "scroll"
      }
   } -Endpoint {
    
        $Session:Elements | ForEach-Object {
           New-UDelement -Tag 'div' -ClassName 'word' -Endpoint {$_} 
        }
        
   }  

Cheers Carl.

Hello ,

I now have something in place which works but was hoping someone could explain to me why having the Invoke-UDJavascript encased in New-UDButton and then calling the click() method works instead of just straight calling the method which does nothing. Also if someone has a more efficient way of doing this like appending only the new elements to the list and displaying them instead of constructing the whole list every time a new element is added.

Cheers Carl.

   1..100 | % {$session:Elements.add("[$_]")} | Out-Null
   start-sleep -Seconds 5

   New-UDButton -Text "Add Item" -OnClick {
      
      $Session:Elements.Add("[$(Get-Date)]") | Out-Null
      Sync-UDElement -Id 'output55'
   }

   New-UDButton -Text "Scroll Bottom" -id "btnscrollbottom" -OnClick {
      Invoke-UDJavaScript -JavaScript 'document.getElementById("output55").scrollTop = 50000;'
   }

   New-UDCard -Content {

      New-UDElement -ClassName 'output55' -Id 'output55' -Tag 'div' -Attributes @{
         style = @{
            height = "400px"
            overflowY = "scroll"
            'background-color' = 'hotpink'
         }
      } -Endpoint {
         start-sleep -Seconds 2
         $Session:Elements | ForEach-Object {
            New-UDelement -Tag 'div' -ClassName 'word' -Content {$_} 
         }         
         Invoke-UDJavaScript -JavaScript 'document.getElementById("btnscrollbottom").click();'
         #Invoke-UDJavaScript -JavaScript 'document.getElementById("output55").scrollTop = 50000;'
         
      } 
   }
1 Like