#1
  1. For POny!
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Location
    Amsterdam
    Posts
    416
    Rep Power
    115

    Search words in text that contain search value


    Hi guys,

    I have been messing around with some code today and pretty much searched my butt off to find what I was looking for. In a nutshell I want to be able to let someone search within the text and than pretty much give an array of all actual words within the page that contain the input. (like an autocomplete, NOte i tried jquiry ui autocomplete, but that requires a nicely formatted array, which I don't have. I have just random text)

    This is what I got so far.
    javascript Code:
     
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" lang="nl">
        <head><meta charset="UTF-8" />       
     
            <title></title>
     
            <style type="text/css">
                .on{color:red;}
                #maintext{padding:20px;background:#f9f9f9;margin:20px 0;}
                #output{padding:20px;line-height: 150%;border:1px solid #eee;border-radius:10px;}
            </style>
        </head>
        <body>
            <form action="" method="post">
                <input id="searcher" type="text" name="input" value="" />
            </form>
            <div id="maintext">
                <ul>
                    <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna</li>
                    <li>ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</li>
                    <li>dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore</li>
                    <li>consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</li>
                </ul>
                <strong>tralala</strong>
            </div>
            <div id="output"></div>
            <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
     
            <script type="text/javascript">
                $("#searcher").keyup(function(e){
     
                    $("#maintext li").each(function(){
                        $(this).removeClass('on');
                    });
     
                    var searchterm = $("#searcher").val().toLowerCase();
                    console.log(searchterm);
     
                    $('#maintext:contains("'+searchterm+'")').each(function(){
                        $('li:contains("'+searchterm+'")').addClass('on');
                    });
     
                    /* this is the part I get lost and start messing */
     
                    var text =  $('#maintext li').html();
                    var words = $(text.match(/\w+/mg));
                    var random = [];
     
                    for(var i=0; i<5; i++) {
     
                        random.push(words[i]);
     
                    }
                    $('strong').text(random.join(', '));
     
     
                });            
            </script>
        </body>
    </html>

    I am getting lost where I am pretty much trying to compare the input value (searchterm) against words that match. I have a feeling I am close but I fail to make this condition.

    Anyone has ideas or tips?

    So in a nutshell. if someone types "ab" it should provide a list of all actual words (so not partially) on that page that contain "ab"
    Last edited by aeternus; February 27th, 2013 at 04:09 PM.
  2. #2
  3. CSS & JS/DOM Adept
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jul 2004
    Location
    USA (verifiably)
    Posts
    20,131
    Rep Power
    4304
    $('#maintext li').html(); only gets the contents of the first matched element. What I would suggest is using jQuery's each() method to run a function for each item.

    Is there a particular reason why you made the loop end at "5"? Might not "words.length" be more suitable?

    Before adding each word to the "random" array, you may want to compare it to "searchterm".
    Spreading knowledge, one newbie at a time.

    Check out my blog. | Learn CSS. | PHP includes | X/HTML Validator | CSS validator | Common CSS Mistakes | Common JS Mistakes

    Remember people spend most of their time on other people's sites (so don't violate web design conventions).
  4. #3
  5. For POny!
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Location
    Amsterdam
    Posts
    416
    Rep Power
    115
    Hi kravitz,

    Thanks for your reply. I have tried (i think) what you said but due to my inexperience with javascript it is still not kind of right. The for loop with 5 I pretty much borrowed in my search for functions that i thought could help me This is what i did (with comments so you see what i think)

    javascript Code:
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" lang="nl">
        <head><meta charset="UTF-8" />       
     
            <title></title>
     
            <style type="text/css">
                .on{color:red;}
                #maintext{padding:20px;background:#f9f9f9;margin:20px 0;}
                #output{padding:20px;line-height: 150%;border:1px solid #eee;border-radius:10px;}
            </style>
        </head>
        <body>
            <form action="" method="post">
                <input id="searcher" type="text" name="input" value="" />
            </form>
            <div id="maintext">
                <ul>
                    <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna</li>
                    <li>ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</li>
                    <li>dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore</li>
                    <li>consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</li>
                </ul>
                <strong>tralala</strong>
            </div>
            <div id="output"></div>
            <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
     
            <script type="text/javascript">
                $("#searcher").keyup(function(e){
     
                    $("#maintext li").each(function(){
                        $(this).removeClass('on');
                    });
     
                    var searchterm = $("#searcher").val().toLowerCase();
                    console.log(searchterm);
     
                    $('#maintext:contains("'+searchterm+'")').each(function(){
                        $('li:contains("'+searchterm+'")').addClass('on');
     
                    });
     
                    /* ## changed the stuff below ## */
     
                    var text = '';
                    //ok lets make sure we only run through the li's that contain the searchterm
                    $('#maintext:contains("'+searchterm+'")').each(function(){
                        //add the content of each li to the variable
                        text += $('#maintext li').html()+' '; // posibly a space needed (screw that last one)
     
     
                    });
     
                    //ok we now have a long string (var text)
                    //now we need to pretty much split this string and compare words with the search term
                    //hmm now i am at a cross road
                    //first make an array of words and than maybe compaire
                    var words = $(text.match(/\w+/mg));
                    //console.log('words are '+words);
     
                    var finalArray = []
     
                    for(var i=0; i<words.length; i++) { // loop over array values
                        //compair
                        // hmm i can't use :contains() here
                        if(words[i].match(searchterm)){ // === is too strict
     
                            finalArray.push(words[i][0]);// first element
     
                        }
     
                    }
                    console.log(finalArray);
     
     
                });           
            </script>
        </body>
    </html>
    Last edited by aeternus; February 27th, 2013 at 06:34 PM. Reason: spelling
  6. #4
  7. For POny!
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Location
    Amsterdam
    Posts
    416
    Rep Power
    115
    Hi Kravitz (and hopefully others)

    I have managed to get what I want. Now the question is how would you and others improve it. Any tips and advice are welcome, because it took quite a while to get to this point and there is no turning back. Not to mention I love to improve!

    here is the result. var finalArray does contain exactly the words i want.

    javascript Code:
     
     <script type="text/javascript">
                $("#searcher").keyup(function(e){
     
                    $("#maintext li").each(function(){
                        $(this).removeClass('on');
                    });
     
                    var searchterm = $("#searcher").val().toLowerCase();
                    console.log(searchterm);
     
                    $('#maintext:contains("'+searchterm+'")').each(function(){
                        $('li:contains("'+searchterm+'")').addClass('on');
     
                    });
     
                    /* ## changed the stuff below ## */
     
                    var text = '';
                    //ok lets make sure we only run through the li's that contain the searchterm
                    $('#maintext li').each(function(){
                        //add the content of each li to the variable
                        text +=  $(this).html().toLowerCase()+' '; // posibly a space needed (screw that last one)
     
     
                    });
                    //console.log(text);
                    //ok we now have a long string (var text)
                    //now we need to pretty much split this string and compare words with the search term
                    //hmm now i am at a cross road
                    //first make an array of words and than maybe compaire
                    var words = text.match(/\w+/mg); //#TOD DO PLACE THIS ABOVE THE keyup!!! no need to call this everytime
                    //allWords = words.join();
                    //console.log('words are '+allWords);
     
                    var finalArray = []
                    var re = new RegExp(searchterm, 'g');
     
                    for(var i=0; i<words.length; i++) { // loop over array values
                        //compair
                        // hmm i can't use :contains() here
                        //console.log(words[i]);
     
                        if(words[i].match(re)){ // === is too strict
     
                            finalArray.push(words[i]);// first element
                            //console.log('a: '+words);
                        }
     
                    }
                    console.log('finalArray = '+finalArray);
     
     
                });           
            </script>
    Last edited by aeternus; February 27th, 2013 at 06:47 PM. Reason: spelling
  8. #5
  9. CSS & JS/DOM Adept
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jul 2004
    Location
    USA (verifiably)
    Posts
    20,131
    Rep Power
    4304
    I would suggest replacing
    Code:
    if(words[i].match(re)){
    with (since both strings are lower-case and you're only matching against whole words)
    Code:
    if(words[i].indexOf(searchterm)!=-1){
    OR (because it's much more efficient than match() when you only need to know if the pattern matches)
    Code:
    if(re.test(words[i])){
    I would also suggest merging the calls to each(), like this (untested):
    Code:
                    var searchterm = $("#searcher").val().toLowerCase();
                    console.log(searchterm);
                    
                    var text = '';
                    //ok lets make sure we only run through the li's that contain the searchterm
                    $('#maintext li').each(function(){
                        $(this).removeClass('on');
    
                        if(!$(this).is(':contains("'+searchterm+'")')) return;
    
                        //add the content of each li to the variable
                        text +=  $(this).addClass('on').html().toLowerCase()+' '; // posibly a space needed (screw that last one)
    
                    });
    Last edited by Kravvitz; February 28th, 2013 at 12:22 AM.
    Spreading knowledge, one newbie at a time.

    Check out my blog. | Learn CSS. | PHP includes | X/HTML Validator | CSS validator | Common CSS Mistakes | Common JS Mistakes

    Remember people spend most of their time on other people's sites (so don't violate web design conventions).
  10. #6
  11. For POny!
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2012
    Location
    Amsterdam
    Posts
    416
    Rep Power
    115
    Hi Kravitz!

    Thanks for your reply and the suggestions, i'll sure test them out and read up on indexOf() and test()

    Good point on merging the code inside one each() function. I was aware of it, but for ease of mind I seperated them

    Thanks again for your help and suggestions!

IMN logo majestic logo threadwatch logo seochat tools logo