I have many tables, in different tabs, with an "Actions" link for each row. Clicking on "Actions" opens a dropdown, and this works like a dropdown should: clicking outside closes dropdown, clicking inside keeps dropdown open. So far so good, a simplified version is here https://jsfiddle.net/ivanhalen/nya69pd2/30/
The relevant JS part is this:
$('.show_actions').on('click', function(){
var el = $(this);
el.closest('tbody').find('.actions').hide();
el.closest('td').find('.actions').show();
});
$(document).on('mouseup', function(e){
var el = $(document).find('.actions').off('click');
if (!el.is(e.target) && el.has(e.target).length === 0) {
el.hide();
}
});
Now another actor comes into the scene
In other tabs I have some content-editable divs. Clicking on them call a CKEditor instance and opens a custom dropdown (I call "palette") with CKE stuff: buttons, fields, etc.
Well, here the same should happen: when clicking outside the "palette" it should close (and destroy CKEditor instance), clicking inside should keep open
The code I wrote does not work well, and I struggle to find a working solution: here's a fiddle: https://jsfiddle.net/ivanhalen/nya69pd2/32/
The relevant code is:
$('.show_actions').on('click', function(){
var el = $(this);
el.closest('tbody').find('.actions').hide();
el.closest('td').find('.actions').show();
$(document).find('.palette').hide();
});
$('.editor').on('click', function(){
var el = $(this);
$(document).find('.actions').hide();
el.closest('.editor_container').find('.palette').show();
// here call a function to instantiate CKeditor
});
$(document).on('mouseup', function(e){
var el = $(document).find('.actions, .palette').off('click');
if (!el.is(e.target) && el.has(e.target).length === 0) {
el.hide();
if (el.hasClass('palette')){
console.log('here destroy CKeditor instance too');
}
}
});
The 'here destroy CKeditor instance too' is always triggered, even clicking on content-editable-div where I should create intead
Please, any help?
It looks to me as if there's some subtle trap in your logic.
As you assign el like this:
var el = $(document).find('.actions, .palette').off('click');
then this if() check will be always true:
if (el.hasClass('palette')){
console.log('here destroy CKeditor instance too');
}
Also, can't figure out if your nested if()s inside the mouseup event will do the job correctly.
I tried to change a bit the mouseup event code and it seems to me - if I understood well your goal - that it does the work:
$(document).on("mouseup", function (e) {
var el = $(document).find(".actions, .palette").off("click");
// first if() check to close the dropdowns
if (!el.is(e.target) && el.has(e.target).length === 0) {
el.hide();
}
// separate if() check, to decide if destroy the instance
// check if my target is NOT the editor
if (!$(e.target).hasClass("editor")) {
console.log("here destroy CKeditor instance too");
}
});