CKEditor (in a SPA) freezes when navigating back to the editor page - ckeditor

I'm trying to integrate CKEditor in a page of a SPA (Single Page Application).
CKEditor behaves correctly within the SPA page on the first visit, but not on next visits. For example, when pressing the backward browser arrow (to display the previous SPA page) and then the forward arrow (to display again the SPA page with CKEditor), CKEditor appears but the content has been erased and it's not reacting anymore. There is no carret when cliking on the text area. Also all API calls (such as setData() or resize()) have no effect anymore (whereas they were working on fist visit).
I presume CKEditor doesn't like its element to be removed from the DOM (that's what happens when switching to another page) and then be re-added to the DOM (that's what happens when visiting the page again).
EDIT ON July 5 2017
Thanks for your proposition to destroy CKEditor when leaving the page and to recreate it when navigating back, but this causes the lost of the editor state such as the the scrollbar position, the caret position, text selection, etc...
Ideally I would like to make it possible for a user to visit another page while he is in the middle of writing something in the editor (for example to check an information or copy a content from another page) and then to continue exactly where he was (no change on scrollbar, caret, selection,...) when he navigates back to the editor.
Is is possible?

Removing CKEditor just by removing its parent container like in your fiddle is not a good solution as CKEditor attaches some listeners to the DOM and by removing the container you are detaching those listeners which are not reattached then.
You should destroy the editor before removing from DOM and then recreate it. Remember that destroying happens in an async manner so to know when it is finished you may listen to destroy event.
Here is modified fiddle using destroy method (without handling destroy event which should be added).
EDIT ON July 10 2017
To preserve the state of the editor (scrollbar position, text selection, etc) between destroy - recreate, state of all this elements should be retained before destroying editor and then set after recreating it. It is doable, but requires some work and quite a lot of custom code.
Ideally I would like to make it possible for a user to visit another page while he is in the middle of writing something in the editor
Since you are creating a SPA application, for the above the better solution will be to use some floating/fixed container in which CKEditor is placed and which does not reload with rest of the page upon navigation (e.g. the same as Facebook chat works).
Also remember that recreating CKEditor takes some time (very short, but it may be still visible) so on every page navigation it will be visible for the user that something is happening with the editor even though its state does not changed.

Related

Force reload component in Nativescript

I want to re-create and animate the same view back when navigated to same page.
this.routerExtension.navigate(['/home']);
Currently if i am in home page and button is tapped in same page which fires the above code, the component is not reloaded. I want to forcefully reload and animate the same view into stack.
It is a bit of a hack, but I got around this by making two routes that refer to the same component, something like '/home' and '/home1', then alternating which one I used.
It would be nice if there was an option in routerExtension to do this.

How can I create a persistent extension page?

Is it possible to make the browserAction popup persistent so that it's not reloaded every time? Failing that, is it possible to have any viewable extension page that can be hidden instead of closed?
I have a complex layout involving a large number of elements that I'm currently saving and loading as a string or using importNode to work around the issue but neither option is great.
No, you can not cause an actual browserAction or pageAction popup to persist. However, just like any HTML page in your extension, you can open that HTML page in either a tab or window.
As to hiding an extension page: A tab does not need to be currently viewed. A window displaying the HTML page could be hidden by minimizing the window you desire to hide. Alternately, you could placed the window you desire to hide under another window by bringing the other window into focus. A third option would be to move the to-be-hidden window to coordinates that are off the screen. All of these are accomplished with windows.update().

Reusing the instance of CKEditor in the Jquery UI Dialog

First, I create an instance of CKEditor named 'richEditor' in a webPage.
Second, upon a button click I am making ajax call, which returns html data, and showing it in a jquery UI dialog.Then I am copying the HTML of 'richEditor' instance already present in the webpage and pasting it in a div in the dialog.
But the reused 'richEditor' instance does not work.Any button click in the editor is throwing javascript error and neither the textarea nor the source text area is editable.
Any help or thought is really appreciated.
You cannot basically copy the HTML of the editor and reuse it. First of all, DOM structure of the instance is strictly connected to the JS code driving the editor (and vice versa). It's much deeper than plain HTML. The second reason is that the editor you use is based on the iframe, which cannot be copied preserving its content.
In other words: You have to create another instance of the editor to run it somewhere else. Please refer to the official guide and API docs to know more about CKEDITOR.replace(), CKEDITOR.appendTo() and CKEDITOR.destroy().

Firefox back button vs iframes

In Firefox if the window.location of an iframe is changed, this gets populated to the history of the top level window.
If the user now clicks the browser back button, the contents of the iframe will change rather than the browser going back to the previous HTML page.
This is totally wrong for some architectures.
Is there any way with JavaScript to prevent Firefox (3.x) from doing this?
(Please stick to just this question, not why/when/how iframes versus other techniques should be used.)
Use .location.replace
I have the same issue and was researching possible ways around it when I read this. I don't know if you solved the problem, but I think I'm going to use the unload event in the IFrame'd window to notify the parent window when it's unloaded.
If the iframe is closed by a 'valid' method, a variable is set at the parent to say the iframe is expected to unload
If the parent reloads / changes the src of the iframe a variable is set to say the unload is expected
If an unexpected unload happens in the iframe I assume it was the back button and update the parent page accordingly (e.g. jump another step back in the parent's history, or do something else).
The only ugly case here is if the parent page is unloaded and the iframe also throws unload - depending on how quickly the parent page changes you might get a race condition where the parent's iframe unload handler is or isn't fired.

Differences in Internet Explorer and Firefox when dynamically loading content then going forward and back

I'm developing a web application where, due to slow database access, not all content in a page is loaded immediately but rather dynamically when the user clicks a button after optionally making a selection.
This works fine. However, after dynamically loading content, if I navigate to a different web page, then navigate back, in Internet Explorer the loaded content will have disappeared, i.e. the page will have reverted to the originally retrieved page. In Firefox (and Opera as well), however, the loaded content will still be there, i.e. the page will look like it did before I navigated away from it.
The Firefox behaviour is the desired behaviour in my case, as the user would routinely navigate to subpages and go back to the main page. My question is therefore, is there any way I can force Internet Explorer to exhibit this behaviour, or are there any possible workarounds to get the desired result?
Here is my workaround solution for IE. It utilizes the fact that, even if the DOM is reset when navigating away and back to a page, input field values are still remembered.
For every dynamically loaded element, I also have a hidden input field where I "cache" the loaded value. I then have a function transferFromCache() which copies the values from each hidden input field to the corresponding element. This function is run at page init - which, in IE's case, is at page load AND every time one navigates back to the page.
This technique could probably be used to store the values of javascript variables as well.
I don't think there's a method to get IE to emulate FF in this manner. The reason is to do with fairly fundamental aspects of the browsers. FF uses a mechanism for it's page history called 'Fast DOM caching' which (from my limited understanding) basically means that when it puts a page into the browser history then it will store the current DOM (so the current page state) in a serialised format, which means that when the page is reloaded from history the state is preserved and FF can do this much quicker as a lot of work is already done (parsing the HTML into a DOM, etc). In comparison, IE will simply store the HTML received initially as it's history file and will reload it when navigating history.
Here is an article about saving state in session variables, which may help

Resources