jQuery select paragraphs with minimum contained text character count - javascript

I'm trying to target paragraphs with a minimum of 500 character. Then use them as a selector to insert a div.in-between every 3 of those paragraphs that meet this criteria.
I know we can do page and individual paragraph text character count using:
Text character count: $('div.container').text().replace(/[^A-Z]/gi,'').length;
Paragraph count: $('div.container p').text().split(' ').length;
How do I accomplish this using jQuery?

You can use a filter to target elements with a minimum of 500 characters.
The \W regex removes anything that does not match a-z, A-Z, 0-9 and underscore.
Once the collection is filtered you can use $.grep to get every third element and insert a div after each of those elements.
var paragraphs = $('p').filter(function() {
return $(this).text().replace(/\W/g, '').length > 500;
});
var nth3 = $.grep(paragraphs, function(_, index) {
return (index + 1) % 3 === 0;
})
$(nth3).after('<div class="in-between"></div>');
FIDDLE

Related

add a dash to a specific digits entered by the user

I did find this function in jQuery that add a dash after very four numbers, but I would like to add a dash to a number entered by the user with the follow format:
1234-1234556-123-1
but I could manage to get it, could you please help me, this is the jQuery function that formats the follow: 1234-1234-1234-1
$('.creditCardText').keyup(function() {
var foo = $(this).val().split("-").join(""); // remove hyphens
if ((foo.length > 0) && (foo.length < 14)) {
foo = foo.match(new RegExp('.{1,4}', 'g')).join("-");
}
$(this).val(foo);
});
You need to use parenthetical matching groups. Put the pattern in parenthesis. This will return an array with the whole match, followed by the parenthetical matches, followed by some match info. So, you have to slice out array elements 1-4, and then join them with dashes. Because some of the matches may be empty, you can clean up with another replace that removes trailing dashes:
Edit: You could also remove all non-numeric characters, instead of just hyphens. (See second line)
$('.creditCardText').keyup(function() {
var foo = $(this).val().replace(/\D/g, ""); // remove non-numerics
if ((foo.length > 0) && (foo.length < 16)) {
foo = foo.match(new RegExp('(\\d{1,4})(\\d{0,7})(\\d{0,3})(\\d?)')).slice(1,5).join("-").replace(/\-+$/, '');
}
$(this).val(foo);
});
Demo: https://jsfiddle.net/oohfksjd/
It is more RegExp issue, not JavaScript.
RegExp('(.{1,4})(.{1,7})(.{1,3})(.{1,1})', 'g')

Getting line number from index of character in file

I have a string input which consists of words. I am using regex.exec (g) to get all the words by function getWord(input)
So my input may look like this:
word word2
someword blah
What I get from from exec is object containing index of match. So it is array like:
[ 'word', index: 0, input: "..."]
...
[ 'someword', index: 11, input: "..."]
...
What I need is to easily calculate that word "someword" is on line 2 by using the index(11) (as I don't have any other value telling me what is the number of lines)
Here is what I came up with: Match '\n's until you match \n with higher index then is index of word. Not sure if this may not be problematic in 10k lines file.
Snippet for idea:
getLineFromIndex: (index, input) ->
regex = /\n/g
line = 1
loop
match = regex.exec(input)
break if not match? or match.index > index
line++
return line
Kinda big optimalization can be done here. I can save the regex and last match, so I won't iterate all the input every time I want to check for line number. Regex will then be executed only when the last match has lower index then current index.
This is the final idea with optimization:
###
#variable content [String] is input content
###
getLineFromIndex: (index) ->
#lineMatcher = #lineMatcher || /\n/g
#lastLine = #lastLine || 1
if #eof isnt true
#lastMatch = #lastMatch || #lineMatcher.exec(#content)
if #eof or index < #lastMatch.index
return #lastLine
else
match = #lineMatcher.exec(#content)
if not #eof and match is null
#eof = true
else
#lastMatch = match
#lastLine++
return #lastLine
Cut input (a.substr(0, 11)).
Split it (a.substr(0, 11).split('\n')).
Count it (a.substr(0, 11).split('\n').length).
Your pseudo-code seems to do the job.
But I do not see how you can infer the line number by the offset of the searched word.
I would split the input text by lines, then look over the array for the searched word, and if found return the line index.
var input= "word word2 \n"+
"someword blah";
function getLinesNumberOf( input, word){
var line_numbers=[];
input.split("\n").forEach(function(line, index){
if( line.indexOf(word)>=0 ) line_numbers.push(index);
});
return line_numbers;
}
console.log(getLinesNumberOf(input,"someword"));
I have add support for multiple occurences of the searched word.
edit
To avoid too memory consumption with large inputs, you can parse sequentially (for the same avantanges of SAX vs DOM):
function getLinesNumberOf( word, input ){
input+= "\n";//make sure to not miss the last line;
var line_numbers=[], current_line=0;
var startline_offset=0;
do{
//get the offset next of the next breakline
endline_offset= input.indexOf("\n",startline_offset);
//get the offset of the searched word in the line
word_offset= input.substring(startline_offset,endline_offset).indexOf(word, 0);
//check if the searched word has been found and if it has been found on current_line
if( word_offset >= 0 && word_offset < endline_offset ) {
//if true the current_line is stored
line_numbers.push(current_line);
}
//the offset of the next line is just after the breakline offset
startline_offset= endline_offset+1;
current_line++;
}while(endline_offset>=0);//we continue while a breakline is found
console.log(line_numbers);
}

Count Specific Words Using Jquery

I have the following HTML code:
<ul>
<li>apples <span id="apples-density">1</span></li>
<li>pears <span id="pears-density">0</span></li>
<li>oranges <span id="oranges-density">2</span></li>
</ul>
<textarea>This is where I love to eat apples and oranges</textarea>
<textarea>I also like oranges on Sundays!</textarea>
What I would to achieve is that when ever the textarea is updated (on key up), the density of the 3 specific words is counted and then the value inside the SPAN is updated.
However, the page can contain up to 10 words that will need to be counted and also an unlimited number of TEXTAREA elements. And... the actual 3 words that are being counted are different each time, so the code has to allow for some sort of automation.
I can sort of see how it should work in my head, but not quite how to implement...
perform a jquery .each on the textarea values.
perform a jquery to grab each of the <li> values
so some sort of regex to match the content of the textarea's and count the words.
update the .text of the correct to show the value.
My own suggestion would be:
function wordsUsed(){
// get all the text from all the textarea elements together in one string:
var text = $('textarea').map(function(){
return $(this).val();
}).get().join(' '),
reg;
// iterate over the span elements found in each li element:
$('li > span').each(function(i,el){
// cache the variable (in case you want to use it more than once):
var that = $(el);
// create a RegExp (regular expression) object:
// the '\\b' is a word boundary double-escaped because it's a string;
// we shorten the id of the current element by removing '-frequency'
// (I didn't think 'density' was an appropriate description) to find
// the word we're looking for;
// 'gi' we look through the whole of the string (the 'g') and
// ignore the case of the text (the 'i'):
reg = new RegExp('\\b' + el.id.replace('-frequency','') + '\\b', 'gi');
// we look for the regular-expression ('reg') matches in the string ('text'):
var matched = text.match(reg),
// if matched does not exist (there were no matched words) we set
// the count to 0, otherwise we use the number of matches (length):
matches = !matched ? 0 : matched.length;
// setting the text of the current element:
that.text(matches);
});
}
$('textarea')
// binding the keyup event-handler, using 'on()':
.on('keyup', wordsUsed)
// triggering the keyup event, so the count is accurate on page-load:
.keyup();
JS Fiddle demo.
The above works on the (pedantically) modified HTML:
<ul>
<li>apples <span id="apples-frequency"></span>
</li>
<li>pears <span id="pears-frequency"></span>
</li>
<li>oranges <span id="oranges-frequency"></span>
</li>
</ul>
<textarea>actual text removed for brevity</textarea>
<textarea>actual text removed for brevity</textarea>
References:
'Plain' JavaScript:
JavaScript regular expressions.
RegExp().
String.prototype.match().
String.prototype.replace().
jQuery:
each().
get().
map().
on().
text().
// Get all the textarea values
var all_text = '';
$('textarea').each(function() {
all_text += ' ' + $(this).text();
}
// Process each of the LIs
$('li span').each(function() {
var word = this.id.split('-')[0]; // Get the search word
// Convert it to a regular expression. Use 'g' option to match all occurrences.
var regex = new RegEx('\b'+word+'\b', 'g');
var count = all_text.match(regex).length;
$(this).text(count);
}

Using String.substring for Words

I have the following example where I am putting a limit on the characters entered in the Textarea:
var tlength = $(this).val().length;
$(this).val($(this).val().substring(0, maxchars));
var tlength = $(this).val().length;
remain = maxchars - parseInt(tlength);
$('#remain').text(remain);
where maxchars is the number of characters. How can I change this example to work with words, so instead of restricting chars, I restrict to a number of words.
http://jsfiddle.net/PzESw/106/
I think you need to change one string of your code to something like this:
$(this).val($(this).val().split(' ').slice(0, maxchars).join(' '));
This code splits text in an array of words (you may need another workflow), removes extra words and joins them back
A simple way would be to converting the full String into array of words.
For example you're having a String as:
var words = "Hi, My name is Afzaal Ahmad Zeeshan.";
var arrayOfWords = words.split(" "); // split at a white space
Now, you'll have an array of words. Loop it using
for (i = 0; i < words.length; i++) {
/* write them all, or limit them in the for loop! */
}
This way, you can write the number of words in the document. Instead of characters!

Find previous <p> after nth character?

I want to create a "Read more" button that appears if an elements contains over 1700 characters.
I have achieved this as such:
var textlength = $(this).text().length;
if(textlength > 1700){
$(this).html($(this).html().substring(0, 1700));
$(this).append(readmorelink);
};
This removes all characters after the 1700th. But I would like to remove characters from the 1700th and back to the last </p> tag.
Does anyone know how I can traverse back from an nth character to a specific element?
Fiddle here: http://jsfiddle.net/xvWcH/
Use the lastIndexOf method to find the last occurance of a string before a specific index in the string:
var text = $(this).html();
var index = text.lastIndexOf('</p>', 1700);
$(this).html(text.substring(0, index + 4));

Categories

Resources