How to create inline menu buttons
In order to make some tasks for the user as intuitive as possible, it might be interesting to add buttons with certain functionality directly to the element they would perform an action on. Those inline buttons, placed directly within the document view, might look like this:
First of all, a display only (see frame only nodes for more details) needs to be created, which displays the menu when clicked. To do this, add the following in the file types_overrides.js
:
// in types_overrides.js dummy element erstellentypes.YOURELEMENT.finalizeForFrame = function(editor, element) {// replace YOURELEMENT with your elementvar div = editor.contentFrame.iframeDoc.createElement('div');div.setAttribute('data-frameonly', 'true');div.className = 'xe-custom-menu-1';element.insertBefore(div, element.dom.firstChild);};
Now a click-listener must be registered so that we can intercept the corresponding event. In order to do this, add the following snippet in the init.js
file:
editor.contentFrame.iframeDoc.onmousedown = Ext.bind(editor.configObj.configData.onMouseDownReplacement, editor);
Now the corresponding listener must be implemented. To do this, add the following lines to the listeners.js
file:
onMouseDownReplacement: function(e) {// check editor modeif (this.editorMode !== 'edit') {// no lookupreturn;}if (['xe-custom-menu-1'].indexOf(e.target.className) !== -1) {// prevent defaulte.preventDefault();// create and open menuthis.configObj.configData.openCustomMenu(this, e);return;}}
Now the actual logic that creates and displays the menu can be implemented. Insert the following sample code:
// build and show menuopenCustomMenu: function(editor, e) {// get matching nodevar node = editor.document.getNode(e.target.parentNode);// check if document node is an Elementif (!(node instanceof Ext.ux.xeditor.Element)) {return;}// get document nodevar documentNode = node.getDocumentNode();// create menuvar menu= editor.configObj.configData.buildContainerElementMenu(editor, documentNode);// get mouse positionvar iframeY = editor.contentFrame.iframeEl.dom.getBoundingClientRect().top;// show menumenu.showAt(e.clientX, e.clientY + iframeY);},buildContainerElementMenu: function(editor, element) {var elementType = element.getType();// sample item for removing elementvar removeItem = {iconCls: 'fa-trash',text: global_phrases['global.remove'],editorElement: element,listeners: {scope: editor,click: function(item, e, eOpts) {// select element before remove in order to have it selected if action is undoneeditor.selectionManager.selectElement(item.editorElement, true);// remove elementif (item.editorElement.removeDeep().selectionCorrected) {// update editor state and sync selectioneditor.updateState();editor.selectionManager.sync();// scroll to selectionvar scrollResult = editor.contentFrame.scrollToSelection('middle', true);if (scrollResult.selectionCorrected) {// update editor state and sync selectioneditor.updateState();editor.selectionManager.sync();}}}}};// store menu itemsvar menuItems = [removeItem];// create menuvar menu = Ext.create('Ext.menu.Menu', {items: menuItems,listeners: {show: function(menu, eOpts) {// add to active menuseditor.activeMenus.push(menu);},hide: function(menu, eOpts) {// remove from active menusExt.Array.remove(editor.activeMenus, menu);}}});return menu;},
Please note that the div element created in the first step with the class xe-custom-menu-1
still needs to be adapted using CSS so that it becomes visible (content, desired styling). This is done in the file editor.css
.