Dynamic editor upload into web page. Need advice - javascript

I am writing intranet site for tracking employees science activities in organization.
There lots of editable information on each personal page (science degree, publications & so on) so I upload editor per request (user clicks "edit" and modal dialog with html editor: set of textboxes/comboboxes/autocomplete features & validation logic appears).
Editor is html layout that is wrapped with jquery dialog plugin + some logic, written as javascript functions that should be invoked from the callee page (onsubmit, validate, afterLoad editor events). There are also attributes (editor preferrable with and height) that are passed to callee page also.
Currently I send these functions & attribute as ... function onsubmit() { }; function validate() { } var width = 640; var height = 800 ... code that is embedded into the request page. Function calls and editor markup wrap with jquery plugin completed in the callee page.
It works, but I have some try { call editor event handler } catch { } stuff in callee page (because not every editor provides these functions) and some attributes (editor width & height for instance) that are loaded as variables declared in javascript.
Please, suggest, is there a better approach to build & use custom editors for my situation.
Thank you in advance!

First off, maybe you can use CKEditor. This editor has a jQuery adapter so that you can instantiate the editor very easy:
$('#editor1').ckeditor({
language : 'en',
toolbar : 'Basic',
width : 640,
height : 800
});
You pass all needed informations at the edit page loading to the callee page and load the editor afterwards:
User click edit link -> Ajax request to get the necessary edit infos -> Editor rendering
Perhaps you can write different editor renderers, one for each use case.

Related

Is it possible to return content from a custom window in TinyMCE 4?

Like many others, due to the limitations of TinyMCE's Image Plugin, I've decided to take the route of creating one that ties into my site's own uploading system.
I've gotten this partially working and pulling up a individual page, designed just for the purpose. However, now I want to return content from selecting images on this page. Is that possible or am I hitting a dead end?
tinymce.PluginManager.add('imageLoader', function(editor, url) {
// Adds a menu item to the tools menu
editor.addButton('imageLoader', {
icon: 'mce-ico mce-i-link',
image: 'Photos.png',
onclick: function() {
// Open window
editor.windowManager.open({
title: 'Image Loader',
url: 'load_images',
width: 500,
height: 400,
onsubmit: function(e) {
// Insert content when the window form is submitted
editor.insertContent('Image To Insert');
}
});
}
});
return {
getMetadata: function () {
return {
name: "Image Loader"
};
}
};
});
We made this a lot easier in TinyMCE 5 with a new URL dialog api:
https://www.tiny.cloud/docs/ui-components/urldialog/
In version 4, I believe the usual technique was to (inside the iframe) access the TinyMCE instance that opened the dialog via window.parent.tinymce.activeEditor, and then replicate the onsubmit function there. With the editor instance you can insert whatever content you need to and then editor.windowManager.close() will close the topmost window (i.e. the url dialog).
For more advanced use cases, editor.windowManager.getParams() can be used to pass information between the plugin and dialog, although perhaps not from the dialog to the plugin. editor.plugins is another possible technique, it's a name/value object of active plugin instances (it's a live reference to the return value from the PluginManager.add init function which can be mutated at runtime).
These are all fairly complicated, but likely more reliable than searching for the dialog iframe from your plugin.
I found an answer, although this is likely not the most elegant solution.
The image that I'm selecting is passed into a hidden text input in my custom page. From there, on Submit or Closing the TinyMCE 4 Frame, I use this snippet:
let getVal = $('[role="application"]').find('iframe')[1].contentWindow.document.getElementById("imgHolder").value;
In order:
It first finds the iFrame. Since both external pages and the editor itself use iFrames, this will generally be the 'second' iFrame - unfortunately, it isn't given an ID.
"contentWindow.document.getElementByID" fetches the hidden input, in my case named "imgHolder"
From here, you can get your content as normal with .value, and insert it into the TinyMCE Editor.
I hope this helps point others in the right direction, especially knowing that it gets asked a lot for TinyMCE 4. Further I hope this can be made a bit more elegent as well.

Disable full screen or modal for StackEdit

Our goal:
We need the StackEdit editor to render exactly at the same place where the textbox is (the way TinyMCE and other editors do) instead of rendering it in modal/fullscreen/covering the entire UI on the HTML page.
We are trying to implement https://stackedit.io/ mark down editor in our application. In order to do that we have set a local instance of https://github.com/benweet/stackedit at following local url say https://localhost:4433.
This would act as a local endpoint http://localhost:8080/app to serve the stackedit editor the way https://stackedit.io/app is having. We set up a local instance so that for editor rendering the remote endpoint of StackEdit domain itself should not hit.
In order to use that endpoint and use stackedit editor on a html page we are using https://benweet.github.io/stackedit.js/ and written the following code to render the editor:
var el = document.querySelector('textarea');
var stackedit = new Stackedit({
url: 'https://localhost:4433/app'
});
// Open the iframe
stackedit.openFile({
name: 'Filename', // with an optional filename
content: {
text: el.value // and the Markdown content.
}
});
// Listen to StackEdit events and apply the changes to the textarea.
stackedit.on('fileChange', (file) => {
el.value = file.content.text;
});
We have taken that code from https://benweet.github.io/stackedit.js/
The issue with the above implementation is that the editor is rendered as a modal and hide all the UI which is on the html page. Here is how it is rendered:
That is not what we need. In our application there will be multiple editors on a single page and having that editor as full screen or in modal will not serve. Our expectation with the editor is to make StackEditor render like popular TinyMCE edito i.e it should be rendered exactly at the same position where the textbox is.
TinyMCE editor:
This is how StackExchange editor comes:
So coming back to my original question, is it even possible with StackEdit to implement the editor in place where the textbox is instead of modal or full screen?
EDIT:
I went to following links with similar request and got no success there also:
https://github.com/benweet/stackedit.js/issues/10
https://github.com/benweet/stackedit.js/issues/14
https://github.com/benweet/stackedit.js/issues/26

How to track activity inside iframe of Wordpress tinyMCE editor

Im looking for solution that can track user activity inside wp_editor, i mean, i want to know if he is idle or not and then save content as concept (autosaving)
I was trying to use this https://css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/ and it's working mostly for all elements on website but i can't use it inside wp_editor because it's iframe.
and i tried also this library:
https://github.com/kidh0/jquery.idle
$('body').idle({
onIdle: function(){
$("#workingState").html('<?=displayInLanguage("<p>Stav: <strong>neaktívny, obsah uložený.</strong></p>", "<p>Status: <strong>inactive, content saved.</strong></p>")?>');
if( $('#show_add_actuality').hasClass('d-block') ){
saveForm('actualityForm_sk', "autoSaveScript");
saveForm('actualityForm_en', "autoSaveScript");
}
},
onActive: function(){
$("#workingState").html('<?=displayInLanguage("<p>Stav: <strong>aktívny</strong></p>", "<p>Status: <strong>active</strong></p>")?>');
},
idle: 2000
});
so as you can see im trying to save form in slovak and english language when user is not active, i will perform ajax request on both forms which includes also wp_editor, but i can't just track activity inside another page (which wp_editor generate another iframe site inside, its blank but still it's not working that way)
So i'm expecting some solution that can help me track user activity inside wordpress editor.
Script is working as expected, the only activity that i can't track is wordpress editor, no typing, no cursor movements nothing it will ignore idle state.
Thanks for any answer.

How to add a custom button with custom functionality in course Activity/Resource

Using Moodle 3.1 and being fairly new to Moodle development, I would like to know how to add a custom button or link inside each Activity/Resource within a course that would do the same job as mark complete checkbox on course view page but from within the individual activity (or resource) page.
Ofcourse, would like to do this in the ideal modular Moodle manner so that even after upgrade, the functionality isn't wiped off.
Is there a setting or configuration that can be done to achieve this OR do I need to write a full fledged plugin ?
If via a plugin, then any steps in that direction would be helpful.
Using the Additional HTML box in the Appearance section of Site Administration, you can add JavaScript that will manipulate the DOM.
It's a bit of a tall order to target all activities and resources, and no other Moodle functionality, but the approach that I used was to find an ID that is unique to that page, and use JavaScript to insert the button and functionality that you want.
For example, let's say that you want to add a new button on the News Forum activity.
There's a div in News Forum with class 'forumaddnew', so I will use that as a place to insert my new button.
var YourCustomButton = '<input type="button" id="mybutton" value="New Function Button" class="custom"/>';
/* make sure script only runs if div exists */
if (!document.getElementsByClassName('forumaddnew')[0]) {
/* do nothing */
} else {
var forum = document.getElementsByClassName('forumaddnew')[0];
forum.insertAdjacentHTML('beforebegin', YourCustomButton);
}
/* EVENT LISTENER FOR CUSTOM BUTTON */
if (!document.getElementById('mybutton')) {
/* do nothing */
} else {
document.getElementById("mybutton").addEventListener('click', function () {
alert('custom button clicked');
//stuff you want your custom button to do
});
}
I have been around Moodle a bit, and I am pretty certain this is not possible. Each resource and activity is stored in the /mod directory on your server. Each of these have their own view.php file. When the activity completes, and entry is written to the prefix_course_modules_completion table
Why not enable self completion by the user.

Lightbox that can open automatically depending on url path

There are a million lightbox type modal overlay scripts out there.. but I am looking for one that has the ability to be automatically triggered, depending on the path that leads there. So a property would have to live in the url string that triggered it. Has anyone seen or implemented any such thing? I know colorbox has the ability to automatically open the modal when you land on the page, but I do not know how I could make that functionality dependant on the path that one arrives there. Any ideas?
You could implement some JavaScript that looks at the referring page and opens the light box accordingly, therefore you shouldn't be limited to a particular implementation. You can tie in to the document ready event to open it.
There is an example of how to access the referrer on the W3Schools website linked below.
http://www.w3schools.com/jsref/prop_doc_referrer.asp
You can do this with Colorbox by varying the settings in your initialisation.
Assuming that you do this to start Colorbox:
$('div.gallery a').colorbox({
onClosed: function() { alert('Colorbox closed');},
current: 'Image {current} of {total}'
});
You could do something like this instead:
var colorBoxSettings = {
onClosed: function() { alert('Colorbox closed');},
current: 'Image {current} of {total}',
open: false
};
if (your_logic) {
colorBoxSettings.open = true;
}
$('div.gallery a').colorbox(colorBoxSettings);
I suggest that there is no need for auto triggering. You can do it this way -
First check the whether the url consists of the appropriate value you want or not.
It can be done by server side language (like PHP ) or through javascript.
If done server side pass say a hidden field as below -
<input type="hidden" name="exists" value="true" />
If done using jquery save value as -
var value = "value from javascript if proper url exists";
If done through server side then -
var value = $('input[name="exists"]').val();
Then you can trigger manual cilck (if url value is as per your expectation) to anchor which consists of overlay link -
$('#id of anchor').trigger('click');
If you want auto triggering overlay though then you can try this -
http://flowplayer.org/tools/demos/overlay/trigger.html

Categories