In OpenLaszlo context menus are attached to a single view. If an object on the screen is composed from multiple views the context menu must be attach to each of these views. This was a problem for me because I had screen objects composed from over 20 views each, and assigning a context menu to each of those views was going to make my code both ugly and bug prone.
My solution was to create classes that automatically inherit their context menu from their parent. These classes are shown below.
I used a timer because
For views …
<class name="view_cm">
<handler name="oninit">
this.focusDelegate = new LzDelegate(this,
"cm_callback");
LzTimer.addTimer(this.focusDelegate, 100);
</handler>
<method name="cm_callback">
if (parent.isinited)
{
var cm = parent.getContextMenu();
if (cm != null)
{
this.setContextMenu(parent.getContextMenu());
return;
}
}
this.focusDelegate = new LzDelegate(this,
"cm_callback");
LzTimer.addTimer(this.focusDelegate, 100);
</method>
</class>
For text …
<class name="text_cm" extends="text">
<handler name="oninit">
this.focusDelegate = new LzDelegate(this,
"cm_callback");
LzTimer.addTimer(this.focusDelegate, 100);
</handler>
<method name="cm_callback">
if (parent.isinited)
{
var cm = parent.getContextMenu();
if (cm != null)
{
this.setContextMenu(parent.getContextMenu());
return;
}
}
this.focusDelegate = new LzDelegate(this,
"cm_callback");
LzTimer.addTimer(this.focusDelegate, 100);
</method>
</class>
The last class is used for views containing images. If you try and attach a context menu to a view with no background or movieclip, a warning is issued. I like my code warning free, so this class waits for the onload event before trying to set the context menu.
<class name="view_cm_load">
<handler name="onload">
this.focusDelegate = new LzDelegate(this,
"cm_callback");
LzTimer.addTimer(this.focusDelegate, 100);
</handler>
<method name="cm_callback">
if (parent.isinited &&
this.getAttribute('resource') != null)
{
var cm = parent.getContextMenu();
if (cm != null)
{
this.setContextMenu(parent.getContextMenu());
return;
}
}
this.focusDelegate = new LzDelegate(this,
"cm_callback");
LzTimer.addTimer(this.focusDelegate, 100);
</method>
</class>
Using these classes is as simple a changing view, class (extends) and text declarations as required e.g. from “<view … />” to “<view_cm … />”. The rest of the code is untouched.
The above classes are something I dreamed up to solve a particular problem I had. I would be interested in any improvements or alternative approaches.
thanks Phil. I was wondering how to add a context menu to a list of inputtext and have stumbled upon your example. It probably save me couple days to trials and errors
looks great, thanks Phil !