Drop-down menu always empty

Hello,

i’ve problems creating a drop-down list for an URCaps application.

According to the official URCaps Software Development Tutorial the
HTML eleemtns<select> and <option> are supporeted, so i’m trying to
create the drop-down menu as follows:

<select id="choose"> <option>Entry1</option> <option>Entry2</option> </select>

Opening this HTML code in a common web browser shows the drop-down menu with
its two entries as expected. But inside UR PolyScope the drop-down list
is always empty at the HTML page of my installed URCaps application (drop-down
list appears as an empty rectangle with no elements inside it).
I’ve also tried to access the created drop-down list inside the Java code of my
URCaps but i always get a NullPointerException, so it doesn’t seem to be initialized
correctly (probably for the same reason that it is always displayed empty).
Other supported GUI elements, such as button, check box, number field, … are working
just fine.

Is something wrong with the above HTML code or inside the URCaps SDK?

Thank you very much

@artiminds,

How are you creating your selectin Java?

Consider having a minimal drop down in HTML, hence you have more flexibility from the Java side to change the items.

<form>
	<select id="selObject">
		<option>&lt;List is empty&gt;</option>
	</select>
</form>

And then in Java initialize and modify the list.

@Select(id = "selObject")
private SelectDropDownList selObject;

@Select(id = "selObject")
public void onSelectChange(SelectEvent event){
	if (event.getEvent() == SelectEvent.EventType.ON_SELECT){
	// Do something
	}
}

private void someSelectListMethod(){
	selObject.addItem("MyItem");
	selObject.selectItemAtIndex(0);
}

private void someOtherSelectListMethod(){
	int item = selObject.getSelectedIndex();
	selObject.removeAllItems();
}
4 Likes

Thanks for the fast replay and help.

I’ve used the tag @Input instead of @Select for the drop-down menu
that was causing the NullPointerException. Now the code works fine.

But I’m wondering why the drop-down list is still empty if i add elements by just
using the<option> tag. I also have to use the addItem() method to add the
elements and see them in the drop-down menu. Just adding them using <option> is not enough (list empty).

But I can live with that because the code and the drop-down menu are working now. Once again thanks for the help.

Hi everyone,
I’m new to UR and Java, but I have other programming experience with robots and programming. I need some help with understanding how Java works.

Could you please explain how I can tell if there are any other events that I could listen to? How is this working exactly? SelectDropdownList doesn’t have method like onSelectChange. Is this part of OSGi specification? Where should I look for it? I looked through ui package in Maven dependencies. In CycleCounter sample similar function is called onSelectComboVariable. Doesn’t name matter?

Right now I am wrestling with this function and it looks like it does not fire.

In the HelloWorld example, the input (text fields) callbacks are annotated by using @Input and a public method taking an InputEvent as an argument.
For dropdowns, this should instead be a @Select annotation linked to the HTML Select ID, and the public method should take a SelectEvent object as an argument.
You might take a look at the Script Wrapper Sample which implements a dropdown.

Ok, so the only requirement is, that method has to be public and accept SelectEvent as argument.
This is my HTML file.

<!DOCTYPE html>
<html>
	<head>
		<title>Timer</title>
	</head>
	<body>
		<p>This program node will do nothing on execution.</p><br \>
		<br/>
		<form>
			<select id="startstop">
				<option>Dropdown list will be empty, because Option does not work</option>
			</select>
			<label id="typepreview"/>
	</form>
	</body>
</html>

This is my function:

@Select(id = "startOrStop")
public void onSelectChange(SelectEvent event) {
	if (event.getEvent() == SelectEvent.EventType.ON_SELECT) {
		if (startOrStop.getSelectedIndex() == 0) {
			this.model.set(TYPE, "START");
		} else if (startOrStop.getSelectedIndex() == 1) {
			this.model.set(TYPE, "STOP");
		}
		typePreview.setText(this.model.get(TYPE, "ERROR"));
	}
	typePreview.setText("onSelect executed");
}

typePreview label doesn’t change its text. I change it openView(), so I know that it works. It seems to me, that this function is not executed. Can you please take a look if there are any errors here?

In the code snippets above, your ID’s does not match - which they should in order to link the two domains together.
In HTML your id is startstop while it is startOrStop in Java.

To check if your SelectEvent callback actually executed, you can also add the following to your callback, and start the simulator from a terminal (./ ursim-current/start-ursim.sh)

// Print debug to terminal, like: "onSelectChange was executed. Selected index was: 1"
System.out.println("onSelectChange was executed. Selected index was: "+startOrStop.getSelectedIndex());

OMG, thanks. I thought I checked everything. I stared at it for hours.
Thank you.

Anyway I am still curious how GUI knows to call this function. It is not
inherited, so the name is not known before. What if I had two functions
that fulfill requirements?

wt., 16.01.2018, 15:01 użytkownik Jacob Bom Madsen <
universal_robots@discoursemail.com> napisał:

I understand that this is because the annotation (@Select (id = "xxxx")) above the method.

I have a very specific question about all this. In my experience so far, the HTML component is the same across all ProgramNodeContribution instances that are created, so they all reference the same object. Following that line, if one ProgramNode updates the options of one SelectDropDownList, that change will be reflected to all program nodes.

Can @jbm or anyone else confirm this? I’m having some issues that may suggest that this does not apply in all cases.

I don’t think so. Every program node contribution has its own model field. If you want to share it across all of them, you need to do it in Installation node or some kind of static variable in your Program node contribution class.

Just to clarify, I know about the DataModel. My question is about HTMLElements (those members that have annotations and are set by Polyscope)

I understand that this is because the annotation (@Select (id = “xxxx”)) above the method.

This annotation connects HTML with object in Java. Polyscope then does just something similar to document.getElementById(), reads value and updates Java Object. This is me just guessing here, but I can only see, that annotation just adds id field to object. It does not say “on event Change call function onSelectChange”.

My question is about HTMLElements (those members that have annotations and are set by Polyscope)

Hmm, I guess you are right. HTML is read by ProgramNodeService. Programmer seems to be responsible to update the values in the view during openView() call.

When the URCap is loaded on boot, the HTML GUI instance is only loaded once (from the ProgramNodeService).
Every time a new node is inserted, the createNode is calles, which creates a new instance of the ProgramNodeContribution, including a new instance in the DataModel.

Hence, since there is only one GUI loaded, it is important to use the openView() call, to populate the GUI with the settings for the specific node the user has in focus. If not doing so, the values shown in the GUI for the “old” node, will also still be there when navigating to the “new” node - however the new node will not be changed by this, since the values are not inserted by user interaction (i.e. no callback to the Inout/SelectEvent).

The linking between HTML and the NodeContribution is handled by PolyScope.
Meaning that PolyScope registers the user interaction with an input element in HTML, and looks into the corresponding NodeContribution to find the callbacks linked to the same ID.