append strange behaviour - javascript

I have some application that adds elements to contentEditable div.
Something like this:
<div id="div" contentEditable="true"></div>
<button id='appendBtn'>append</button>
<style>
.bracket {
color: blue;
}
.template-content {
color: green;
}
#div {
border: solid 1px gray;
margin-bottom: 10px;
}
</style>
<script>
function appendContent() {
var content = "<span class='template-block'>" +
"<span class='bracket'>{</span>" +
"<span class='template-content'>param</span>" +
"<span class='bracket'>}</span>" +
"</span>";
$("#div").append(content);
}
document.getElementById ("appendBtn").addEventListener ("click", appendContent, false);
</script>
I wrote a working example in jsfiddle.
The problem is that when I click append and continue typing after added element all next text comes green. It happens because all next text pasts into last span tag (of class bracket with green color)...
<span class="bracket">}some text</span>
The solution is adding a after last closing span tag. Like this:
var content = "<span class='template-block'>" +
"<span class='bracket'>{</span>" +
"<span class='template-content'>param</span>" +
"<span class='bracket'>}</span>" +
"</span> ";
But it brings a lot of unwanted staff I have to do with the text after. How can I solve this?

Thats a default behaviour of content editable setting the pointer behind the last character inside. In Your case the pointer is set
<span class='bracket'>}--> pointer <--</span>
You could try a workaround with ​ entity (zero width space)
if you dont want the

Related

Place a button and its div with one command

Currently, I have a button class which lets me place a clickable button inside a sentence, and a div class which lets me add content to the button which I placed at the end of the paragraph containing the sentence.
This is an example of how I use them
Try to click <button class="col">THIS</button> and see what happens.
<div class="con">nice!</div>
Did you try?
When this text is displayed on the page, the two sentences are placed inside two different paragraphs, so the div object is placed between them.
Here is a snippet with the css classes and the javascript.
( function() {
coll = document.getElementsByClassName("col");
conn = document.getElementsByClassName("con");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].setAttribute('data-id', 'con' + i);
conn[i].setAttribute('id', 'con' + i);
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = document.getElementById(this.getAttribute('data-id'));
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
} )();
.col {
cursor: help;
border-radius: 0;
border: none;
outline: none;
background: none;
padding: 0;
font-size: 1em;
color: red;
}
.con {
padding: 0 1em;
max-height: 0;
overflow: hidden;
transition: .3s ease;
background-color: yellow;
}
Try to click <button class="col">THIS</button> and see what happens.
<div class="con">nice!</div>
Did you try?
I wonder if it is possible to implement a shortcut to place the two objects with one command, that is to obtain the previous example by using something like this
Try to click [[THIS|nice!]] and see what happens.
Did you try?
What I mean is that the command [[THIS|nice!]] should place the object <button class="col">THIS</button> in the same position and the object <div class="con">nice!</div> at the end of the paragraph containing the command.
Is it possible to implement such a command (or a similar one)?
EDIT
I forgot to say that the content of the button, ie what is written inside the div, should also be possible to be a wordpress shortcode, which is a shortcut/macro for a longer piece of code or text.
Using jQuery, closest() find the nearest <p> element and add <div class="con">nice!</div> after <p> element. To toggle you can use class active and add or remove .con element.
$('.col').click(function(){
let traget = $(this).closest('p');
if(traget.hasClass('active')) {
traget.removeClass('active');
traget.next('.con').remove();
} else {
traget.addClass('active');
traget.after(`<div class="con">${$(this).data('message')}</div>`);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Try to click <button class="col" data-message="Hello">THIS</button> and see what happens.</p>
<p>Did you try?</p>
You usually dont use div to type text. you use it to define areas or group items. you could obtain what youre asking for in a 1 sentence like this:
html
<h1> some random text <a class="btnID">button</> some more text<h1>
css
.btnID {
color: red;
}

Styling jQuery script output

So here’s the code
<script>
function get_price(){
var price_margin = 0.00174;
jQuery.get("https://min- api.cryptocompare.com/data/price? fsym=XRP&tsyms=USD").then(function(data){
jQuery('#xrp_price').text(function(price){
return "PRICE " + data["USD"].toFixed(5);
});
.......
That returns a value 0.45678 for e.g but I’d like to make the last 3 digits really small so just the 0.45 stands out.
I have tried changing the .text to .html and adding or but that just makes the whole value bold and not the last 3 digits. Hmmmmmm (scratches chin).
All help is greatly appreciated
Instead set .text set .html
and set the 3 first chars in span with class='bold'
and the other chars get by use data.toFixed(5).slice(3) and set another class='small'
then style in css according classes in html
var data=0.45678 ;
$('#xrp_price').html(function(price){
return "PRICE <span class='bold'>" + data.toFixed(2) + "</span> <span class='small'>"+ data.toFixed(5).slice(3) + "</span>";
});
.bold{
font-weight: bold;
}
.small{
font-size:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="xrp_price"></div>
EDIT:
You can use <small> DOM instead <span class='small'>

Perfect conversion from <div> to <br> in a WYSIWYG editor

I need to sanitize HTML in a WYSIWYG editor. The output must not contain any <div>s. All <div> elements must be replaced with <br> elements. This original text MUST render the same as the sanitized text.
This is my attempt so far (notice the unwanted extra whitespace in the output) – thanks to Nimit for the rendering containers:
let text = `<div>aoeu</div><div><ul><li>eu</li><li>a</li></ul><div><br></div></div><div>eu</div>`;
// let text = 'aoeu<ul><li>aoeu</li><ul><li>aoue</li></ul></ul><div><br></div></div></div><div><br></div><div><br></div><div><br></div><div>oe</div><div><ul><li>u</li></ul></div>'
document.getElementById("pre1").innerHTML = "<strong>With Div</strong> </br>" + text;
text = text
.replace(/<div><div>(.*)<\/div><\/div>/g, '<div>$1</div>') // meaningless directly double wrapped divs
.replace(/<div><br><\/div>/g, '<br>') // div with a br is only one newline
.replace(/<div>(?!<div>)(.*?)<\/div>/g, '$1<br>') // divs always make a newline after
document.getElementById("pre2").innerHTML = "<strong>Without Div</strong> </br>" + text;
.preContainer {
display:inline-block;
width:200px;
vertical-align:top;
}
.preContainer:first-child{
border-right:1px solid black;
}
<div class="preContainer"><pre id="pre1"></pre></div>
<div class="preContainer"><pre id="pre2"></pre></div>
So basically I can't seem to figure out how to perfectly convert from <div> to <br>. Any help much appreciated.
I think you can achieve your result with below replace script.
.replace("<div>", "<br>").replace("</div>", "");
Check below snippet, you can inspect both pre, second pre doesn't have any div tag:
function showItInPre(text){
//let text = `aoeua<div><ul><li>oe</li><li>a</li><li>oeu</li></ul><div><br></div></div><div><br></div><div><br></div><div>aoe</div><div><ul><li>u</li></ul><div><br></div></div><div><br></div><div>u</div><div><div><br></div></div><div>o</div><div><ul><li>o</li><li>o</li><li>a</li><li><br></li></ul></div>`;
document.getElementById("pre1").innerHTML = "<strong>With Div</strong> </br>" + text;
text = text
.replace(/<div><br><\/div>/ig, '<br>')
.replace(/<\/div><\/div>/ig, '<br>')
.replace(/<div>/ig, "").replace(/<\/div>/ig, "<br>");
document.getElementById("pre2").innerHTML = "<strong>Without Div</strong> </br>" + text;
}
document.getElementById("testit").addEventListener("click", function(){showItInPre(document.getElementById("textarea").value)});
.preContainer {
display:inline-block;
width:200px;
vertical-align:top;
}
#pre1{
border-right:1px solid black;
}
#textarea {
width:500px; height:50px;
}
<div><textarea id="textarea"></textarea><button id="testit">Test</button></div>
<div class="preContainer"><pre id="pre1"></pre></div>
<div class="preContainer"><pre id="pre2"></pre></div>

javascript - Why do I get a if I script ?

I having hard time to insert a single space at the end of my </span> in a document.execCommand().
document.execCommand("insertHTML", false, "<span class='own-class2'>"+"Test"+"</span>");
The reason behind this is I want the cursor to be outside the <span> after having made the insertion.
Here is a simple jsFiddle to show you what I mean:
jsFiddle
In that example, if you click the image and then write something, the text will be green. That means the text is still inside the span.
So What I want is to insert a normal space after </span>.
What I have already tried:
a space like this '</span> ' -> I get no space in Chrome.
a space like this '</span> ' -> I get </span> in Chrome
So my question is how to add a single space in order to get a result equivalent to this '</span> ' or '</span> ' and not '</span> ' ?
WHAT I GET ON THE INSPECTOR : https://ibb.co/cqCW2x
if I do :
document.execCommand("insertHTML", false, "<span class='own-class2'>"+"Test"+"</span> ");
Maybe you could use the zero width no break space character (invisible character) : \uFEFF.
The advantage of this solution is it does not create an (maybe?) unwanted visible space after the span
function Test() {
document.execCommand("insertHTML", false, "<span class='own-class2'>"+"Test"+"</span>\uFEFF");
}
#textBox {
width: 540px;
height: 200px;
border: 1px #000000 solid;
padding: 0;
overflow: scroll;
}
.own-class2 {color:green;}
<div id="toolBar">
<button height="20px" onclick="Test()" >insert a span</button>
</div>
<div id="textBox" class="textbox" contenteditable="true"></div>

contentEditable div replace url links

I have a contentEditable DIV where I would like to replace any user typed URL (by matching the string with regular expression) with blue color text wrapped inside a span tag.
However, different browsers return different results. Besides, replacing the matched text with span puts cursor at the beginning of the text.
Here is the link: jsfiddle
CSS
.class{
position:relative;
outline:none;
border:5px solid #96C;
font-size:16px;
width:500px;
height:60px;
padding:0px 2px;
word-wrap:break-word;
}
HTML
<div class='class' id='div' contentEditable='true'></div>
JavaScript
var regExUrl = /https?:\/\/([\w\d-\.]+)?[\w\d-\.]+\.{1}[\w]{1,4}(\/{1})?([a-zA-Z0-9&-#_\+.‌​~#?\/=]*)?/gi;
var div = document.getElementById('div');
div.onkeyup = function () {
if (div.innerHTML.match(regExUrl)) {
st = div.innerHTML.match(regExUrl);
div.innerHTML = div.innerHTML.replace(regExUrl, "<span style='color:blue;text-decoration:underline'>" + st[0] + "</span>");
}
}
How can I set the cursor at the end of the replaced text and continue typing with the default color (black)?
Not a direct answer but a suggestion of another way of achieving the same user experience in a simpler way:
http://jsbin.com/EZizIge/1/
var regExUrl = /https?:\/\/([\w\d-\.]+)?[\w\d-\.]+\.{1}[\w]{1,4}((\/{1})?)([a-zA-Z0-9&-#_\+.‌​~#?\/=]*)?/gi;
var div = document.getElementById('div');
div.onkeyup = function(){
if(div.innerHTML.match(regExUrl)){
$("div").addClass("link");
} else {
$("div").removeClass("link");
}
}
With css:
.link{
text-decoration: underline;
color: blue;
}

Categories