Force CKEditor to load an HTML file from disk - ckeditor

I am trying to use CKEditor to edit fairly long HTML files. I need to edit the underlying HTML a bit but the search and replace plug-in doesn't work on the underlying code. And I want to automate via a keyboard shortcut or macro the things I do over and over.
For example, I repeatedly need to change the name of a specific div class--e.g., from "todo" to "done".
....div class="todo"..... ===> ....div class="done"....
I am doing this now by using Autohotkey macros to automate mouse movements and mouse clicks, and toggling into and out of Source mode, but this is very clunky and unreliable. Since I do this daily for maybe 30 sections of a displayed file, I want it to be speedy and robust. I'd like to use Python or Autohotkey to work on the underlying file. So my question is: when the underlying file is changed, how can I automate getting CKEditor to update--i.e., to reload the file from disk?
The goal is to have a single keystroke that will call Python or AHK, use them to make the change in the file, then force CKE to update the display ("done" reveals itself by changing the background color of that section).

Javascript can't read file directly from disc. (Except, selecting manually, e.g. https://www.html5rocks.com/en/tutorials/file/dndfiles/)
So it's required to use server-side language, and get file content on page load or with AJAX request.
For example with ajax jquery
$.ajax({
url: "/path/to/your/file.html",
async: false,
success: function (result){
CKEDITOR.instances["YOUR_INSTANCE"].setData(result)
}
});
However, for task like changing class and other html related. it's possible to use javascript / jquery to manipulate with CKEDITOR content.
e.g.
HTML
<textarea id="ckeditor"><div class="todo">lol</div></textarea>
JS
CKEDITOR.replace("ckeditor", { allowedContent: true, });
CKEDITOR.on( 'instanceReady', function( evt ) {
$(CKEDITOR.instances["ckeditor"].window.$.document).find('.todo').removeClass( "todo" ).addClass( "done" );
})
UPDATE:
You need to replace url: "/path/to/your/file.html", with path of file you want to open. (Please, also check if i was correct assuming your CKEditor instance is named 'editor1') And put this code after you load jquery.
<script>
$( document ).ready(
$.ajax({
url: "/path/to/your/file.html",
async: false,
success: function (result){
CKEDITOR.instances["editor1"].setData(result);
}
}));
</script>

Related

The view area of ckEditor sometimes shows empty at the start

I am using the following directive to create a ckEditor view. There are other lines to the directive to save the data but these are not included as saving always works for me.
app.directive('ckEditor', [function () {
return {
require: '?ngModel',
link: function ($scope, elm, attr, ngModel) {
var ck = ck = CKEDITOR.replace(elm[0]);
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
setTimeout(function () {
ck.setData(ngModel.$modelValue);
}, 1000);
}; }
};
}])
The window appears but almost always the first time around it is empty. Then after clicking the [SOURCE] button to show the source and clicking it again the window is populated with data.
I'm very sure that the ck.setData works as I tried a ck.getData and then logged the output to the console. However it seems like ck.setData does not make the data visible at the start.
Is there some way to force the view window contents to appear?
You can call render on the model at any time and it will simply do whatever you've told it to do. In your case, calling ngModel.$render() will grab the $modelValue and pass it to ck.setData(). Angular will automatically call $render whenever it needs to during its digest cycle (i.e. whenever it notices that the model has been updated). However, I have noticed that there are times when Angular doesn't update properly, especially in instances where the $modelValue is set prior to the directive being compiled.
So, you can simply call ngModel.$render() when your modal object is set. The only problem with that is you have to have access to the ngModel object to do that, which you don't have in your controller. My suggestion would be to do the following:
In your controller:
$scope.editRow = function (row, entityType) {
$scope.modal.data = row;
$scope.modal.visible = true;
...
...
// trigger event after $scope.modal is set
$scope.$emit('modalObjectSet', $scope.modal); //passing $scope.modal is optional
}
In your directive:
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
};
scope.$on('modalObjectSet', function(e, modalData){
// force a call to render
ngModel.$render();
});
Its not a particularly clean solution, but it should allow you to call $render whenever you need to. I hope that helps.
UPDATE: (after your update)
I wasn't aware that your controllers were nested. This can get really icky in Angular, but I'll try to provide a few possible solutions (given that I'm not able to see all your code and project layout). Scope events (as noted here) are specific to the nesting of the scope and only emit events to child scopes. Because of that, I would suggest trying one of the three following solutions (listed in order of my personal preference):
1) Reorganize your code to have a cleaner layout (less nesting of controllers) so that your scopes are direct decendants (rather than sibling controllers).
2) I'm going to assume that 1) wasn't possible. Next I would try to use the $scope.$broadcast() function. The specs for that are listed here as well. The difference between $emit and $broadcast is that $emit only sends event to child $scopes, while $broadcast will send events to both parent and child scopes.
3) Forget using $scope events in angular and just use generic javascript events (using a framework such as jQuery or even just roll your own as in the example here)
There's a fairly simple answer to the question. I checked the DOM and found out the data was getting loaded in fact all of the time. However it was not displaying in the Chrome browser. So the problem is more of a display issue with ckEditor. Strange solution seems to be to do a resize of the ckEditor window which then makes the text visible.
This is a strange issue with ckeditor when your ckeditor is hidden by default. Trying to show the editor has a 30% chance of the editor being uneditable and the editor data is cleared. If you are trying to hide/show your editor, use a css trick like position:absolute;left-9999px; to hide the editor and just return it back by css. This way, the ckeditor is not being removed in the DOM but is just positioned elsewhere.
Use this java script code that is very simple and effective.Note editor1 is my textarea id
<script>
$(function () {
CKEDITOR.timestamp= new Date();
CKEDITOR.replace('editor1');
});
</script>
Second way In controller ,when your query is fetch data from database then use th
is code after .success(function().
$http.get(url).success(function(){
CKEDITOR.replace('editor1');
});
I know, that this thread is dead for a year, but I got the same problem and I found another (still ugly) solution to this problem:
instance.setData(html, function(){
instance.setData(html);
});

Dojo Xhr: Result Content is Not Appearing until there is a mouse click anywhere on page

i'm building an offline application with Dojo 1.7, using Dojo RDD, generating forms dynamically and storing them in cache.
now every time when i fetch something through ajax i have to remove dojo registry because dojo binds widgets by id if i dont clear registry it will cause problem in parsing dojo widgets because their ids already exist in widget registry, but when i clear registry every time it causes another problem. everything works fine but the result content only appear when clicking anywhere on page. same as described in:
Dynamic Elements are not appearing in IE8 until there is a mouse click
but, in this case this problem is with Chrome.
and the solution provided in above url doesn't work in this case.
exp:
//in some cases registry is destructor is not called.
dojo.xhrGet({
url: serverUrl,
content: {},
load: function(result) {
//destroying widget registry.(before any parsing)
dijit.registry._destroyAll();
// here is html processing.
},
error: function(error) {
utility.handleException(error);
}
});

How to get an AJAX call in my TYPO3 Extbase Extension?

I have trouble doing this, I've been looking for some manuals, but they don't seems to work for me (they're either or detailed enough or I'm too stupid, probably something from both).
So I want to start an AJAX call from my Fluid View HTML file by some event, then it should go for the action in some controller and return some value (any value would be fine for the moment, I just can't seem to get anything to work here when it comes to AJAX in Extbase).
With no details I can only guess what is your problem
First and most important thing is ... using FireBug to check what the problem with AJAX call is. It can be just wrong URL (action, controller etc...) or some problem in your action which doesn't return required output. FireBug will allow you to check where it stacks.
But most probably...
There is VERY important thing to remember while writing JS/CSS code directly into your Fluid view and unfortunately it's almost never mentioned:
Fluid uses braces to indicate that the string is a variable: {someVar}, therefore if you put AJAX or other JavaScript function into the Fluid template it will be most probably considered just as Fluid variable. This sample pasted to the template:
$.ajax({
url: "index.php"
data: "tx_myextension_plugin[controller]=MyController&tx_myextension_plugin[action]=getData&type=89657201"
success: function(result) {
alert(result);
}
});
Will be rendered just as:
$.ajax(Array);
Solution:
Escaping it directly in the template is hard, therefore it's definitely easier just to save all your JavaScript into separate file under Resources/Public directory of your extension, and include it with common HTML tag:
<script type="text/javascript" src="typo3conf/ext/yourext/Resources/Public/ajaxFunctions.js"></script>
$("#searchFach").change(function(){
$.ajax({
type: 'POST',
url:"fragen/controller/Question/searchQuestions",
data: {mainCategoryId:$("#searchFach").val()},
success: function(response) { $("#searchCategory").html(response);
},
});
});`

JQuery Mobile and JSONP

I have my jquery mobile app pulling data from our mysql db using JSONP. The data is pulling fine, but the problem comes when I go back to the previous "page" in my app then click on a different option, it doubles the data on the next screen, and it will just keep stacking the data as many times as I do that. What am I missing?
The app doesn't look right in any browsers, but it looks fine in the ios simulator or appmobi simulator. I can post some code if needed, just know it won't look right in your browser.
Thank you for any help you can provide
$('#two').bind('pagecreate',function(event){
var img = getUrlVars()["st"];
var photo = $('#img');
$.ajax({
type: 'GET',
url: 'http://serverhidden/json/img.php?st='+img,
dataType: 'jsonp',
success: function(data) {
$.each(data, function(i,item){
var image = '<img class="stmap" src="images/states/lrg/'+item.img+' "/>';
photo.html(image);
});
},
error: function(e) {
//called if there is an error
//console.log(e.message);
}
});
});
Make sure you are not subscribing your event multiple times. It seems silly but is easy to do.
I would recommend you add logs to your JQM site so that you can see how many times your site is being updated.
You should also be aware that updating a JQMobile page often requires a call to a method to update content after a page is rendered. See here: jQuery Mobile rendering problems with content being added after the page is initialized
Hope those help.
So without any code from your project this is a shot in the dark but it seems like you populate a pseudo-page with information on pageshow with an .append() call. Instead of using .append(), use .html() as it will replace the information already present rather than add to it.
If each state has an individual page then you can bind to the pagecreate (or similar) event so the data will only be appended once rather than on each pageshow event.

Ajax causing refresh on select change - not sure why

I'm putting some kind of configuration area together, where basically the menu is on the left side of the screen and the actual configuration takes place on the right.
Upon clicking on a menu item, the appropriate config screen is displayed. This works with no problem.
The problem I'm having is that one config screen requires some JSON pulling from the database, using a script that I've used elsewhere that worked perfectly (though it isn't called from a page that itself was called via ajax). Basically, the JSON pull is made when a dropdown menu is changed, but I don't know why, but once the action is complete the container is refreshed. Though this only happens for some reason if I don't include the jQuery library on the called page (even though it is already present in the top parent).
If I do include the library, then for some reason when I make the change, the requested JSON pull is made 3 times (instead of 1) and no refresh happens (as it should).
Have I done something very wrong? I've tried including the jQuery/javascript processing to make onchange in the top parent, but it doesn't work at all if there - even though the ajax calls don't use 'click' but 'live'.
To call the config area on menu click:
$("#setting_choice ul li").click(function(event){
event.stopPropagation();
$("#setting_choice ul li").each(function(){
$("#setting_choice ul li").removeClass("active");
});
$(this).addClass("active");
var setting = $(this).attr('id');
$.ajax({
type: "GET",
url: "settings.php",
data: "setting="+setting,
success: function(msg){
$("#setting_action").ajaxComplete(function(event, request, settings){
event.stopPropagation();
$("#setting_action").html(msg);
});
}
});
});
The code used to make the JSON call (but not everything, as the same still happens when called) - the JSON call is successfull as I've done console.log(j); and seen the JSON contents:
$('#country').change(function(){
alert('executed');
$.getJSON("regions.php",{id: $(this).val(), ajax: 'true'}, function(j){
var options = '';
....
$('select#county').html(options);
alert('complete');
})
});
I can see that the changes are made when 'complete' is alerted, but then it all refreshes for some reason...

Resources