tinyMCE as drop target for ng2-dnd - javascript

I'm using tinyMCE in my angular2 app according to the guideline given here: https://www.tinymce.com/docs/integrations/angular2/
Now I would like as a drop target for ng2-dnd like this:
<textarea dnd-droppable (onDropSuccess)="itemDropped($event)" id="{{elementId}}"></textarea>
However, no event is fired. I suppose this has something to do with tinyMCE replacing the textarea with an iframe, but I'm not yet familiar enough with angular2 to understand how the following link could be applied here.
How to make tinymce textarea editor droppable?
Thanks in advance for any suggestions!

There are some issues that makes this not work.
Firstly, as mentioned, TinyMCE has its own elements including an iframe for rendering the actual editor. The iframe causes events in the editor not to bubble upwards.
Adding dnd-droppable to the texarea, which ends up being hidden, does not give any visible element to drop on.
Adding a div element around the textarea will give you a droppable area in the TinyMCE header, but unfortunately not in the editor. (due to the iframe).
However, using the TinyMCE built-in events, you can still use the editor as a drop-target. You also need to add the 'paste_data_images' attribute.
tinymce.init({
selector: '#' + this.elementId,
plugins: ['link', 'paste', 'table'],
skin_url: 'assets/skins/lightgray',
paste_data_images: true,
setup: editor => {
editor.on('drop', e => {
console.log(e);
});
}
});
Note that the drop event you receive is a standard drop-event which is not processed with dnd. I assume this is fine for your case, and if not you can turn to dnd documentation to process it further.

Related

Generate Bootstrap tooltip on-the-fly

I have a page with a text and some words in the text can change dynamically. These words have an element and should have a tooltip. When the user hovers the word (or I guess on a touch device clicks it), a tooltip should be generated using generateSpecialMarkupElement($(element).text()). Once the HTML has been rendered to the DOM another JavaScript function has to be called replaceMarkupHTML().
I don't have control over these functions unfortunately.
Now I'm wondering if there is a simple way in bootstrap get this done. For instance a before event to run the first function and an after event to call the second one.
Here is a simple example text and simplified versions of the functions:
http://jsfiddle.net/8aqz5auk/1/
So is there a bootstrap-way of hooking/intercepting this kind of thing? Or is there maybe another simple way it could be done?
Edit: I just had an idea. When bootstrap shows a tooltip, it seems to inject an element into the DOM. The interesting part is the container with the class 'tooltip-inner'. So I tried to listen on the body for new elements matching '.tooltip-inner' to be injected and whenever that happens I try to manipulate it:
$('body').on('DOMNodeInserted', '.tooltip-inner', function () {
var el = $(this)
el.html("") // empty the tooltip element
el.append(generateSpecialMarkupElement(el.text())) // insert the generated markup element
replaceMarkupHTML() // replace the markup element with normal html
});
Unfortunately it doesn't work. It just throws a a million errors and the site freezes when I try it.
Edit 2:
Thanks to Chris Barr, I got a little bit closer: http://jsfiddle.net/8aqz5auk/2/
But the tooltip doesn't always show up and the position of the tooltip seems to be kind of wrong (shows up on top of the word, rather then next to/above/below/...).
You might want to look into the tooltip events listed in the docs: https://getbootstrap.com/docs/3.3/javascript/#tooltips-events
$('.elements-with-tooltips').on('show.bs.tooltip', function () {
// do something…
})
You can run a function: before being shown, after being shown, before hiding, after hiding, and when the element is inserted into the DOM.

How can I get HTML5 drag and drop events to work with an iFrame?

I'm using CKEditor, and what I want to do is allow the user to drag an LI element into the editor and use the CKEditor API to then insert the drag data into the text.
The problem I'm having is that CKEditor is using an iFrame inside the WYSIWYG, and this doesn't seem to have "ondrop" or "ondragover" events. Is there some way that I can work around this? I don't need to actually be able to pass data directly into the iFrame. On the drop event, I'd do something like this:
var data = ev.originalEvent.dataTransfer.getData('id');
CKEDITOR.instances.story_body.insertText("[asset-id:" + data + "]");
See this fiddle I created for you:
http://jsfiddle.net/ojt16v8L/
my surrounding div is handling the dragenter, you can obviously do it for drop and any other event.
cont.addEventListener("dragenter",handleDragEnter,false);
BR,
Saar

get css class of html text in CKEditor

I have a CKeditor that loads text which includes html text as well. The html text has a css class assigned to certain span text areas. When the user does a mouse-over or mouse-click on text surrounded by a span with a particular class in the CKEditor textbox, I want to fire the mouse-over event or click event.
Here is the text that I programmatically load into the CKEditor
var editorHtml = '<span class="noedit">no edit text</span> edit this';
and I am trying to catch the events via this code.
$(document).ready(function () {
$('.noedit').mouseover(function () {
alert('hello');
});
});
It doesn't seem to be working. What am I doing wrong? Is this even possible to do?
Try to use event delegation here since your span is probably added dynamically by CKEditor here:
$(document).ready(function () {
$(document).on('mouseover','.noedit', function() {
alert('hello');
});
});
What is the this question really about? Your question reads: "get css class of html text in CKEditor". But I guess you want the class="noedit" element not editable. Maybe block it with a popup saying: "No editing allowed?"
The best way to add non editiable content is with widgets. This post explains what widgets are. If you follow the tutorial, you will be able to create a template for a simple box with two editable fields. You want NOT editable? It's in tutorial part one:
Please note that only elements defined in CKEDITOR.dtd.$editable can
be converted into editable widget elements.
By not specifying editable your widget will not be editable.
I do not know exactly what you try to achieve. But it seems that <span class="noedit">no edit text</span> should be a widget. You can still insert your widget with var editorHtml but you could also use a button.
I hope my answer is useful! Enjoy.

jQuery Mobile "enhance" dynamically re-generated html

jQuery Mobile 1.2.0
I generate the HTML using JavaScript ($(selector).html(content)), add it to the DOM and then display it ($.mobile.changePage()).
Then I invoke an AJAX call, get some data, and re-generate the html (but the parent element, the same $(selector), stays the same, I just change its html(...)).
At this poing the HTML is not "enhanced" by jQM, no styling applied on it.
Now according to the docs I should simply call the page() function on the parent element, i.e $(selector).page().
Other places in the docs suggest triggering the create event, i.e $(selector).trigger("create").
The problem is that non of the above two methods works - the styling of jQM is not applied.
Looking at the code of jQM, I've tried triggering the pagecreate event on that element and it does work, but, this is not documented anywhere, so I'm uncertain of it, especially concerning future releases of jQM.
At some poing in the docs I've read that I can call page() on a page only once..
Anyway, is there any concise/standard way to tell jQM to "enhance" the whole element and its child-elements? Or should I simply stay with triggering the pagecreate event?
Thank you!
To recreate a whole page use this:
$(selector).trigger("pagecreate");
This was my answer to a simmilar question: https://stackoverflow.com/a/14011070/1848600. There's an example of page recreation. Take a look, this should probably solve your problem.
What is the scope of
$(selector).trigger("create");
You should be able to add any elements on the 'pagecreate' event which comes right before 'pageshow' jqm styling is applied to elements. For example I dynamically add a header/footer like this
$(document).on('pagecreate', "[data-role=page]", function() {
var header = "<div data-role='header'>some header stuff</div>";
var footer= "<div data-role='footer'>some footer stuff</div>";
$(this).prepend(header);
$(this).append(footer);
$("[data-role=header]").fixedtoolbar({tapToggle: false});
$("[data-role=footer]").fixedtoolbar({tapToggle: false});
});
Make sure you're using jquery 1.7 or above I think that's when the on method was introduced;
It sounds like you may be generating the DOM and then changing the page, try it the other way around go to the page first then dynamically edit the dom.
EDIT
set the reload page option to true
$.mobile.changePage($(page), {reloadPage: true});
Edit 2
$(selector).children().each(function(){
$(this).trigger('create');
})

handling events with jWYSIWYG online editor

I'm trying to enable a button when the text in the jWYSIWYG textarea is changed. As far as i know, the jWYSIWYG when invoked, removes the textarea and places an iframe in its place, so $("#my-textarea-id") selector wont return any object. These are the attempts i made, all of them failed:
ATTEMPT 1:
as shown here this code should work, but it does not :(
$("#my-textarea-id").wysiwyg({
event:{
keyup: function(e){
$("#my-button").attr("disabled",false);
}
}
});
ATTEMPT 2:
in following attempts i'm initalizating the jWYSIWYG textareas from a diferent script that applies the .wysiwyg(...) function to all .RTF elements in the page (my textarea has this class).
The new frame that jWYSIWYG places has [old_textarea_id]-wysiwyg-iframe as ID, so i tried this:
$("#my-textarea-id-wysiwyg-iframe").keyup(function(){
$("#my-button").attr('disabled',false);
});
but failed again.
ATTEMPT 3:
The iframe part containing the text of the textarea has the .wysiwyg class. My last attempt was this:
$(".wysiwyg").keyup(function(){
$("#my-button").attr('disabled',false);
});
I have no idea how to handle the events over the jWYSIWYG elements so i ask for your help. Thank you!
this solved my problem
Adding event handler to an iframe using JQuery
jWYSIWYG replaces the textarea for an iframe. The below question's answer tells the appropiate way to bind events to the iframes and this way one can handle events of the RTF online editor.
i think the question can be useful for people so i'll not delete it for now.

Categories

Resources