CKEditor and iframes - javascript

I'm experiencing stuff with CKEditor. I read the doc, but I can't find a way to do what I'm trying to do.(I'm in Java, in a jsp page)
I have a path
String path = request.getContextPath();
And I need to call this path
<%=path%>/docX/Controller
What I have is very basic:
<div id="editor">
<h1>Hello world!</h1>
</div>
<script>
initSample();
</script>
That works very well, but I want to add content when the page load.
I tried to manually add an iframe in the code with my path, such as
<iframe src="<%=path%>/docX/Controller"></iframe>
But it shows something like this : http://docs.cksource.com/images/9/93/CKEditor_iframe_example1.png
Which is normal if I understood well. If I click on "preview" I'll see what I'm suppose to see. But I want to see it at first and I want to be able to edit it.
The file it will return will be a .html file. So I must get the 'innerHTML' from that file and put it somehow in the editor. It doesn't have to be an iframe if there's an easier way to get the data.
Now I'm trying to get the html from the iframe and put it into a <p>. What I got so far looks like this :
<%
String path = request.getContextPath();
%>
<div class="main">
<div class="grid-container">
<div class="grid-width-100">
<div id="editor">
<h1>Hello world!</h1>
<iframe id="frame" src="<%=path%>/docX/Controller"></iframe>
</div>
</div>
</div>
</div>
<script>
initSample();
var iframe = document.getElementById("frame");
var iframe_contents = iframe.contentDocument.body.innerHTML;
alert(iframe_contents);
</script>
My alert() shows an empty string, but if I click on preview, I can see the text.
Any kind of help is always appreciated.
EDIT: My html file only have "test" inside it. Nothing like <html> <head> and stuff. I tried
$(document).ready(function () {
var test = $("#frame").contents().find("html").html();
alert(test);
})
But it returns <html></html><body></body>
EDIT 2:
I changed it for
$(document).ready(function () {
var mydocument = document.getElementById("frame").contentDocument;
var serializer = new XMLSerializer();
var content = serializer.serializeToString(mydocument);
alert(content);
})
My result is : <html xmlns="http://www.w3.org/1999/xhtml"><head><style type="text/css"></style></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"></pre></body></html>
If I open my .html file, all I see is test

I'll answer my question so if someone has the same issue, he could try this solution.
So I removed the <iframe> from my CKEditor and I added an empty <p>. I simply took the returned data of my URL and put it in that <p>.
<%
String path = request.getContextPath();
%>
<div class="main">
<div class="grid-container">
<div class="grid-width-100">
<div id="editor">
<p id="content"></p>
</div>
</div>
</div>
</div>
<script>
initSample();
$(document).ready(function () {
$.get('<%=path%>/docX/Controller').then(function(responseData) {
$("#content").append(responseData);
});
})
</script>
In my case, responseData returns "test". It will also take properties, if your text is bold for exemple.
This will work in IE. But to make it work in chrome, in my case, it will return object XMLDocument. I had to do something like this:
$.ajax({
url: '<%=path%>/docX/Controller',
type: 'GET',
dataType: 'text',
success: function(data){
alert(data);
}
});

Related

Can someone explain to me why this isn't working? Ajax Load + scripts on html

The script won't load after the ajax has loaded the html content, why is this simply step not working. Here is what I got:
MakoStart.html: (The main page that will change)
<div class="makoislandintro" id="makochange">
<div class="makochoicesfirst">
<img src="../img/makoislandspecial/makobeach.jpg" class="makoislandbeach" id="makoislandbeach" alt="current">
<br>
</div>
</div>
<script>
document.getElementById("makoislandbeach").onclick = function() {
$('#makochange').load('makoisland.html');
};
</script>
This works, when i click the image with the id: makoislandbeach, the content changes to whats in makoisland.html.
Here is what is in makoisland.html:
<div class="makochoices">
<div id="rightside">
<img src="../img/makoislandspecial/waterstream.jpg" class="makoislandchoice" id="waterstream" alt="right choice">
</div>
<div id="leftside">
<img src="../img/makoislandspecial/islandside.jpg" class="makoislandchoice" id="islandside" alt="left choice">
</div>
</div>
<script>
document.getElementById("waterstream").onclick = function() {
$('#makochange').load('waterstream.html');
};
document.getElementById("islandside").onclick = function() {
$('#makochange').load('islandside.html');
};
</script>
Once the content changed, the script doesn't execute when i click the 2 new images that have replaced the old content. I have made a waterstream.html, it is the same as makoisland.html but with different images, but the script won't work after the first transition.
Take a look at this answer. As it said:
When calling .load() using a URL without a suffixed selector expression, the content is passed to .html() prior to scripts being removed. This executes the script blocks before they are discarded. If .load() is called with a selector expression appended to the URL, however, the scripts are stripped out prior to the DOM being updated, and thus are not executed.
Maybe you could do something like this. Instead of using load, use ajax. It's slightly different.
<div class="makoislandintro" id="makochange">
<div class="makochoicesfirst">
<img src="../img/makoislandspecial/makobeach.jpg" class="makoislandbeach" id="makoislandbeach" alt="current">
<br>
</div>
</div>
<script>
document.getElementById("makoislandbeach").onclick = function() {
$.ajax({
url: "makoisland.html",
context: document.body,
success: function(responseText) {
$("#makoislandbeach").html(responseText);
$("#makoislandbeach").find("script").each(function(i) {
eval($(this).text());
});
}
});
};
</script>

JavaScript: Trying to use a variable from a page loaded inside a DIV in another DIV

I'm trying to use a variable from a page loaded inside a DIV in another DIV.
The text in the "bar" DIV on the "index.html" page should be replaced by the item id selected from the "page.html" loaded as an <object></object> inside the "content" DIV.
Or the item id should at least be stored in a global variable - which hasn't been working either - because when I run a function from the "index.html" page to retrieve it, it displays as "undefined".
All the code is below:
index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="index_style.css">
<title>Access element of other DIV</title>
</head>
<body>
<div id="bar">This text should be replaced by the Item ID selected below</div>
<div id="content">
<object type="text/html" data="page.html" width="100%" height="100%"></object>
</div>
</body>
</html>
index_style.css
body{
margin: 0px;font-family:arial;font-size:30px;text-align:center;color:#fff;
}
#bar{
position:relative;height:100px;line-height:100px;background-color:#555c60;color:#74de90;
}
#content{
position:absolute;top:100px;bottom:0px;right:0;left:0;overflow-y:hidden;
}
page.html
<link rel="stylesheet" href="page_style.css">
<script type="text/javascript" src="main.js"></script>
<center>
This is <b>page.html</b> which has been loaded <u>inside</u> the "content" DIV<br><br>
</center>
<div class="items" onclick="use_item_id(this);" id="item1">Item 1</div>
<div class="items" onclick="use_item_id(this);" id="item2">Item 2</div>
<div class="items" onclick="use_item_id(this);" id="item3">Item 3</div>
page_style.css
body{font-family:arial;font-size:30px;color:#fff;background-color:#1b1e4b;text-align:center;}
.items{cursor:pointer;}
.items:hover{color:#ff0000;}
main.js
function use_item_id(selected)
{
current_item = selected.getAttribute("id");
document.getElementById('bar').innerHTML = current_item;
alert(current_item);
}
The line document.getElementById('bar').innerHTML = current_item; in "main.js" seems to be the problem and I can't get it to work. The alert(current_item); works fine when the line above it isn't there so it's definitely getting the item id's correctly from "page.html". It's just not setting them as the innerHTML on the "index.html" page, or even storing them in a global variable to be retrieved from a function run on the "index.html" page (as mentioned above). Any code examples would be greatly appreciated.
I think it might be because the use_item_id() function is being executed from another page, so I might need some alternatives or other functions to get it to work.
It'd be great if anyone knows what the issue is. I appreciate all replies. Thanks in advance :)
You are not on the same document ... then in main.js
replace
document.getElementById('bar').innerHTML = current_item;
with
parent.document.getElementById('bar').innerHTML = current_item;
this solves your problem.
If you're trying to access variables from HTML documents it's highly recommended to use the data attribute. This is an example for a comment section:
In my item I set the data key for loading
<div class='resp-col col-12 comment-user-data'>
<div class='resp-col col-9'>
<div class="post-profile-image" style='background-image:url("<?=$user->profile_image?>")'></div>
<?=Html::a("<p class='post-user'>".$username."</p>", Url::to(['/account/'.$user->id.'/'.$user->username]))?>
</div>
<div class='resp-col col-3'><button class='reply-to' data-assoc-id='<?=$model->id?>' data-assoc-name='<?=$username?>'><i class="material-icons">reply</i></button></div> <-- set the data-assoc-id
</div>
<div class='resp-col col-12 comment-content-data'>
<?=$model->content?>
</div>
jQuery to load data key
$('.reply-to').on('click',function(){
$('#submit-comment').data('assoc-id', $(this).data('assoc-id'));
$('#comment-content').val('#'+$(this).data('assoc-name')+' ');
$('.base-modal').animate({
scrollTop: $("#comment-content").offset().top
}, 2000);
if($('#comment-content').css('display') == 'none'){
toggleCommentVisibility();
}
});

ContentTools.js getting me nowhere

I recently came across ContentTools.js and i thought that might be nice addition to the site im working on. Going through getting started/tutorials gets me nowhere - script is not working however I look at it.
Copying exact same scripts from author page or running it back from master bin works but implementing to actual website fails.
The only thing that worked for me (on empty html page) was that script loaded editable fields erasing it's content either saved or canceled edit (if that makes and sense to you).
$(document).ready(function() {
window.onload = function() {
var editor;
editor = ContentTools.EditorApp.get();
editor.init('.editable', 'data-name');
editor.bind('save', function(regions) {
var xhr, payload, name;
this.busy(true);
payload = new FormData();
for (name in regions) {
if (regions.hasOwnProperty(name)) {
payload.append(name, regions[name]);
}
}
function onStateChange(ev) {
if (ev.target.readyState == 4) {
editor.busy(false);
if (ev.target.status == '200') {
new ContentTools.FlashUI('ok');
} else {
new ContentTools.FlashUI('no');
}
}
}
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', '/save-my-page');
xhr.send(payload);
});
}).call(this);
<link href="http://getcontenttools.com/styles/content-tools.css" rel="stylesheet" />
<script src="http://getcontenttools.com/scripts/content-tools.js"></script>
<!DOCTYPE html>
<html>
<body>
<p class="editable" data-name="c1">asd</p>
<p class="editable" data-name="c2">123</p>
<p class="editable" data-name="c3">asd123</p>
<div class="ct-app">
<div class="ct-widget ct-ignition ct-ignition--ready ct-widget--active">
<div class="ct-ignition__button ct-ignition__button--edit"></div>
<div class="ct-ignition__button ct-ignition__button--confirm"></div>
<div class="ct-ignition__button ct-ignition__button--cancel"></div>
<div class="ct-ignition__button ct-ignition__button--busy"></div>
</div>
</div>
</body>
</html>
Ofc all libraries are loaded and there is no js errors. It just doesn't work.
First off, you have error in your code, some brackets are not aligned, also you should have one div element around your p elements and init editor around it, in this case it will init editor for each p, here is fiddle http://jsfiddle.net/zx4sw47L/
P.S. There is a problem with loading fonts, because of cross-domain issue, but example is working.
I'm also starting using getContentTools.
From what I understand you have some errors in your HTML markup and you're missing another js file to init getContentTools
<!DOCTYPE html>
<html>
<head>
<link href="http://getcontenttools.com/styles/content-tools.css" rel="stylesheet" />
<script src="http://getcontenttools.com/scripts/content-tools.js"></script>
<script src="/path/to/editor.js"></script>
</head>
<body>
<div data-editable data-name="c1">
<p class="editable">asd</p>
</div>
<div data-editable data-name="c2">
<p class="editable">123</p>
</div>
<div data-editable data-name="c3">
<p class="editable">asd123</p>
</div>
<!-- this should be deleted as it is generated by getContentTools -->
<!--
<div class="ct-app">
<div class="ct-widget ct-ignition ct-ignition--ready ct-widget--active">
<div class="ct-ignition__button ct-ignition__button--edit"></div>
<div class="ct-ignition__button ct-ignition__button--confirm"></div>
<div class="ct-ignition__button ct-ignition__button--cancel"></div>
<div class="ct-ignition__button ct-ignition__button--busy"></div>
</div>
-->
</body>
</html>
The editor.js file should look like this to start
window.addEventListener('load', function() {
var editor;
});
Hope this helps

rendering xml and html tags in a code snippet HTML

simply,how to render code snippet with <html> tags like this
<div id="container">
<div id="header_area"><tiles:insertAttribute name="header" /></div>
<div id="body_area"><tiles:insertAttribute name="body" /></div>
<div id="sidebar_area"><tiles:insertAttribute name="sidebar" /></div>
<div id="footer_area"><tiles:insertAttribute name="footer" /></div>
</div>
i found this code.but it adds endtag to all />
function encodePreElements() {
var pre = document.getElementsByTagName('pre');
for(var i = 0; i < pre.length; i++) {
var encoded = htmlEncode(pre[i].innerHTML);
pre[i].innerHTML = encoded;
}
};
function htmlEncode(value) {
var div = document.createElement('div');
var text = document.createTextNode(value);
div.appendChild(text);
return div.innerHTML;
}
so above code will be like this
<div id="container">
<div id="header_area"><tiles:insertattribute name="header"></tiles:insertattribute></div>
<div id="body_area"><tiles:insertattribute name="body"></tiles:insertattribute></div>
<div id="sidebar_area"><tiles:insertattribute name="sidebar"></tiles:insertattribute></div>
<div id="footer_area"><tiles:insertattribute name="footer"></tiles:insertattribute></div>
</div>
.innerHTML renders correctly in javascript alert. so how can i render code snippet like first? what is the easy way to do this process?
OK, so I assume that in your question, the first quoted block is embedded inside a <pre> element, like this:
<pre>
<div id="container">
...
</div>
</pre>
And you are trying to convert that so that it becomes:
<pre> <div ... </pre>
The problem is that when the page is loaded, the contents of <pre> is loaded into the DOM. When you get the value of pre[i].innerHTML, it returns you a value that accurately represents the DOM state, but is not the same as your original HTML.
If you want to preserve the exact HTML used in the page, you need to encode that HTML when you generate the page. By the time any JavaScript has access to the content, it's too late - the original HTML is gone, and all you have left is the DOM contents.

JavaScript - iframe inside document: getElemById()

I have the following page code:
<html>
<body>
<div id="AAA"> SOME CODE </div>
<div>
<iframe>
<html>
<div id="AAA"> SOME CODE </div>
<div id="myDiv"> MORE CODE </div>
</html>
</iframe>
<iframe>
<html>
<div id="AAA"> SOME CODE </div>
<div id="myDiv2"> MORE CODE </div>
</html>
</iframe>
</div>
</body>
</html>
Now, the fun part.
I can put my hands on the div "myDiv". Then I want to modify the content of div "AAA", the one that is in the same iframe.
However if I do
myDiv.ownerDocument.getElementById("AAA")
I get the element outside the iframe - notice there are three elements with id="AAA"...
My question is, given an element, how can I put my hands on its containing iframe, and not on the most top level document?
Any help is appreciated.
Out of my sleeve, try such function:
function GetTopElement(child) {
var parent = child.parentNode;
while (parent) {
var node = parent.nodeName.toLowerCase();
if (node == "body" || node == "html")
break;
parent = parent.parentNode;
}
return parent;
}
//usage:
var topLevel = GetTopElement(myDiv);
topLevel.getElementById("AAA")...
Use jQuery: $('iframe').contents().find('#123')
Can you not use the following?
first_iframe = document.getElementsByTagName('iframe')[0];
first_iframe.contentWindow.document.getElementById('123')
Then you can reference sucesive iframes:
first_iframes_child = first_iframe.document.getElementsByTagName('iframe')[0];
...
Though I'd advise to your company to use jQuery/Prototype and not use iframes, it'll probably make your life easier.

Categories