CKEditor smooth setData - javascript

I am currently using CKEditor to be able to edit and to view documents in my SQL database. If I change the content of the document in the sql database it should automatically update the CKEditor instance with the new text. My only problem is that it flashes when ever it updates (ie: it goes blank and then updates to the new text). Does anyone know of a way to make it a smother transition. I'm also using JQuery so I'm not sure if there is anything that could be used there to make a smooth transition to the new text.
CKEDITOR.instances.content.setData("data");
CKEDITOR.instance.content.setData("new data");
The change from data to new data will have a quick bit of lag.

There's no way to avoid some slight flickering when setting data in framed (based on wysiwygarea plugin) editor instance. This is because the entire contents of the iframe containing your work must be re-created. This is nothing like a piece of cake and I hardly think we can bypass this thing.
I'd recommend you to play with element.setHtml( html ) on editable though:
CKEDITOR.instances.editor1.editable().setHtml( '<p>FooBar</p>' );
This is not a valid method for setting editor contents in any way because it bypasses internal filtering, processing and stuff. Yet it may work formay you if you're careful.
P.S. You'll probably also want to cache editor1.editable() object to speed-up things.
There are quite some core developers of CKEditor active on stack
overflow.
Yep. We are ;)

It seems that the screen flickers because the page is reloading an iframe within the editor. By using the divarea plugin for CKEditor I can get rid of the flickering. The only problem now is that the CKEditor.readOnly property no longer works...

Related

Language set up with out loading whole page

Are there any alternate way of below code to set app language? Below code refresh the whole page always that gives bad experience to users.
window.location.search = "sap-language=EN";
This is also one way to achieve.
sap.ui.getCore().getConfiguration().setLanguage("EN");
However, some standard controls after rendered don't change the labels. Let me know if there are any other way that help here because loading whole page doesn't make any sense.
You can use Ajax by getting all the new markup and replacing the existing content by the reloaded content.
It might create some issues with other running scripts like loading images and sliders etc that holds a reference to an element so you have to reinitialize every single script that is running on settimeout() on your page.
Moreover you can use jQuery Localisation plugin

JS/Jquery: Initiate window resize without actually resizing

So I have a very specific problem that presented itself recently (right before our planned launch day tomorrow) and I am not completely sure how to solve it. I have built our website of an HTML-template with my modest front-end skills and we are very pleased with it. However, I can't seem to solve this.
The problem:
I have a filter system that allows a user to filter articles that are presented on a page. A user can even fill in this filter on the home page, direct to the page with the articles and have the filter applied. However, if then the filter is broadened (less strict) and new articles present itself, the pictures do not show up. Found out this is the case because the flexslider behind it has to be initialized again which happens on a window load (e.g. when the window is resized). The function that controls the initialization of the flexslider is in an external js file and I am not sure whether I can call on it from my own custom.js file, so I am thinking of just calling a resize/reload window function to active it.
The question:
Can I run a resize window function (or something that activates the flexslider) without hindering user experience (more specifically, without ACTUALLY resizing/reloading the window)? I will run this on a change in the filter.
I know this is a very specific question but hopefully somebody can help me out.
Take care!
p.s. it would be ideal if I could run the actual function that loads the flexslider but this is located in an external js file.
EDIT:
Briefly some additional info. If I go straight to the article page, it has no filter active and thus shows all articles, if I then start flipping through the filter, all is good. It is however only if I arrive from the homepage with a set filter that the problems arise. You then arrive on the article page which shows only the articles that are within the boundaries, and when the filter is taken away it has problems loading the images of the new articles showing up. As if it had not loaded these because they were not open on window load the first time.
You can trigger a resize event by creating a new event and passing it into the dispatchEvent command on window. There's a nice guide here. You'll want the type of event to be resize, since that's what it's listening for.
window.dispatchEvent(new Event('resize'))
This will work for events that were added via jQuery as well as events added via addEventListener.
I managed to solve it after all by delaying the function that drops the filter values into my inputs so it loads in all images initially before applying the filter. It happens at such speed it's hardly noticeable.
Also, I did try to initiate a window resize function, it did work without actually resizing anything, but unfortunately the images did not load in properly (overlap and such).
Anyway, it has been solved. Thanks for all the input!

Notify screen reader a page changed [duplicate]

Imagine you have a simple, single-page application - regardless of whether it was written using Backbone, Angular, Ember or anything else.
How can you tell a screen reader that we've changed 'page' when a route is followed?
In a classic application, when I navigate from /index.html to /about.html the screen reader obviously detects the page change, and re-reads as you'd expect.
In my Backbone application though, when I follow a route I cannot work out how to trigger a 're-read'. I've tried triggering a focus event which I'd seen somewhere, but that doesn't seem to work.
Note: I'm currently testing with NVDA/Chrome.
Overall, you should not need to trigger a 're-read', and depending on your UI that might not be a good thing anyway.
My experience has been with angular.js (as an accessibility person rather than the developer), and our overall approach was to manage the focus rather than trigger a re-read. (We do extensive accessibility testing.)
The key thing from a UI point of view (primarily for screen reader users) is that selecting a link (e.g. about.html) should take you somewhere.
In this case the appropriate place to put the focus would be the top of the content area of the about 'page', hopefully an <h1>.
In order for that to work the target element should be focusable via a script, so probably needs tabindex unless it is a link or form control:
<h1 id="test" tabindex="-1">
The -1 means it is not in the default tab order, but is focusable via a script. See more at WAI-ARIA authoring practices.
Then at the end of the function that loads the new content, including the tabindex attribute, add something like:
$('#test').attr('tabindex', '-1').css('outline', 'none');
$('#test').focus();
When adding tabindex dynamically it is best to do so in a line before the focus() function otherwise it may not work (I remember that from testing with JAWS).
To test this I would use either:
NVDA & Firefox, Windows
Jaws & IE, Windows
It is also good to test with VoiceOver on Safari/OSX, but that works differently and may not hit the same issues as a windows based screen reader.
You will hit a lot of issues with Chrome/NVDA as that is not supported very well, and end-users are very unlikely to use that. IE is ok with NVDA, but Firefox is best.
Overall, it is worth getting to know the WAI-ARIA authoring practices, particularly Using ARIA in HTML. Even though you are using a JS app, the browser (and therefore screen reader) is interpreting the resulting HTML so that advice is still relevant.
Lastly, if you are updating page content without the user pressing space/enter to activate something, you might find that JAWS/NVDA do not know about the new content as their 'virtual buffer' has not updated. In that case, you might need to add a JS shim to make them update, but only do that if you run into problems in testing, it should not be a global patch.
Taking the answer from #AlastairC, and the comments below it. I've taken this a bit further now and am going with this as my solution going forward:
My go-forward solution
I found that just reading out the first heading wasn't really that useful. Especially if the last page you were on was a loading sequence. You can hear that there something new has been focused, but it's certainly not clear that this forms the part of a whole now page.
Add some useful, descriptive text to the page
As such I now have a single paragraph at the top of my page layout template. This includes a screen-reader friendly message, along with a very rough overview of what the page.
<p class="screenreader-summary" tabindex="-1">
The <strong>Dashboard</strong> page is now on-screen.
It contains several widgets for summarizing your data.
</p>
Note that the tabindex value allows us to focus this element with JavaScript. You might not want to use a p element for this, you can use anything you like really.
Hide it off-screen (optional, only required if it would break your design/readability)
This is then coupled with CSS to move this element off-screen:
.screenreader-summary {
position: absolute;
left:-10000px;
top:auto;
width:1px;
height:1px;
overflow:hidden;
outline: none; /* Important, don't show an outline on-focus */
}
Focus this element, when a new page is shown on-screen
Finally, in the JavaScript code that shows your page on screen (e.g. in MarionetteJS using onShow or the show event):
$yourViewEl.find('.screenreader-summary').focus();
The result
I'm a sighted person, so take what I say with a pinch of salt - however I found that reading out a short description is so much more useful.
For angular the url changes, If someone REALLY needs to reread everything, (like me because of requirements), what did the trick for us was this:
$(window).on('hashchange', function () {
location.reload();
});
and we just added extra code to handle pages like "success" were no reloads are supposed to happen.
this simulates the actual page loading, and screen readers will read it normally like a page change.
kind of defeats the purpose of angular in a way, but this will help people like me who already have the application, and want a quick fix.

CKEDITOR.inline first load

CKEDITOR is giving me some hard time with the first load, i use:
CKEDITOR.inline
on the first load it takes about 2 seconds to load, on these two seconds if the user edit the div's content, when the CKEDITOR finally loads it restores it to before the edit :\ is there a way to fix it or maybe read-only the text untill the CKEDITOR loads? Right now i use opacity0 untill ckeditor is ready but it is a cheap hack and doesnt look good.
on the first load, the toolbar starts at the most left side of the screen, which on the other loads doesnt happen when it appears perfectly above the div being eddited.
I cant figure out how on the ckeditor inline demo they did it perfectly.
The question is a little too vague to really grasp any single underlying question. I would post this as a comment, but it is too long, so I'll just go ahead and add as answer. What do you mean by preloading the editor? Do you want to stop the user from editing content or do you want to load the editor before loading the HTML body content? Both are basically the same as "use opacity0 until ckeditor is ready but it is a cheap hack and doesn't look good.", what is the difference?
I wasn't talking about server performance in my comment, I was talking about client performance. There are many, many things you could try
Build a prettier fake preloader; for example mask the site with an overlay until CKE is ready
Defer DOM creation until CKEDITOR.instanceready or whatever event is usable for you. By this I mean you can just create a pretty loading animation and get the actual editable content with JS, this will look like a preloader too
Enable content editable only in document.ready or in some other later event, that might help
Monitor the network, see how long CKE requests load and if that is acceptable for you
Check that you are not using the source version of CKE
Check that caching works as expected
Minimize the load by removing any and all plugins you don't need
All of that is just for question number 1. As for "on the first load, the toolbar starts at the most left side of the screen, which on the other loads doesn't happen when it appears perfectly above the div being edited.", could we get a sample or how to reproduce this or a URL where this happens or even a screenshot? Based on that it is very hard to reproduce.

How much content being replaced with an AJAX call is too much?

I run into a common problem when trying to do AJAX development. Where possible, I like to try and just update data in an existing layout, and not the layout itself. For example, take the div below:
<div id="content-5">Here is some content</div>
I would get the updated value for content-5 from the server and just replace the contents of content-5 with the value. This makes a lot of sense for simple data replacements where the value is always going to be displayed in its pure form.
Sometimes the content is more complicated, and I have to actually get more than just raw data... maybe there is some logic to determine how a value is displayed and perhaps the style needs to be different depending on the data inside. In that case, I generally produce the HTML on the server side and inject the HTML into the element instead of just raw data.
Example: A status field from the controller comes back as "complete", but from the design doc, "complete" is supposed to show the user the text "Available" and it needs to be styled in a way different from other statuses.
Doing this in Javascript would require some in-depth view knowledge that the template layer probably already handles. The end result would be the same (code snippet below), but the difference is that there could possibly be some code duplication and a far more complicated Javascript layer.
<div id="content-5"><span class="success">Available</span></div>
Without fail, the requirement comes up that the system will need to handle "new" contents as well. The easiest solution to implement is to just get all of the content's at the same time so that I do not need to handle the extra complexity of injecting a new element instead of just replacing existing content.
So, I create a new template, wrap the contents in another element with an ID, and bulk replace all of the content divs at the same time any time there is a change.
<div id="allContent">
<div id="content-1">Some content A</div>
<div id="content-2">Some content B</div>
<div id="content-3">Some content C</div>
<div id="content-4">Some content D</div>
<div id="content-5">Some content E</div>
</div>
At some point, I have to wonder: Where is the line? At some point it feels like I'll eventually just be replacing the whole page with an AJAX request. Would this really be a problem?
I realize this may be pretty subjective, but what are some good strategies for determining to which level you should be replacing content with AJAX? Replacing just the data seems to be my preferred method when possible as it makes the AJAX controllers very simple. Replacing larger chunks of HTML from a template seems to be the easiest for handling more complicating layout and design issues and also feels like it could be more easily maintained. Are there other options I have not considered?
I expect there will be some discussion about manipulating the DOM programatically, but I personally really dislike this. The code ends up looking pretty horrible and really starts to integrate too much layout and design into the JS layer for my liking. Since I generally work with template libraries of some sort (whether raw PHP, PHP templates like Smarty or JSP in Java) it seems to make more sense to leave as much visual design there as possible.
EDIT
Based on the first few answers, it seems like this is being read as trying to keep the user on the same page but navigating around around the site or otherwise changing the page in a radical way with each update. The question is more about how to determine where the layout work for AJAX calls should happen and whether or not it is an acceptable practice to change large chunks of code with an AJAX request, knowing that replacement code may look nearly identical to what had been there before.
I think the most important requirement is the refresh requirement. If after several AJAX updates I hit refresh, the page I was just looking at should be the page that arrives. If the page reverts to a previous state for any reason then the URL is wrong. If for any reason your AJAX data is going to make the URL in the browser invalid then you should not be using AJAX to fetch that data.
There are exceptions, of course for data the is even newer than the last AJAX request. But that's obviously not what I'm talking about. A live chat screen could receive an update between the last AJAX request and the refresh. No big deal. I'm talking about the logical content and the URL describing it should always be in sync.
Complete personal opinion ex nihil, my rule of thumb is to change no more than 1 "panel" unit or 33% of the page whichever is less.
The basis for this is that the user should be able to clearly recognise the previous page state is related to the new state - how would you feel if you were suddenly teleported into the building to your right? Be gentle with your poor user.
There are also serious technical questions about the benefits of moving and inserting basically a page worth of data, which I think is a bit of an AJAX anti-pattern. What benefit does AJAX provide if you're going to do that?
Your specific question seems dependant on the supposition that the response coming back from your AJAX request isn't "just" data. This feels wrong to me from a separation of concerns point of view: I would expect a page to have all the layout information it requires already, the AJAX response itself to provide nothing more than dumb data/markup, and the JS event handler which created the request to sew the two together, MVC style. In that respect I think, yes, you're doing too much.
(by panel, I mean one logical design element - a menu, a ribbon, an item metadata panel, etc..)
edit: now that I think about it, I think SO's user profile page breaks my rule of thumb with those tab clicks
Depending on whether you want people to be able to to link to / bookmark etc the current page, you might want to navigate the user's browser.
This isn't a concern for some apps like GMail etc, and they won't ever refresh the page.
For myself, I tend to think it's a good practice to navigate the browser when navigating to a logically different place. eg. a person's profile vs. a list of their messages.
Sorry if this is vague, it's rather subjective :-)
A good guideline for something like this is to ask yourself, "Is this dynamic application 'content', or is it content-content?" Your use case sounds like application content that will change with each user. This is probably the best place for Ajax, but with everything, it's always nice not to just have one hammer. You don't want to do too much on one page. For instance, if one part breaks, the entire thing might, thereby frustrating the user.
Anywhere you're looking at actual page content or anything where the information is static, I strongly suggest avoiding the use of JavaScript, as it runs the risk of being invisible to search engines. Make sure anything linking to information like this is crawlable. The first step towards this is dynamic generation on the server side rather than browser side.
If you're using Smarty templates to produce a page, just fragment a template into various meaningful sections - news.tpl, email.tpl, weather.tpl - and have a master.tpl producing the structure of the page and calling child templates.
Then, if you're for example using an AJAX call triggered by a timeout to refresh the news, you can just call the server, cram the necessary data into news.tpl, and return the results into the news div you set up with master.tpl. This way your news layout is always following the pattern of news.tpl. (If you used JavaScript to manipulate formatting bits or set up event handling on document load, you'll need to attach that post-processing to fire after the AJAX call.)
You haven't really gotten specific about the types of things you're trying to replace here, and my initial reaction is that, if a single event is triggering multiple sections of the page to update at once, that's a sign that maybe you should be coallating those sections into a single display.
How much formatting gets done on the server end versus how much gets done on the client end with JavaScript? I'd say server-side formatting if possible, that way you have code that reflects discussions you've made about display layout and logic. Client-side formatting can be used for more interface-based issues - sorting rows in a table and alternating row colors with :odd and :even selectors, showing and hiding divs to create a "tabbed display" without hitting the server since the data won't change just from selecting a new tab, that sort of thing.
Finally, AJAX is one-way. If your web page is a view on a database, this isn't as much of a problem, but using AJAX manipulation to take the place of normal navigation is a terrible idea.
If you were habitually replacing the entire contents of a page using AJAX calls, I would agree that you have a problem. However, it appears to me that you are attempting to carefully think through the implications of your design and attempting, where possible, to avoid what annakata has called this "AJAX anti-pattern."
My rule is a bit simpler: as long as a substantial amount of context (e.g. menu on the left, header, various controls, page title, etc.) remains on a page, I am Ok with replacing almost anything with an AJAX call. That being said, I've never struggled with a page that has as much AJAX-generated code as you are.
I do have one question though: isn't it possible to encode state so that you can just replace some of the Divs in your example rather than all of them? If not, have you thought about doing so?

Categories

Resources