How to do a Word Count on Multiple Textareas using jQuery? - javascript

I have successfully did a word count on a text area using the following JS:
jQuery('span.after-amount').append(' - You have <span class="wordcount">0</span> words.');
jQuery('textarea').on('input', function($) {
var regex = /\s+/gi;
var count = jQuery(this).val().trim().replace(regex, ' ').split(" ").length;
$('.wordcount').html(count);
});
My HTML:
<textarea class="tmcp-field tmcp-textarea" name="tmcp_textarea_2"></textarea>
<span class="after-amount">You have <span class="wordcount">0</span> words.</span>
<textarea class="tmcp-field tmcp-textarea" name="tmcp_textarea_2"></textarea>
<span class="after-amount">You have <span class="wordcount">0</span> words.</span>
<textarea class="tmcp-field tmcp-textarea" name="tmcp_textarea_2"></textarea>
<span class="after-amount">You have <span class="wordcount">0</span> words.</span>
Here is a Fiddle.
I need to get a word count for each text area, is there an easy way to do this without selecting each textarea individually?

This is my solution, first I change your event handler to keyup, and starting count of each textarea value's length using $(this) so you get the current textarea.
$(function(){
$('textarea').on('keyup', function(){
var wordsLength = $(this).val().length;
$(this).next().find('.wordcount').html(wordsLength);
});
});
Check this updated jsfiddle. Hope this helps

Just finding .wordcount into <li>
jQuery('textarea').on('input', function($) {
var regex = /\s+/gi;
var count = jQuery(this).val().trim().replace(regex, ' ').split(" ").length;
jQuery(this).parent().find('.wordcount').html(count);
);

Related

Creating step numbers dynamically in jquery

I hate manually typing steps numbers. So I was trying to write a small function to find some text and replace it with generated step numbers.
And I can't use the ol/li tags because I have multiple groups on the page. So I need to add an "a", "b", etc after the number.
My HTML:
<span class="grouping" v="a">
----My first step
----This is another
----And another
</span>
<br/>
<span class="grouping" v="b">
----second group
----second group 2
</span>
This is my jquery (but it doesn't replace the ---- to a step number).
$(function(){
$(".grouping").each(function(){
var val=$(this).attr("v");
var counter=1;
$(this).find(":contains('----')").each(function(){
$(this).text("("+counter+val+") ");
counter++;
});
});
});
So eventually, I want the webpage to finish like this:
(1a) My first step
(2a) This is another
(3a) And another
(1b) second group
(2b) second group 2
For each of the groupings, get the inner html and split it by newline
If it starts with '----', replace it with an incrementing line number, and append the v value.
Put the html back into the grouping.
$('.grouping').each(function(index, grouping){
var lines = grouping.innerHTML.trim().split("\n");
var lineNumber = 0;
var v = grouping.getAttribute('v');
lines.forEach(function(line, index){
if (line.startsWith('----')) {
lines[index] = '('+ (++lineNumber) + v +') '+ line.slice(4);
}
});
grouping.innerHTML = lines.join('\n');
});
.grouping { white-space: pre; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="grouping" v="a">
----My first step
----This is another
I should not have a line number.
----And another
</span>
<br/>
<span class="grouping" v="b">
I also should not have a line number.
----second group
----second group 2
</span>
You can use split to split the text at '----' and concat with the values (added brs for lisibility so I used html instead of text):
$(function(){
$(".grouping").each(function(){
var val=$(this).attr("v");
var arr = $(this).html().split('----');
if(arr.length > 1){
var str = arr[0], i, l = arr.length;
for(i = 1; i < l; i++){
str += '(' + i + val + ') ' + arr[i];
}
$(this).html(str);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="grouping" v="a">
----My first step<br>
----This is another<br>
----And another<br>
</span>
<br/>
<span class="grouping" v="b">
----second group<br>
----second group 2<br>
</span>
.find() will not work. You should get text of the element and split() it and then change it using map() and replace() and reset text()
$(function(){
$(".grouping").each(function(){
var val=$(this).attr("v");
var counter=1;
let lines = $(this).text().split('\n');
lines = lines.map(ln => {
if(ln.includes('----')){
ln = ln.replace('----',`(${counter}${val})`)
counter++;
}
return ln;
})
lines = lines.filter(ln => ln !== '');
$(this).text(lines.join('\n'));
});
});
.grouping { white-space: pre; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="grouping" v="a">
----My first step
----This is another
----And another
</span>
<br/>
<span class="grouping" v="b">
----second group
----second group 2
</span>
First, I suggest wraping those groups into some kind of tag. for example, span:
<span class="grouping" v="a">
<span class="grouping-item">My first step</span>
</span>
And so on, it will be easier and faster to target those elements.
Then create one function to search through those new tags
$(function(){
// This will create those numbers
function createNumbers(el) {
const mainGroup = el.attr("v");
const children = el.children(".grouping-item");
let i = 1;
children.each(function(){
const currentText = $(this).text();
$(this).text( '('+i+mainGroup+')' + currentText );
i++;
});
}
$(".grouping").each(function(){
createNumbers($(this));
});
});

Get last part of the url

Trying to get the last part of the url in a pretty weird html structure. Don't ask why it's built that way. There is a very good reason behind it.
The html looks like this
<li class="lifilter"><input type="checkbox" class="filtercheck" id="Cheeks...">
<label for="Cheeks...">
Cheeks
</label>
</li>
and the js i'm trying to use
$('#Cheeks... label a').each(function(){
var lasturl = $(this).attr('href');
var urlsplit = url.split("/");
var finalvar = urlsplit[4];
$(this).addClass(finalvar);
});
edit: damn.. i can only post once every 90 minutes.
here is updated question with updated html
<li class="lifilter">
<input type="checkbox" class="filtercheck" id="Cheeks...">
<label for="Cheeks...">
Cheeks
</label>
</li>
and the js code i'm trying to use (from a previous answer)
$('.lifilter').each(function(){
$(this).find(".filtercheck").next('label').find('a').each(function(){
var lasturl = $(this).attr('href');
var urlsplit = lasturl.split("/");
console.log(urlsplit);
var finalvar = urlsplit.pop();
console.log('Adding class: ' + finalvar);
$(this).addClass(finalvar);
});
});
OK, so it appears no one here attempted to try the solution here before posting.
First things first cheeks.... This is a tricky ID to find (You have to escape the periods). The label is also not part of the internal html where ID is cheeks..., so we need to find the adjacent element and look the a anchor tag you're looking for.
Here's the code:
$(document).ready(function() {
$('#Cheeks\\.\\.\\.').next('label').find('a').each(function(){
var lasturl = $(this).attr('href');
var urlsplit = lasturl.split("/");
console.log(urlsplit);
var finalvar = urlsplit.pop();
console.log('Adding class: ' + finalvar);
$(this).addClass(finalvar);
});
});
And here is a working jsfiddle with the solution.
keeping it simple like your code you'd do
finalvar = urlsplit[urlsplit.length-1];
in case you don't want the base url as a valid return then:
finalvar = ( urlsplit.length > 1 ? urlsplit[urlsplit.length-1] : "" );
replace "" with your preferred error/default return
you could also try to find the index of the last '/' and do a substring.
try this.
FIDDLE DEMO
var URI = 'www.example.com/sub1/sub2/sub3/',
parts = URI.split('/'),
lastPart = parts.pop() == '' ? parts[parts.length - 1] : parts.pop();
//RESULT : "sub3"
You can extract the last section of a path (i.e. everything after the last /) by using a regular expression:
text.replace(/.*\//g, "")
This will remove all of the text before a slash, as well as the slash itself. You'll also notice that your selector wasn't matching any elements; you're looking for labels nested within inputs, which doesn't match the html you posted (and isn't a valid DOM structure). An appropriate selector would be .lifilter label a, since the <label> is within the <li>.
$(function() {
setTimeout(function() {
$('.lifilter label a').each(function() {
// strip everything up to and including the last forward slash
var path = $(this).attr('href').replace(/.*\//g, "");
$(this).addClass(path);
});
}, 1500);
});
a.cheeks:after {
content: " (className = 'cheeks')";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<li class="lifilter">
<input type="checkbox" class="filtercheck" id="Cheeks...">
<label for="Cheeks...">
Cheeks
</label>
</li>
if you want the last section of url for example activation code or id.You can try this.
var url = 'www.abc.com/code=12345',
parts = url.split('='),
lastPart = parts.pop()
//lastPart = 12345

Is there a way to use document.write() and not overlap everything?

I have this HTML/Javascript code and I want to be able to print the product of a function inside the body of my code. Here is my code:
<form>
<div class="answer1wrap">
<label>Select your top champion:</label>
<select id="topSelect">
<option value="void">Select a champion</option>
<option value="aatrox">Aatrox</option>
<option value="ahri">Ahri</option>
<option value="akali">Akali</option>
</select>
</div>
</form>
<button class="btn btn-default" id="checkbtn" onclick="topAnswer();" type="button"><span class="glyphicon glyphicon-check"></span> Calculate Win Chance</button>
The JavaScript I have is this:
< script >
function topAnswer() {
var element = document.getElementById("topSelect");
var elementValue = element.value;
if (elementValue == "aatrox") {
document.write("You selected Aatrox for your teams top lane champion");
}
}
< /script>
If you select "Aatrox" it executes the document.write and prints what I want it to. But I don't want to to overwrite everything. What do I use to make my message appear after the "The top champion you selected is" line.
Here is a jsbin of the console: http://jsbin.com/eSiveyU/2/
Thanks
You have to create an additional DOM element and put the result value there. Quick example: http://jsbin.com/OkERuQeJ/1
document.getElementById("selectionResult").innerHTML = elementValue;
This might help you. http://jsfiddle.net/KPz6X/embedded/result/
I have created a div which will display your result below your button. No need to use document.write(). You can simple use the text() method of jQuery to modify the text of the div.
HTML
<form>
<div class="answer1wrap">
<label>Select your top champion:</label>
<select id="topSelect">
<option value="void">Select a champion</option>
<option value="aatrox">Aatrox</option>
<option value="ahri">Ahri</option>
<option value="akali">Akali</option>
</select>
</div>
</form>
<button class="btn btn-default" id="checkbtn" type="button"><span class="glyphicon glyphicon-check"></span> Calculate Win Chance</button>
<div class="display">
<p>The top champion you selected is: </p>
</div>
jQuery
$(document).ready(function(){
$(".btn-default").on('click', function () {
if ($("#topSelect").val() == "aatrox") {
$(".display p").text("You selected Aatrox for your teams top lane champion.");
}
});
});
You can store the message 'The top champion you selected is:' in variable once and concate it with selected option and display it in result box. The code would be for this.
function topAnswer(){
var element = document.getElementById("topSelect");
var elementValue = element.value;
if(elementValue == "aatrox"){
var div = document.getElementsByClassName('display')[0];
var ptag = div.getElementsByTagName('p')[0];
if(typeof greeting == 'undefined'){
greeting = ptag.innerHTML;
}
ptag.innerHTML = greeting + elementValue;
}
}
document.getElementById('checkbtn').addEventListener('click', topAnswer);
Here is the Demo.
Hey FYI your question does not contain all the HTML, making it very confusing. Thankfully the jsbin does.
I don't think document.write() is the right way, because of this:
Why is document.write considered a "bad practice"?
First, you need to wrap "The top champion you selected is:" in a span with an id.
<span id='bottomText'>The top champion you selected is:</span>
If you want to use pure JavaScript, here is what to do:
http://jsbin.com/EzUNuTUy/1/edit
Taken from here: How to do insert After() in JavaScript without using a library?
<script>
//This function will insert a node after an element
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function topAnswer(){
var element = document.getElementById("topSelect");
var elementValue = element.value;
if(elementValue == "aatrox"){
var el = document.createElement("span");
el.innerHTML = "You selected Aatrox for your teams top lane champion.";
var div = document.getElementById("bottomText");
insertAfter(div, el);
}
}
</script>
If you want to use jQuery, it is really easy:
<script>
function topAnswer(){
var element = document.getElementById("topSelect");
var elementValue = element.value;
if(elementValue == "aatrox"){
$("You selected Aatrox for your teams top lane champion.").insertAfter($("#bottomText"));
}
}
</script>
You seem to be new to HTML/JavaScript, I would definitely recommend learning a library like jQuery. It will make your life much easier.

How to add array items to <li> Jquery

I'm working on something really simple, a short quiz, and I am trying to make the items I have listed in a 2-d array each display as a <li>. I tried using the JS array.join() method but it didn't really do what I wanted. I'd like to place them into a list, and then add a radio button for each one.
I have taken the tiny little leap to Jquery, so alot of this is my unfamiliarity with the "syntax". I skimmed over something on their API, $.each...? I'm sure this works like the for statement, I just can't get it to work without crashing everything I've got.
Here's the HTML pretty interesting stuff.
<div id="main_">
<div class="facts_div">
<ul>
</ul>
</div>
<form>
<input id="x" type="button" class="myBtn" value="Press Me">
</form>
</div>
And, here is some extremely complex code. Hold on to your hats...
$(document).ready (function () {
var array = [["Fee","Fi","Fo"],
["La","Dee","Da"]];
var q = ["<li>Fee-ing?","La-ing?</li>"];
var counter = 0;
$('.myBtn').on('click', function () {
$('#main_ .facts_div').text(q[counter]);
$('.facts_div ul').append('<input type= "radio">'
+ array[counter]);
counter++;
if (counter > q.length) {
$('#main_ .facts_div').text('You are done with the quiz.');
$('.myBtn').hide();
}
});
});
Try
<div id="main_">
<div class="facts_div"> <span class="question"></span>
<ul></ul>
</div>
<form>
<input id="x" type="button" class="myBtn" value="Press Me" />
</form>
</div>
and
jQuery(function ($) {
//
var array = [
["Fee", "Fi", "Fo"],
["La", "Dee", "Da"]
];
var q = ["Fee-ing?", "La-ing?"];
var counter = 0;
//cache all the possible values since they are requested multiple times
var $facts = $('#main_ .facts_div'),
$question = $facts.find('.question'),
$ul = $facts.find('ul'),
$btn = $('.myBtn');
$btn.on('click', function () {
//display the question details only of it is available
if (counter < q.length) {
$question.text(q[counter]);
//create a single string containing all the anwers for the given question - look at the documentation for jQuery.map for details
var ansstring = $.map(array[counter], function (value) {
return '<li><input type="radio" name="ans"/>' + value + '</li>'
}).join('');
$ul.html(ansstring);
counter++;
} else {
$facts.text('You are done with the quiz.');
$(this).hide();
}
});
//
});
Demo: Fiddle
You can use $.each to iterate over array[counter] and create li elements for your options:
var list = $('.facts_div ul');
$.each(array[counter], function() {
$('<li></li>').html('<input type="radio" /> ' + this).appendTo(list);
}
The first parameter is your array and the second one is an anonymous function to do your action, in which this will hold the current element value.
Also, if you do this:
$('#main_ .facts_div').text(q[counter]);
You will be replacing the contents of your element with q[counter], losing your ul tag inside it. In this case, you could use the prepend method instead of text to add this text to the start of your tag, or create a new element just for holding this piece of text.

How to get the html element from jquery object

I have a html like follows.
<tr class="meta-info" id="${page.id}">
<td>
<div class="pull-left">
<font size="1">
Like
</font>
</div>
<div class="pull-right" style="font-size:1">
<span class="badge"><i class="icon-thumbs-up"></i>1</span>
</div>
</td>
</tr>
I am trying to increase the number of likes when ever the user cliks on Like hyperlink.
Here is my jquery code. I want to know how i can get the html element from the jquery object.
$(".like").click(function(event){
var parentTr = $(event.target).closest("tr");
if(parentTr.length){
var pageId = parentTr.attr("id");
var spanEle = parentTr.get(0)+" div span:first-child"; ------(1)
var lastNumber = parseInt(spanEle.text());
spanEle.text(lastNumber+1);
}
});
I don't know if i am doing right on line which is marked 1.
I think you need to add an extra <span> tag so that you can replace the count without touching the adjacent icon
<span class="badge"><i class="icon-thumbs-up"></i>
<span class="like-count">1</span>
</span>
then you can address it
$(".like").click(function() {
var spanEle = $(this).closest('tr').find('.like-count').first();
if (spanEle.length) {
var newCount = parseInt(spanEle.text());
spanEle.text(newCount + 1);
}
});
In an event handler, the this reference is event.target. You may be able to handle the element doesn't exist case neater than that too but that way's safe.
JSFiddle demo: http://jsfiddle.net/rupw/VfCvK/
Try this...
$(".like").click(function(event) {
var parentTr = $(event.target).closest("tr");
if (parentTr.length) {
var pageId = parentTr.attr("id");
var spanEle = parentTr.first('.badge');
var lastNumber = parseInt(spanEle.text(), 10);
spanEle.text(lastNumber + 1);
}
});
If the span element always has that classname then it will find the first (only?) one and return an int value of the text within.
Try: Fiddle
var lastNumber = parseInt(parentTr.find('.pull-right span').text(), 10);
You code will look like:
$(".like").click(function(event) {
var parentTr = $(event.target).closest("tr");
if (parentTr.length) {
var pageId = parentTr.attr("id");
var spanEle = parentTr.find('.pull-right span');
var lastNumber = parseInt(spanEle.text(), 10);
spanEle.text(lastNumber + 1);
}
});
Update: If you wish to keep the <i> tag then use:
spanEle.html(spanEle.html().replace(lastNumber, lastNumber + 1));
insteadof : spanEle.text(lastNumber + 1);
Sample

Categories

Resources