Tao Schencks
Tao Schencks

Reputation: 57

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...

  1. perform a jquery .each on the textarea values.
  2. perform a jquery to grab each of the <li> values
  3. so some sort of regex to match the content of the textarea's and count the words.
  4. update the .text of the correct to show the value.

Upvotes: 0

Views: 2558

Answers (2)

David Thomas
David Thomas

Reputation: 253496

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:

Upvotes: 2

Barmar
Barmar

Reputation: 782624

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

Upvotes: 1

Related Questions