1

I'm new to writing jQuery plug-ins so I'm a little unsure how to do this. The plug-in is to display labels as tips inside text and password inputs. It's kind of simple - on element focus, the label is hidden. Also on document load it checks to see if the browser has auto-completed any field forms - if so, the label is hidden. The problem I am having is autocomplete of other fields. To solve this, I'm trying to bind a function to the onblur and keyup events of the element to loop through other form elements and work out whether they've been autocompleted.

Here is the annotated code.

(function( $ ){
  $.fn.innerLabels = function( ) {
    return this.each(function() {        
    var $this = $(this);
// Initialise all form elements with class
    $this.each(function() {
    var lngth = $(this).val().length;
    if(lngth > 0){
        $(this).parent().children('label').hide();
    }else{
        $(this).parent().children('label').show();
    };
    });
// onfocus event - clears label
    $this.focus(function() {
    $this.parent().children('label').hide();
    });
// onblur/keyup event re-enstates label if length of value is zero or hides if autocompleted.
    $this.bind("blur keyup",function() {
// check all fields in case of autocomplete <- this is the problem
    $(this).each(function() {
    var lngth = $(this).val().length;
    //alert(lngth);
    if(lngth > 0){
        $(this).parent().children('label').hide();
    }else{
        $(this).parent().children('label').show();
    };
    });
    });
    });
  };
})( jQuery );

It's triggered by doing this.

$(document).ready(function(){
     $('.txtbox').innerLabels();
});

.txtbox is a class that I add to form text and password fields that I want to use this on.

I think it's a scope problem. The last $(this).each is the problem. Rather than looping through all elements with the .txtbox class, it's looping through the value of the input in which the event is taking place. I don't want to add the class name to the plug-in because it will add extra code and make it less flexible.

Any advice on this would be appreciated.

Cheers

Greg

4

2 回答 2

0

In jquery you can select the siblings by using the next() function

$(this).next()

will select the next one.

More on next()

于 2011-05-29T02:40:49.387 回答
0

Just by looking at your code it looks like you're trying to execute the initialization code again upon blur. Is this the case? If so, refactor that common code into a function and simply call it from your event handler:

(function($) {
    $.fn.innerLabels = function() {
        var $self = this;
        var hideElements = function() {
            $self.each(function() {
                var lngth = $(this).val().length;
                if (lngth > 0) {
                    $(this).parent().children('label').hide();
                } else {
                    $(this).parent().children('label').show();
                };
            });  
        };

        hideElements();

        return $self.focus(function() {
            $(this).parent().children("label").hide();
        }).bind("blur keyup", hideElements);
    };
})(jQuery);

After some refactoring I also didn't see the need for the .each call (in the return statement), since assigning event handlers will work for every item in the set of matched elements.

Hope that's what you were after.

于 2011-05-29T03:08:21.180 回答