Hi guys,
Trying to build an optionset control. Fired up the debug harness, and it's stuck on "Loading control harness...".
Using the following Manifest.
<?xml version="1.0" encoding="utf-8" ?>
<manifest>
<control namespace="ControlsAndrewLy" constructor="ColorOptionsets" version="0.0.1" display-name-key="ColorOptionsets_Display_Key" description-key="ColorOptionsets_Desc_Key" control-type="standard">
<!-- property node identifies a specific, configurable piece of data that the control expects from CDS -->
<property name="inputOptionSet" display-name-key="Option Set" description-key="Option Set from CDS" of-type="OptionSet" usage="bound" required="true" />
<property name="inputColorHexString" display-name-key="Color Hex Codes" description-key="Provide a list of color hex codes separated by a comma. e.g. #8B0000,#FF6347,#8B0000" of-type="SingleLine.Text" required="true" />
<resources>
<code path="index.ts" order="1"/>
<!-- <css path="css/ColorOptionsets.css" order="1" />-->
</resources>
<!-- UNCOMMENT TO ENABLE THE SPECIFIED API
<feature-usage>
<uses-feature name="Device.captureAudio" required="true" />
<uses-feature name="Device.captureImage" required="true" />
<uses-feature name="Device.captureVideo" required="true" />
<uses-feature name="Device.getBarcodeValue" required="true" />
<uses-feature name="Device.getCurrentPosition" required="true" />
<uses-feature name="Device.pickFile" required="true" />
<uses-feature name="Utility" required="true" />
<uses-feature name="WebAPI" required="true" />
</feature-usage>
-->
</control>
</manifest>
And the following index.ts file
import {IInputs, IOutputs} from "./generated/ManifestTypes";
export class ColorOptionsets implements ComponentFramework.StandardControl<IInputs, IOutputs> {
// Value of the field is stored and used inside the control
private _value: number;
// string with hex codes
private _colorhexcodes: "#FF0000,#800000,#FF6347";
private _colorhexcodesarray : string[];
// PowerApps component framework framework delegate which will be assigned to this object which would be called whenever an update happens.
private _notifyOutputChanged: () => void;
// label element created as part of this control
private label: HTMLInputElement;
// Hold field options of bounded optionset field
private _fieldOptions: Array<ComponentFramework.PropertyHelper.OptionMetadata>;
// Reference to the control container HTMLDivElement
// This element contains all elements of our custom control example
private _container: HTMLDivElement;
// Reference to ComponentFramework Context object
private _context: ComponentFramework.Context<IInputs>;
private _dropdownSelect: HTMLSelectElement;
/**
* Empty constructor.
*/
constructor()
{
}
/**
* Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here.
* Data-set values are not initialized here, use updateView.
* @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions.
* @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously.
* @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface.
* @param container If a control is marked control-type='starndard', it will receive an empty div element within which it can render its content.
*/
public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container:HTMLDivElement)
{
this._context = context;
// vectorise hex colour codes
this._colorhexcodesarray = this._colorhexcodes.split(",");
/*
// set the optionsetfield options
if (this._context.parameters.inputOptionSet.attributes) {
this._fieldOptions = this._context.parameters.inputOptionSet.attributes.Options;
this._dropdownSelect = document.createElement("select");
// add each individual option
for(let i=0; i<this._fieldOptions.length; i++){
var selectOption = document.createElement("option");
selectOption.value = this._fieldOptions[i].Value.toLocaleString();
selectOption.text = this._fieldOptions[i].Label;
this._dropdownSelect.appendChild( selectOption );
}
}*/
this._notifyOutputChanged = notifyOutputChanged;
// Adding the label and button created to the container DIV.
this._container = document.createElement("div");
this._container.appendChild(this._dropdownSelect);
container.appendChild(this._container);
}
/**
* Called when any value in the property bag has changed. This includes field values, data-sets, global values such as container height and width, offline status, control metadata values such as label, visible, etc.
* @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions
*/
public updateView(context: ComponentFramework.Context<IInputs>): void
{
// This method would render the control with the updated values after we call NotifyOutputChanged
//set the value of the field control to the raw value from the configured field
this._value = context.parameters.inputOptionSet.raw;
this.label.value = this._value != null ? this._value.toString(): "";
if(context.parameters.inputOptionSet.error)
{
this.label.innerHTML = this._value.toString();
this.label.style.backgroundColor = this._colorhexcodesarray[0];
//this.label.classList.add("SimpleIncrement_Input_Error_Style");
}
else
{
this.label.innerHTML = this._value.toString();
this.label.style.backgroundColor = this._colorhexcodesarray[0];
//this.label.classList.remove("SimpleIncrement_Input_Error_Style");
}
}
/**
* It is called by the framework prior to a control receiving new data.
* @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as “bound” or “output”
*/
public getOutputs(): IOutputs
{
return {};
}
/**
* Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup.
* i.e. cancelling any pending remote calls, removing listeners, etc.
*/
public destroy(): void
{
// Add code to cleanup control if necessary
}
}Thanks again guys.
@HemantG @GregHurlmanMSFT