CKEditor 4.4.5 removing page throw html, how to prevent? - ckeditor

In previous versions(3.5) of CKEditor I was able to enter:
<br style="page-break-after: always;" />
However, after upgrading to 4.4.5, I noticed that the RTE no longer shows this HTML source, from the Database column, and so if one resaves the form with this RTE on it, then NULL is saved back to the database. It seems that CKEditor is stripping this HTML out for some reason.
How can I prevent this?
Many thanks.
EDIT 1
Discovered this to be added to config.js:
config.allowedContent = 'br {page-break-after}';
But does not work, although it should do....
EDIT 2
Link for above config setting
EDIT 3
I can try to enter the above HTML, in HTML Source View, but if I toggle the HTML Source button, and go back to Source View, it is now gone. So CKEditor is stripping this HTML out for some reason.
EDIT 4
Removed as now irrelevant
EDIT 5
Looking at the Browser source I see:
<textarea class="RuleRTE" cols="20" id="myCk" rows="2"><br style="page-break-after: always;" /> </textarea>
So clearly the data is there and being retrieved, but being converted which prevents me seeing it in the HTML Source view.
I have now found this is irrelevant as <p>test</p> test fine and it gets converted as well, I guess to prevent it being rendered like normal HTML in the page. So it seems the CKEditor does not like the tag ???
EDIT 6:
Removed as now irrelevant to question.
EDIT 7:
Debug JS:
<script type="text/javascript" language="javascript">
var editor = CKEDITOR.replace('Content', {
allowedContent: 'br[*]'
});
editor.on('instanceReady', function () {
console.log(editor.filter.allowedContent);
});
Results seem to show allowedContent is working fine, but BR element still invisible.
[Object, Object]
0: Object attributes: true
classes: null
elements: Object br: true

I suspect that there's a syntax or usage error with the way you're attempting to modify the allowedContent setting. Try doing something more simple along these lines: (do it in code rather than the config file)
var your_ck_editor = CKEDITOR.replace( 'your_ck_element_id', {
allowedContent: 'br[*]'
} );
The br[*] setting should allow any <br /> element with any attribute.
For troubleshooting purposes try this:
console.log( your_ck_editor.filter.allowedContent );
If this code does not work for you please post all the code that you use to set up your CKEditor as well as the output of your console.log call.

Related

Why does dojo's xhr call to get JSP file content not process the onShow event in InternetExplorer as it does for Firefox and Chrome?

I'm trying to resolve a problem seen only with the IE browser but not Firefox or Chrome. I'm using the dojox.widget.Wizard along with the dojox.widget.WizardPane where each pane in the wizard gets added to the Wizard like so:
nextWizPane = new dojox.widget.WizardPane({
paneId: chosenPaneId,
passFunction: handleNext,
onShow: showingPane
}).placeAt(wizard, newPaneIndex);
loadPaneContents(nextWizPane);
where the loadPaneContents() function dynamically loads the contents for the new WizardPane by using the "dojo/request/xhr" module. The xhr's "then" function accepts the anonymous callback function which accepts the contents of a JSP file which is finally used to set the contents of the WizardPane like so:
xhr(contextPath+"/lib/wizardPanes/UrsPage_"+wizPane.paneId+".jsp",
{sync:true}).then(function(responseFromXhr) {
nextWizPane.set("content", responseFromXhr);
});
where the file that xhr is loading, e.g. UrsPage_1_1_1.jsp, defines the contents for the wizard pane. The contents of the UrsPage_1_1_1.jsp file starts out like:
<%#page session="true" contentType="text/html" pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<fmt:setBundle basename="/WEB-INF/config/resourcebundle"/>
<div wizardpageidline data-dojo-type="dijit/form/Form" id="1_1_1" encType="multipart/form-data" action="" method="" paneName="Contact Information">
<script type="dojo/on" data-dojo-event="show" data-dojo-args="e">
console.log("UP111 onShow form2");
alert("UP111 onShow form2");
require(
{ packages:[ { name:'lib', location:'/lib' } ] },
["lib/UrsController",
"dojo/on",
"dojo/dom",
"dojo/domReady!"
], function(ursController, dojoOn, dom){
dojoOn(dom.byId("mailingAddressSameAsPrincipal"), "change", function(){
console.log("UP111 changed SameAsMailingAddress this.checked="+this.checked);
alert("UP111 checked Same As box="+this.checked);
});
});
</script>
...<snipped dojo/dijit/HTML markup>
</div>
The log and alert calls above appear when this runs in Chrome and Firefox, but are completely ignored and unexecuted when run in IE8. What am I missing? The JSP file's markup that is snipped does contain dojo/dijit markup that is successfully parsed in both IE, Firefox and Chrome, so it's not like the whole file is being ignored by the dojo parser, just the onShow for the outer . Any help would be appreciated on how to debug this issue.
Thank you,
Gregor
I was faced with this same issue in IE11 and have narrowed it down to this: in an asynch block, it appears that IE has lost scope of the config.contextPath. You may have to get creative on how to gain this value and store it in your widget as a property that can be passed to your asynch call. Example:
var prefix = config.contextPath;
topic.publish("/widget/selected", row.id, prefix); //may need this.prefix depending upon where you gain/store the property and where used.
For my purpose, the code executed fine when IE debug panel or console was open, but failed when console was closed. Alert statements were the only thing that could aid in this matter. Basically, confirm the url you are building before executing the ajax

Grails remoteLink ajax issue populating JQuery accordion

Following the simple example from Jquery: Accordion Example
Using a remoteLink function from grails (AJAX) the information is pulled back from the controller and sent back to the GSP, which works fine. I do however want this data to be placed within a Accordion container... click here for screenshot of current functionality.
(Event Create Page rendering form template) _form - GSP:
<g:remoteLink controller="event" action="showContacts" method="GET" update="divContactList">Show Contacts!</g:remoteLink>
<div id="divContactList">
<g:render template="contactListAjax" model="[contactList: contactList]" />
</div>
<script type="text/javascript">
$(document).ready(function()
{
alert("Checking if I'm ready :)");
$( "#accordion" ).accordion({
header: 'h3',
collapsible: true
});
});
</script>
_contactListAjax - GSP Template
<div id="accordion">
<g:each in="${contactList}" status = "i" var="contact">
<h3>${contact.contactForename}</h3>
<div><p>${contact.email}</p></div>
</g:each>
</div>
Not quite sure what I'm doing wrong here, as I'm encasing the data with the div with an id accordion, yet doesn't load. Please refer to screenshot link above to see what is currently happening.
UPDATE
Event (Standard Generated CRUD, only showing where the relivant imports are) create - GSP
<link rel="stylesheet" href="${resource(dir: 'css', file: 'jquery.ui.accordion.css')}"/>
<g:javascript src="jquery-1.7.1.min.js"></g:javascript>
<g:javascript src="jquery-ui.min.js"></g:javascript>
Try replacing:
$(function() {
$( "#accordion" ).accordion({
collapsible: true
});
})
with
$( "#accordion" ).accordion({
collapsible: true
});
Edit:
You can't use an <r:script /> tag after the request is finished. The server has already laid out all of the resources. Change it to a standard javascript tag. Also the inclusion of your javascript and css files should be elsewhere on the page.
I solved this... (well Hack & Slash for now... not the best, but only viable solution for now)
var whatever is the stored HTML generated by the AJAX and placed into the divContactList on the update function. The Accordion is deleted and then rebuilt (not the best approach I realise)
var whatever = $('#divContactList').html();
$('#accordion').append(whatever)
.accordion('destroy').accordion({
collapsible: true,
active: false
});

CkEditor Doesn't post value

When a form with a textarea using CkEditor is submitted using ajax the post is empty on the server side.
If I remove CkEditor, the value is posted. Any ideas?
On submit, run this code:
for (instance in CKEDITOR.instances) {
CKEDITOR.instances[instance].updateElement();
}
.. basically for AJAX, you need to force CKEditor to update your textareas so they contain the data you see in the CKEditor windows. See this question for more details.
You don't really need to update anything with JS. All you have to do is to make sure your textarea (the one you replace with CKEDITOR.replace() on $(document).ready()) has the same name as the property you want to set value of, e.g.:
<textarea id="editor" name="Body">#Model?.Body</textarea>
This works for me:
CKEDITOR.replace( 'content' );
function updateAllMessageForms()
{
for (instance in CKEDITOR.instances) {
CKEDITOR.instances[instance].updateElement();
}
}

JQuery Accordion doesn't 'accordionize' new panels loaded via AJAX

I have to load accordion panels into one of my pages using AJAX and I'm finding that JQuery is 'accordionizing' all of the panels defined in the HTML file, but none of the panels loaded via Javascript. One other little quirk: I'm doing this on a nested accordion - the accordion within an accordion. It's accordion inception, if you will.
I checked other Stack Overflow questions and the JQuery Forum and I found that most of them are about resizing panels after loading data. The closest question I found was here, but it doesn't answer my question because trying to destroy and then re-accordion-ize my JS-loaded panels does not work.
This is the relevant section of my html head section:
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/flick/jquery-ui.css" type="text/css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".accordion").accordion({
collapsible: true,
icons: false,
autoHeight: false,
active: false
});
});
</script>
This is the relevant section of my html body section:
<div class="accordion">
<h3 id="acc1">First panel title</h3>
<div>First panel content</div>
<h3 id="acc2">Second panel title</h3>
<div class="accordion" id="ajaxresults-aliaslist">This is where the nested accordion goes</div>
<h3 id="acc3">Third panel title</h3>
<div>Thirdpanel content</div>
</div>
<script type="text/javascript">
$("#ajaxresults-aliaslist").load("/loadaliaslist/");
</script>
When javascript loads "/loadaliaslist/", it received a message with the following content:
<h3>1st panel within a panel title</h3>
<div>1st panel within a panel content</div>
<h3>2nd panel within a panel title</h3>
<div>2nd panel within a panel content</div>
<h3>3rd panel within a panel title</h3>
<div>3rd panel within a panel content</div>
I know that the content above is being passed to the div because the content appears un-accordionized when I load the page. Instead of an accordion within an accordion, I just get a bunch of boring content sitting at the first level of the dream sequence. I've got to go down a level... Wait, where was I?
Right, one more thing: I have tried two things that did not work:
- I tried putting both the load and the accordion scripts at the bottom of the page (load first), hoping that the order would matter. (noobish? not sure...)
- I tried adding a script at the end to destroy and recreate the panels like so:
$("#ajaxresults-aliaslist").accordion('destroy').accordion();
That's all. I really hope someone out there is the Leonardo DiCaprio of accordions, and can help rescue me from my predicament. Much appreciated!
Untested but try something like this...
The issue is most likely due to the fact that the event handlers aren't being attached to the inserted content (via Ajax).
$(function() {
var config = {
collapsible: true,
icons: false,
autoHeight: false,
active: false
}
$(".accordion").live('load', function(){
$(this).accordion(config);
}).accordion(config);
});
EDIT: Changed the code a bit (still untested).
EDIT FROM OP: SOLUTION FOUND
After playing around more, I found a way to solve this problem as long as AJAX is loading the new data immediately on pageload. Solution was to call the accordion function, only once, immediately after the load. As in the solution below:
<script type="text/javascript">
$("#ajaxresults-aliaslist").load("/loadaliaslist/",
function(response, status, xhr) {
if (status == "error") {
var msg = "Sorry but there was an <strong>error</strong>: ";
$("#error").html(msg + xhr.status + " " + xhr.statusText);
}
/* All panels are accordionized immediately after loading the content */
$(".accordion").accordion({
collapsible: true,
icons: false,
autoHeight: false,
active: false
});
});
</script>
A word of caution: This will only work if all of the accordion content is loaded immediately. If there are pieces of content loaded after the first accor
I suppose that you want to reset the accordion control. Try to do this:
$('#accordion')[0].innerHTML = "";
After that fill the control with your HTML using the append.

How can I make an AJAX link work once it is moved out of the iFrame?

I am using an iFrame with a form that return some content with an AJAX link.
I am then moving the returned content out of the iFrame into the main page.
However, then the ajax link does not work and the error "Element is null" is created once the link is clicked.
How can I move content from the iFrame and still have the AJAX link working?
Here's the code returned by the iFrame:
<span id="top">
<a id="link8" onclick=" event.returnValue = false; return false;" href="/item_pictures/delete/7">
<img src="/img/delete.bmp"/>
</a>
<script type="text/javascript">
parent.Event.observe('link8', 'click', function(event) {
new Ajax.Updater('top','/item_pictures/delete/3', {
asynchronous:true, evalScripts:true,
onCreate:function(request, xhr) {
document.getElementById("top").innerHTML = "<img src=\"/img/spinner_small.gif\">";
},
requestHeaders:['X-Update', 'top']
})
}, false);
</script>
</span>
I see two problems with your code.
First the solution (I think :-))
When your iframe loads, the javascript in it runs. Javascript attaches an observer to parent document's link8.
Inside the observer you define another function (onCreate). This function will run in iframe context, making document object refer to iframe and not to main document. When you remove link8 from iframe to move it to main document, document.getElementById("top") will become null - hence error.
Perhaps change it to:
parent.document.getElementById("top").innerHTML = "<img src=\"/img/spinner_small.gif\">";
Second problem (that is not really a problem in this particular case) is, if you move whole span (including the script) to main document, the javascript will run again in main document's context. In your case, you should see an error or warning after you move the content, stating that parent is null (or similar).
To remove the second problem, return your iframe data in two divs or similar. Then copy only div with html to main document.
What I did was move the AJAX call out to an external js file and called the function once the link was clicked. It works now.

Resources