How do I initialize TinyMCE on a ajax loaded textarea in 4.x? - tinymce

I am upgrading to tinyMCE 4.x and I am attempting to initialize tinyMCE on a textarea loaded via AJAX. In 3.x I did something of the sort: TinyMCE - attach to divs loaded via AJAX calls but this does not seem to work in 4.x.

tinymce.remove();
tinymce.init();
This works well!

In TinyMCE 4.x mceRemoveControl and mceAddControl have been removed. You have to use mceRemoveEditor and mceAddEditor instead.
Got it from: [Resolved] mceRemoveControl and mceAddControl in tinymce 4
Otherwise, you can reload tinymce.init({ ... }) but that should not be the way as it would be slower.

You can load TinyMCE after including textarea with the following code:
//initialize tinyMCE in page
tinymce.init({selector:'textarea'});

just for then running into the same problem.
I solved the problem with wrapping the init Script into a function like this.
in my init.js file
initializeTinyMce();
function initializeTinyMce(selector){
if(selector == undefined){selector = 'textarea';}
...
tinymce.init({
selector: selector,
...
});
}
so on your ajax request result you add
<script type="text/javascript">
$(document).ready(function(){
initMCE('textarea#someId');
});
</script>
works fine for me

tinymce.init({ selector:'textarea' });
just use this in ajax and if you are not able to pick the value then Before submitting the form, call
tinyMCE.triggerSave();

Related

TinyMCE file_browser_callback not showing browse button

I am unable to get the TinyMCE file_browser_callback property to work, so that the Image dialog shows a browse button.
I downloaded TinyMCE 5.08 from tiny.cloud (prod version). I insert the library, then call init() below. I added a file_browser_callback property with a callback function, which is supposed to open a modal window, from where I pick up a file from a media library and insert it back.
For reasons I cannot understand I cannot make the browse button, in the image dialog, visible.
<script src="{{ asset('js/tinymce/tinymce.min.js') }}"></script>
<script>
$(function() {
tinymce.init({
height: 500,
selector: 'textarea.wysiwyg',
plugins: ['image'],
branding: false,
convert_urls: false,
file_browser_callback: function(field_name, url, type, win) {
$('#file-modal').modal({
duration: 200,
onApprove: function () {
if ($('#file-modal .file.selected').length) {
let $file = $('#file-modal .file.selected');
win.document.getElementById(field_name).value = $file.data('path');
}
}
}).modal('show');
}
});
});
</script>
The browse button should appear when the callback exists. I've tried implementing the callback as a separate function and passingit as a string with no luck. There are no error messages visible in the console.
I also tried 5.07 with no luck. I have this working on a separate application
The API you are using is a TinyMCE 4 API. Per the migration documentation, in TinyMCE 5 you need to use file_picker_callback instead:
https://www.tiny.cloud/docs/migration-from-4x/#file_browser_callbackfile_picker_callback
https://www.tiny.cloud/docs/configure/file-image-upload/#file_picker_callback
Well, it appears TinyMCE dropped the support for file_browser_callback from their 5.x versions. Propably because they offer file hosting cloud services themselves now and it might be a premium plugin. What a fantastic solution. I'll fall back to using 4.9.4 prod version.

TinyMCE: How do I prevent `<br data-mce-bogus="1">` text in editor?

I have a page with several TinyMCE (v4) editors, which all work great ... until I try and add:
inline: true
to their configuration. When I do that the inline-ing part works great (the toolbar is gone, then appears when I focus the editor), but for some strange reason the editor stops working at that point. Inside the editor I see:
<br data-mce-bogus="1">
but I can't edit that text, or add new text, or do anything at all really with the editor.
I can make the editor work again if I remove inline: true, but I really want the inline effect. Does anyone have any idea how I can get inline without breaking my editors?
Actually, the "bogus" br tags appear for inline divs, too. They are added whenever the input field is empty. There appears to be no easy way to get rid of them. I use a CSS rule during the preview phase:
br[data-mce-bogus="1"] {
display:none;
}
And then strip them out if they make it to the server when the user tries to save.
I recently had this problem, inline: true would not work with a textarea. I change mine to a div and it now works as expected.
Are you using the tinymce jQuery package? The same thing was happening to me until I tried using the normal tinymce package instead.
<script>
$(document).ready(function () {
$("#comment").ready(function () {
$("#comment").val("")
})
})
</script>
I add this jquery script in html to solve this bug.
Add this snippet to your CSS file. That would prevent video bogus.
[data-mce-bogus="all"] {
display:none;
}

Repositioning fancybox to center after loading new ajax content

I have implemented a fancybox which opens and loads ajax content without any problems. But when I load new ajax content into a div in the FancyBox using jquery I need to center the FancyBox on the screen again.
function refreshContent(url) {
$("#content").fadeOut("slow", function(){
$.fancybox.showLoading();
$("#content").load(url,false, function() {
$.fancybox.hideLoading()
$("#content").fadeIn("slow");
$.fancybox.reposition();
});
})
As you can see, I have tried with the reposition() method, but with no effect. The same applies to center()
What am I missing here?
I'm using Fancybox ver 2.0.5
Maybe is a little late but in fancy 2 there is a method:
$.fancybox.reposition();
You can see the other methods here:
http://fancyapps.com/fancybox/#docs
Regards
Probably need to put you reposition call inside the complete function of the fadeIn. Otherwise it gets called before the content is visible.

Sharethis button does not work on pages loaded via ajax

I am trying to use the sharethis button on a page which is loaded via ajax.
The buttons do not show up. Please help.
Regards,
Pankaj
After adding the new content to the dom, call
stButtons.locateElements();
// or if you want to be a bit defensive about whether the lib has been
// loaded or not:
if (window.stButtons){stButtons.locateElements();} // Parse ShareThis markup
Article another another
Updated 09/2017 Answer
The stButtons object doesn't exist anymore, now you can use
window.__sharethis__.initialize()
To reinitialize the buttons
Updated 03/2020 Answer
As found in The Ape's answer above: https://stackoverflow.com/a/45958039/1172189
window.__sharethis__.initialize()
This still works, however there is a catch if your URL changes on the AJAX request, you need to make sure the URL you want shared is set as a data attribute (data-url) on the inline sharing div. You can also update the title using data-title attribute.
<div class="sharethis-inline-share-buttons" data-url="http://sharethis.com" data-title="Sharing is great!"></div>
Use case:
I'm using a WordPress/PHP function to generate specific content based on a query string. If you don't set the data-url attribute on the ShareThis div, ShareThis will hold the first URL that was clicked to share, regardless of the URL update on AJAX request.
This solution will also work for NodeJS based frameworks, like Meteor.
stButtons.locateElements();
is needed in the rendered callback of a template, to ensure that the shareThis buttons will appear on a page redirect.
I was facing the same problem with sharethis and Ajax pagination.
The buttons was not showing after posts loaded by Ajax so I've searched and found this.
I've just added the function stButtons.locateElements(); on Ajax success:
something like success: stButtons.locateElements();
Hope this will be helpful for someone like me.
Thanks
Ibnul
For the new API following solution worked for me
if (__sharethis__ && __sharethis__.config) {
__sharethis__.init(__sharethis__.config);
}
Add this code after loading ajax content.
do this:
window.__sharethis__.load('inline-share-buttons', config);
and config your buttons with javascript.
The following should work with current ShareThis javascript. If sharethis js isn't loaded, the script loads it. If it is already loaded, ShareThis is re-initialized using the current URL so that it works on pages loaded via Ajax. Working fine for me when used with mounted method on Vue component.
const st = window.__sharethis__
if (!st) {
const script = document.createElement('script')
script.src =
'https://platform-api.sharethis.com/js/sharethis.js#property=<your_property_id>&product=sop'
document.body.appendChild(script)
} else if (typeof st.initialize === 'function') {
st.href = window.location.href
st.initialize()
}
Make sure you use your property id provided by ShareThis in the script src url.
In Drupal you can achieve this by adding following code:
(function($){
Drupal.behaviors.osShareThis = {
attach: function(context, settings) {
stLight.options({
publisher: settings.publisherId
});
// In case we're being attached after new content was placed via Ajax,
// force ShareThis to create the new buttons.
stButtons.locateElements();
}
};
});
I found the following solution on one of the addThis forums and it worked great for me.
I called the function as a callback to my ajax call. Hoep this helps
<script type="text/javascript">
function ReinitializeAddThis(){
if (window.addthis){
window.addthis.ost = 0;
window.addthis.ready();
}
}
...
$('#camps-slide .results').load(loc+suffix, function() {ReinitializeAddThis();});
</script>

tiny question about jquery's live()

How would I change the html of a tag like so:
$('#someId').html('<p>foo bar</p>');
while using the live() or delegate() function? Just for clarification I don't want this to happen on hover or focus or click... I just want jquery to immediately change the html inside of a certain tag.
Basically, I'm trying to change the logo in the Mojomotor's little dropdown panel and I don't want to change the logo every time I upgrade to a new version.
Any suggestions?
.live() and .delegate() don't work like this, what you're after is still done through the .livequery() plugin or simply in the document.ready if it's present on page load, like this:
$(function() {
$('#someId').html('<p>foo bar</p>');
});
Or with .livequery() if it's replaced dynamically in the page:
$('#someId').livequery(function() {
$(this).html('<p>foo bar</p>');
});
.live() and .delegate() work off of event bubbling...an element just appearing doesn't do this whereas a click or change, etc would.
Just do it when the DOM loads.
<script type="text/javascript">
$(document).ready(function() {
$('#someId').html('<p>foo bar</p>');
});
</script>