Javascript DOM failing when moving a CKEditor node - javascript

I need to be able to swap CKEditor rich text areas throughout my webpage. My current script works great when there's no CKEditor applied, but does not successfully move the text area (and entered text) when CKEditor is applied. Here's some code(it needs ckeditor to work):
<html>
<head>
<title>Sample - CKEditor</title>
<script type="text/javascript" src="/ckeditor/ckeditor.js"></script>
</head>
<body>
<form method="post">
<p>
My Editor:<br />
first link
<textarea name="editor1"><p>Initial value.</p></textarea>
<script type="text/javascript">
CKEDITOR.replace( 'editor1' );
</script>
</p>
<p>
My Editor2:<br />
<textarea name="editor2"><p>Initial value2.</p></textarea>
<script type="text/javascript">
CKEDITOR.replace( 'editor2' );
</script>
</p>
<p>
<input type="submit" />
</p>
</form>
</body>
</html>
<script>
function swap(from, to){
if(from && to){
var parent = from.parentNode;
var t;
if(parent){
t = parent.removeChild(from);
parent.insertBefore(t, to);
t = null;
}
delete(t);
delete(parent);
}
}
</script>
If you comment out the CKEDITOR.replace() calls, there's no problem doing the swap. Any suggestions for how I can fix this? Thanks.

Turns out it's a bug. http://cksource.com/forums/viewtopic.php?t=18417

You have to destroy instances do your dom move and then apply CKEDITOR again
something like
var target = $( evt.target ).closest('.root');
var next = target.next();
var cke = target.find('.cke' ).attr('id')
cke = cke.replace('cke_','');
CKEDITOR.instances[cke].destroy();
var cke = next.find('.cke' ).attr('id')
cke = cke.replace('cke_','');
CKEDITOR.instances[cke].destroy();
next.after(target);
CKEDITOR.replace( $( 'textarea' , target)[0] ,{height: '250px'});
CKEDITOR.replace( $( 'textarea' , next)[0] ,{height: '250px'});

Here is my method, using jQuery.
My context: I want to move "div1" after "div2". Each DIV contains a textarea with CKEditor.
<div id="div1"><textarea id="txt1">Bla bla</textarea></div>
<div id="div2"><textarea id="txt2">Lorem ipsum</textarea></div>
<script>
CKEDITOR.replace('txt1');
CKEDITOR.replace('txt2');
</script>
Then, to move "div1" after "div2":
<script>
var current = $('#div1');
var next = current.next();//Same as $("div2")
//Remove instance of CKE
//but first, get the data from the wysiwyg editor
//(what you have typed can be lost)
var CKEinstance1 = CKEDITOR.instances['txt1'];
$('#txt1').html(CKEinstance1.getData());
CKEDITOR.remove(CKEinstance1);
//Also remove the wysiwyg from the DOM
//Its ID is always prefixed by "cke_" and followed by the textarea ID
$('#cke_txt1').remove();
//Move Div1 after Div2
current.insertAfter(next);
//Rebind CKE to txt1
CKEDITOR.replace('txt1');
</script>

Related

Unable to get text from ace.js-div in express.js

I'm using ace.js(https://github.com/ajaxorg/ace) to create a snippet-editor. The html looks like this:
<div id="editor" name="editor">{{ text }}</div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js"></script>
<script>
var editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/javascript");
</script>
When I've changed the text, I would like to save to a mongoose-db. But I'm not able to get the text from the editor in my post-request. How do I get the text from the div when I call the save-request?
router.route("/home/save/:id")
.post(function(request, response) {
console.log(request.body.editor) // -> undefined
console.log(request.body) // -> {}
});
Sorry for the perhaps fussy question. Had a hard time explaining the problem. But if anyone for some reason get in the same situation, I solved it by making a kind of a lazy solution.
I took inspiration from https://jsfiddle.net/deepumohanp/tGF6y/ and got the text from the ace-div and placed it in an input. Then I just got the input from the next request:
{{> nav }}
<div id="editor">{{ text }}</div>
<form action="/home/save/{{ this.sessionId }}" method="post">
<input type="text" value="" name="content" id="content">
<button>Save</button>
</form>
<script src="http://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js"></script>
<script>
var textarea = document.querySelector("#content");
var editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.getSession().setMode("ace/mode/javascript");
console.log(textarea.value);
console.log(editor.getSession().getValue());
editor.getSession().on("change", function () {
textarea.value = editor.getSession().getValue();
});
textarea.value = editor.getSession().getValue();
</script>
That way, the request.body.content returned with the text:
router.route("/home/save/:id")
.post(function(request, response) {
console.log(request.body.content) // -> text
});

Rendering MathJax updated with .html()

jsfiddle example: https://jsfiddle.net/3qu846tu/
I'm trying to update MathJax-math by means of .html(), however, it seems my code isn't working. My current code looks somewhat like this, but it outputs "1+2=3" unrendered:
$$\class{x}{2}+\class{y}{2}=\class{z}{5}$$
<script>
$( '.x' ).html( '1' );
$( '.y' ).html( '2' );
$( '.z' ).html( '3' );
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
</script>
I've tried different commands, but none seems to work. ["Rerender", MathJax.Hub] just renders "2+2=5", so it seems like the .html() is reset:
<script>
MathJax.Hub.Queue(["Rerender",MathJax.Hub]);
</script>
The wanted result would look somewhat like this (js omitted), where \class{x}{} (and others) may appear more than once in different places:
<span>You have chosen \(\class{x}{}\) and \(\class{y}{}\)</span>
$$\class{x}{}+\class{y}{}=\class{z}{}$$
Is there any way of rendering "1+2=3" this way? $( '.x' ) may be changed a number of times, not just once.
Frank, use the following code:
HTML:
<html>
<head>
<script
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML">
</script>
</head>
<body>
<div id="formula"></div>
A: <input type="text" id="valueA">
B: <input type="text" id="valueB">
C: <input type="text" id="valueC">
<p><input type="button" value="Update" onclick="DynamicMJ.update()" /></p>
<script>
var DynamicMJ = {
formula: document.getElementById("formula"),
update: function () {
var a = document.getElementById("valueA").value;
b = document.getElementById("valueB").value;
var c = document.getElementById("valueC").value;
var tex = "\\frac{"+a+"}{2}+ \\frac{"+b+"}{2} = \\frac{"+c+"}{5}";
this.formula.innerHTML = "\\["+tex+"\\]";
MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.formula]);
}
};
DynamicMJ.update();
</script>
</body>
</html>
EXPLANATION:
You need to use an HTML element(div in this example) in order to write the values, and then you can insert the values of the textboxes directly into the formula.
Hope this helps!

Can't display language variables in javascript code using mustache.js

I'm trying to handle translations with Mustache.js and it works fine for some part of the code but not for another part.
<script>
function MyFunction() {
// If a submit button is pressed, do some stuff and run this function to display the result
var tmpText = "";
tmpText = "<b>{{someTextInJSfunction}}</b>"; // this is NOT OK
document.getElementById("totalText").innerHTML = tmpText;
}
</script>
</head>
<body>
<div id="sampleArea">
</div>
<script id="personTpl" type="text/template">
<span id="totalText"></span></p>
<b>{{ImpNotice}}</b> {{Contact}} // this is OK
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="js/mustache.js"></script>
<script>
$( document ).ready(function() {
var lang = 'en_us';
$.getJSON('json/'+lang+'.json', function(data) {
var template = $('#personTpl').html();
var html = Mustache.to_html(template, data);
$('#sampleArea').html(html);
});
});
</script>
When I click a Submit button, my JS function is called and depending on some calculation, some text should be displayed in the page. This is the part that doesn't work, {{someTextInJSfunction}} is displayed instead of the actual content of {{someTextInJSfunction}}.
The content of {{ImpNotice}} and {{Contact}} is correctly displayed because I assume the variables are located in the <script id="personTpl"> tags.
I'm not sure how to fix it for the variables located in my JS functions, such as {{someTextInJSfunction}}.

Referencing elements by 'class' and not 'id'

I am trying to reference elements (to get pieces of text) in a news website and display them in a simple way.
I watched a YouTube tutorial about referencing elements and it referenced paragraphs using 'getElementById.'
The website I want to use doesn't use 'Id=' very much, it mostly uses 'class=' so I cannot use this same method.
I tried swapping the above 'getElementById' for 'getElementsByClassName' however I am getting the answer 'undefined.'
Code:
<html lang="en">
<body>
<p class="para1" > this is the 1st paragraph </p>
<p> <br/> </p>
<p> <br/> </p>
<p> <br/> </p>
<p class="para2" > this is the 2nd paragraph </p>
</body>
</html>
<script type="text/javascript">
var input=document.createElement("input");
input.type="button";
input.value="Check";
input.onclick = showAlert1;
input.setAttribute("style", "font-size:18px;position:absolute;top:100px;right:40px;");
document.body.appendChild(input);//Placement of check button on website;
function showAlert1()
{
alert(document.getElementsByClassName('para2').innerHTML);
}
</script>
getElementsByClassName returns a collection of elements(like an array). So you need to access those using indexes like this:
document.getElementsByClassName("someClass")[0];
//Or if you want to access all
var len = document.getElementsByClassName("someClass").length;
for(var i=0;i<len;i++){
//access like document.getElementsByClassName("someClass")[i]
}
In your case
document.getElementsByClassName('para2')[0].innerHTML
you have to add the script after html tag.
<div class="increased">hi</div> <!-- first specify the tag-->
<script type="text/javascript"> <!-- then call in script-->
var i = 23;
var elems=document.getElementsByClassName("increased");
for(var k = 0; k < elems.length; k++) {
elems[k].style.size = '100px';
}
</script>

How to create an element in JavaScript, under a specific HTML tag

I want to create a paragraph element from JavaScript, but I want it to be placed under a certain tag in HTML. How would I do this?
Try with this.
var element = document.createElement("p"); //div,span,h1
element.appendChild(document.createTextNode('the text you want if you want'));
document.getElementById('theElementToAppend').appendChild(element);
<html>
<head>
<title>appendChild() Example</title>
<script type="text/javascript">
function appendMessage() {
var oNewP = document.createElement("p");
var oText = document.createTextNode("www.java2s.com");
oNewP.appendChild(oText);
document.body.appendChild(oNewP);
}
</script>
</head>
<body onload="appendMessage()">
</body>
</html>

Categories

Resources