I am trying to get the formatted text from a contenteditable='true' div to send to my server.
I used to use a textarea and when you get the value of a textarea it preserves white space and line breaks, but when using a contenteditable div even when using styles such as the following I can not get the properly formatted text:
white-space: pre-wrap;
word-wrap: break-word;
For example if I type this into my div:
"a
aa
asdf"
I will get this out with textContent:
"a aaasdf"
Is there any way to get formatted text out of a contenteditable div like a textarea?
Use .innerHTML to get the linebreaks too.
Readup: .innerHTML | MDN
Working Code Snippet:
document.getElementById('copy').addEventListener('click', function(){
var text = document.getElementById('input').innerHTML;
document.getElementById('output').innerHTML = text;
});
div{
width: 200px;
height: 200px;
border: 1px solid black;
display: inline-block;
vertical-align: top;
}
<div contenteditable='true' id="input">Enter something funny<br>;)</div>
<button id="copy">Copy Text</button>
<div id="output">Text will be copied here.</div>
Example from: Extracting text from a contentEditable div
function getContentEditableText(id) {
var ce = $("<pre />").html($("#" + id).html());
if ($.browser.webkit)
ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
if ($.browser.msie)
ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; });
if ($.browser.mozilla || $.browser.opera || $.browser.msie)
ce.find("br").replaceWith("\n");
return ce.text();
}
Or:
$.fn.getPreText = function () {
var ce = $("<pre />").html(this.html());
if ($.browser.webkit)
ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
if ($.browser.msie)
ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; });
if ($.browser.mozilla || $.browser.opera || $.browser.msie)
ce.find("br").replaceWith("\n");
return ce.text();
};
This require jQuery, though.
When you enter content into a contenteditable element, this auto-generates HTML nodes within the target element.so you need to access its .innerHTML property and treat the content as HTML, not plain text
You can access this HTML content using the .innerHTML property, or you can use .innerText, which returns plain text but preserves the formatting as shown in #Rahul Desai's answer and in this blog post:
document.getElementById('getText').onclick = function () {
console.log(document.getElementById('edit').innerHTML);
};
<div id='edit' contenteditable='true'>Type here</div>
<input id='getText' type='button' value='Get Text' />
If I enter
Hello
how
are you
into that div and then click the button, the console shows:
<p>Hello</p><p>how</p><p><br></p><p>are you</p>
document.getElementById('getText').onclick = function () {
console.log(document.getElementById('edit').innerHTML);
};
<div id='edit' contenteditable='true'>Type here</div>
<input id='getText' type='button' value='Get Text' />
Related
I have a pagaraph (p) appended to a div, that shows <textarea> value, and it works well.
The <textarea> supposed to be a part of a page that allows the users to add new lines to the text content, exactly like how we can type <br> for a new line in textarea.
But since they don't know how to do that I'm trying to make it easy for them by:
(typing plus sign twice ++ OR pressing Enter on the keyboard)
Both should add a <br> tag automatically while typing (onkeyup)...
var textarea = document.getElementById('textarea');
var textareaPreview = document.querySelector('.textarea-preview');
var currentText;
textarea.onkeyup = function(){
currentText = textarea.value;
var previewAsString = "<p class='p-preview'>" + currentText + "</p>"
textareaPreview.innerHTML = previewAsString;
};
textarea {
width: 300px;
height: 80px;
resize: vertical;
}
<div class="block">
<textarea id="textarea" placeholder="Type here.."></textarea>
</div>
<div class="block">
<div class="textarea-preview"></div>
</div>
It sounds like all you need is to replace ++ and newlines with <br>:
var textarea = document.getElementById('textarea');
var textareaPreview = document.querySelector('.textarea-preview');
var currentText;
textarea.onkeyup = function(){
currentText = textarea.value;
var previewAsString = "<p class='p-preview'>" + currentText.replace(/\+\+|\n/g, '<br>') + "</p>"
textareaPreview.innerHTML = previewAsString;
};
textarea {
width: 300px;
height: 80px;
resize: vertical;
}
<div class="block">
<textarea id="textarea" placeholder="Type here.."></textarea>
</div>
<div class="block">
<div class="textarea-preview"></div>
</div>
Find html character and reduce size, not sure what the function is to do this?
jQuery("body").children().each(function () {
jQuery(this).html( jQuery(this).html().match("•").attr('style', "font-size:'9px'"));
});
As commented,
You will have to set style to element and not string.
To do this, you will have to fetch the string and then wrap matched string in an element with necessary style.
In your code jQuery(this).html().match("•").attr('style', "font-size:'9px'"), .match will return an array of matched values. They are still string and not HTML Element.
Sample
document.getElementById("btn").addEventListener("click", handleClick);
function handleClick(){
var input = document.getElementById("input").value;
if(!input) return;
var p = document.querySelector("p");
var parsed = p.innerHTML.replace(new RegExp(input, "gi"), function(t){
return "<span class='highlight'>" + t + "</span>"
});
p.innerHTML = parsed;
}
.highlight{
font-size: 12px;
border-bottom: 1px dashed gray;
}
span{
font-size: 16px;
}
<p> This is a sample Text</p>
<input type="text" id="input" />
<button id="btn">Update Style</button>
I would like to display a text copied from a site, for example Wikipedia, in a div. This text has to be strictly without the tags that the computer copies with the text from wikipedia.
I think that the solution is to set a sort of formatting of the text but I don't know.
This is how it should be (Press OK). But I don't want to paste the text in the code, I have to paste the text in the textarea.
In fact if you try to paste something from Wikipedia in the textarea of this Jsfiddle you will see that the result is horrible and with all the html tags.
HTML:
<div id="faketxt" contenteditable></div>
<button id='btn'>OK</button>
<button class="fontStyle" onclick="document.execCommand( 'bold',false,null);" title="Bold Highlighted Text"><b>B</b>
</button>
<button class="fontStyle" onclick="document.execCommand( 'underline',false,null);"><u>U</u>
</button> <br>
<div id='boxes'>
</div>
CSS:
#faketxt {
-moz-appearance: textfield-multiline;
-webkit-appearance: textarea;
border: 1px solid gray;
height: 28px;
overflow: auto;
padding: 2px;
resize: both;
width: 400px;
}
.fakes{
width: 150px;
height: 300px;
font-size: 10px;
border-style: solid;
display:inline-block;
float: left;
}
#boxes{
display : flex;
display:inline-block;
}
jQuery:
$('#btn').click(function() {
var primo = document.getElementById('faketxt');
var wordLimit = 130;
var words = primo.innerHTML.replace(/(<([^>]+)>)/ig,"").split(/\s/);
if (words.length) {
var count = 0;
var div = createDiv();
var bold = false;
words.forEach(function(word) {
if (++count > wordLimit) {
count = 1;
div = createDiv();
}
if (div.innerHTML) {
div.append(' ');
}
if (word.indexOf('<b>') != -1) {
bold = true;
}
if (bold) {
$(div).html($(div).html() + '<b>' +
word + '</b>');
} else {
$(div).html($(div).html() +
word);
}
if (word.indexOf('</b>') != -1) {
bold = false;
}
});
}
});
function createDiv() {
div = document.createElement('div');
div.className = 'fakes';
document.getElementById('boxes').append(div);
return div;
}
innerHTML or jquery's $.html() will pull the content (including HTML) of an element. But textContent or jquery's $.text() will just get the text.
Instead of var words = primo.innerHTML have you tried using var words = primo.textContent or var words = $(primo).text()?
try using
words = primo.textContent.replace(/(<^>]+)>)/ig,"").split(/\s/);
instead of
words = primo.innerHTML.replace(/(<([^>]+)>)/ig,"").split(/\s/);
Rather than getting the innerHTML of the source, simply get the text content using either the javascript or JQuery text() functions.
So, given you are using jQuery, change your words variable to initialise as follows.
var words = $(primo).text().split(/\s/);
It is my sample demo:
<span style="color: blue; text-decoration: underline;">CHANGE</span>
<form>
<textarea >hello, world</textarea/>
</form>
I want to change the selected text color( selected text will be dynamic) an input field. Color change can be according to:
he : red color(if he selected)
hello : blue (if hello selected), so on.
selected color will be changed after click CHANGE text.
You can't do this in a textarea. Any text-related property will affect the whole text within the the textarea.
Following way you can change the color of text dynamically for p element.
Use contenteditable="true" to your p tag
function getText() {
if (window.getSelection) {
return window.getSelection();
} else if (document.selection) {
return document.selection.createRange().text;
}
return '';
}
document.getElementById('btnClick').addEventListener('click', function()
{
if(getText() == "hello")
document.execCommand('foreColor', false, "#ff0000")
else
document.execCommand('foreColor', false, "#0000ff")
});
<button id="btnClick">Change Color</button>
<p id="text1" contenteditable="true">hello, world</p>
This way you can check if text is hello then will change that selected text to red. Else for another text change it to blue.
You can change the condition as per your requirement.
Check my accepted answer here for more details.
Use contenteditable='true' instead of textarea
Try this:
document.getElementById('handler').addEventListener('click', function() {
document.getElementById('red').classList.add('red');
document.getElementById('blue').classList.add('blue');
});
.red {
color: red;
}
.blue {
color: blue;
}
<span style="color: blue; text-decoration: underline;" id='handler'>CHANGE</span>
<form>
<div contenteditable='true'>
<span id='red'>hello, </span>
<span id='blue'>world</span>
</div>
</form>
update your html as suggested by #rayon Dabre
HTML
<span style="color: blue; text-decoration: underline;" id='handler'>CHANGE</span>
<div contenteditable='true'>
<span id='txt'>hello, world</span>
</div>
JS
document.getElementById('txt').addEventListener('mouseup', function(e){
var selection = (window.getSelection) ? window.getSelection().toString() : document.selection.createRange().text;
this.textContent = this.textContent; //remove child tags before wrap
wrapWithTag(this, selection ? selection : "");
}, false);
var textAndColor = {//Object to update color as per selected text
"he": "red",
"hello": "blue",
"world": "yellow"
};
function wrapWithTag(stringElement, txtToWrap) {
if(!txtToWrap) {return;}
var originalTxt = stringElement.textContent;
var beforeString = originalTxt.substring(originalTxt.indexOf(txtToWrap), 0);
var AfterString = originalTxt.substring(originalTxt.indexOf(txtToWrap) + txtToWrap.length);
if(textAndColor[txtToWrap]) {
stringElement.innerHTML = beforeString + "<span id='highlight' class=' "+ textAndColor[txtToWrap] +"'>" + txtToWrap + "</span>" + AfterString;
}
}
document.getElementById('handler').addEventListener('click', function(e){
var textContainer = document.getElementById('highlight');
if(textContainer) {
textContainer.style.color = textContainer.className;
}
}, false);
I am a newbie so my question is pretty simple and straight forward.
I have a simple html text. When I click on that html text, the text should change to input field with the value retained and when the user clicks outside the text box, the input text field now should change to html text.
<div class="myText"> Hellow World </div>
Can somebody do this in jquery/Meteor. I am actually building a meteor project
You can do that with the contenteditable attribute
<div class="myText" contenteditable="true"> Hellow World </div>
<!-- Your div is now editable -->
Updated DEMO jsFiddle
$(document).ready(function() {
$('.editable').on('click', function() {
var that = $(this);
if (that.find('input').length > 0) {
return;
}
var currentText = that.text();
var $input = $('<input>').val(currentText)
.css({
'position': 'absolute',
top: '0px',
left: '0px',
width: that.width(),
height: that.height(),
opacity: 0.9,
padding: '10px'
});
$(this).append($input);
// Handle outside click
$(document).click(function(event) {
if(!$(event.target).closest('.editable').length) {
if ($input.val()) {
that.text($input.val());
}
that.find('input').remove();
}
});
});
});
In my solution you need to add class="editable" to all editable divs.
You also need to set position: relative to these divs. May be you can update my code and edit the css:
.editable {
position: relative;
}
To correctly align the input inside the div, you need to remove the border or set the .css({}) of the input to left: -1px and top: -1px. The border actually pushes the input 1px left and 1px form the top.
Try this:
$(function() {
$('div.myText').on('click', function() {
var div = $(this);
var tb = div.find('input:text');//get textbox, if exist
if (tb.length) {//text box already exist
div.text(tb.val());//remove text box & put its current value as text to the div
} else {
tb = $('<input>').prop({
'type': 'text',
'value': div.text()//set text box value from div current text
});
div.empty().append(tb);//add new text box
tb.focus();//put text box on focus
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="myText">Hello world</div>
<div class="myText">This is second</div>
Try this:
$(document).click(function() {
$('.myText').html("Hello World");
});
$(".myText").click(function(event) {
$('.myText').html("<input type='text' id='test' value='Hello World'/>");
$('#test').focus();
event.stopPropagation();
});
FIDDLE.
To do it very easily and understandable you can also make two elements instead of changing.
Working fiddle: http://jsfiddle.net/45utpzhx/
It does an onClick event and onBlur.
html
<div>
<span class="myText">Hello World</span>
<input class="myInput" />
</div>
jQuery
$(document).ready(function() {
$(".myText").click(function() {
$(this).hide();
var t = $('.myText').html();
$('.myInput').val(t);
$('.myInput').show();
});
$(".myInput").blur(function() {
$(this).hide();
var t = $('.myInput').val();
$('.myText').html(t);
$('.myText').show();
});
});
Replace the clicked element with an input with value equal to the clicked element's text
$(document).on('click', '.myText', function() {
var that = $(this);
var text = that.text();
that.wrap('<div id="wrp" />');
$('#wrp').html('<input type="text" value="' + text + '" />');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="myText"> Hellow World </div>
You can try this solution :
$('.myText').click(function(){
var m = $(this).text();
$(this).html('');
$('<input/>',{
value : m
}).appendTo(this).focus();
});
$(document).on('blur','input',function(){
var m = $(this).val();
$(this).parent().find('input').remove().end().html(m);
});
working DEMO
$('#text').on('click', function() {
$("#text").hide();
if ($("#text").text()=="Add New text"){
$('#in_text').val("");
}else{
$('#in_text').val($("#text").text());
}
$("#in_text").show();
});
// Handle outside click
$(document).click(function(event) {
if(!$(event.target).closest('.editable').length) {
if($("#text").css('display') == 'none'){
$("#in_text").hide();
if ($("#in_text").val()=="" ){
$('#text').text("Add New text");
$('#text').addClass("asd");
}else{
$('#text').removeClass("asd");
$('#text').text($("#in_text").val());
}
$("#text").show();
}
}
});
#in_text{
display:none;
}
.editable{
width:50%;
}
.asd{
border-bottom : 1px dashed #333;
}
#text{
display: inline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="editable">
<div id="text" >Text in div</div>
<input type="text" placeholder="Add New Text" id="in_text"/></div>