Select One Dropdown Populated Dynamically

So what I am trying to do is a basic HtmlSelectOne dropdown list. This list will have sub groups (optGroups) which will give the appearance of nested options. So it would show like this for example:
CA Users
User1
User2
MA Users
User3
User4

The users are returned by a web service (note I am just using ‘users’ as an example), and based upon specific criteria I am going to create multiple option groups and then add them to the Select on dropdown. I have tried creating multiple ‘SelectItemGroupProviders’ in java with the options however I cannot figure out for the life of me how to add these providers to the actual dropdown in java. I realize I can hardcode (manually add the option groups in the dropdown options) in Designer but the number and size of these groups is dynamic so hard coding is not an option. Any ideas/suggestions would be greatly appreciated, thanks!

You would need to add a new javax.faces.component.UISeelctItems control as a child of the HtmlSelectOne control.

For example, I haven’t tried it, but it would be something like below. You didn’t say which version of MWS you are using, but if it is a recent version, it is safest to manipulate the component tree by overriding the preRenderResponse method and doing the logic there.


	/* (non-Javadoc)
	 * @see com.webmethods.caf.faces.bean.BaseViewBean#preRenderResponse(javax.faces.event.PreRenderViewEvent)
	 */
	@Override
	public void preRenderResponse(PreRenderViewEvent e) {
		//get the dropdown control
		HtmlSelectOne dropdown = (HtmlSelectOne)findComponentInRoot("your_dropdown_id_here");
		List<UIComponent> children = dropdown.getChildren();
		//TODO: clear the list if you wish to remove any previously existing children.
		// children.clear(); 
		
		//add new children
		UISelectItems selectGroup = new UISelectItems();
		ISelectItemGroupProvider groupProvider = null; //TODO: construct the provider from your data
		selectGroup.setValue(groupProvider);
		//add to the list of children
		children.add(selectGroup);
		
		super.preRenderResponse(e);
	}
1 Like

Thanks for the quick response Eric! So I tried a different way of doing so based upon your solution but I am still having some issues. I decided to add the options manually in lieu of using the group provider. So what I ended up doing was this:

//get UI Object/children
HtmlSelectOne dropdown = (HtmlSelectOne)findComponentInRoot("htmlSelectBusinessGroup");  
List<UIComponent> children = dropdown.getChildren(); 
children.clear();   

//create new option group
UISelectItems selectGroup = new UISelectItems();
//create new option		
UISelectItem firstItem = new UISelectItem();
firstItem.setItemLabel("TEST FIRST OPTION");
firstItem.setValue("TEST VALUE");

//add option to group
selectGroup.getChildren().add(firstItem);

//add group to dropdown
children.add(selectGroup);

however the option is not rendered. Curiously enough though I added just the option and not the group and it displayed just fine, any thoughts?

The list of SelectItems for a select group would need to be provided via the “value” property. Pass it a single SelectItem or an array or colllection of SelectItem objects.

JavaDocs for your reference: https://javaserverfaces.java.net/docs/2.2/javadocs/javax/faces/component/UISelectItems.html

For example, something like this:


//get UI Object/children
HtmlSelectOne dropdown = (HtmlSelectOne)findComponentInRoot("htmlSelectBusinessGroup");  
List<UIComponent> children = dropdown.getChildren(); 
children.clear();   

//create new option group
UISelectItems selectGroup = new UISelectItems();
//create new option		
UISelectItem firstItem = new UISelectItem();
firstItem.setItemLabel("TEST FIRST OPTION");
firstItem.setValue("TEST VALUE");

//add option to group by setting the item as the group value
selectGroup.setValue(firstItem);

//add group to dropdown
children.add(selectGroup);

Hi Eric, thank you very much for your help, that did the trick!

Hello Eric,
I tried this approach, but I get the following error when running the portlet:


(jsf:ERROR)  [RID:1108298] - Render phase of the portlet failed
java.lang.NullPointerException
	at com.webmethods.caf.faces.data.object.DefaultSelectItemProvider.initialize(DefaultSelectItemProvider.java:196)
	at com.webmethods.caf.faces.data.object.DefaultSelectItemProvider.initialize(DefaultSelectItemProvider.java:231)
	at com.webmethods.caf.faces.data.object.DefaultSelectItemProvider.<init>(DefaultSelectItemProvider.java:64)
	at com.webmethods.caf.faces.data.object.DefaultSelectItemGroupProvider.initialize(DefaultSelectItemGroupProvider.java:298)
	at com.webmethods.caf.faces.data.object.DefaultSelectItemGroupProvider.initialize(DefaultSelectItemGroupProvider.java:364)
	at com.webmethods.caf.faces.data.object.DefaultSelectItemGroupProvider.initialize(DefaultSelectItemGroupProvider.java:245)
	at com.webmethods.caf.faces.data.object.DefaultSelectItemGroupProvider.<init>(DefaultSelectItemGroupProvider.java:64)
	at com.webmethods.caf.faces.component.select.TopSelectItemsIterator.<init>(TopSelectItemsIterator.java:59)
	at com.webmethods.caf.faces.render.html.select.SelectOneRenderer.writeItems(SelectOneRenderer.java:109)
	at com.webmethods.caf.faces.render.html.select.SelectOneRenderer.encodeEnd(SelectOneRenderer.java:85)
	at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919)
...

Have you got any idea what might cause this error?

Best regards,
Marcus

Hello again,
luckily, the approach explained by Paul worked for me.

Best regards,
Marcus