Find previous <p> after nth character? - javascript

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));

Related

regex replace first element

I have the need to replace a HTML string's contents from one <br> to two. But what I can't achieve is when I have one tag following another one:
(<br\s*\/?>)
will match all the tags in this text:
var text = 'text<BR><BR>text text<BR>text;'
will match and with the replace I will have
text = text.replace.replace(/(<br\s*\/?>)>/gi, "<BR\/><BR\/>")
console.log(text); //text<BR/><BR/><BR/><BR/>text text<BR/><BR/>text;"
Is there a way to only increment one tag with the regex? And achieve this:
console.log(text); //text<BR/><BR/><BR/>text text<BR/><BR/>text;"
Or I only will achieve this with a loop?
You may use either
var text = 'text<BR><BR>text text<BR>text;'
text = text.replace(/(<br\s*\/?>)+/gi, "$&$1");
console.log(text); // => text<BR><BR><BR>text text<BR><BR>text;
Here, (<br\s*\/?>)+/gi matches 1 or more sequences of <br>s in a case insensitive way while capturing each tag on its way (keeping the last value in the group beffer after the last it, and "$&$1" will replace with the whole match ($&) and will add the last <br> with $1.
Or
var text = 'text<BR><BR>text text<BR>text;'
text = text.replace(/(?:<br\s*\/?>)+/gi, function ($0) {
return $0.replace(/<br\s*\/?>/gi, "<BR/>") + "<BR/>";
})
console.log(text); // => text<BR/><BR/><BR/>text text<BR/><BR/>text;
Here, the (?:<br\s*\/?>)+ will also match 1 or more <br>s but without capturing each occurrence, and inside the callback, all <br>s will get normalized as <BR/> and a <BR/> will get appended to the result.
You can use negative look ahead (<br\s*\/?>)(?!<br\s*\/?>)/ to increment only the last tag if there are any consecutive:
var text = 'text<BR><BR>text text<BR>text;'
text = text.replace(/(<br\s*\/?>)(?!<br\s*\/?>)/gi, "<BR\/><BR\/>")
console.log(text);

matching a word from the textarea

I am trying to match words strating with # from a textarea
var start=/#/ig; // # Match
var word=/#(\w+)/ig; //#abc Match
var content=$('#text').val();
var go= content.match(start); //Content Matching #
var name= content.match(word); //Content Matching #abc
Here it checks the value in the text area and gives the output word which starts with #
If there is two matches found it's showing the two matches,but i need only the last match
the .match() function returns an array of matches.
If you want to select the last element, you need to select it like this:
name[name.length-1];
name.length returns the number of elements
-1 because array keys start with 0 and not 1
Here is a fiddle, thanks to Dave Briand
Try this
content = "~test content ~thanks ok ~fine";
strFine = content.lastIndexOf('~');
It gives index for last match character or word or string what you have passed...
The re method match usually returns an array. To get the last match, you can use the following:
var name= content.match(word);
var lastMatch = (!!name) ? name.pop() : name;
If there's no match, the method returns null and you want to be sure you do not try to manipulate null as an array.
What about this?
var text = $('textarea').val(); // "#maxi kcdjnd dcjjncd #ijicd"
//Find all ocurrences of words starting with # and ending in space, period or end of text
var lastMatch = text.match(/(#.*?)(\s|$|\.)/g).pop();
// match returns ["maxi", "#ijicd"]. pop will get the last element

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

jQuery select paragraphs with minimum contained text character count

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

Replace last digit occurrence in square brackets

I have a variable like:
var text = 'researchOrganisationTrait.keywords[0].freeKeyword[1].texts[en_GB]';
Which I wish to maintain the index of the last occurrence (dynamic added content)
I have tried using the code like:
var text = 'researchOrganisationTrait.keywords[0].freeKeyword[1].texts[en_GB]';
text = text.replace(/\[\d*](?!.*\[)/, '[newIndex]');
alert(text);
But this does not replace freeKeyword[1] with freeKeyword[newIndex]
How to I match the last occurrence of square digit?
JSFiddle: http://jsfiddle.net/4eALF/
Append \d:
text = text.replace(/\[\d+](?!.*\[\d)/, '[newIndex]')

Categories

Resources