4

I am facing one problem while searching a text. I think it is the issue of regex/replace issue.

My search function is working fine but problem is that when I search for a capital letter "N" all small letter "n" change to capital letters.

Here what i am using... Try search for "N" and you see all small "n" change to capital "N".

http://jsfiddle.net/ravi1989/4BAau/3/

function searchAndHighlight(searchTerm, selector) {
    if (searchTerm) {
        //var wholeWordOnly = new RegExp("\\g"+searchTerm+"\\g","ig"); //matches whole word only
        //var anyCharacter = new RegExp("\\g["+searchTerm+"]\\g","ig"); //matches any word with any of search chars characters
        var selector = selector || "#realTimeContents"; //use body as selector if none provided
        var searchTermRegEx = new RegExp(searchTerm, "ig");
        var matches = $(selector).text().match(searchTermRegEx);
        if (matches != null && matches.length > 0) {
            $('.highlighted').removeClass('highlighted'); //Remove old search highlights  

            //Remove the previous matches
            $span = $('#realTimeContents span');
            $span.replaceWith($span.html());
            var content = "<span class='match'>" + searchTerm + "</span>";
            var replaced = $(selector).text().replace(searchTermRegEx, content);
            $(selector).html(replaced);;
            $('.match:first').addClass('highlighted');

            var i = 0;

            $('.next_h').off('click').on('click', function () {
                i++;

                if (i >= $('.match').length) i = 0;

                $('.match').removeClass('highlighted');
                $('.match').eq(i).addClass('highlighted');
                $('.ui-mobile-viewport').animate({
                    scrollTop: $('.match').eq(i).offset().top
                }, 300);
            });
            $('.previous_h').off('click').on('click', function () {

                i--;

                if (i < 0) i = $('.match').length - 1;

                $('.match').removeClass('highlighted');
                $('.match').eq(i).addClass('highlighted');
                $('.ui-mobile-viewport').animate({
                    scrollTop: $('.match').eq(i).offset().top
                }, 300);
            });




            if ($('.highlighted:first').length) { //if match found, scroll to where the first one appears
                $(window).scrollTop($('.highlighted:first').position().top);
            }
            return true;
        }
    }
    return false;
}

$(document).on('click', '.searchButtonClickText_h', function (event) {

    $(".highlighted").removeClass("highlighted").removeClass("match");
    if (!searchAndHighlight($('.textSearchvalue_h').val())) {
        alert("No results found");
    }


});
Sergio
  • 28,539
  • 11
  • 85
  • 132
Rohit
  • 685
  • 3
  • 13
  • 28
  • You are replacing pieces of the text with the search term, and not just wrapping the matches, and when doing case insensitive searches that doesn't work, you have to keep the text in the original matches and just wrap them with spans. – adeneo Jul 19 '13 at 01:02
  • can you please give me an example ? actually i need if user search for "n" it also search capital "N" but not change the text which is written on page. – Rohit Jul 19 '13 at 01:07
  • 1
    http://jsfiddle.net/4BAau/4/ – adeneo Jul 19 '13 at 01:08
  • As a sidenote : http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – adeneo Jul 19 '13 at 01:10
  • But one more issue if user click special character like & ,% is append in search text .& with &amp , &ls like how to remove that – Rohit Jul 19 '13 at 01:16
  • http://jsfiddle.net/4BAau/5/ – adeneo Jul 19 '13 at 01:19
  • what you do for that can you explain ? so that i will never do in future,, – Rohit Jul 19 '13 at 01:22
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33731/discussion-between-rohit-and-adeneo) – Rohit Jul 19 '13 at 01:23
  • It's just a regex replace, look at the code, I didn't change much! – adeneo Jul 19 '13 at 01:24
  • Do you have any idea of socket programming ?Actually very body suggested me to use pusher socket.io do you have any idea? – Rohit Jul 19 '13 at 01:29
  • can you please whelp in this http://stackoverflow.com/questions/17707575/unexpected-behaviour-shown-while-opening-the-pop-up-screen-in-ipad-usingjquery-m?noredirect=1#comment25817956_17707575 – Rohit Jul 19 '13 at 01:41
  • I'm not very good at node.js or jQuery mobile, post the questions again on a weekday morning as that's usually when most people are on, and see if anyone can help you. – adeneo Jul 19 '13 at 01:50
  • Application crash on using .."(+?)" ? why testing bug – Rohit Jul 19 '13 at 07:07

1 Answers1

1

The main problem is that you're creating a variable that wraps the search term being passed in in a span, not the matches being found. Therefore, when you then replace all regex matches (case insensitive, because "ig") with that wrapped search term, it replaces all instances of that term regardless of case with the exact text passed in. It's worth noting that it happens with every letter, not just N. Any letter you search for in capital form replaces its lowercase counterparts in the document.

To fix this, instead of doing a 1:1 replace (a.replace('thing','otherthing'), try passing in a function as the second parameter. When you do that, each individual match in the string gets passed in to that function and replaced by the function's return value.

For example:

var a = 'abbacca';
var r = new RegExp('A','ig');
a.replace(r, function(m){ 
  return '_' + m + '_'; 
});

// returns '_a_bb_a_cc_a_'

So instead of this:

var content = "<span class='match'>" + searchTerm + "</span>";
var replaced = $(selector).text().replace(searchTermRegEx, content);

try this:

var replaced = $(selector).text().replace(searchTermRegEx, function(m){
  return '<span class="match">' + m + '</span>';
});

Here's the fiddle with that change

Craig Burton
  • 188
  • 1
  • 9