0

ive been doing this for a week. still couldnt find the answer. i am trying to convert only some of the keyword to link instead of all. for example if theres 7 keywords in a paragraph, how can i only convert 3 of it? can someone help? please

currently this is my code.

(function($) {


       $.fn.replacetext = function(target, replacement) {
             // Get all text nodes:
             var $textNodes = this

                    .find("*")
                     .andSelf()
                     .contents()
                     .filter(function() {
                         return this.nodeType === 3 && 
                             !$(this).parent("a").length;
                     });

             $textNodes.each(function(index, element) {
                 var contents = $(element).text();
                 contents = contents.replace(target, replacement);
                 $(element).replaceWith(contents);

             });
        };
    })(jQuery);


     $("p").replacetext(/\bdress\b/gi, "<a href='http://www.google.com'>$&</a>");
rmdsf
  • 23
  • 7
  • 1
    what's the criteria? for example, first 3 of it or only specific keywords etc? – gp. Jan 23 '15 at 03:05
  • Is the idea to only replace words that match the `target` regex that you pass in? – mr rogers Jan 23 '15 at 03:06
  • it can be random. anything. as long as its 3. – rmdsf Jan 23 '15 at 03:06
  • Can you give an example? Like ... what should the output be if the paragraph tag has "this is a fine dress. we like dresses like these. So if you dress in a dress, we want your address to send the new dress"? – mr rogers Jan 23 '15 at 03:08

1 Answers1

1

I would suggest using a limit on the function, then checking if the count of the matched item in the set of items matched so far exceeds this limit. The following will modify the first max items.

(function($) {
   $.fn.replacetext = function (target, replacement, max) {
       var limit = max || -1;

       // Get all text nodes:
       var $textNodes = this  
           .find("*")
           .andSelf()
           .contents()
           .filter(function () {
           return this.nodeType === 3 && !$(this).parent("a").length;
       });

       $textNodes.each(function (index, element) {
           var $element = $(element);
           var words = $element.text().split(/\b/);
           var matches = 0;
           var text = words.map(function (word, index) {
               if (matches >= limit) {
                   return word;
               }

               if (word.match(target)) {
                   ++matches;
                   return word.replace(target, replacement);
               }

               return word;
           });

           $element.replaceWith(text.join(''));
       });
   };
})(jQuery);

Used as

$("p").replacetext(/dress/i, "<a href='http://www.google.com'>$&</a>", 3);

In the case where you want all, simply omit the max value and it should default to all the keywords.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • I see the problem. I was assuming that the code broke the paragraph into it's component words and iterated over them. Serves me right for not reading the code more carefully. It looks like you only want to match whole words, is that correct? – tvanfosson Jan 23 '15 at 03:44
  • @fsdmr fixed. Had to significantly modify the code. See fiddle at http://jsfiddle.net/n2tguhom/ – tvanfosson Jan 23 '15 at 04:15
  • how can i make it random? i dont want to select only first three, but i want it to be random. please help. @tvanfosson – rmdsf Jan 27 '15 at 03:54
  • @rmdsf - count the number of occurrences of the word. Construct an array of that size where each element is equal to it's index, e.g., `[0, 1, 2, ...]` Shuffle that array (http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript) and truncate it at the number of words that you want to select. This gives you the (random) indices of the words to translate. In each iteration of the translation loop, check to see if the value of `index` is in the list of selected indices, if not continue, if so, then translate. If the count is less than you need, do them all. – tvanfosson Jan 27 '15 at 13:53
  • thanks i got it but i thought u only display 3 keyword? but at the fiddle, its more than 3. – rmdsf Jan 30 '15 at 08:46
  • @rmdsf 3 per paragraph - if you only want 3 per page, you'd have to select the container for all of the paragraphs rather than each paragraph element separately. So, for example, your "article" was in a `DIV` with class `content`, `$('.content').replacetext(...)` – tvanfosson Jan 31 '15 at 16:58