Community Spring Cleaning week is here! Join your fellow Maveryx in digging through your old posts and marking comments on them as solved. Learn more here!

Dev Space

Customize and extend the power of Alteryx with SDKs, APIs, custom tools, and more.
SOLVED

HTML SDK - Triggering Events with Alteryx Plugin Widget

joshuaburkhow
ACE Emeritus
ACE Emeritus

I am using the (fairly) new HTML/Javascript SDK [which is awesome btw] but I am having a hard time on a specific action. 

 

Here is the html code I am trying (it's not triggering the test() function):

 

<alteryx-pluginwidget type="DropDown" id="model_dd" dataName="models" onchange="test()"></alteryx-pluginwidget>

 

this is a dropdown that i just want to trigger a function once a user changes the value in the dropdown, standard stuff. What's bizzare though is if I use some other events like "onmouseleave" it works in the way it should. 

 

I looked at the Dropdown.jsx file that I believe is rendering this alteryx-pluginwidget and I see this:

 

return (
<Select name="DropDownSelect" ref="widget" multi={this.state.isMultiselect}
value={newtonJsonSpecialValue} options={this.state.options ? this.state.options : options} searchable={false}
placeholder={this.props.placeholder ? this.props.placeholder : "Select..."} clearable={false}
onChange={this.handleChanged} {...this.props}/>
);

 

and 

 

handleChanged = (value) => {

if (this.dataItem) {
let isAddFieldOption = value === DropDown.AddFieldLabel;
if(value.split(',').length > 1 && this.dataItem.GetFieldList){
let selected = [];
if (this.dataItem !== null) {
for (let i of value.split(',')) {
selected.push(i);
}
this.dataItem.setValue(selected, false);
}
}
else if(this.dataItem.setValue && value.split(',').length === 1){
if(value) {
this.dataItem.setValue(isAddFieldOption ? DropDown.AddFieldLabel : value, false, isAddFieldOption);
}
else {
let newValue = this.state.isMultiselect ? [] : null;
this.dataItem.setValue(isAddFieldOption ? DropDown.AddFieldLabel : newValue,false, isAddFieldOption);
}
}
else if(this.dataItem.value['#text']){
this.dataItem.value['#text'] = value;
this.dataItem.setValue(this.dataItem.value);
}

if (isAddFieldOption) {
this.setState({displayAddFieldTextBox: true});
}

this.updateParentDataItem();
}

if (typeof this.props.onchange === 'function') this.props.onchange(value);
if (this.props.onChange) this.props.onChange(value);

this.setState({value: value});
};

 

I am not understanding how this piece is working: " onChange={this.handleChanged}"

 

any ideas?

Joshua Burkhow - Alteryx Ace | Global Alteryx Architect @PwC | Blogger @ AlterTricks
8 REPLIES 8
NeilR
Alteryx Alumni (Retired)

Try...

Alteryx.Gui.AfterLoad = function(manager, AlteryxDataItems) {
   manager.GetDataItem("models").BindUserDataChanged(test);
}
RachelW
Alteryx Alumni (Retired)

I wanted to update this thread to let you know that we have new SDK documentation available for our HTML GUI SDK, which was released in as a beta in 11.5. You can find documentation for both the HTML GUI SDK online. We'd love for you to provide your feedback here

Rachel Wynn
Product Manager - Designer
rpaugh
11 - Bolide

Hello,

 

Has something changed?  I tried this and get the error "...manager.getDataItem(...).BindUserDataChanged is not a function".  I reviewed the documentation and this is what I see for the manager object:

 

Public Methods
public 

bindDataItemToWidget(dataItem: DataItem, widgetId: string)

Binds a data item to a widget.

 
public 

deleteProp(widgetId: string, prop: string)

Deletes a property from a widget.

 
public 

getProp(widgetId: string, prop: string): *

Returns the value of a widget property.

 
public 

removeWidget(widgetId: string, removeTag: boolean)

Removes a widget from the manager.

 
public 

setProp(widgetId: string, prop: string, value: *)

Sets a property of a widget.

 
public 

setProps(widgetId: string, props: object)

Sets multiple properties of a widget.

 
public 

unbindDataItemFromWidget(dataItem: DataItem, widgetId: string)

Unbinds a data item from a widget.

 

What is the best way to trigger an event based on a drop-down selection change without the "BindUserDataChanged" method?

 

Update: I also reviewed all of the methods for the dataItem and extended objects and didn't see anything there either.

 

Update 2: it looks like "registerPropertyListener" is what I'm looking for so nevermind.

 

Thanks,

 

Rick

RuchikaMangla
8 - Asteroid

Hi @rpaugh @joshuaburkhow @RachelW @NeilR @TashaA 

 

I'm working on a custom tool using HTML python SDK. And in that I have a drop down and list box.

My use case is to set the Listbox items based on dropdown value. All the items listed under dropdown and listbox are static. So, can anyone please guide me how can I read the selected dropdown value in HTML/javascript?

 

Currently I'm using manager.getDataItem('dropdownWidgetId').getValue() but it is throwing below error-

 

RuchikaMangla_0-1605621262640.png

 

 

Thanks in advance!!

rpaugh
11 - Bolide

@RuchikaMangla Would you mind providing some background code for the data item? It's difficult to troubleshoot without seeing how values are assigned to your dropdown widget and when and where you're attempting to run getValue().

RuchikaMangla
8 - Asteroid

Thanks @rpaugh for your response

 

Below is the javascript code. I want that if i select any item from the dropdown, then list box should also get refreshed.

In below code, if i select InputA in dropdown then list box should only populate Item1 and Item2, if InputB is selected then Item3 and Item4 should be shown in listbox. Please let me know if anything else you need to troubleshoot it. Thanks!

 

<script type="text/javascript">

const getDrpDownValue = () => {
return Alteryx.Gui.Manager.getDataItem('dict').getValue()}

Alteryx.Gui.AfterLoad = function (manager, AlteryxDataItems) {
getDrpDownValue()
manager.getDataItem('dict').registerPropertyListener('value',getDrpDownValue)}

Alteryx.Gui.BeforeLoad = function (manager, AlteryxDataItems, json) {

var stringSelector2 = new AlteryxDataItems.StringSelector('dictionary', {
optionList: [
{label: 'XMSG("InputA")', value: "InputA"},
{label: 'XMSG("InputB")', value: "InputB"}
]
})
manager.addDataItem(stringSelector2)
manager.bindDataItemToWidget(stringSelector2, 'dict') // Bind to widget

//alert(manager.getDataItem('dict').getValue)
if (manager.getDataItem('dictionary').value == "InputA"){
var stringSelectorMulti = new AlteryxDataItems.StringSelectorMulti('ListBoxStringSelector', {
optionList: [
{label: 'XMSG("Item1")', value: "Item1"},
{label: 'XMSG("Item2")', value: "Item2"}

]
})
manager.addDataItem(stringSelectorMulti)
manager.bindDataItemToWidget(stringSelectorMulti, 'ListBoxA')
}
else if (manager.getDataItem('dictionary').getValue == "InputB"){
var stringSelectorMulti = new AlteryxDataItems.StringSelectorMulti('ListBoxStringSelector', {
optionList: [
{label: 'XMSG("Item3")', value: "Item3"},
{label: 'XMSG("Item4")', value: "Item4"}
]
})
manager.addDataItem(stringSelectorMulti)
manager.bindDataItemToWidget(stringSelectorMulti, 'ListBoxA')
}

}


</script>

rpaugh
11 - Bolide

@RuchikaMangla I think your issue is with variable scope. When you're setting the constant getDrpDownValue, the "dict" data item hasn't been loaded yet and so it's returning an empty value. When registering your property listener, you'll have to send in what you want it to reference. You also seem to be setting the value of the same data item you're retrieving (e.g. property listener listening to "dict" to then set the value on "dict" rather than the dependent list box). Here's an example based on what works in my tool, adapted from what I understand of your code:

 

Alteryx.Gui.AfterLoad = function (manager) {
	//Get the reference to the dependent list box data item
	var fieldsDataItem = manager.getDataItem('ListBoxStringSelector');

	//Set the option list to whatever is already selected in the 'dictionary' data item (this is important for re-loading your configuration after clicking on/off the canvas and/or loading a saved workflow)
	fieldsDataItem.setOptionList(setFields(manager.getDataItem('dictionary').getValue()));

	//Register the property listener on the 'dictionary' object
	manager.getDataItem('dictionary').registerPropertyListener('value', 
		function (e) { 
		//Clear out existing list items first
		manager.getDataItem('ListBoxStringSelector').setValue([]);
		//Set the list to the new values based on the value selected in the 'dictionary' data item
		fieldsDataItem.setOptionList(setFields(e.value)); //e.value = selected 'dictionary' value
	}
	);
}

 

And the setFields() method reference above would look something like this:

 

setFields = function(dictionaryValue) {
	var fields = [];

	if (dictionaryValue == "InputA") {
		fields.push({ label: "Item1", value: "Item1" });
		fields.push({ label: "Item2", value: "Item2" });
	}
  
	if (dictionaryValue == "InputB") {
		fields.push({ label: "Item3", value: "Item3" });
		fields.push({ label: "Item4", value: "Item4" });
	}

	return fields;
}

 

RuchikaMangla
8 - Asteroid

Thanks, @rpaugh 

 

Really appreciate for the help! it worked like a charm! 🙂

 

thanks for pointing out the issue and describing it in detail as well. I don't have that much knowledge of java-script but this is good example to learn from.

Thanks for your help again!!