jquery ui - Is there any knockout plugin for showing a nested context menu? -
is there knockout plugin showing nested context menu?
my specific need show contextmenu list items, has "sendto" menuitem , possible subitems have set @ runtime.
in apparent lack of suitable plugins went more direct knockout approach. i'm sure code can more elegantly packed in custom binding solution came with, if need similar. in case menu build each time it's opened because makes sense in usecase. i'm sure code can customized other scenarios.
so... markup:
<li data-bind="event: { contextmenu: $root.showsendtomenu }/>
used show popup menu, item on right click. , markup menu itself:
@*the send popup menu*@ <ul class="context-menu" data-bind="visible:contextmenu.activeelement, style:{left:contextmenu.left, top:contextmenu.top}, template: { name: 'menu-item-template', foreach: contextmenu.items }, event: { mouseleave: contextmenu.contextmouseleave }"></ul> @*template menu item*@ <script type="text/html" id="menu-item-template"> <li> <!-- ko if: children --> <span data-bind="text:text"></span> <ul data-bind="template: { name: 'menu-item-template', foreach: children }"></ul> <!-- /ko --> <!-- ko if: !children --> <a href="#" data-bind="text:text, click:$root.oncontextclick"></a> <!-- /ko --> </li> </script>
and in viewmodel, have following code (typescript):
contextmenu = { activeelement: ko.observable(null), left: ko.observable('0px'), top: ko.observable('200px'), items: ko.observablearray(<menuitem[]>[]), contextmouseleave : () => { this.contextmenu.activeelement(null); } }; showsendtomenu = (item, event) => { //set menu position this.contextmenu.left(event.pagex + 'px'); this.contextmenu.top(event.pagey + 'px'); //build menu var lines = []; (var = 0; < this.prodlines().length; i++) { var line = this.prodlines()[i]; if (line.lists().length > 0) { var lists = []; (var j = 0; j < line.lists().length; j++) { var list = line.lists()[j]; lists.push(new menuitem(list.name(), null, list)); } lines.push(new menuitem(line.name + "->", lists, line)); } } var items = [new menuitem("sendto ->", lines)]; //set menu this.contextmenu.items(items); this.contextmenu.activeelement(item); } oncontextclick = (menuitem: menuitem) => { var sendtolist = menuitem.tag; var item = this.contextmenu.activeelement(); this.droptolist(item, sendtolist); //hide menu this.contextmenu.activeelement(null); }
and lastly, used piece of css make menu behave menu-like:
.context-menu { position: absolute; padding: 0; margin: 0; z-index: 1030; background-color: #dddddd; box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3); min-width:100px; border: 1px solid gray; text-decoration:none; } .context-menu ul { position: absolute; z-index: 1031; line-height: 1.6; padding: 0; margin: 0; box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3); display:none; left:98px; min-width:100px; top:-1px; background-color:#dddddd; border: 1px solid gray; text-decoration:none; } .context-menu li { position:relative; } .context-menu li:hover > ul { display:block; } .context-menu li { padding: 4px 20px; margin: 0; list-style-type: none; cursor: pointer; white-space: nowrap; color: #333333; } .context-menu ul > li:hover { background-color: white; text-decoration:underline; }
i hope someone
Comments
Post a Comment