Hi all.

I've built an "auto search" plugin (or live search to give it another
name) using jQuery 1.2.1 which does an ajax call as letters are typed
into an input box.

It works flawlessly in firefox, opera and safari, but in IE7 and IE6
jQuery fails at line 906:

                        if ( value != undefined ) elem[name] = value;

the value of um, value is "NaNpx"

I've done some digging around the web and a have found mention of this
problem ( here: http://dev.jquery.com/ticket/1861 ), but without any
fixes. As far as I can work it it stems from IE returning some border
measurements as non-integers ("medium" for example"). I am explicitly
setting my borders to pixel values so I'm not sure if this is relevant
to my problem.

Here's my code:

HTML:

<html>
<head>
<title>Autosearch demo</title>
<script src='js/jquery-1.2.1.js'></script>
<script src='js/f8.jquery.autosearch.js'></script>
<link rel='stylesheet' type='text/css' href='css/
f8.jquery.autosearch.css'>

<script>
$(document).ready(function () {

        $("#search").autosearch("rpc.php");

});
</script>

<style>
* {
        margin: 0;
        padding: 0;
  border: 0;
}
html {
        font-family: verdana, sans-serif;
}
body {
        margin: 1em;
}

fieldset {
        padding: .25em;
}
</style>
</head>
<body>
        <h1>Autosearch demo</h1>
        <form>
                <fieldset>
                        <legend>search</legend>
                        <div><label for='search'>search for</label> <input 
id='search'
name='search1' type='text' /></div>
                </fieldset>
        </form>
</body>
</html>


f8.jquery.autosearch.js:

/**
 * autosearch
 * uses ajax to peform as you type search queries
 * @usage: $("#input_box").autosearch(url);
 */
jQuery.fn.autosearch = function(url) {

        var timeout = undefined; // used to ensure queries are sent only when
typing has stopped

        var delay = 500; // delay (in ms) after the last keystroke to wait
before we do the ajax call

        var last_search = undefined; // stores last search query to cut down
on roundtrips

        var $input = $(this); // input element

        // append the hidden search results container to the dom after the
input element
        var $result = $("<ul class='autosearch_result'></
ul>").hide().css("position", "absolute").insertAfter($input);

        // switch off the browser auto complete for the input box
        $input.attr("autocomplete", "off").addClass("autosearch_input");

        $input.blur(function () {

                setTimeout(function() {
                        $result.hide()}, 200
                );

        });

        // bind the ajax call to the input box key up event
        $input.keyup(function() {

                if(timeout != undefined) {
                        clearTimeout(timeout);
                }

                if (last_search != $input.val()) {

                        // new search is different to the last search

                        timeout = setTimeout(function() {

                                timeout = undefined;
                                ajax_search();
                                last_search = $input.val(); // remember this 
search so we don't do
it again next time

                        }, delay);

                }

        });

        function ajax_search() {

                $result.hide().empty();

                if ($input.val() != "") {

                        // only search if we have something to search for

                        $input.addClass("autosearch_loading"); // adds the ajax 
anim to the
input box

                        // perform the ajax call
                        $.ajax({

                                url: url + "?q="+$input.val(),

                                success: function(data) {

                                        if ($.trim(data) == "") {

                                                $result.hide();

                                        }
                                        else {

                                                // append the results to the 
results container
                                                $result.append(data);

                                                // re-position the results 
container in case the dom has changed

                                                var pos = 
findPos(document.getElementById($input.attr("id")));

                                                $result.css({
                                                        top: (pos.y + 
$input.offsetHeight) + "px",
                                                        left: pos.x + "px"
                                                }).show();

                                        }

                                },
                                complete: function () {
                                        // hide the ajax anim
                                        
$input.removeClass("autosearch_loading");
                                }

                        });

                }

        }

        /**
         * works out the screen position of an element
         */
        function findPos(obj) {

                var curleft = obj.offsetLeft || 0;
                var curtop = obj.offsetTop || 0;

                // work our way back up the dom till we have no more parents
                while (obj = obj.offsetParent) {

                        curleft += obj.offsetLeft
                        curtop += obj.offsetTop

                }

                return {
                        x:curleft,
                        y:curtop
                };

        }

}

f8.jquery.autosearch.css:

.autosearch_input {
        border: 1px solid #CCC;
        padding: 1px 18px 1px 1px;
}
.autosearch_result {
        width: 20em;
        border: 1px solid #CCC;
        background: #FFF;
        list-style: none;
        font-size: .8em;
}
.autosearch_result li {
        border-bottom: 1px solid #CCC;
        padding: 2px;
}
.autosearch_result h2 {
        font-size: 1em;
}
.autosearch_result p {
        margin-left: 1em;
        font-style: italic;
}
.autosearch_loading {
        background: url(../img/indicator.gif) no-repeat top right;
}


I had a dig around in the jQuery source (great work by the way guys!)
and tried the following fix:

                        if ( value != undefined && value != "NaNpx") elem[name] 
= value;

Which stops the error, but my popup window is now appearing over the
top of the input box.

I've tried the latest nightly build and still get the same error.

Any help resolving this would be greatly appreciated.

Thanks in advance,
Richard.

Reply via email to