I'm creting a jquery context menu, using https://swisnl.github.io/jQuery-contextMenu/ .
I've sucessfully done the creation part of the submenu.
I had to use build, in order to have some data that is only available on runtime.
This data appears on a submenu, and I need to have a title on each of those submenu items, as well as click funtion on each of them.
I cant seem to make it work, both the title and the function on those submenu items.
Here is my code:
$.contextMenu({
selector: '.gridRelatorioCursorMorada',
build: function ($triggerElement, e) {
var coords = $triggerElement[0].attributes['data-coord'].nodeValue;
var coordsArray = coords.split(',');
return {
callback: function (key) {
if (key === 'get') {
getdata();
}
},
items: {
get: {
name: "Get data"
},
see: {
name: "See data",
items: {
normal: { name: coords },
graus: { name: dd2dms(coordsArray[0], coordsArray[1]) },
siresp: { name: decimalToSIRESPCoordinates(coordsArray[0], coordsArray[1]) }
}
}
}
};
}
});
Since the events part of contextMenu doesnt work with build, I dont know what else to do.
I've also added the following code:
$(document).on('contextmenu', function () {
$('.context-menu-submenu > ul > li').attr('title', 'tituro');
});
But it also doesnt work.
My mistake.
Event does work on build.
This got me to get the title on each of the submenu items.
The click function I got it working with the callback function.
Related
I have Electron app and I am trying to hide or show label base on user input. The label aways show. I am trying to hide or show Tutorials
{
id: "tut",
label: "Tutorials",
submenu: [
{
id: "subTut",
label: "Tutorials",
click: async () => {
const { shell } = require("electron");
await shell.openExternal("https://example.app/tutorials");
},
},
],
},
In my main.js process I call the menu
When I call:
Menu.getApplicationMenu().getMenuItemById("tut").visible = false;
it does not hide anything, however it I call
Menu.getApplicationMenu().getMenuItemById("subTut").visible = false;
it will hide the sub menu item
Here is a solution for any that runs across this issue this can be done by using the function
Menu.setApplicationMenu()
Just pass object to the function where you call you menu to handle if item is visible or not
const MenuItems = (options) => {
// MENU
const template = [
{
label: "Window",
submenu: [
{
visible: options.option,
label: "Support",
click: async () => {
await shell.openExternal("https://example.com");
},
},
]
]
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
};
When you run the function for you menu just pass object in function for what's to show.
In Mac OS, you cannot hide top-level menu items, just submenu items:
Nota Bene: The enabled and visibility properties are not available for top-level menu items in the tray on macOS.
Source: docs
We use AngularJS to override the Browser Context Menu (https://github.com/Templarian/ui.bootstrap.contextMenu).
Here is the some example code
$scope.menuOptions = [
{
text: \'Cut\',
click: function () {
alert(\'Cut\');
}
},
{
text: \'Copy\',
click: function () {
alert(\'Copy\');
}
},
{
text: \'Pase\',
click: function () {
alert(\'Paste\');
}
}
' . $showDebugMenu . '
];
The showDebugMenu var gets a further function to show the source code of the website if the setting in the database is set to on.
My question: Is there a function to show the source code or to call the browser to show source code function?
I am trying to create toolbar button in TinyMCE with options that are derived from the array. I've followed the examples on Tiny's website and the button is getting generated as expected. Here is the code:
var mergeFields = {one: "first", two: "second", three: "third"};
tinymce.init({
selector: 'textarea',
menubar: false,
toolbar: 'mergefields',
setup: function (editor) {
editor.ui.registry.addMenuButton('mergefields', {
text: 'Merge Fields',
fetch: function (callback) {
var items = [];
for (var fieldName in mergeFields) {
var menuItem = {
type: 'menuitem',
text: mergeFields[fieldName],
onAction: function() {
// The problem: this function always inserts the last element of the array
// instead of the expected fieldName associated with this menuItem
editor.insertContent(fieldName);
},
};
items.push(menuItem);
}
callback(items);
},
});
}
});
<script src="https://cloud.tinymce.com/5/tinymce.min.js?apiKey=XXXXX"></script>
<textarea>Editor</textarea>
The problem happens when one of the options is selected and the anonymous function assigned to onAction property is executed -- it always inserts "three" into the document (presumably because after running through the whole array, fieldName is set to "three"). How can I make the onAction handler insert the right value into the document?
This needs to work in TinyMCE 5.
I've found a similar question here: Adding custom dropdown menu to tinyMCE and insert dynamic contents, but it was referring to TinyMCE 4 and unfortunately the provided answer does not work for TinyMCE 5.
Thanks for your help!
I had the same problem.
I solved it using value+onSetup
https://jsfiddle.net/stvakis/tjh7k20v/8/
var mergeFields = {
one: "first",
two: "second",
three: "third"
};
tinymce.init({
selector: 'textarea',
menubar: false,
toolbar: 'mergefields',
setup: function(editor) {
editor.ui.registry.addMenuButton('mergefields', {
text: 'Merge Fields',
fetch: function(callback) {
var items = [];
for (var fieldName in mergeFields) {
var menuItem = {
type: 'menuitem',
text: mergeFields[fieldName],
value:fieldName,
onSetup: function(buttonApi) {
var $this = this;
this.onAction = function() {
editor.insertContent($this.data.value);
};
},
};
items.push(menuItem);
}
callback(items);
},
});
}
});
I'm using the video.js 4.12 library and I want replace control bar items. For example, move one of my custom buttons to the 2nd slot of the control bar.
How do I change the order of items on the taskbar? I had no luck on Google.
Videojs place good class on elements. By this way you can identify control bar's elements.
To handle the item's order I used Jquery :
var createPrevButton = function() {
var props = {
className: 'vjs-control player-prev-button', //We use this class in Jquery
innerHTML: '<div class="vjs-control-content"></div>',
role: 'button',
'aria-live': 'polite',
tabIndex: 0
};
return videojs.Component.prototype.createEl(null, props);
};
var myPlayer = me.player = videojs(me.idVideo, {
plugins : { chapters : {} },
children: {
controlBar: {
children: [
{
name: 'playToggle'
},
{
name: 'currentTimeDisplay'
},
{
name: 'timeDivider'
},
{
name: 'durationDisplay'
}
/*
...........
*/
]
}
}
});
$(".player-prev-button").insertAfter(".vjs-play-control");
$(".player-next-button").insertAfter(".player-prev-button");
After the instanciation of my player just handle item by Jquery.
I think it's better than use CSS.
But the best way should be by videojs's option or somethink like that
I'm slowly trying to slug my way through learning OOJS by building an accordion toggle and I'm having a hard time.
EDIT: Slowly getting there. I've got the toggle functioning how I want to. Unfortunately I'm calling the add / remove class incorrectly(?).
I'm currently calling it like:
accordion.ELEMENTS.TRIGGER.click(function() {
if ($(this).parent().hasClass(accordion.CLASSES.OPEN)){
$(this).parent().removeClass('open')
}
else {
$(this).parent().addClass('open');
}
});
And I would rather call it via the EVENTS.OPEN & EVENTS.CLOSE or even throw both of this into the EVENTS.BIND and have BIND sort out whether or not if it is open or not :
Here's a JSFiddle, I'm trying to bind the EVENTS.OPEN and EVENTS.CLOSE instead of trying to find the parents.
var accordion = {
ELEMENTS: {
HOME: $('.js-accordion-toggle'),
TRIGGER: $('.js-accordion-trigger'),
PANEL: $('.js-accordion-panel')
},
CLASSES: {
OPEN: 'open'
},
EVENTS: {
OPEN: function() {
if (ELEMENTS.HOME.hasClass(accordion.CLASSES.OPEN)) {
console.log(this + "open");
ELEMENTS.HOME.addClass(accordion.CLASSES.OPEN);
}
else {
console.log("this should close");
this.close();
}
},
CLOSE: function() {
accordion.ELEMENTS.HOME.removeClass(accordion.CLASSES.OPEN);
},
//BIND: function() {
// accordion.ELEMENTS.HOME.each(function() {
// accordion.EVENTS.OPEN();
// });
//}
},
fn: {
attachEvents: function() {
accordion.ELEMENTS.TRIGGER.click(function() {
console.log(this);
if ($(this).parent().hasClass(accordion.CLASSES.OPEN)){
$(this).parent().removeClass('open')
}
else {
$(this).parent().addClass('open');
}
});
}
},
init: function() {
accordion.fn.attachEvents();
}
}
accordion.init();
I managed to get your original fiddle to work by invoking accordion.init() after your object definition. I also had to replace your line 37 with accordion.ELEMENTS.PANEL.addClass(accordion.CLASSES.OPEN); to get rid of some undefined object error.
As for your new codes, you can simplify your codes by removing the if..else statement in line 19 and 22 with jQuery.toggleClass, to make it looks like:
$(this).closest(toggleHome).toggleClass(toggleClass);