Knime-WebUi - 5.0, 5.1

Hi everyone,
Recently, I’m working with KNIME modern UI (v5.0.0, 5.1.0) and trying to develop a node with the web-ui capabilities.
I wonder if it is possible to to dynamically change dialog based on selected drop down (without pushing OK button and reopening the dialog)? if possible, how can one do that?

As an example, in the below pictures, when user selects Person type then the corresponding columns appears and when selects Date then the corresponding columns appears.

1 Like

Hi @nmorti,

you could use different settings per “Type” and hide/show them using Effects (might be cumbersome) or try with the ChoicesUpdateHandler in the ChoicesWidget.

Please let me know if it helps!

But also please remember that the current WebUI API is internal and will change in the future (i.e. breaking changes are very likely).

3 Likes

Hi @hotzm,

I faced with various challenges so I decided to post my settings code and comment my requirements.

@SuppressWarnings("restriction")
public class MyNodeSettings implements DefaultNodeSettings {
	
	@Widget(title = "Types")
	@ChoicesWidget(choices = Types.class)
	String m_type;
	
	@Widget(title = "Columns")
	@ArrayWidget
	@Effect(signals = {}, type = EffectType.SHOW)
	/*
	 * Requirement 1:
	 * First time the user opens the dialog, no columns appears. by choosing a type, related columns appear in the dialog.
	 * It seems to define signals on m_type, but how? 
	 * type choices are not fixed values so using {@link IsSpecificStringCondition} and defining multiple ArrayWidget for each of them not the case.
	 */
	Column[] m_columns = new Column[0];
	
	private static String[] typesChoices;
	
	MyNodeSettings() {
	}
	
	MyNodeSettings(final SettingsCreationContext context) {
		List<Column> columns = new ArrayList<>();
		context.getDataTableSpecs()[0].stream().forEach(ColumnSpec ->
			columns.add(new Column(ColumnSpec.getName()))
		);
		m_columns = columns.toArray(Column[]::new);
	}
	
	static final class Column implements DefaultNodeSettings {
		
		@HorizontalLayout
		interface MyLayout {
		}

		@Widget(title = "Column")
		@ChoicesWidget(choices = AllColumns.class, choicesUpdateHandler = ?) 
		/* 
		 * Requirement 2:
		 *	Here, I want to update choices based on value of m_type but I don't know how a ChoiceUpdateHandler can be implemented!
		 * 	any sample implementation would be appreciated!
		 */ 
		@Layout(MyLayout.class)
		public String m_columnName;

		Column() {
		}
		
		Column(String name) {
			m_columnName = name;
		}
	}
	
	private static final class AllColumns implements ChoicesProvider {
		@Override
		public String[] choices(final SettingsCreationContext context) {
			var spec = context.getDataTableSpecs()[0];
			return spec == null ? new String[0] : spec.getColumnNames();
		}
	}
	
	private static final class Types implements ChoicesProvider {
		@Override
		public String[] choices(SettingsCreationContext context) {
			typesChoices = Utils.getTypesFromService(); // types are coming from calling an external service, So they may change after sometimes.
			return typesChoices;
		}
	}