Failure is not an option :: Feel Alive, Skydive

 

Current Articles | Categories | Search | Syndication

LiveSearch content with jQuery

Couple of notes:

  • To avoid Javascript frameworks conflicts here the JQuery object is accessed with JQ instead of the $ symbol.
  • The solution works better when you have better descriptions for the items used in search ranking
  • If you have any improvements to the code please feel free to comment

Javascript code

(function(JQ) {
    JQ.fn.liveUpdate = function(list, childElement) {
        list = JQ(list);
        if (list.length) {
            if (typeof (childElement) == 'undefined') childElement = 'li';
            var rows = list.children(childElement),
                cache = rows.map(function() {
                    return JQ(this).html().toLowerCase();
                });

            this
                .keyup(filter).keyup()
                .parents('form').submit(function() {
                    return false;
                });
        }
        return this;

        function filter() {
            var term = JQ.trim(JQ(this).val().toLowerCase()), scores = [];

            if (!term) {
                rows.show();
            } else {
                rows.hide();

                cache.each(function(i) {
                    var score = this.score(term);
                    if (score > 0) { scores.push([score, i]); }
                });
                JQ.each(scores.sort(function(a, b) { return b[0] - a[0]; }), function() {
                    JQ(rows[this[1]]).show();
                });
            }
        }
    };
})(jQuery);

String.prototype.score = function(abbreviation, offset) {
    offset = offset || 0;

    if (abbreviation.length == 0) return 0.9;
    if (abbreviation.length > this.length) return 0.0;

    for (var i = abbreviation.length; i > 0; i--) {
        var sub_abbreviation = abbreviation.substring(0, i);
        var index = this.indexOf(sub_abbreviation);
        if (index < 0) continue;
        if (index + abbreviation.length > this.length + offset) continue;

        var next_string = this.substring(index + sub_abbreviation.length);
        var next_abbreviation = null;
        if (i >= abbreviation.length)
            next_abbreviation = '';
        else
            next_abbreviation = abbreviation.substring(i);

        var remaining_score = next_string.score(next_abbreviation, offset + index);

        if (remaining_score > 0) {
            var score = this.length - next_string.length;
            if (index != 0) {
                var j = 0;
                var c = this.charCodeAt(index - 1);
                if (c == 32 || c == 9) {
                    for (var j = (index - 2); j >= 0; j--) {
                        c = this.charCodeAt(j);
                        score -= ((c == 32 || c == 9) ? 1 : 0.15);
                    }
                } else {
                    score -= index;
                }
            }

            score += remaining_score * next_string.length;
            score /= this.length;
            return score;
        }
    }
    return 0.0;
};

HTML code

The following HTML code renders an input text box used to type the search filter and the markup of the content to be indexed and searched. I've done this using DIV elements but you can also use liveSearch with unorderder lists (UL elements). <script type="text/javascript">
    JQ(document).ready(
        function() {
            JQ('#snModules_txtSearch').liveUpdate('#snlist', 'div').focus();
        }
    );
</script>

<input name="snModules$txtSearch" type="text" id="snModules_txtSearch" class="NormalTextBox" />

<div id="snlist" style="overflow:auto;width:100%;height:300px"> 
        <div id="dm_5" rel="5" class="module-global "> 
    <div class="reasonbar"> 
        <div class="prod-title">Text<div class="reason"></div></div> 
    </div> 
    <div class="description-bar"> 
        This module renders a snippet of HTML or text. The Html/Text module includes an edit page, which allows authorized users to the HTML or text snippets directly. The snippets are stored in the SQL database. 
    </div> 
</div><div id="dm_61" rel="61" class="module-global "> 
    <div class="reasonbar"> 
        <div class="prod-title">Content Rotator<div class="reason"></div></div> 
    </div> 
</div><div id="dm_128" rel="128" class="module-global News"> 
    <div class="reasonbar"> 
        <div class="prod-title">Articles - News Archive<div class="reason">News</div></div> 
    </div> 
    <div class="description-bar"> 
        Allows you to display a list of articles by month.
    </div> 
</div>
</div>

posted on by Tiago D'Herbe.  98 views.


Digg  del.icio.us  Technorati  StumbleUpon  eKudos  Google  TwitThis  Facebook  YahooMyWeb  YahooBuzz  LinkedIn  E-mail this story to a friend!  

Previous Page | Next Page

Responses to “Search content with jQuery in a live fashion”

    Currently, there are no comments. Be the first to post one!
Click here to post a comment