Count characters in paragraph using jQuery (*not* for input/textarea) - javascript

How do I work out in jQuery a character counter of a p/div tag?
Basically i want to show a different css value IF the character value >=50.
Been struggling for hours with it :)

Use
$("#myDiv").text().length;

var $div = $('#mydiv');
if($div.text().length >= 50) {
$div.addClass('class');
}

Put a "long" class on all div and p elements with more than 50 characters:
$("p, div").filter(function(){
return $(this).text().length >=50;
}).addClass('long');
If you don't know how much content you have, though, then presumably this content is generated dynamically by the server, right? And if this is the case, wouldn't it make more sense to have the server—which knows how much content it's plopping into these containers—add the class dynamically while generating the page to send? Why rely on jQuery?

Try this snippet it works even if the text's length was greater than 50 characters.
You can also calculate the character digits of the paragraph. (Excluding new lines and space bars)
window.setInterval(function() {
var txt = $("#txt").val();
var parLength = $("#data").text().length;
var charLength = txt.replace(/ /g, '').replace(/\n/g, '').length;
$("#data").text(txt);
$("#calcLength").text("The paragrapgh's length is: " + parLength);
$("#calcChar").text("The amount of characters is: " + charLength);
}, 10);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="txt" placeholder="Enter text here..." style="height:100px;width:250px"></textarea>
<p id="data"></p>
<p id="calcLength"></p>
<b>Note: even a space character is calculated through the length function</b>
<p id="calcChar"></p>
<b>Note: a space bar,and every empty line is trimmed in the second calculated value</b>
I have provided this example to make it simple for use and compatability.

Related

How can I get the value of the first and second line in a textarea?

I'm trying to get the value of the first and second line from a textarea in HTML.
The main problem is that the first and second line can be of different lengths, so I can't just copy X amount of characters.
Most of the solutions I've seen include JQuery, which I'm not familiar with, so I would prefer an answer that doesn't involve JQuery. However, if you do have an answer that does use JQuery, I'll also give it a go.
Here's my code so far:
textarea {
resize: none;
}
<textarea id="c" placeholder="c" spellcheck="false"></textarea>
function getfirstAndsecondLine(inp) {
var splittedInput = document.getElementById(inp).value.split('\n');
var firstLine = splittedInput[0];
var secondLine = splittedInput[1];
console.log('first Line :' + firstLine);
console.log(" ");
console.log('second Line :' + secondLine);
}
<textarea id="c" placeholder="c" spellcheck="false"></textarea>
<button onclick=getfirstAndsecondLine('c')>
get first and second line
</button>
Assuming that the first and second line are separated by a newline (by pressing enter), you split it by "\n" then get the second element.
function getSecondLine() {
var tarea = document.getElementById("c")
var tareavalue = tarea.value;
var secondLine = tareavalue.split("\n")[1];
console.log(secondLine)
}

Hashtag Counter

I'm wanting to create a similar thing to the character counter on this website - https://character-counter.uk/. However, instead of counting every character I only want to count hashtags. So if I entered #happy and #sad the counter would return the number 2.
I'm new to javaScript and jQuery so am not sure how I could get this to happen.
Say I have this html
<textarea rows="16" class="form-control"></textarea>
<div class="remaining-counter">Characters Counted: <span
class="well text-well">0</span></div>
I want the 0 belonging to the text-well span to jump up once whenever a hashtag is typed into the text area.
I've been tinkering around with some things but so far can only come up with this code
var count = 0;
$("textarea").on("input", function() {
if ($(this).val().match(/#/)) {
$('.text-well').html(count++);
} else {
return;
}
});
When entering it into the character counter site using the console the counter still counts up whenever I start typing into the textarea and then resets and starts counting up in twos when a # is entered.
Any help is appreciated.
To achieve this you can simply use the match() method to find the number of hashtags within the value of the given textarea, something like this:
$("textarea").on("input", function() {
var text = $(this).val();
var count = (text.match(/(^|\W)(#[a-z\d][\w-]*)/g) || []).length;
$('.text-well').html(count);
}).trigger('input');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<textarea rows="10" cols="40" class="form-control">Lorem #ipsum dolor #sit amet #consectetur adipiscing</textarea>
<div class="remaining-counter">Hashtags Counted: <span class="well text-well">0</span></div>
Note that I got the hashtag regex from this question
var count = 0;
$("textarea").on('change keyup paste', function() {
if ($(this).val().match(/#/)) {
$('.text-well').html(count++);
}
});
This will count hash tags, requiring each pound sign counted to be followed by at least one word character:
$("textarea").on("keyup", function() {
var matches = $(this).val().match(/#\w+\b/g);
var count = matches ? matches.length : 0;
$('.text-well').html(count);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea rows="10" class="form-control"></textarea>
<div class="remaining-counter">Characters Counted: <span
class="well text-well">0</span></div>
Basically:
Instead of trying to keep track of a counter, do the entire count every time.
Use .match(pattern).length to get the number of matches, remembering to use the g flag so you actually count all matches.
If you only want to count hashes, /#/ works fine. If you want to match hash tags, ensure the hashtag is followed by a letter by using /#\w/.
Use the keyup event to ensure your count is updated on every letter press.

How to insert a line break in createTextNode

For a little program that outputs some XML Code in a p element I need to have some line breaks in the output.
In the last week I tried a lot of things like document.createElement("br"); or inserting escape character \n or unicode whitespace-character \u000A but nothing worked.
My output now:
<viva:form rdf:parseType="Resource"> <viva:title>55</viva:title>
I need it that way:
<viva:form rdf:parseType="Resource">
<viva:title>55</viva:title>
My code:
var vivaTitle;
function elementeAbrufen() {
vivaTitle = document.getElementById("inputVivaTitle").value;
var p = document.createElement("p");
var t = document.createTextNode(headErzeugen());
p.appendChild(t);
document.body.appendChild(p)
}
function headErzeugen() {
// insert unicode lf
var lf = "\u000A";
var xmlHeadStruktur = "<viva:form rdf:parseType=\"Resource\">";
var xmlHeadTitle = "<viva:title>" + vivaTitle + "</viva:title>";
return xmlHeadStruktur + lf + xmlHeadTitle
}
<p id="vivaTitle" title="">viva:title:
<input type="text" id="inputVivaTitle" value="">
<button onclick="elementeAbrufen()">send</button>
I'm thankfull for every help.
Cheers, Didier
Using \n works fine. Here's a jsfiddle:
https://jsfiddle.net/Lftqy9b0/1/
var text = document.createTextNode("Hello\u000aWorld");
document.body.appendChild(text);
document.body.style = "white-space: pre;"
'\n', '\u000a', etc. should all be valid, but I recommend using '\n'. Most people will recognize it better.
The reason this isn't working for you is that HTML collapses all whitespace. So even though the text node DOES contain a newline, it's just the same as a newline typed into HTML (those are text nodes too.)
You can see in the above snippet that I included a 'white-space: pre;' rule. This causes it not to collapse whitespace. See here for more options:
https://developer.mozilla.org/en-US/docs/Web/CSS/white-space
If you're formatting raw text for display like this, that's probably the easiest way. Of course, you should put the white-space rule in a separate css file.
Does this work?
var t = document.createTextNode(headErzeugen() + '<br />');

dynamically increase input type text textbox width according to the characters entering into it

I have a textbox where the user can enter any number of characters, But I want its width to be increased dynamically with respect to the number of characters entered into it.
I have done a workaround shown below and it works partially, it will increase the width dynamically but not so precisely and will hide the first entered characters after a while because of my poor logic applied in it. I've just given a wild cutoff of 17 characters count to start the increment.
It should start the width increment only if the character count reaches the end of textbox.
UPDATE:
I am looking to make visible all the characters entered in the field, whereas in default the text box hides the leftmost characters.
FIDDLE DEMO
HTML
<input type="text" id="txtbox" />
SCRIPT
$('#txtbox').keypress(function() {
var txtWidth = $(this).width();
var cs = $(this).val().length;
if(cs>17){
$(this).width(txtWidth+5);
}
});
I have tried this code and it works fine.
<html>
<head>
<script type="text/javascript">
function Expand(obj){
if (!obj.savesize) obj.savesize=obj.size;
obj.size=Math.max(obj.savesize,obj.value.length);
}
</script>
</head>
<body>
<form>
<input type="text" size="5" style="font-family:Courier;" onkeyup="Expand(this);">
</form>
</body>
</html>
Be sure to use mono space fonts in text box, otherwise the size attr. and number of characters won't match
Adding a simple inline code in onkeyUp should help
<input type="text" name="fname" onkeypress="this.style.minWidth = ((this.value.length + 1) * 7) + 'px';">
<input type="text" id="txtbox" size="10"/>
$('#txtbox').keypress(function() {
var txtWidth = $(this).attr('size');
var cs = $(this).val().length-6;
txtWidth = parseInt(txtWidth);
if(cs>txtWidth){
$(this).attr('size',txtWidth+5); }
});
You were using width field which is actually meant for type = image.
You can get more info here.
I have used size attribute which is used to set the size of input tag in pixels. When its 1 it can take 6 characters by default hence -6. Hope it helps.
A solution similar to #Tejas', but doesn't require the font to be mono-space:
The trick is to use scrollWidth, which gives us the total string length, even on single-line textboxes without a scrollbar:
https://stackoverflow.com/a/9312727/1869660
NOTE: I couldn't get this to work in IE, where scrollWidth always returned 2 for some reason..
Some code:
function expand(textbox) {
if (!textbox.startW) { textbox.startW = textbox.offsetWidth; }
var style = textbox.style;
//Force complete recalculation of width
//in case characters are deleted and not added:
style.width = 0;
var desiredW = textbox.scrollWidth;
//Optional padding to reduce "jerkyness" when typing:
desiredW += textbox.offsetHeight;
style.width = Math.max(desiredW, textbox.startW) + 'px';
}
...
<input type="text" onkeyup="expand(this);" >
JSFiddle example
On the x-editable documentation you can find the option type so i guess you have to add data-editable-type="textarea"

How to wrap a class around the first half of a headline?

I'm trying to wrap a class around the first or the second half of a headline so that I could create more dynamic and cool headlines with jQuery.
In theory I want to find all of the spaces in the sentence and divide it into two. If the headline contains an uneven number of words the script should detect that and also add the class to the nearest word.
This is an interesting problem. I would approach with the handy javascript splice method. Splice can be used to insert and delete items of an array. I'd recommend opening up an inspector and trying out some of the examples I've written below.
First we'll use jQuery to select the header then manipulate the html content string. I'm assuming that the specific header you want to manipulate will have a class and I've substituted 'dynamic':
var header = $("h1.dynamic").text();
=> "Header with some other stuff"
var header_as_array = header.split(" ")
=> ["Header", "with", "some", "other", "stuff"]
var first_half = header_as_array.splice(0, header_as_array.length/2)
Keep in mind that splice changes the original array, so at this point:
first_half = ["Header", "with"]
header_as_array = ["some", "other", "stuff"]
Now, you can join them back together and wrap them with spans like so:
var first = '<span class="first_half">'+first_half.join(" ")+'</span>';
var second = '<span class="second_half">'+header_as_array.join(" ")+'</span>';
var finished = first+" "+second;
Finally, we'll put our finished string back into the header with jQuery:
$("h1.dynamic").html(finished);
The way I've written it a header with an odd number of words will always have the second half as the longer half. If you would prefer it the other way around you could do this:
var splice_location = Math.ceil(test_as_array.length/2);
var first_half = header_as_array.splice(0, splice_location);
By default a non-integer value will be truncated, but here we are using the ceiling function to round things up instead of down.
Nice one #lashleigh. You can have a look at a working example here:
http://jsfiddle.net/johnhunter/KRJdm/
#Tony, I've implemented what you are after as a jquery plugin. You call it on the header you want formatted:
$(function() {
$('h1').splitWords();
});
...and it will produce html output like this:
Before:
<h1>This is a long headline</h1>
After:
<h1>
<span class="wrap-1">This is </span>
<span class="wrap-2">a long headline </span>
</h1>
UPDATED:
Not part of the original question but I have updated the example to allow you to specify at which word the wrapping occurs. If you provide an index argument it will use that offset on the list of words (minus values count back from the end). e.g:
$('h1.a').splitWords(); // Split these words equally
$('h1.b').splitWords(1); // Split these after the first word
$('h1.c').splitWords(-2); // Split these after the second last word
http://jsfiddle.net/johnhunter/KRJdm/
Try the following
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="jquery-1.5.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var headlineText = $('h1.mainHeader').text();
var headlineWords = headlineText.split(' ');
var headlineLength = headlineWords.length;
var headlineMidPoint = (headlineLength / 2) + 1;
var headlineFirstHalfText = headlineWords.slice(0, headlineMidPoint).join(' ') + ' ';
var headlineSecondHalfText = headlineWords.slice(headlineMidPoint).join(' ');
var d = document;
var headlineFirstHalf = $(d.createElement('span')).addClass('headlineHead').text(headlineFirstHalfText);
var headlineSecondHalf = $(d.createElement('span')).addClass('headlineTail').text(headlineSecondHalfText);
var headline = $(d.createElement('h1')).addClass('mainHeader').append(headlineFirstHalf).append(headlineSecondHalf);
$('h1.mainheader').replaceWith(headline);
});
</script>
<style type="text/css">
h1 { font-size:18px;}
span.headlineTail {font-size:1.2em;}
</style>
</head>
<body>
<h1 class="mainHeader">This is a dynamic headline</h1>
<p>Lorem ipsum dolor sit amet, consectetur...</p>
</body>
</html>
lashleigh's answer is great, however, I would challenge the premise that jQuery is the best choice of technology for achieving this effect. I would be inclined to suggest doing the same server-side. Phrasing the markup using PHP, Python or whatever language you are using and then caching the output with the inserted class. Saves on page weight and means the user's browser doesn't have to calculate everything when each a page is loaded. A significant benefit on light clients such as mobile devices.
Here is an example in PHP.
<?php
$headline = "This is a headline of epic proportions";
$split = explode(' ', $headline);
$a = array_slice($split, 0, (count($split)/2));
$b = array_slice($split, (count($split)/2));
$headline = '<span class="whatever">'. join(' ', $a) . '</span>' . join(' ', $b);
print $headline;
?>

Categories

Resources