I am using TinyMCE 4 and trying to build a dynamic menu. In order to do this I am building an array of menu items which includes an onclick function. The menu displays, but the onclick function does not work because when building the array, the value I need to pass to the function is out of scope - I believe.
var MenuItems = [{"Id":"1","Name":"MenuItem 1"},{"Id":"2","Name":"MenuItem 2"}];
var Menu = [];
for (var i=0;i<MenuItems.length;i++)
{
Menu.push({
text: MenuItems[i].Name,
onclick: function(){
alert(MenuItems[i].Id);
}
});
}
In the onclick declaration, MenuItems[i].Id is not in scope - I believe.
How can I pass the values to the onclick function.
I am then passing the array to the TinyMCE plugin, but I don't believe this is a problem with TinyMCE, but posting this part in case there is a better way.
tinymce.PluginManager.add('myplugin', function(editor, url) {
editor.addButton('menu', {
text: 'MyMenu',
type: 'menubutton',
icon: false,
menu: Menu
});
});
MenuItems[] won't be available when the callback for myplugin would run.
This would also mean, that once, onclick of any menuItem is called, it would try accessing MenuItems[].
To fix this, once way could be to change the implementation like:
var MenuItems = [{"Id":"1","Name":"MenuItem 1"},{"Id":"2","Name":"MenuItem 2"}];
var Menu = [];
for (var i=0;i<MenuItems.length;i++)
{
const id = MenuItems[i].Id;
Menu.push({
text: MenuItems[i].Name,
onclick: function(){
alert(id);
}
});
}
Related
I have a jquery-ui button test-button that has a data attribute.
That button calls a custom widget customWidget that has a callback function fnSaveCallback.
$(".test-button").button({
icons: {
primary: 'icon-test icon-mixed icon-custom'
},
text: false
}).customWidget({
id: "custom-widget",
title: "My custom widget",
fnSaveCallback: function() {
// Need to get the data-test attribute from the "test-button"
}
});
I'm having problems trying to access the the test-button in order to get the value of the data-attribute from the callback function.
Any idea how can i do that? Thanks in advance!
I've found an easy way to handle this adding a class on the click event.
$(".test-button").button({
icons: {
primary: 'icon-test icon-mixed icon-custom'
},
text: false
}).click(function() {
// remove opener class from other test-buttons
$(.test-button.opener).removeClass("opener");
// add opener class to the clicked button
$(this).addClass("opener");
}.customWidget({
id: "custom-widget",
title: "My custom widget",
fnSaveCallback: function() {
// Get the data-test attribute from the "test-button"
$(".test-button.opener").data("test");
}
});
You need to have a reference of the element somewhere.
const test_button = document.getElementById('test-button');
and then in fvSaveCallback:
fnSaveCallback: function() {
// Need to get the data-test attribute from the "test-button"
console.log(test_button.dataset.test);
}
EDIT: After your edit, as far as I understand you are trying to apply that method to all .test-button buttons.
You should only need to get a list of nodes, and iterate through it :)
const test_buttons = document.getElementsByClassName('test-button')
;
for (let i = 0; i < test_buttons.length; i++)
{ const button = test_buttons[i]; //This is the button
// Do with 'button' whatever you want here.
console.log(button.dataset.some_data);
}
I'm trying to please JSLint's desire not to use this except in special cases. I have an original function, like this:
$.fn.extend({
my_original_function: function ([arguments]){
[arbitrary routine]
}
});
...called like this on an ID selector:
$('#my_id').my_original_function([arguments]);
In my original version of the function, I used this within it to return the selected DOM element on which the function is operating. However, JSLint doesn't like it, and so I'm trying to find a way to reference #my_id (in this example), which the function is being called on, within the function...without using this!
This seems like more of an academic exercise than anything, but I'm scratching my head on how I could retrieve the id within the function without using this. Any ideas?
* THE FUNCTION IN QUESTION *
It's a toggle function for switching text links when they are clicked. Here's the original version with this:
$.fn.extend({
toggleText: function(open, close) {
var isClicked = false;
var that = $(this);
$(this).click(function () {
if (isClicked) {
that.text(open);
isClicked = false;
} else {
that.text(close);
isClicked = true;
}
});
return $(this);
}
});
$('#id_one').toggleText("Toggle Text 1", "Toggle Text 2");
$('#id_two').toggleText("Hello", "Goodbye");
$.fn.extend({
toggleText: function(open, close, that) {...
$('#id_one').toggleText("Toggle Text 1", "Toggle Text 2", $('#id_one'));
I'm using jQuery dataTables to display a table. I need to be able to pass a row selection event on to my Aura component that handles the selection and performs some operations on the data from that row.
In the initialize() function:
initialize: function()
{
$("#mytable tbody").click(function(event)
{
$(mytable.fnSettings().aoData).each(function ()
{
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
});
mytable = $('#mytable').dataTable();
},
I set up the click handler for the row selection, but how do I get a reference to the enclosing component so I can sandbox.emit() function to issue messages? I can put a reference to the component into the Closure, but that essentially makes this component a singleton and I could never have two instances of the component on the page at the same time.
Is there a standard way, using jQuery selectors or some other method, that I can retrieve a reference to the enclosing component from inside the click() handler?
Edit: I should never try to write code until I have had 32oz of caffine. You can pass a reference to the current component via the click() method itself. Like so:
$("#mytable tbody").click(this, function(event)
{
$(mytable.fnSettings().aoData).each(function ()
{
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
event.data.sandbox.emit('mychannel', {data: 'stuff'});
});
If I understand your question correctly, you could try something like this
initialize: function () {
var that = this;
$("#mytable tbody").click(function(event) {
//have acces to component as 'that'
});
}
what I used for events is view inside component configuration:
View: {
events: {
'click a[data-question-edit-id]': function (e) {
var button = $(e.currentTarget),
id = button.attr('data-question-edit-id'),
examId = this.component.examModel.get('id');
this.sandbox.router.navigate('/exams/' + examId + '/questions/' + id + '/edit', {trigger: true});
},
'click a[data-question-delete-id]': function (e) {
var button = $(e.currentTarget),
id = button.attr('data-question-delete-id');
this.component.showDeleteConfirmation(id);
}
}
}
If you'll find be helpful, here is my repo of aura project I'm working on:
https://github.com/lyubomyr-rudko/aura-test-project
I am creating a link that changes text when it is clicked. I want the link text to change back to the original text after all the processing is complete. It was working fine, but the code was spread all over my js file, so I am trying to abstract it into a function. This is the function, textToggle. In the textToggle function we are publishing an event. This event is the one that I cannot get to fire off at the right time.
var textToggle = function(data) {
var original_text = $(data.element).text();
var id = data.id;
var $element = $(data.element);
$element.text(data.replacement_text);
$('body').on(data.event, function(e) {
e.preventDefault();
$this.text(original_text);
});
};
Here is the function that sets up the textToggle. At the end of the function, we are triggering another event `clinical.status'.
$('#clinicalPatients').on('click', '[data-role="auth-process"]', function(e) {
e.preventDefault();
var $this = $(this);
var _id = $target.attr('id');
textToggle({
id: _id,
element: $this,
replacement_text: "Processing...",
event: "clinical.status.finished"
});
$('#clinicalPatients').trigger('clinical.status', [{
id: _id,
target: $target,
action: _type
}]);
});
At the end of clinical.status is when I want to fire the event in toggleText, clinical.status.finished. This is the code for that event.
$('body').trigger('clinical.status.finished', [{
id: originalId
}]);
clinical.status.finished is not getting triggered at the right time. There is no other place in the code that is using this, so it has to be the way that I am setting it up. If I leaved that event out of the toggleText function, and drop it in the function where I set up the toggleText function, then everything works like it is supposed to. By putting on event into a separate function, will this cause issues. Please, any help will be appreciated. Thanks.
I'm trying to bind a function to the anchor onclick attribute. I'm not using the traditional jQuery's bind/live/on/whatever because I have some other scripts stopping the events propagation (it sucks, I know).
To bind the function to the onclick attribute I'm passing a JSON object to a module like this:
function foo() {
alert('foo')
}
$('document').ready(function() {
var options = {
opt1: 'fooID',
opt2: 'barID',
json: mightyJSON,
actions: [
{ url: 'contact/_id_/edit', text: "Edit", iconPath: 'edit.png' },
{ url: '#', onClick: foo, text: "Delete", iconPath: 'delete.png' }
]
};
var trolol = myModule.configure(options);
});
As you can see the function named "foo" is passed via the onClick property of the JSON. The function is defined above the object.
In myModule I'm creating the anchor tag like this:
var buildLinks = function(objectID)
{
var linksNbr = actions.length;
var link, cssClass;
for (var i = 0; i < linksNbr; i++)
{
// Adding the object ID to the URL
link = actions[i].url.replace('_id_', objectID);
cssClass = actions[i].cssClass || '';
var $link = $(document.createElement('a')).attr('onClick', actions[i].onClick)
.attr('href', link)
.attr('title', actions[i].text)
.addClass(cssClass)
.text('foo');
}
return $link.html();
};
The thing is, as you can expect 'foo' is executed when the script is parsed and only there. The onclick doesn't even work after.
I can pass it like this onClick: 'foo()'. The onclick works but it's also executed at parsing and it's, in my opinion, very ugly.
I'd like to still be able to pass it like this onClick: foo but working correctly (i.e. not being executed at loading but only when clicking.
It has to work with jQuery 1.4.4 unfortunately.
I would do it like this:
var $link = $('<a></a>',{
href : link,
title : actions[i].text,
'class' : cssClass,
text : 'foo',
click : actions[i].onclick
})
return $link;
Then use one of these (1,2) functions to insert the node, which is the html with events.
for the propagation issue i would do something like this:
html <a href="#no" ....>text</a>
js $('a[href="#no"]').live('click',function(){ return false; });
This way whenever the href is pointing to #no the event is eventually propagated
if at all possible, return the element, and not its .html()
having done that, don't use .attr('onclick', ...) when you've already got a function reference, use .prop, or even just element.onclick = ...
e.g.
$link = $('<a>', {
href: link,
title: actions[i].text,
'class': cssClass,
text: 'foo'
}).prop('onclick', actions[i].onClick);
Here is a fiddle snippet. If this approach is fine, you could as below set onclick on jquery's raw element, like this:
$link[0].onclick = options.actions[i].onClick;