Javascript button ceases to write to texarea once user has added text - javascript

I am trying to make a simple text editing box so that I can eventually post text to another section of a website. I'm attempting to make buttons to make text bold, italicized, add a code box etc, (hence insertAdjacentHTML not insertAdjacentText) but I decided to just start making sure I could get plain text to print to a textarea.
I have achieved this easily but now my question becomes how do I make it so that the button still affects the text area after a user has added text to it? the code below will happily type out "hello"'s up until you click on the textarea, and from that point on it refuses to and I can't figure out why.
window.hello = function(textarea) {
var obj = document.getElementById("text");
obj.insertAdjacentHTML('beforeend', 'hello');
}
<body>
<button onclick="hello()">hello</button>
<form>
<p></p>
<textarea id="text"></textarea>
</form>
</body>

As you can read from MDN a textarea can contain only Character data.
This is the reason because you cannot use insertAdjacentHTML and instead you can use the value.
If you need to add text in bold or ... you can use a contenteditable div element.
The snippet:
window.helloDiv = function() {
var obj = document.getElementById("textDiv");
obj.insertAdjacentHTML('beforeend', 'hello');
};
window.helloTxtArea = function() {
var obj = document.getElementById("textTxtArea");
obj.value += 'hello';
}
div {
width: 300px;
height: 100px;
border: 1px;
border-style: solid;
}
textarea {
width: 300px;
height: 100px;
margin-top: 10px;
}
<button onclick="helloDiv()">helloDiv</button>
<button onclick="helloTxtArea()">helloTextArea</button>
<form>
<p></p>
<div id="textDiv" contenteditable="true"></div>
<textarea id="textTxtArea" contenteditable="true"></textarea>
</form>

Related

How Can I Copy Text From Hidden Textarea to Clipboard?

I have a hidden text area like this with some values set:
<textarea style="display: none;" id="element_html"></textarea>
On click of a button, I try to copy its content to clipboard using this JS code:
$('#element_html').select();
document.execCommand('copy');
It works only if the text area is visible. How can I copy the hidden text area content to clipboard?
opacity: .01;
does the job. You should combine it with:
height:0;
position:absolute;
z-index: -1;
Do not use pointer-events:none; as it will stop .select() from working, as well.
function copyContents() {
$('#element_html').select();
document.execCommand('copy');
}
#element_html {
position: absolute;
opacity: .01;
height: 0;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="element_html">Which textarea?</textarea>
<button onclick="copyContents()">Copy</button>
<input type="text" placeholder="Paste it here...">
You can create a temporary input element that is appended to the body, set it its value to the textarea's content and then use it for the copy function. Then you remove it from the dom. This will work - irrespective of the display state of the text area.
Note that I did not create this method - I got it from somewhere (possibly another SO answer) and have used it since in a number of instances.
function copyContents() {
var $temp = $("<input>");
var content = $('#element_html').text();
$("body").append($temp);
$temp.val(content).select();
document.execCommand("copy");
$temp.remove();
}
#element_html {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="element_html">Hidden textarea content</textarea>
<button onclick="copyContents()">Click to copy</button>
<input type="text" placeholder="Paste here">
The problem is that since the textarea has its display property set to none, its content can not be selected. You can absolutely position the textarea to the left with position: absolute and left: -9999px. You should also add z-index: -9999 so it will always be placed under other elements (unless they have a lower z-index).
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea style="position: absolute; left: -9999px;" id="element_html">Text inside textarea</textarea>
<button onClick="copy()">
Copy
</button>
<p/>
<textarea placeholder="Paste text here..."></textarea>
<script>
function copy(){
$('#element_html').select();
document.execCommand('copy');
}
</script>
The Following codes worked for my problem. paste the js code inside your script tag/file.also add the css style to hide the textarea. Also, I found the following ideas through stackoverflow forum so all credit to those folks.
HTML code:
function cpy(n)
{
var id=n;
var txt=document.getElementById(id);
txt.select();
document.execCommand("copy");
};
/* The Following Code is to Hide textarea from The user view area */
textarea{
opacity: 0;
position: absolute;
z-index: -9999;
pointer-events: none;
}
<!-- readonly attribute is used because i found that in mobile devices, keyboard poped-up while i clicked the button to copy text-->
<textarea id="c1" readonly>
This is a text from textarea One.
</textarea><br>
<!--The cpy(this.id) passes button id to js function-->
<button id="c1" onclick="cpy(this.id)">Copy</button>
<input type=text placeholder="Paste Here to test">

Replace text inside HTML leaving other HTML intact with vanilla javascript

I'm trying to write pure javascript function to replace the text "Passed" to "Completed". The HTML inside the div#prompt should remain in tact and is variable. Here is the HTML -
<div id="prompt">
Passed
Take a survey
<button type="button" data-behavior="hide.prompt"></button>
</div>
I tried replacing text but that doesn't seem to be working
var text = document.getElementById('prompt').textContent;
text.replace("Passed", "Completed");
Also tried this -
var text = document.getElementById('prompt').innerHTML;
text.replace("Passed", "Completed");
What am I doing wrong? Appreciate the help!
replace does not mutate the string, it returns a new one. Strings are immutable.
var text = document.getElementById('prompt');
text.textContent = text.textContent.replace("Passed", "Completed");
Actually your element contains a text node that you can override:
document.getElementById('prompt').childNodes[0].textContent = "Completed";
Instead of replacing text, how about toggle a class on the outer div.
With that you can also customize its HTML as well.
Stack snippet
.prompt::before {
content: 'Passed';
}
.prompt.hidden::before {
content: 'Completed';
}
.prompt.hidden button {
display: none;
}
/* demo styles */
.prompt button { padding: 5px 20px; }
hr { margin: 20px 0; }
<div class="prompt">
Take a survey
<button type="button" data-behavior="hide.prompt"></button>
</div>
<hr>
<div class="prompt hidden">
Take a survey
<button type="button" data-behavior="hide.prompt"></button>
</div>

Adding a newline character and display input from a textarea

I have a text are in a form. I used this code
$('textarea').keypress(function (event) {
if (event.which == 13) {
event.preventDefault();
var s = $(this).val();
$(this).val(s + "<br />");
}
});
to allow users to go the next line using the enter button. I tried using both and \n
In the form, the user is able to go to a new line. However, when the input is displayed on a page, the new line doesn't show, and any text after the new line does not appear. However, it is still there- if you go to edit the form it stills shows the text typed after you click enter. I added
white-space: pre-wrap;
into the css for text boxes in my css file trying to resolve the issue. However, it still did not work. Any suggestions/ input on how to resolve this?
You don't want to insert the <br/> tag as they type. You really don't want to do anything to their text as they type. If you want to maintain their line breaks, you can convert them to <br/> tags before you inject them into an element.
$('#text').keyup(function(event) {
var text = $("#text").val();
text = text.replace(/(?:\r\n|\r|\n)/g, '<br />');
$("#result").html(text);
});
textarea {
min-width: 200px;
min-height: 200px;
float: left;
}
#result {
float: left;
border: 1px solid red;
padding: 10px;
margin-left: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="text" placeholder="Type in here"></textarea>
<div id="result"></div>

HTML Elements inside Contenteditable?

I have a contenteditable tag, and I want my users to be able to type code into it. However, when I type into the contenteditable tag, my code shows up as text rather than an actual element. Is there a way for a user to create a full, working HTML element in a contenteditable box? I know it is possible for the client to insert code using javascript, but what about users who do not have access to javascript? How could users get code such as buttons inside a contenteditable box?
<p contenteditable="true">Try typing code in here as user, code will only be text...</p>
Is there a javascript way to accomplish this without JQUERY?
EDIT
I spent a long time searching for answers on Google, but nothing came up. The best solution I've gotten at this point has been #Dekel's comment on CKEditor. If there is another solution, I want to hear it. If there isn't, I'm sticking to CKEditor. I don't have much time, so I need a solution fast.
MORE EDIT =D
I recently developed my own answer to my question by looking at #Brandon's .replace answer (which only worked for client-coding, not user-coding) and modifying it to work with user-coding.
This isn't pretty, but you could make it work if you are looking to add HTML only. Otherwise an inline editor might work best.
var el = document.querySelector('p')
el.addEventListener('blur', function() {
var map = {amp: '&', lt: '<', gt: '>', quot: '"', '#039': "'"}
var html = this.innerHTML.replace(/&([^;]+);/g, (m, c) => map[c]);
this.innerHTML = html;
});
<p contenteditable="true">Try typing <b>code</b> in here as user, code will only be text...</p>
This answer is similar to #Brandon's idea, but is much more simple.
https://jsfiddle.net/azopqLe4/
<iframe width="100%" height="300" src="//jsfiddle.net/azopqLe4/embedded/js,html,result/dark/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
function convertit() {
var convet = document.getElementById("convet");
var text = convet.innerHTML;
var newtext;
newtext = text.replace(/</g, "<").replace(/>/g, ">");
convet.innerHTML = newtext;
}
//this version runs onrightclick =D
<p contenteditable="true" oncontextmenu="convertit();" id="convet">
Type some code here, then right-click... =D
</p>
In the second snippet, I typed <b>Test</b>, right-clicked it, and it became Test! My answer works through simple array replacement methods, although it is frustrating and time-wasting to keep right-clicking all the time. To prevent the actual contextmenu from popping up, just add .preventDefault().
You can't insert code, but you can insert DOMElements with JS. No need for jQuery.
var element=document.createElement("button");
element.innerHTML="Hello";
document.getElementById("yourContentEditable").append(element);
The idea with this would be to have a button to prompt for the code and insert it. Something like this:
(It is very ugly and buggy but it's just an example I just wrote)
var editorSelection=null;
function openCodePopup() {
//Store cursor position before editor loses focus
editorSelection=getEditorSelection();
//Open the popup
document.querySelector("#codePopup").style.display="block";
var ta=document.querySelector("#userCode");
ta.value="";
ta.focus();
}
function closeCodePopup() {
document.querySelector("#codePopup").style.display="none";
}
function insertCode() {
var code=document.querySelector("#userCode").value;
closeCodePopup();
if(code=="") return;
insertIntoEditor(html2dom(code));
}
function getEditorSelection() {
//TODO make crossbrowser
//TODO (VERY IMPORTANT) validate if selection is whitin the editor
var sel=window.getSelection();
if(sel.rangeCount) return sel.getRangeAt(0);
return null;
}
function insertIntoEditor(dom) {
if(editorSelection) {
editorSelection.deleteContents();
editorSelection.insertNode(dom);
} else {
//Insert at the end
document.querySelector("#editor").append(dom);
}
}
function html2dom(code) {
//A lazy way to convert html to DOMElements, you can use jQuery or any other
var foo=document.createElement('div'); //or you could use an inline element
foo.contentEditable=false;
foo.innerHTML=code;
return foo;
}
#editor {
height: 180px;
overflow: auto;
border: 1px solid #ccc;
}
#toolbar {
position: relative;
}
#codePopup {
position: absolute;
left: 10px;
top: 15px;
background-color: #fff;
border: 1px solid #ccc;
padding: 5px;
display: none;
}
#userCode {
display: block;
width: 200px;
height: 100px;
}
<div id="toolbar">
<button onclick="openCodePopup()"></></button>
<div id="codePopup">
<textarea id="userCode" placeholder="Type code here"></textarea>
<button onclick="insertCode()">Ok</button>
<button onclick="closeCodePopup()">Cancel</button>
</div>
</div>
<div contenteditable="true" id="editor"></div>
With the same idea you could create other options to convert element (example, text->link, etc.).

using a div contentEditable innerText and innerHTML neither have newlines to and from database

I'm using a div for people to enter text and then I tried saving
div.innerText
and
div.innerHTML
to my database but when I bring it back from the database and put it back into the div all of the carriage returns or newlines are gone
innerHTML to database
a
b
c
//in database like this <div>a</div><div></div><div>b</div><div></div><div>c</div>
innerText to database
a
a
a
a
a
a
//how it stored in database aaaaaa
if you could tell me how to handle this situation I would appreciate it greatly thank you for your time
div.innerHTML creates an HTML output of your new lines using <div> containers.
Therefore the line breaks will be "replaced".
div.innerText uses the "invisible" character \n or \r\n to mark new lines and it is possible that they are not shown in your database. You can however replace them by <br> tags to see if they are there.
document.getElementById("output").addEventListener("click", function() {
console.log("HTML:");
console.log(document.getElementById("text").innerHTML);
console.log("Text:");
var text = document.getElementById("text").innerText;
console.log(text.replace(/(?:\r\n|\r|\n)/g, '<br>'));
});
#text {
background-color:#FAFAFA;
border: red solid 1px;
height:150px;
width: 200px;
}
<button id="output">
Show in console
</button>
<div id="text" contenteditable>
</div>
console.log(text.replace(/(?:\r\n|\r|\n)/g, '<br>')); replaces all different kinds of possible new lines into <br> tags.
You can substitute <textarea> element for <div> with contenteditable attribute set. Encode, decode .value of textarea using encodeURIComponent(), decodeURIComponent() or format data as JSON utilizing JSON.stringify(), JSON.parse()
var button = document.querySelector("button")
var textarea = document.querySelector("textarea");
button.onclick = function() {
var value = textarea.value
console.log(encodeURIComponent(value)
, decodeURIComponent(value)
, JSON.stringify(value)
, JSON.parse(JSON.stringify(value))
);
}
textarea {
border: 1px solid navy;
width: 300px;
height: 200px;
}
You can use
<button>click</button><br>
<textarea></textarea>

Categories