Zoli
Zoli

Reputation: 1081

jQuery live problem: in select list filter function, live doesn't work with keyup event

I have a jQuery script, which is filtering an html select list. It works fine when I use the keyup event, but I recently tried to use instead the live("keyup", but it doesn't work.

Here is the script:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta name="Description" content="" />
    <meta name="Keywords" content="" />
    <meta name="Distribution" content="Global" />
    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=9" />
    <title>Select list filter</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

    <script type="text/javascript">
//simple keyup
    ;(function($) {
        $.fn.selectFilter = function() {

            var sel = $(this);
            $(this).after("<input style='display: block;' type='text' />");
            $(this).css("display", "block");
            if($(this).attr("size")<2)
            {
                $(this).attr("size", "3");
            }
            $(this).next("input[type='text']").keyup(function(){
                sel.children('option').hide();
                var a = new Array();
                var txt = $(this).val().toLowerCase();
                sel.children('option').each(function(i, selected){
                    var pattern=new RegExp(txt);
                    var value = $(this).text().toLowerCase();
                    if(pattern.test(value))
                    {
                        $(selected).show();
                    }
                });
            }); 
        };
        })(jQuery);

//live keyup    
    ;(function($) {
        $.fn.liveSelectFilter = function() {

            var sel = $(this);
            $(this).after("<input style='display: block;' type='text' />");
            $(this).css("display", "block");
            if($(this).attr("size")<2)
            {
                $(this).attr("size", "3");
            }
            $(this).next("input[type='text']").live("keyup", function(){
                sel.children('option').hide();
                var a = new Array();
                var txt = $(this).val().toLowerCase();
                sel.children('option').each(function(i, selected){
                    var pattern=new RegExp(txt);
                    var value = $(this).text().toLowerCase();
                    if(pattern.test(value))
                    {
                        $(selected).show();
                    }
                });
            }); 
        };
        })(jQuery);
    

    jQuery(document).ready(function(){
        jQuery("#select-list").selectFilter();
        jQuery("#live-select-list").liveSelectFilter();
    });
    </script>
</head>
<body>
<form action="" method="post">
Keyup: 
<select id="select-list" size="5" name='test' style="width:200px">
  <option value='1'>John Smith</option>
  <option value='2'>John Doe</option>
  <option value='3'>Jason Bradley</option>

  <option value='4'>Bob Smith</option>
  <option value='5'>Jane Doe</option>
  <option value='6'>David White</option>
  <option value='7'>Neal Johnson</option>
  <option value='8'>Richard Bradman</option>
</select>
<br /><br />Live keyup: 

<select id="live-select-list" size="5" name='test' style="width:200px">
  <option value='1'>John Smith</option>
  <option value='2'>John Doe</option>
  <option value='3'>Jason Bradley</option>
  <option value='4'>Bob Smith</option>
  <option value='5'>Jane Doe</option>
  <option value='6'>David White</option>

  <option value='7'>Neal Johnson</option>
  <option value='8'>Richard Bradman</option>
</select>
</form>
</body>
</html>

How can I fix this?

Upvotes: 1

Views: 902

Answers (1)

Gabriele Petrioli
Gabriele Petrioli

Reputation: 195992

The problem is that .live() works with selectors and not specified elements.

Quoting from the docs

Attach a handler to the event for all elements which match the current selector, now and in the future.

and

DOM traversal methods are not supported for finding elements to send to .live(). Rather, the .live() method should always be called directly after a selector, as in the example above.

So you should change the way you bind the live event to

$(this.selector + " + input[type='text']").live("keyup", function(){

this.selector will return the original selector used and the + input[type='text'] is the next adjacent selector

live at http://jsfiddle.net/gaby/u9uhV/

Upvotes: 1

Related Questions