Related
I'm trying to store the html element of a table which includes textarea tags also.
I need to store the textarea with value when I call html() method in jquery.
Code in html:
<div id="test">
<textarea></textarea>
</div>
After user input for textarea field, for example user inputs "Mango".
Then when I call
var test = $('#test').html();
it should return the output as "< textarea >Mango< / textarea >"
Any ideas please. Thanks in Advance.
A <textarea> can contain innerHTML, which is displayed when there's no value:
$("#test textarea").append("<strong>Inner</strong> html");
console.log($("textarea").html())
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="test"><textarea></textarea></div>
though it's mostly ignored (as shown above) and lost when user enters a value.
So we can take advantage of that by setting the HTML to the value just before reading the HTML and it should work. Here's a snippet that loops through all text areas as sets their HTML to the value:
// empty on load
console.log($("#test").html())
$("button").click(() => {
$("textarea").html(function() { return $(this).val(); });
// output the outer #test div's innerHTML
// includes both textareas and their newly set HTML
console.log($("#test").html())
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="test">
<textarea></textarea>
<textarea></textarea>
</div>
<button>click me</button>
I am using HTML textarea for user to input some data and save that to App Engine's model
The problem is that when I retrieve the content it is just text and all formatting is gone
The reason is because in textarea there is no formatting that we can make
Question:
is there any way to retain the format that user provides?
is there any other element(other than textarea), that i'll have to use?(which one?)
P.S I am very new to area of web development and working on my first project
Thank you
What you want is a Rich Text Editor. The standard HTML <textarea> tag only accepts plain text (even if the text is or includes HTML markup). There are a lot of example out there (including some listed on the page linked) but I would highly recommend using a prepackaged one for this. Coding your own is fairly complicated for people who are new, and even for a lot who have some experience. Both TinyMCE and CKEditor are very common ones, but there are many others as well.
A text box is like wordpad, you cant format it, if you paste in from word or any other formatted text it will wipe all the formatting and you will be left with just the text.
You need add an editor to the text areas, I use TinyMCE, but there are many other out there too.
To implement you need to have all the source (which you can get from TinyMCE) in your web directory.
Here's an example which you can try:
Add this the the head section of your page:
<script language="javascript" type="text/javascript" src="/js/tiny_mce/tiny_mce.js"></script>
<script language="javascript" type="text/javascript">
tinyMCE.init({
theme : "advanced",
mode: "exact",
elements : "elm1",
theme_advanced_toolbar_location : "top",
theme_advanced_buttons1 : "bold,italic,underline,strikethrough,separator,"
+ "justifyleft,justifycenter,justifyright,justifyfull,formatselect,"
+ "bullist,numlist,outdent,indent",
theme_advanced_buttons2 : "link,unlink,anchor,image,separator,"
+"undo,redo,cleanup,code,separator,sub,sup,charmap",
theme_advanced_buttons3 : "",
height:"350px",
width:"600px"
});
</script>
<script type="text/javascript">
tinyMCE.init({
// General options
mode : "textareas",
theme : "advanced",
plugins : "autolink,lists,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
// Theme options
theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_location : "bottom",
theme_advanced_resizing : true,
// Skin options
skin : "o2k7",
skin_variant : "silver",
// Example content CSS (should be your site CSS)
content_css : "css/example.css",
// Drop lists for link/image/media/template dialogs
template_external_list_url : "js/template_list.js",
external_link_list_url : "js/link_list.js",
external_image_list_url : "js/image_list.js",
media_external_list_url : "js/media_list.js",
// Replace values for the template plugin
template_replace_values : {
username : "Some User",
staffid : "991234"
}
});
</script>
Then to call the textarea:
<textarea name="content" style="width:100%">YOUR TEXT HERE</textarea>
NB: You need to download and have in your directory the js files for <script language="javascript" type="text/javascript" src="/js/tiny_mce/tiny_mce.js"></script>
Hope this helps!
This won't solve the case when you want somebody to be able to format their text (e.g. with WYSIWYG bold buttons etc.), but if you want to be able to accept pre-formatted HTML (e.g. copy and paste from other HTML source such as a webpage), then you can do this:
<form ...>
<label>Paste your HTML in the box below</label>
<textarea style='display:none' id='foo'></textarea>
<div id='htmlsource' contenteditable style='border:solid 1px black;padding:1em;width:100%;min-height:2em;' ></div>
<input type='submit' />
</form>
<script>
jQuery(function(){
jQuery('form').submit( function(e) {
jQuery('textarea').val( jQuery('#htmlsource').html() );
});
});
</script>
This uses a contenteditable div element which you can format to look like an input box and will accept pasted HTML, and a hidden textarea#foo which will be populated with the pasted HTML just before the form is submitted.
Note that this is not an accessible solution as it stands.
Depending on your goal for the programm it could already be sufficient to just add "pre" tags left and right to the input of your textarea. for example if your code submits to a form whatever is inside a textarea and than echos it in the target File this would already work.
> File 1:
>
> <form action="Output.php" methode=post>
> <textarea name="Input"></textarea>
> </form>
>
> File Output.php
>
> $UserInput = $_POST["Input"];
> $UserInput = "<pre>" . $UserInput . "</pre>"
> echo $UserInput
this already will retain all Enters for example that where used in the original user input and echo them correctly
If you retrieve the content from the App Engine Saving the Content with the pre tags added already in most cases does the trick
I have ghost text in textfields that disappear when you focus on them using HTML5's placeholder attribute:
<input type="text" name="email" placeholder="Enter email"/>
I want to use that same mechanism to have multiline placeholder text in a textarea, maybe something like this:
<textarea name="story" placeholder="Enter story\n next line\n more"></textarea>
But those \ns show up in the text and don't cause newlines... Is there a way to have a multiline placeholder?
UPDATE: The only way I got this to work was utilizing the jQuery Watermark plugin, which accepts HTML in the placeholder text:
$('.textarea_class').watermark('Enter story<br/> * newline', {fallback: false});
For <textarea>s the spec specifically outlines that carriage returns + line breaks in the placeholder attribute MUST be rendered as linebreaks by the browser.
User agents should present this hint to the user when the element's value is the empty string and the control is not focused (e.g. by displaying it inside a blank unfocused control). All U+000D CARRIAGE RETURN U+000A LINE FEED character pairs (CRLF) in the hint, as well as all other U+000D CARRIAGE RETURN (CR) and U+000A LINE FEED (LF) characters in the hint, must be treated as line breaks when rendering the hint.
Also reflected on MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attr-placeholder
FWIW, when I try on Chrome 63.0.3239.132, it does indeed work as it says it should.
On most (see details below) browsers, editing the placeholder in javascript allows multiline placeholder.
As it has been said, it's not compliant with the specification and you shouldn't expect it to work in the future (edit: it does work).
This example replaces all multiline textarea's placeholder.
var textAreas = document.getElementsByTagName('textarea');
Array.prototype.forEach.call(textAreas, function(elem) {
elem.placeholder = elem.placeholder.replace(/\\n/g, '\n');
});
<textarea class="textAreaMultiline"
placeholder="Hello, \nThis is multiline example \n\nHave Fun"
rows="5" cols="35"></textarea>
JsFiddle snippet.
Expected result
Based on comments it seems some browser accepts this hack and others don't.
This is the results of tests I ran (with browsertshots and browserstack)
Chrome: >= 35.0.1916.69
Firefox: >= 35.0 (results varies on platform)
IE: >= 10
KHTML based browsers: 4.8
Safari: No (tested = Safari 8.0.6 Mac OS X 10.8)
Opera: No (tested <= 15.0.1147.72)
Fused with theses statistics, this means that it works on about 88.7% of currently (Oct 2015) used browsers.
Update: Today, it works on at least 94.4% of currently (July 2018) used browsers.
I find that if you use a lot of spaces, the browser will wrap it properly. Don't worry about using an exact number of spaces, just throw a lot in there, and the browser should properly wrap to the first non space character on the next line.
<textarea name="address" placeholder="1313 Mockingbird Ln Saginaw, MI 45100"></textarea>
There is actual a hack which makes it possible to add multiline placeholders in Webkit browsers, Chrome used to work but in more recent versions they removed it:
First add the first line of your placeholder to the html5 as usual
<textarea id="text1" placeholder="Line 1" rows="10"></textarea>
then add the rest of the line by css:
#text1::-webkit-input-placeholder::after {
display:block;
content:"Line 2\A Line 3";
}
If you want to keep your lines at one place you can try the following. The downside of this is that other browsers than chrome, safari, webkit-etc. don't even show the first line:
<textarea id="text2" placeholder="." rows="10"></textarea>
then add the rest of the line by css:
#text2::-webkit-input-placeholder{
color:transparent;
}
#text2::-webkit-input-placeholder::before {
color:#666;
content:"Line 1\A Line 2\A Line 3\A";
}
Demo Fiddle
It would be very great, if s.o. could get a similar demo working on Firefox.
According to MDN,
Carriage returns or line-feeds within the placeholder text must be treated as line breaks when rendering the hint.
This means that if you just jump to a new line, it should be rendered correctly. I.e.
<textarea placeholder="The car horn plays La Cucaracha.
You can choose your own color as long as it's black.
The GPS has the voice of Darth Vader.
"></textarea>
should render like this:
If you're using AngularJS, you can simply use braces to place whatever you'd like in it: Here's a fiddle.
<textarea rows="6" cols="45" placeholder="{{'Address Line1\nAddress Line2\nCity State, Zip\nCountry'}}"></textarea>
React:
If you are using React, you can do it as follows:
placeholder={'Address Line1\nAddress Line2\nCity State, Zip\nCountry'}
This can apparently be done by just typing normally,
<textarea name="" id="" placeholder="Hello awesome world. I will break line now
Yup! Line break seems to work."></textarea>
The html5 spec expressly rejects new lines in the place holder field. Versions of Webkit /will/ insert new lines when presented with line feeds in the placeholder, however this is incorrect behaviour and should not be relied upon.
I guess paragraphs aren't brief enough for w3 ;)
If your textarea have a static width you can use combination of non-breaking space and automatic textarea wrapping. Just replace spaces to nbsp for every line and make sure that two neighbour lines can't fit into one. In practice line length > cols/2.
This isn't the best way, but could be the only cross-browser solution.
<textarea class="textAreaMultiligne"
placeholder="Hello, This is multiligne example Have Fun "
rows="5" cols="35"></textarea>
With Vue.js:
<textarea name="story" :placeholder="'Enter story\n next line\n more'"></textarea>
in php with function chr(13) :
echo '<textarea class="form-control" rows="5" style="width:100%;" name="responsable" placeholder="NOM prénom du responsable légal'.chr(13).'Adresse'.chr(13).'CP VILLE'.chr(13).'Téléphone'.chr(13).'Adresse de messagerie" id="responsable"></textarea>';
The ASCII character code 13 chr(13) is called a Carriage Return or CR
You can try using CSS, it works for me. The attribute placeholder=" " is required here.
<textarea id="myID" placeholder=" "></textarea>
<style>
#myID::-webkit-input-placeholder::before {
content: "1st line...\A2nd line...\A3rd line...";
}
</style>
Bootstrap + contenteditable + multiline placeholder
Demo: https://jsfiddle.net/39mptojs/4/
based on the #cyrbil and #daniel answer
Using Bootstrap, jQuery and https://github.com/gr2m/bootstrap-expandable-input to enable placeholder in contenteditable.
Using "placeholder replace" javascript and adding "white-space: pre" to css, multiline placeholder is shown.
Html:
<div class="form-group">
<label for="exampleContenteditable">Example contenteditable</label>
<div id="exampleContenteditable" contenteditable="true" placeholder="test\nmultiple line\nhere\n\nTested on Windows in Chrome 41, Firefox 36, IE 11, Safari 5.1.7 ...\nCredits StackOveflow: .placeholder.replace() trick, white-space:pre" class="form-control">
</div>
</div>
Javascript:
$(document).ready(function() {
$('div[contenteditable="true"]').each(function() {
var s=$(this).attr('placeholder');
if (s) {
var s1=s.replace(/\\n/g, String.fromCharCode(10));
$(this).attr('placeholder',s1);
}
});
});
Css:
.form-control[contenteditable="true"] {
border:1px solid rgb(238, 238, 238);
padding:3px 3px 3px 3px;
white-space: pre !important;
height:auto !important;
min-height:38px;
}
.form-control[contenteditable="true"]:focus {
border-color:#66afe9;
}
If you're using a framework like Aurelia that allows one to bind view-model properties to HTML5 element properties, then you can do the following:
<textarea placeholder.bind="placeholder"></textarea>
export class MyClass {
placeholder = 'This is a \r\n multiline placeholder.'
}
In this case the carriage return and line feed is respected when bound to the element.
Watermark solution in the original post works great. Thanks for it.
In case anyone needs it, here is an angular directive for it.
(function () {
'use strict';
angular.module('app')
.directive('placeholder', function () {
return {
restrict: 'A',
link: function (scope, element, attributes) {
if (element.prop('nodeName') === 'TEXTAREA') {
var placeholderText = attributes.placeholder.trim();
if (placeholderText.length) {
// support for both '\n' symbol and an actual newline in the placeholder element
var placeholderLines = Array.prototype.concat
.apply([], placeholderText.split('\n').map(line => line.split('\\n')))
.map(line => line.trim());
if (placeholderLines.length > 1) {
element.watermark(placeholderLines.join('<br>\n'));
}
}
}
}
};
});
}());
I am filling a textarea with content for the user to edit.
Is it possible to make it stretch to fit content with CSS (like overflow:show for a div)?
one line only
<textarea name="text" oninput='this.style.height = "";this.style.height = this.scrollHeight + "px"'></textarea>
Not really. This is normally done using javascript.
there is a good discussion of ways of doing this here...
Autosizing textarea using Prototype
Alternatively, you could use a contenteditable element, this will fit to the text inside.
<div contenteditable>Try typing and returning.</div>
Please note that it's not possible to send this value along in a form, without using some javascript. Also contenteditable will possibly generate HTML-content and allows styling, so this may need to be filtered out upon form submit.
This is a very simple solution, but it works for me:
<!--TEXT-AREA-->
<textarea id="textBox1" name="content" TextMode="MultiLine" onkeyup="setHeight('textBox1');" onkeydown="setHeight('textBox1');">Hello World</textarea>
<!--JAVASCRIPT-->
<script type="text/javascript">
function setHeight(fieldId){
document.getElementById(fieldId).style.height = document.getElementById(fieldId).scrollHeight+'px';
}
setHeight('textBox1');
</script>
Here is a function that works with jQuery (for height only, not width):
function setHeight(jq_in){
jq_in.each(function(index, elem){
// This line will work with pure Javascript (taken from NicB's answer):
elem.style.height = elem.scrollHeight+'px';
});
}
setHeight($('<put selector here>'));
Note:
The op asked for a solution that does not use Javascript, however this should be helpful to many people who come across this question.
Not 100% related to the question as this is for Angular when using Angular Material Design only.
There is a npm package associated with Angular called #angular/cdk (if using Angular Material Design). There is a property included in this package that can be associated to a textarea called cdkTextareaAutosize. This automatically sets the textarea to 1 line and stretches the textarea to fit the content accordingly. If you are using this library, something like this should work.
<textarea
maxLength="200"
cdkTextareaAutosize
type="text">
</textarea>
Another simple solution for dynamic textarea control.
<!--JAVASCRIPT-->
<script type="text/javascript">
$('textarea').on('input', function () {
this.style.height = "";
this.style.height = this.scrollHeight + "px";
});
</script>
Answers here were good but were lacking a piece of code that I had to add to avoid a shrinking that is not welcome when you type for the first time :
var $textareas = $('textarea');
$textareas.each(function() { // to avoid the shrinking
this.style.minHeight = this.offsetHeight + 'px';
});
$textareas.on('input', function() {
this.style.height = '';
this.style.height = this.scrollHeight + 'px';
});
There are a lot of answers here already, but I think some improvement can still be made to the textarea resizing code.
This script snippet will loop over ALL of the textareas on your page, and make sure they resize both on load and on change.
<script>
document.querySelectorAll("textarea").forEach(element => {
function autoResize(el) {
el.style.height = el.scrollHeight + 'px';
}
autoResize(element);
element.addEventListener('input', () => autoResize(element));
});
</script>
Vanilla JS only, no libraries needed.
Solution for React
I used the length of the text that was being displayed and divided that number by 30 (I adjusted this number until it felt right form my App)
{array.map((text) => (
<textarea
rows={text.length / 30}
value={text}
></textarea>
)}
In my site, I would like to implement a textbox where people can input a set of strings separated by a separator character.
For example the tags textbox at the bottom of this page: tags(strings) delimited by space(separator).
To make it more clear to the user, it would make a lot of sence to give each string a different background color or other visual hint.
I don't think this is possible with a regular input[text] control.
Do you deem it possible to create something like that with javascript? Has somebody done this before me already? Do you have any other suggestions?
Basic Steps
Put a textbox in a div and style it too hide it.
Make the div look like a text box.
In the onClick handler of the div, set the input focus to the hidden text box.
Handle the onKeyUp event of the hidden text box to capture text, format as necessary and alter the innerHtml of the div.
Tis quite straightforward. I'll leave you to write your formatter but basically you'd just splitString on separator as per the Semi-Working-Example.
Simple Outline
<html>
<head>
<script language="javascript" type="text/javascript">
function focusHiddenInput()
{
var txt = document.getElementById("txtHidden");
txt.focus();
}
function formatInputAndDumpToDiv()
{
alert('Up to you how to format');
}
</script>
</head>
<body>
<div onclick="focusHiddenInput();">
Some label here followed by a divved textbox:
<input id="txtHidden" style="width:0px;" onKeyPress="formatInputAndDumpToDiv()" type="text">
</div>
</body>
</html>
Semi-Working Example
You still need to extend the click handlers to account for tag deletion/editing/backspacing/etc via keyboard.... or you could just use a click event to pop up another context menu div. But with tags and spacer ids identified in the code below that should be pretty easy:
<html>
<head>
<script language="javascript" type="text/javascript">
var myTags=null;
function init()
{
document.getElementById("txtHidden").onkeyup= runFormatter;
}
function focusHiddenInput()
{
document.getElementById("txtHidden").focus();
}
function runFormatter()
{
var txt = document.getElementById("txtHidden");
var txtdiv = document.getElementById("txtBoxDiv");
txtdiv.innerHTML = "";
formatText(txt.value, txtdiv);
}
function formatText(tagText, divTextBox)
{
var tagString="";
var newTag;
var newSpace;
myTags = tagText.split(' ');
for(i=0;i<myTags.length;i++) {
newTag = document.createElement("span");
newTag.setAttribute("id", "tagId_" + i);
newTag.setAttribute("title", myTags[i]);
newTag.setAttribute("innerText", myTags[i]);
if ((i % 2)==0) {
newTag.style.backgroundColor='#eee999';
}
else
{
newTag.style.backgroundColor='#ccceee';
}
divTextBox.appendChild(newTag);
newTag.onclick = function(){tagClickedHandler(this);}
newSpace = document.createElement("span");
newSpace.setAttribute("id", "spId_" + i);
newSpace.setAttribute("innerText", " ");
divTextBox.appendChild(newSpace);
newSpace.onclick = function(){spaceClickedHandler(this);}
}
}
function tagClickedHandler(tag)
{
alert('You clicked a tag:' + tag.title);
}
function spaceClickedHandler(spacer)
{
alert('You clicked a spacer');
}
window.onload=init;
</script>
</head>
<body>
<div id="txtBoxDivContainer">
Enter tags below (Click and Type):<div id="txtBoxDiv" style="border: solid 1px #cccccc; height:20px;width:400px;" onclick="focusHiddenInput();"></div>
<input id="txtHidden" style="width:0px;" type="text">
</div>
</body>
</html>
Cursor
You could CSS the cursor using blink (check support) or otherwise just advance and hide as necessary an animated gif.
This is quite interesting. The short answer to your question is no. Not with the basic input element.
The real answer is: Maybe with some trickery with javascript.
Apparently Facebook does something close to this. When you write a new message to multiple persons in Facebook, you can type their names this sort of way. Each recognized new name is added a bit like an tag here and has an small cross next to it for removing it.
What they seem to do, is fake the input area size by drawing an input-looking box and removing all styling from the actual input with css. Then they have plenty of logic done with javascript so that if you have added an friend as a tag and start backspacing, it will remove the whole friends name at once. etc.
So, yes, it's doable, but takes plenty of effort and adds accessibility problems.
You can look how they do that at scripts like TinyMCE, which add such features to textareas. In textareas you can use HTML to colorize text.
You can use multiple textboxes
textbox1 <space> textbox2 <space> textbox3 ....
and so on... You can then apply the background-color style to each textbox.