Strictly Limit the number of rows in textarea Angular - html

I am looking for a resolution on how to limit the allowed rows and columns to input in a textarea in an Angular way. I found a lot of solution using a jQuery, and it is a little bit messy. I am wondering if there's an Angular way to do this.
So let say, I do have a text area that needs to strictly limit the number of rows and columns. I set this up this way.
<textarea matInput formControlName="cardDescription" rows="5" cols="5" placeholder="Card Description"></textarea>
Unfortunately, this line of code only initialises the view for about 5 rows and I think the cols does not do anything.
What am I missing here?

Try to do this
html:
<textarea cols="30" rows="5" [(ngModel)]="data" (ngModelChange)="doSomething($event)"></textarea>
.ts:
data: any = '';
doSomething(event){
var lines = 5;
let newLines = this.data.split("\n").length;
if(event.keyCode == 13 && newLines >= lines) {
console.log('limit exceeded')
}
else {
console.log('input under limit')
}
}

Related

How can I Modify column widths with input fields in html

I am struggling to create an html table with columns of variant widths.
Here is an example of one of my attempts
<th style="width:300px;"><input class="form-control" type="text" value = "NAME"></th>
The style attribute of the th does not seem to have any effect on the output. I have also tried:
<th style="width:30%;"><input class="form-control" type="text" value = "NAME"></th>
The problem I am trying to solve is that I am trying to write some Python code to create htm tables with some data that might need to be modified (the reason for the text input box). In my initial attempts the table columns all have the same width but some columns (like name) need to be wider so the full contents are displayed (or closer to the full contents)
I have also tried
<th colspan = "2"><input class="form-control" type="text" value = "NAME"></th>
All of these suggestions were based on reading the similar questions that popped up as I was writing this question. If it matters I am looking at the results in Firefox but I do hope the solution is consistent across browsers.
None of these suggestions are working in that all the columns are displayed with the same width.
Here's a simple example with vanilla javascript that might help you:
var rng = document.querySelector("input");
read("mousedown");
read("mousemove");
function read(evtType) {
rng.addEventListener(evtType, function() {
window.requestAnimationFrame(function () {
document.querySelector("div").style.width = rng.value + "px";
});
});
}
#column {
width: 300px;
height: 600px;
background: lightblue;
}
input {
width: 297px;
margin-bottom: 10px;
}
<input type="range" min="40" max="550"/>
<div id="column"></div>
As you can see, it changes the width based of the user's input ;)

Textarea with maximum one row

Is it possible to have a textarea in HTML with a single line that never wraps to a 2nd line?
I'd like to behave pretty much like an input.
I've tried :
<textarea class="compact" rows="1" wrap="soft"> </textarea>
.compact{
resize: none;
line-height: 20px;
height: 20px;
overflow: hidden;
white-space: nowrap;
}
Why am I not using an input actually?
Mostly because of the IE 10 compatibility and requirement to copy-paste text in the control. If the pasted text contains \r\n, IE 10 will simply trim any other characters after \r\n and paste that result in the input.
For example, the text
1
2
3
will be pasted as 1 without the rest of the text.
I think I got it. I wired up an jQuery listener.
Using this, no word wrapping is allowed, even when pasting a multi-line string into it. And spaces are still preserved.
$(document).ready(function () {
$('#formatTextArea').on("keyup", function () {
var string1 = $('#formatTextArea').val()
string1 = string1.replace(/(\r\n|\n|\r)/gm, "");
$('#formatTextArea').val(string1)
});
});
<textarea class="compact" id="formatTextArea" rows="1" cols="30" wrap="off"></textarea>
It looks like you can use wrap="soft" and possibly max-length
<textarea rows="1" wrap="soft" maxlength="20" ></textarea>
You can use a little javascript:
var textarea = $("#your_textarea");
textarea[0].onpaste = function() {
window.setTimeout(function() {
var output = textarea.val().replace(/\r?\n|\r/g, ' ') ;
textarea.val(output )
}, 1);
}
See this demo
You can use contenteditable attribute on a div. Its widely supported in old browsers http://caniuse.com/#search=contenteditable
I created a small fiddle here:
http://jsfiddle.net/wr14yLh5/
Html
<div contenteditable></div>
Css
div{
background: green;
color: #fff;
}
div br{
display: none;
}
JS
$("div").keypress(function(e){ return e.which != 13; });

Define maxlength for an html textarea

I currently try to restrict the the maximal amount of characters allowed in a textarea.
With:
<textarea rows="4" cols="50" maxlength="50">
It works like it should in Firefox, however there seems to be no effect in IE which poses a problem since quite a lot of the website-users still use IE.
Do you have any suggestions or a workaround?
You can use Javascript to implement maxlength in Internet Explorer.
<textarea rows="4" cols="50" maxlength="50" onKeyPress="return(this.value.length < 50);">
I am suggesting this since you had placed php in the tags, you can truncate the input from the server side using substr
$trunc = substr($_POST['textareaname'], 0, 50);
alternatively you can also use Javascript function.
UPDATE to your comment on how to provide a feedback to the user when limit is reached.
$("#element").keypress(function (e) {
var str = $(this).val();
if (str.length > 100) {
e.preventDefault();
alert('You have reached max limit');
return false;
}
});

Having a permanent value in an input field while still being able to add text to it

I don't know if this is possible but I would like to have an input field where I would have a value that is not editable by the user.
However, I don't want the input field to be "readonly" because I still want the user to be able to add text after the value.
If you have any idea on how to do this, let me know please that would help me a lot.
EDIT: I use html forms.
You can position the text on top of the input field to make it look as if it is inside it. Something like this:
<input type="text" name="year" style="width:3.5em;padding-left:1.5em;font:inherit"><span style="margin-left:-3em;margin-right:10em;">19</span>
This way your input field will start with "19" which can not be edited, and the user can add information behind this.
Basically what you do is set the input field to a fixed width, so that you know how much negative margin-left to give the span with your text in it in order for it to be positioned exactly at the start of the input field.
You might need to fiddle with the margin-left of the span depending on the rest of your css.
Then also adding pedding-left to the input field, to make sure the user starts typing after your text and not under it.
font:inherit should make sure both your text and the text typed by the user are in the same font.
And if you want to put anything to the right of this input field, do add margin-right to the span with your text, as otherwise other content might start running over your input field as well.
seems a little weird to me ..why not just use a text output and afterwards the input field?
like sometimes used for the birthdate (although, maybe not anymore..)
birthyear: 19[input field]
edit:
with some javascript stuff you could realise something like that you asked for, though
an input field with text and catching keystrokes within that field while only allowing some after what you want to be always there - but, well, you would need to use js ..and if its just for that, Id rather say its not necessary
edit:
if you want to use a trick just for the viewer you could use a background-image/border-style that surrounds a text and the input field, thus making it look like text and input are the same input-box.
Sounds like you want placeholder text. In HTML5 you can set the placeholder attribute on any input element. This will work in modern browsers.
<input type="email" placeholder="jappleseed#appletree.com" name="reg_email" />
Now, for older browsers this won't work. You'll need a JavaScript alternative to provide the same UI value.
This can work for all browsers:
<input type="text" value="Search" onfocus="if (this.value == 'Search') {this.value = '';}" onblur="if (this.value == '') {this.value = 'Search';}">
but it's not recommended because there is a better way (really, it's a combination of the first two approaches): Use HTML5 markup for new browsers; jQuery and modernizr for old browsers. This way you can have only one set of code that will support all user cases.
Taken directly from webdesignerwall.com:
<script src="jquery.js"></script>
<script src="modernizr.js"></script>
<script>
$(document).ready(function(){
if(!Modernizr.input.placeholder){
$('[placeholder]').focus(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
input.removeClass('placeholder');
}
}).blur(function() {
var input = $(this);
if (input.val() == '' || input.val() == input.attr('placeholder')) {
input.addClass('placeholder');
input.val(input.attr('placeholder'));
}
}).blur();
$('[placeholder]').parents('form').submit(function() {
$(this).find('[placeholder]').each(function() {
var input = $(this);
if (input.val() == input.attr('placeholder')) {
input.val('');
}
})
});
}
</script>
[You'll need both jquery.js and modernizr.js installed in the same folder as your webpage.]
Note: I have a feeling that a little more research might reveal that modernizr isn't needed for this at all, though I could be wrong about that particular point.
Perhaps, then, you want a select menu?
<select name="mySelectMenu">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
Sorry if this isn't what you want either. I'm grasping at straws because what you are asking for is very vague. Maybe you should give an example of what one of these 'editable but not editable' inputs would be used for.
Also, you could use a select and a text input.
The main problem is to determine the position of the cursor. This can be done e.g. using the following function:
function getCaret(el) {
var pos = -1;
if (el.selectionStart) {
pos = el.selectionStart;
}
else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r != null) {
var re = el.createTextRange();
var rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
pos = rc.text.length;
}
}
return pos;
}
Now you can install an event handler for the key press and check whether the pressed key was inside the immutable part of the value of the textarea. If it was there the event handler returns false, otherwise true. This behavior can be wrapped into a simple object:
function Input(id, immutableText) {
this.el = document.getElementById(id);
this.el.value = immutableText;
this.immutableText = immutableText;
this.el.onkeypress = keyPress(this);
}
function keyPress(el) {
return function() {
var self = el;
return getCaret(self.el) >= self.immutableText.length;
}
}
Input.prototype.getUserText = function() {
return this.el.value.substring(this.immutableText.length);
};
var input = new Input("ta", "Enter your name: ");
var userText = input.getUserText();
You can check it on jsFiddle (use Firefox or Chrome).
I came up with this:
```
if (e.target.value == '' || e.target.value.length <= 3) {
e.target.value = '+91-';
}
```

Can you have multiline HTML5 placeholder text in a <textarea>?

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'));
}
}
}
}
};
});
}());