New Multi or Single Select Component for UniversalDashboard

This component originated from the request for help here:-

You can download this awesome component right here:-

PowerShell Gallery | UniversalDashboard.UDSelector 1.0.0

Once again I was blessed to receive some extra help from @BoSen29 who was very kind and donated his personal time to help on this project. I mean I build all these components in my spare time, so it’s great to receive some extra help, and some good banter at the same time.
I had actually managed to build the component, bind the component (from taking the same steps from his previous help which I blogged about here:- Number Mask Input Component | Powershell Blog) so had the component fully working. But the way I was passing the data to the menu was in an array so @BoSen29 constructed it as a scriptblock, and even developed a handy mini-funtion to load the data into the multi-select. I have tested this component for a few days, and it is very responsive, so far I have only loaded 250 items into the selection menu via a hashtable, and this is lightning fast and responsive. You can also use this as a single select, as well as a multi select.
selectorFin
I decided to name this New-UDSelector as it can be used for single selection as well as multi-selection.
It can be a tad tricky getting the values back, but I have put a demo file here:-
https://github.com/psDevUK/UD-Selector/blob/master/UniversalDashboard.UDSelector/ImprovedDemo.ps1
Which shows the mini-function in-use and it also shows how this component can be styled to your requirements.
This component is like the 5th most popular react component out there. So hopefully this will prove the same for fellow dashboarders and give me loads of downloads :wink:

Ok this is by no means the prettiest code out there, but this is showing how you can get the values from a multi selection, or a single selection:-

Import-Module UniversalDashboard.Community
Import-Module UniversalDashboard.UDSelector
Get-UDDashboard | Stop-UDDashboard
$theme = New-UDTheme -Name "Basic" -Definition @{
    '.css-1wa3eu0-placeholder'        = @{
        'color' = "rgb(164, 174, 193) !important"
    }
    '.css-1okebmr-indicatorSeparator' = @{
        'background-color' = "rgb(164, 174, 193) !important"
    }
    '.css-1hwfws3'                    = @{
        'height'      = "30px"
        'align-items' = "flex-start"
        'box-sizing'  = "initial !important"
        'flex-wrap'   = "initial !important"
    }
    '.css-1rhbuit-multiValue'         = @{
        'background-color' = "rgb(183, 195, 219) !important"

    }
    '.css-xb97g8'                     = @{
        'background-color' = "rgb(164, 174, 193)"
        'color'            = "#fffaf4"
    }
    '.css-12jo7m5'                    = @{
        'color' = "rgb(255, 255, 255) !important"
    }
    '.css-tlfecz-indicatorContainer'  = @{
        'color' = "rgb(164, 174, 193) !important"
    }
    '.css-yk16xz-control'             = @{
        'border-color' = "rgb(164, 174, 193) !important"
    }
    '.css-1g6gooi'                    = @{
        'padding-top' = "9px !important"
        'color'       = "rgb(164, 174, 193) !important"
    }
} -Parent "Default"
$dashboard = New-UDDashboard -Title "New Component" -Theme $theme -Content {
    New-UDRow -Columns {
        New-UDColumn -size 5 -Content {
            New-UDCard -BackgroundColor "#8789c0" -Content {
                New-UDSelector -Id "stuff" -options {
                    @{ value = "merry"; label = "Merry" },
                    @{ value = "christmas"; label = "Christmas" },
                    @{ value = "everyone"; label = "Everyone" },
                    @{ value = "pal"; label = "Pal" }
                }
            }

            New-UDButton -Text "Toast" -OnClick {
                $val2 = (Get-UDElement -id "stuff").Attributes.selectedOption.Count | ConvertTo-Json | ConvertFrom-Json
                if ([int]$val2 -gt 1) {
                    $val = (Get-UDElement -id "stuff").Attributes.selectedOption | ConvertTo-Json -Depth 1 | ConvertFrom-Json | Select-Object -ExpandProperty SyncRoot
                    [array]$source = $val | Select-Object -ExpandProperty SyncRoot
                    $c = 0
                    $values = $source | ? { $c % 2 -eq 0; $c++ }
                    $length = $values.length
                    $i = 0
                    Do {
                        $value += "'$($values[$i])'" + ","
                        $i++
                    }
                    While ($i -le $length)
                    $Session:value2 = $value.Substring(0, $value.Length - 4)
                    Show-UDToast -Message "Selected Values:- $Session:value2" -Position topLeft -Duration 4000
                    @("GridData", "InsideGrid") | Sync-UDElement
                }
                elseif ([int]$val2 -eq 1) {
                    $single = (Get-UDElement -id "stuff").Attributes.selectedOption
                    $selection = $single | Select-Object Root | ConvertTo-Json -Depth 2 | ConvertFrom-Json
                    $finalvalue = $selection | Select-Object -ExpandProperty Root
                    $Session:value2 = $finalvalue | Select-Object -First 1
                    Show-UDToast -Message "You Selected $Session:value2"
                }
            }
        }
    }
}
Start-UDDashboard -Dashboard $dashboard -Port 10005

Once again massive respect to @BoSen29 for the help, and secondly download your copy today :sunglasses:

8 Likes

This is awesome! Thank you again @psDevUK for your contributions to the community. One thing it appears in using the link to the improved demo is that it doesn’t have the same handling if there is only a single value selected (like the nested script does). Or, very possible, am I missing something on that? When I load the improved demo and only select one item, I’m not getting a value returned to the toast.

I am happy you think this is a good addition. This is a super popular react component, so was very pleased to bring this to the UD world, and get contributions/improvements, from some other UD forum members. Ok so I am using the multi-select aka New-UDSelector to select a load of codes from the DB and do a search on those products in an sql query…so I needed all my items or item in a fashion of ‘item’,‘item2’,‘item3’ etc…this is how I achieved this:-

New-UDCard -BackgroundColor "#8789c0" -Content {
New-UDButtonParticle -Id "Explode" -Text "Search" -Color "#2e3d55" -BackgroundColor "#2e3d55" -Icon search -onClick {
function Get-UDSelectorValue {
param($SelectorId)
$value = (((Get-UDElement -Id $SelectorId).Attributes.selectedOption | Select-Object Root -ErrorAction SilentlyContinue) | ConvertTo-Json -Depth 2 | ConvertFrom-Json | Select-Object -ExpandProperty Root -ErrorAction SilentlyContinue) | Select-Object -First 1
if (!$value) {
$val = ((Get-UDElement -Id $SelectorId).Attributes.selectedOption | ConvertTo-Json -Depth 1 | ConvertFrom-Json | Select-Object -ExpandProperty SyncRoot) | Select-Object -ExpandProperty SyncRoot
$length = $val.length
$i = 0
Do {
if (($i % 2) -eq 0) {
$value += "'$($val[$i])'" + ","
}
$i++
}
While ($i -le $length)
$value = $value.TrimEnd(",")
}
return $value
}
###so I gave my new-udselector the -id of 'selector'
$Selected =  (Get-UDSelectorValue -SelectorId 'selector') -replace ",''"
if (($Selected) -notmatch "\A'" )
{
$Selected = "'$Selected'"
}
###### $Selected > C:\Adam\output.txt ##verify the result by outputting them somewhere
$Session:Selected = $Selected


Show-UDToast -Message "You selected $Selected"
@("GridData","InsideGrid","GridData2","InsideGrid2") | Sync-UDElement
start-sleep -Seconds 5
}
}

I am also using my UDButtonParticle in this dashboard I have running, as think it is a great indicator to the user that they clicked the button, and something is happening as you suddenly see grids loading below…I hope this helps, if you need further advice, or information I can provide on this control just let me know, as it has become a super-handy component for me, or anyone who needs multiple or single selection, and do something with all the item(s) selected.

Hi,
this is a great plugin, is there a sample code that shows how to use the selected options to tie it with the other report elements like a grid or chart to actually filter the data based on the selection.

1 Like

Thanks @cprogramer84 and a big welcome to UDForums. Yep more than happy to share a full working page to show this in action. I am using this on my work dashboard to populate grids and charts with the information selected…I can even then put this into my pivot-table component which is another nice way to break data down…at work now will post later. Peace
One demo file is here:- https://github.com/psDevUK/UD-Selector/blob/master/DEMO.ps1
I will edit the README on github, which should then refresh the marketplace.

Hi @psDevUK,
Thanks for your quick response, I have setup the environment on my windows 10 machine with PS version 5.1.1773 , when i try to execute the script through the ISE i get the below error.

What could be the issue?

Sorry at work…doh…this component had some community love put into it by other members so the demo file is now out of date as a newer release has changed the options to be a script block instead of an array
so where it goes -options @( ) you need the options parameter to be a scriptblock -options { }
I promise I will update the readme on this component to make it easier for others to understand and use, as it is really handy…
Sorry this is the updated link which shows it as a script block

@psDevUK

FYI: The demo is not showing values if only one item is selected

I had a look into the demo and you can use the following simplified code for your Toast button

New-UDButton -Text "Toast" -OnClick {
    $values = (Get-UDElement -id "stuff").Attributes.selectedOption | %{if($_){ConvertFrom-Json -InputObject $_.ToString()}} | Select -ExpandProperty value
            
    Show-UDToast -Message "Selected Values: $($values -join ', ')" -Position topLeft -Duration 4000
}
1 Like

Thanks man…gonna dig out my working code I got real soon and post it on the official readme then link that here for future reference. :+1:

1 Like

Right my homework is now complete :grinning: please read the brand new readme I just finished writing and hopefully this component will make a lot more sense to you…if there is anything I have missed out let me know…

looks good, maybe you can use the following code snipped in your Get-UDSelectorValue function in order to simplify it :wink:

$values = (Get-UDElement -id "stuff").Attributes.selectedOption | %{if($_){ConvertFrom-Json -InputObject $_.ToString()}} | Select -ExpandProperty value
1 Like

Hi @psDevUK,
Many thanks for looking into my query. The new code works and I am able to populate the dashboard page only minor issue is that I am getting the message " Component not registered: UD-Selector" I tried to google\follow this article Component not registered but couldnt find any corresponding code in the file
C:\Program Files (x86)\WindowsPowerShell\Modules\UniversalDashboard.UDSelector\1.0.0\UniversalDashboard.UDSelector.psm1

Sorry to hear you still having issues man…you have imported the module yeah? I assume you are just using the demo script? I am kind of getting ready for work now…will test on a machine once I get into work and post the code…

Yes the module has been imported, but it says its not registered module. No hurry please reply when you can . thanks for your support and quick response on this . appreciate it.

So as long as you followed the readme and done the following command with admin rights:-
Install-Module UniversalDashboard.UDSelector

Then try running the following script:-

Import-Module UniversalDashboard.Community -RequiredVersion 2.8.1
Import-Module UniversalDashboard.UDSelector
function New-UDSelectorItem {
    [CmdletBinding(DefaultParameterSetName = "Default")]
    param(
        [Parameter(
            ValueFromPipeline = $true,
            Mandatory = $true,
            Position = 0
        )]
        [string]$Value,
        [Parameter(
            ValueFromPipeline = $true,
            Mandatory = $false,
            Position = 1
        )]
        [string]$Label,
        [Parameter(
            Mandatory = $false,
            ParameterSetName = "Disabled"
        )]
        [switch]$isDisabled
    )
    Begin {
        $out = @{ };
    }

    Process {
        if ($null -eq $Label) {
            $Label = $Value
        }

        $out.label = $Label
        $out.value = $Value


        if ($isDisabled.IsPresent) {
            $out.isDisabled = $true
        }
    }

    End {
        return $out
    }
}
Get-UDDashboard | Stop-UDDashboard
$theme = New-UDTheme -Name "Basic" -Definition @{
    '.css-1wa3eu0-placeholder'        = @{
        'color' = "#56587b !important"
    }
    '.css-1okebmr-indicatorSeparator' = @{
        'background-color' = "#56587b !important"
    }
    '.css-1hwfws3'                    = @{
        'height'      = "30px"
        'align-items' = "flex-start"
        'box-sizing'  = "initial !important"
        'flex-wrap'   = "initial !important"
    }
    '.css-1rhbuit-multiValue'         = @{
        'background-color' = "#323246 !important"

    }
    '.css-xb97g8'                     = @{
        'background-color' = "#56587b"
        'color'            = "#fffaf4"
    }
    '.css-12jo7m5'                    = @{
        'color' = "rgb(255, 255, 255) !important"
    }
    '.css-tlfecz-indicatorContainer'  = @{
        'color' = "#56587b !important"
    }
    '.css-yk16xz-control'             = @{
        'border-color' = "#56587b !important"
    }
    '.css-1g6gooi'                    = @{
        'padding-top' = "9px !important"
        'color'       = "#56587b !important"
    }
} -Parent "Default"
$dashboard = New-UDDashboard -Title "New Component" -Theme $theme -Content {
    New-UDRow -Columns {
        New-UDColumn -size 7 -Content {
            New-UDCard -BackgroundColor "#8789c0" -Content {
                New-UDSelector -id  "stuff" -Options {

                    New-UDSelectorItem -value "SomeStuff1" -label "FancyLabel1"
                    New-UDSelectorItem -value "SomeStuff2" -label "FancyLabel2"
                    New-UDSelectorItem -value "SomeStuff3" -label "FancyLabel3"
                    New-UDSelectorItem -value "SomeStuff4" -label "FancyLabel4" -isDisabled
                } -PlaceHolder "New Fancy Component..."
            }
            New-UDButton -Text "Toast" -OnClick {
                $val = (Get-UDElement -id "stuff").Attributes.selectedOption | ConvertTo-Json -Depth 1 | ConvertFrom-Json | Select-Object -ExpandProperty SyncRoot
                $source = @(($val | Select-Object -ExpandProperty SyncRoot))
                $length = $source.length
                $i = 0
                Do {
                    if (($i % 2) -eq 0) {
                        $value += $source[$i] + ","
                    }
                    $i++
                }
                While ($i -le $length)
                $value = $value.TrimEnd(",")
                Show-UDToast -Message "Selected Values:- $value" -Position topLeft -Duration 4000

            }
            New-UDButton -Text "RemoveMe" -OnClick {
                Remove-UDElement -id "stuff"
            }
            New-UDButton -text "ShowME" -OnClick {
                Set-UDElement -id "stuff" -Attributes @{
                    hidden = $false
                }
            }
            New-UDButton -Text "ClearMe" -OnClick {
                Clear-UDElement -Id "stuff"
            }

        }

    }
}

Start-UDDashboard -Dashboard $dashboard -Port 10005

This should give you


This works in every browser I tried Chrome, FireFox even IE

1 Like

Many Thanks! it works now. I am great full for your timely support and quick response.
I will now try to hook it up to data and see if i am able to make it work .

What I am trying to do it take baby steps towards building a dashboard which will look as below,
I will experiment to move this plugin to the extreme left and use it a slicer \criteria for data.
so ideally this plugin would take the top column and replace with the Filter1

Side note: I had to go back one version to 2.8.1 to get this working, not sure if there is additional plugin registration requirement in version 2.8.2. However 2.8.1. also works for me to explorer and create the sample.

Thanks again.

1 Like

Yes. 2.8.1 appears to really be required. Failing is similar fashion when using 2.9.0

Hey @cadayton I am only running on 2.8.1 at home and at work…waiting for the big release of v3 before I look at upgrading…it does however seem really odd, as it only seems to be this component which other users seem to be having issues with running in any other version of UD other than 2.8.1…I would need to call upon the advice of @adam or @AlonGvili to explain this, as seems so odd it, doesn’t want to work in other versions of UD? As mentioned not had same issue reported with any of the other 40 odd components I put out there so really cannot explain this behaviour :confused: I will re-look through my code see if I done anything weird, but to my knowledge I built this the same way I do with all other components…

Not a big deal for me. I’ve just been testing several of the controls individually. I do appreciate the time and effort you put into creating new controls. Thanks.

1 Like

I have been running this component on 2.9.0 with no issues. Not sure why it is working for me and not for others.

1 Like