Summernote has uneditable inputs in modals with dialogsInBody - jquery-ui-dialog

I have one instance of summnernote in jQuery UI dialog.
By default all summernote's modals look like this:
But when I remove <div class="modal-backdrop in"></div>, I can write into all inputs in these modals:
Well, I've found a solution with dialogsInBody:
$('someTarget').summernote({
dialogsInBody: true,
... //another options
});
But when I turn it on, all text inputs inside the summernote's modals are uneditable! I can interact with checkboxes and file inputs, even the cursor changes to "text", but I am not allowed to write anything into text inputs:
I've inspected, there aren't any blocks over them. And I can't find any extra styles to block inputs (e.g. like pointer-events).
What does exactly do option dialogsInBody? Why inputs aren't editable?

Ok, I've resolved this problem by myself.
There are details:
In summernote.js there are such usage of dialogsInBody:
var $container = options.dialogsInBody ? $(document.body) : $editor;
Therefore modal window appends itself to body (instead summernote editor) when we set {dialogsInBody:true}. Nothing else.
Jquery UI Dialog has a behavior that blocks all text inputs outside of itself (see this). So when summernote is opened inside ui-dialog all of its modals has uneditable inputs.
My solution is to exclude all inputs in summernote modals from list of disallowed items. it required to override a dialog method _allowInteraction:
//fix problem that block inputs in modal dialog outside main UI Dialog
if ($.ui.dialog.prototype._allowInteraction) {
var originalAllowInteraction = $.ui.dialog.prototype._allowInteraction;
$.ui.dialog.prototype._allowInteraction = function(e) {
var isInModal = $(e.target).closest('.modal-dialog').length > 0;
return isInModal || originalAllowInteraction(e);
};
}

Related

JQuery UI Sortable - Grab shift when zooming

I was trying to use JQuery UI Sortable plugin for multiple tables. The idea was to grab and drop elements in cells of a table, by connecting all <td> tags with this plugin.
It looks like this: https://jsfiddle.net/Lhm3z0bw/3/
By changing zoom with mouse wheel controls, we can actually grab the elements already placed in the table.
However, when the scale is changing, moving them makes a shift on the current grabbed element.
I tried adding some functions from the JQuery UI API for resetting positions for the element or updating the helper, but there's no good results on it.
$(".sortableCards").sortable({
connectWith: ".sortableCards",
containment: "window",
scroll: false,
placeholder: "sortable-placeholder",
items: ".card1",
forcePlaceholderSize: false,
sort: function(evt,ui) {
//////////
// Maybe some fix needed here ?
//////////
}
receive: function(event, ui) {
if ($(ui.sender).hasClass('cards')) {
if ($(this).find('.card1').length > 2) {
$(ui.sender).sortable('cancel');
} else {
ui.item.clone().appendTo($(ui.sender));
}
}
}
});
Here is another linked question with the same issue : How to get JqueryUI Sortable working with Zoom/Scale - mouse movements

Pulling a style from a TinyMCE selection

I'm trying to implement a TinyMCE button that will apply the style of the selection to the entire box. I'm having trouble, though, reading the style of the selection when the selection is buried in a span in a span in a paragraph. Let's consider 'color' for example. Below I have a box with some text and I've selected "here" in the paragraph and made it red.
The HTML for the paragraph is now:
The code behind my button to apply the style of the selection to the box is
var selected_color = $(ed.selection.getNode()).css('color');
console.log("color pulled is ", selected_color);
$(ed.bodyElement).css('color', selected_color);
It doesn't work because the color pulled is black, not red, so the third line just re-applies the black that's already there. (If I replace selected_color in the third line with 'blue' everything goes blue.) So the problem is pulling the color of the current selection.
Does anyone know how I can do this reliably, no matter how buried the selection is?
Thanks for any help.
I also noticed somewhat a strange behavior up and there, with selections of nested span's and div's, but honestly i'm not able to recognize if this is a bug of TinyMCE, a browser issue or a combination of both (most probably).
So, waiting for some more information from you (maybe also your plugin code) in the meanwhile i realized two proposal to achieve what you want: the first plugin behaves like the format painter in word, the second is simply applying the current detected foreground color to the whole paragraph.
As you move throug the editor with the keyboard or mouse, you will see the current detected foreground color highlighted and applied as background to the second plugin button.
Key point here are two functions to get the styles back from the cursor position:
function findStyle(el, attr) {
var styles, style, color;
try {
styles = $(el).attr('style');
if(typeof styles !== typeof undefined && styles !== false) {
styles.split(";").forEach(function(e) {
style = e.split(":");
if($.trim(style[0]) === attr) {
color = $(el).css(attr);
}
});
}
} catch (err) {}
return color;
}
function findForeColor(node) {
var $el = $(node), color;
while ($el.prop("tagName").toUpperCase() != "BODY") {
color = findStyle($el, "color");
if (color) break;
$el = $el.parent();
}
return color;
}
The try...catch block is needed to avoid some occasional errors when a selected text is restyled. If you look at the TinyMCE sorce code you will notice a plenty of timing events, this is a unavoidable and common practice when dealing with styles and css, even more with user interaction. There was a great job done by the authors of TinyMCE to make the editor cross-browser.
You can try out the first plugin in the Fiddle below. The second plugin is simpler as the first one. lastForeColor is determined in ed.on('NodeChange'), so the code in button click is very easy.
tinymce.PluginManager.add('example2', function(ed, url) {
// Add a button that opens a window
ed.addButton('example2', {
text: '',
icon: "apply-forecolor",
onclick: function() {
if(lastForeColor) {
var applyColor = lastForeColor;
ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);
ed.selection.collapse(false);
ed.fire('SelectionChange');
}
return false;
}
});
});
Moreover: i think there is a potential issue with your piece of code here:
$(ed.bodyElement).css('color', selected_color);
i guess the style should be applied in a different way, so in my example i'm using standard TinyMCE commands to apply the foreground color to all, as i wasn't able to exactly convert your screenshot to code. Please share your thoughts in a comment.
Fiddle with both plugins: https://jsfiddle.net/ufp0Lvow/
deblocker,
Amazing work! Thank you!
Your jsfiddle did the trick. I replaced the HTML with what was in my example and changed the selector in tinymce.init from a textarea to a div and it pulls the color out perfectly from my example. The modified jsfiddle is at https://jsfiddle.net/79r3vkyq/3/ . I'll be studying and learning from your code for a long time.
Regarding your question about
$(ed.bodyElement).css('color', selected_color);
the divs I attach tinymce to all have ids and the one the editor is currently attached to is reported in ed.bodyElement. I haven't had any trouble using this but I have no problem using your
ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);
Thanks again! Great job!

Trying to bind a class to a toggled div for CSS targeting

I have an accordion and unfortunately there is no active or current class assigned to the qafp-faq div which serves as a container for each item.
My main objective is to add icons indicating toggle state.
I added:
$( ".qafp-faq-anchor" ).click(function() {
$( this).find( ".fa-caret-right" ).toggleClass( "open", 1000 );
return false;
});
Which works great for allowing me to target the title if I open a div via the title, but not when the accordion behavior hides an open div when clicking another div.
You can see the problem here: http://jsfiddle.net/Qzwvr/2/
The solution I'm really after is how I can add a class to the qafp-faq div whenevr it is toggled.
I've definitely been learning a lot about jQuery and hope I can figure this out. Thank you.
The easiest way to do this would be to change it from toggleClass into a removeClass and addClass
$(".qafp-faq-anchor").click(function () {
// Remove open class if this is open
if($(this).find('.fa-caret-right').hasClass('open')) {
$(this).find('.fa-caret-right').removeClass('open');
}
else {
// Removes open class no matter where it is
$('.open').removeClass( "open", 1000 );
// Adds open class to clicked element
$(this).find(".fa-caret-right").addClass("open", 1000);
return false;
}
});
Updated jsFiddle
If you have multiple accordions you could make the selector for removing the open class more specific if you want multiple open at the same time

Adding css with jQuery based on class

Seeking a solution to my problem...
I partially found an answer from another thread on here, using this script
$(function () {
$(".myclass").hover(function ()
{}, function ()
{
$(".myclass>li").fadeTo(200, 1)
});
$(".myclass>li").hoverIntent(function ()
{
$(this).attr("id", "current");
$(this).siblings().fadeTo(200, .6);
$(this).fadeTo(300, 1)
}, function ()
{
$(".myclass>li").removeAttr("id");
$(this).fadeTo(200, 1)
})})
When an item in the list is hovered, the script fades all other items out. Original demo is here http://jsbin.com/usobe
This works OK on my site, though the list ( a grid of thumbnails) is part of a bigger slider script, which loads "previews" via ajax. When a list item is clicked a hidden section expands on the page, and the slider script assigns the list item a class "active".
When the hidden section is open I would like the activated thumbnail to remain at 1 opacity, while the rest are faded to .6, exactly as it is with the hover effect using the script above. What I am trying to achieve becomes obvious when you click a thumbnail to activate the ajax script. Is it possible to use the active class to make this happen i.e. if class is not active set to .6 opacity?
Thanks in advance
----EDIT
Thanks everyone for suggestions - I am not having much luck so far! Using the code above, would it be possible to modify it so that when a list item is clicked it holds the specified levels of opacity? That would do nicely, I think. Then I could use onclick I guess to fade all items back to full opacity when the hidden div is closed.
I'm trying to guess how your code work, for what I understand you should do something like this:
// this is the selector that gets the click on the thumbnail
$('li.item').click(function() {
// fade all the thumbnails to op 1.0
$('#li.item').css('opacity', '.6');
// let the active thumbnail to 1.0
$(this).css('opacity', 1);
//show your hidden div
});
Then, when you close the hidden div:
$('div#hiddenDiv').onClose(function()
// about to close
$(this).fadeTo('fast', 1);
});
You could use an on click targeting the zetaThumbs li elements, set the current target to 1 and its siblings to .6
$('.zetaThumbs li').click(function(){
$(this).css({'opacity':1}).siblings().css({'opacity':.6});
})

using Jquery Ui - setting width on a particular multiselect box

I am using Jquery UI like this:
$("#companyType").multiselect({
multiple: false,
header: "Type",
noneSelectedText: "Type",
selectedList: 1
});
$('.ui-multiselect').css('width', '100px');
What I'd like to do is set the .ui-multiselect for only the #companyType div. Something like this:
$('#companyType.ui-multiselect').css('width', '100px');
Is there a way to do this?
Thank you!
Try this code with minWidth option. It is the minimum width of the entire widget in pixels. Setting to “auto” will disable, and the default is: 225
$("#companyType").multiselect({
multiple: false,
header: "Type",
noneSelectedText: "Type",
selectedList: 1
minWidth:100
});
not sure what version you use, but v1.5 includes a new "classes" parameter that you can set for styling your multiselect element.
Have a look here on how to use it :
http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/
it says
Additional class(es) to apply to BOTH the button and menu for further
customization. Separate multiple classes
with a space. You’ll need to scope your CSS to differentiate between the button/menu:
Example
$("#companyType").multiselect({
classes : "myClass"
});
then in the css file use:
/* button */
.ui-multiselect.myClass {}
/* menu */
.ui-multiselect-menu.myClass {}
If you want to set that particular css rule for only elements with class .ui-multiselect contained in the div #companyType I think jquery ui has no influence in it.
Try this:
$('#companyType .ui-multiselect').css('width', '100px');
This will set width = 100px to all elements contained in #companyType that have a class 'ui-multiselect'
Another simple method for adding width to the multiselect list box is like these
It is easy than adding another class or inline styling
$('#companyType .ui-multiselect').width(200);
This will set a with of 200 px to the specified list box
For the reference, if you want to a percentage for the width (e.g 100%) apply it within resize event of the window.
$(window).resize(function () {
$('#companyType .ui-multiselect').css('width', '100%');
});
You can also assign it to another element's width dynamically:
$(window).resize(function () {
$('#companyType .ui-multiselect').css('width', $('#anotherElement').css('width'));
});

Resources