V2.9.0 - Get-UDElement properties of custom element

I’m trying to get specific properties (files or value) from a custom input element created with New-UDElement, but Get-UDElement doesn’t seem to see them. Is there any way to retrieve the data from this element?

New-UDElement -Id 'test' -Tag 'input' -Attributes @{type="file"}
New-UDButton -Text 'Submit' -OnClick {
    $test = (Get-UDElement -Id 'test')
    $test | Out-File c:\test.txt
    $test2 = (Get-UDElement -Id 'test').Attributes
    $test2 | Out-File c:\test2.txt
}

Element:

Tag             : input
Attributes      : {type, ref, id}
Properties      : 
Events          : {}
Content         : 
JavaScriptPath  : 
JavaScriptId    : 
ComponentName   : 
ModuleName      : 
Type            : element
Key             : 0f76d65a-e45a-4974-8908-abae4b0640c9
OnMount         : 
Id              : 
Callback        : 
RefreshInterval : 0
AutoRefresh     : False
Error           : 
HasCallback     : False

Attributes:

Name                           Value
----                           -----                                                                                    
type                           file                                                                                     
ref                            element                                                                                  
id                             test

I’m not sure on that one, but out of interest, why not just use New-UDInput an take the input from that? https://docs.universaldashboard.io/components/inputs

The form I’m working on is a bit complicated and I find New-UDInput to be a little restrictive in both design and functionality.

I have chucked a load of custom components on the marketplace https://marketplace.universaldashboard.io/ if you search for PSDEVUK then you should see a fair few controls to choose from, I have documented them where I can…I do use these myself to collect and display user input

Thanks! I’ve already put your New-UDSelector and New-UDSingleSelector to good use.

I’ll probably end up trying to reverse engineer how you did your custom components and try to construct a New-UDFileSelector or some nonsense that will allow for retrieving a file and its properties.

Not a huge priority at this point. I was just hoping that I was missing something obvious with New-UDElement and/or Get-UDElement.

I been down that road already and failed myself…I tried to build numerous drag and drop file uploads but failed each time to get it working correctly. I learnt my skills from the man himself Mr Driscoll when he did the youtube video on custom components…I mean I have teamed-up in the past with other UD members…I know I can build the component to drag and drop upload, but I do not have the REACT know-how to get it all fully working correctly…more than happy to post this on github if you want to team-up?

Alright…
After spending the last few days watching the custom components youtube video, looking through various existing custom components, and giving it the ole college try at making my own, I may have come up with something. This is only utilizing the html input tag so I’m not sure if you’d be able to take any of this to work with a drag and drop component. I know almost nothing about react and only have a basic working knowledge of javascript so please don’t judge my code too harshly.

For the life of me I cannot figure out how to expose a component’s properties to Get-UDElement so I ended up going a different route. In the custom component video Adam showed how to post properties back to UD/powershell from an onedit event and I did something similar with the input’s onchange event. My specific use case was to try and get .txt/.ps1 file contents back into UD/powershell and my code is tailored towards that end. I’m sure its possible for it to be variablized to become a lot more flexible of a component in terms of file types and/or the data that gets posted back to UD/powershell.

.jsx:

import React from 'react';

class UDFileSelector extends React.Component {

  constructor() {
	super();
	this.state = {
	  file: ''
	}
  }

  onFileChanged(e) {
	var file = e.target.files[0]
	var id = this.props.id
	var reader = new FileReader();
	reader.onload = function() {
	  UniversalDashboard.post(`/api/internal/component/element/${id}FileSelected`, reader.result)
	}
	reader.readAsDataURL(file);
  }

  render() {
	var field = {
	  id: this.props.id,
	  buttontext: this.props.buttontext,
	}
	var self = this;
	return (
	  <div className="file-field input-field">
		<div className="btn">
			<span>{field.buttontext}</span>
			<input id={field.id} type="file" accept=".ps1" onChange={e => self.onFileChanged(e) } />
		</div>
		<div className="file-path-wrapper">
			<input className="file-path validate" type="text" value={this.state.file} />
		</div>
	  </div>
	)
  }

}

export default UDFileSelector

.ps1:

function New-UDFileSelector {
	param(
		[Parameter()]
		[string]$Id = ([Guid]::NewGuid()),
		[Parameter()]
		[string]$ButtonText,
		[Parameter()]
		[scriptblock]$OnFileSelected
	)

	End {

		if ($null -ne $OnFileSelected) {
			$FileSelected = New-UDEndpoint -Endpoint $OnFileSelected -Id "$($Id)FileSelected"
		}

		@{
			# The AssetID of the main JS File
			assetId = $AssetId 
			# Tell UD this is a plugin
			isPlugin = $true 
			# This ID must be the same as the one used in the JavaScript to register the control with UD
			type = "file"
			# An ID is mandatory 
			id = $Id

			# This is where you can put any other properties. They are passed to the React control's props
			# The keys are case-sensitive in JS. 
			buttontext = $ButtonText
		}
	}
}

example:

New-UDFileSelector -Id 'test' -ButtonText 'file' -OnFileSelected {
	param($Body)
	$base64 = $Body.Substring(1,$Body.Length-2).Split(',')[1]
	$bytes = [Convert]::FromBase64String($base64)
	$contents = [System.Text.Encoding]::ASCII.GetString($bytes)
	$contents | Out-File $desktop\test.txt
}
2 Likes