Context Menu - configuration via XML initialization data - 3 questions

I run on 3 Questions while configuring Context Menu:

Q1. Tried to implement animation of Contexy menu. Failed. http://webix.com/snippet/0fed20b6
Enabled animation of menu with default settings, and sub-menu with:

<animate type="flip" subtype="horizontal"/>

Am I configuring it correctly?

Q2. Menu has property “autowidth”. http://docs.webix.com/api__link__ui.contextmenu_autowidth_config.html. Tried. Looks like it does not work for Context Menu: http://webix.com/snippet/82af380d

Same with some other props, like borderless

Q3. Menu and Sub-Menu code is executed when Sub-Menu Item is selected. The following XML code contains “click” handlers for Menu and Sub-Menu:
http://lab.softcreator.com/ContextMenuGenerator.ashx?ContextMenuID=6

Why Webix executes “click” handler of Menu and Sub-Menu when I click on Sub-Menu and it supposed to execute Sub-Menu handler only?
http://webix.com/snippet/58809cd2

(Q1) Currently animate will not have effect on popup elements, such as menu panels

(Q2) autowidth works for horizontal menu panels, autoheight for vertical menu panels only. We will update the documentation.

(Q3) It is by design. When creating complex menu, it allows to define a single handler, on top menu object, to handle all clicks in the menu. ( for webix - each submenu is a separate object, but when you are working with UI, in most case you expect that all menu panels will works as a single component )

You can use onItemClick event that is separate for each menu object.

(Q3) It is by design.

How can I handle events when feeding data and configuration via XML?
Tried this way (all 3: click, onItemClick and onMenuItemClick):

<data>
	<config width="250">
		<on>
			<onMenuItemClick>
				<![CDATA[ webix.message("Main Menu");]]>
			</onMenuItemClick>
		</on>
	</config>
	<item id="12" value="New User Page">
		<config width="250">
			<on>
				<onMenuItemClick>
					<![CDATA[ webix.message("Sub-Menu");]]>
				</onMenuItemClick>
			</on>
		</config>
		<submenu stack="1">
			<item id="1500" value="Accordion container"/>
			<item id="1600" value="Carousel container"/>
			<item id="3200" value="Tree"/>
			<item id="3300" value="Tree table"/>
		</submenu>
	</item>
</data>

Event fires when I open context menu, and does not fire when I select menu item.

Also, is there a way to pass id? The following code as event handler does not work:

function(id) {
	webix.message(this.getMenuItem(id).id);
}
  • you need to use onItemClick if you want to handle only items on the same level
  • function in xml need to be formatted a bit differently
<data>
    <config width="250">
        <on>
            <onItemClick>
                <![CDATA[ (function(){ webix.message("Main Menu"); }) ]]>
            </onItemClick>
        </on>
    </config>
    <item id="12" value="New User Page">
        <config width="250">
            <on>
                <onItemClick>
                    <![CDATA[ (function(id){ webix.message(id); }) ]]>
                </onItemClick>
            </on>
        </config>
        <submenu stack="1">
            <item id="1500" value="Accordion container"/>
            <item id="1600" value="Carousel container"/>
            <item id="3200" value="Tree"/>
            <item id="3300" value="Tree table"/>
        </submenu>
    </item>
</data>

onItemClick resolved the issue with multiple fires of code.

Also, proper formatting resolved the issut of early fire.

Thank you.

There is another issue that still remaining – only the 1st line of the event handler gets executed. In the example below when I click on sub-menu the only message I see is: “Sub-Menu1”:

<data>
	<config  width="250">
		<on>
			<onItemClick>
				<![CDATA[(function(id) { webix.message("Main Menu");})]]>
			</onItemClick>
		</on>
	</config>
	<item id="12" value="New User Page">
		<config  width="250" template="<span class=&apos;webix_icon fa-#icon#&apos;></span> #value#">
			<on>
				<onItemClick>
					<![CDATA[(function(id) {
	webix.message("Sub-Menu1");
	var context = this.getContext();
	webix.message("Sub-Menu2");
	var list = context.obj; //list item object
	webix.message("Sub-Menu3");
	var listId = context.id; //id of the clicked list item
	webix.message("Sub-Menu4");
	webix.message("List item: <i>" + listId + "</i> <br/> Context menu item: <i>" + this.getMenuItem(id).value + " (" + this.getMenuItem(id).id + ")</i>");})]]>
				</onItemClick>
			</on>
		</config>
		<submenu stack="1">
			<item id="1500" value="Accordion container"/>
			<item id="1600" value="Carousel container"/>
			<item id="3200" value="Tree"/>
			<item id="3300" value="Tree table"/>
		</submenu>
	</item>
</data>

Any idea why don’t I see Sub-Menu2,3,4 messages?

More details:

(function(id) {
	try {
		var context = this.getContext();
	}
	catch(err) {
		webix.message(err.name + " : " + err.message);
	}
...

Returns an exception: “TypeError: undefined is not a function”.

Looks like “this” is not visible inside of event handler.

Try to use

var context = this.getTopMenu().getContext();

Again, in case of single event handler on top menu object, your original code is correct. But as you are attaching handlers for separate sub menu you need to use getTopMenu to get the top menu object in hierarchy.

this.getTopMenu().getContext();

did the trick. Thank you.