A life in the day

3/31/2007

Overlabel with JQuery

Filed under: — Scott Sauyet @ 2:24 pm

I’ve been playing with JQuery lately, and when I found a need to use the wonderful little accessible compact form script by Mike Brittain, I thought I’d try to duplicate it with JQuery’s simpler syntax. This is my first attempt at anything close to a JQuery plugin. It works for me, as you can see on the test page.

Here’s the code I wrote (Update: There is an updated version in the comments.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
jQuery.fn.overlabel = function() {
    this.each(function(index) {
        var label = $(this); var field;
        var id = this.htmlFor || label.attr('for');
        if (id && (field = document.getElementById(id))) {
            var control = $(field);
            label.addClass("overlabel-apply");
            if (field.value !== '') {
                label.css("text-indent", "-1000px");
            }
            control.focus(function () {label.css("text-indent", "-1000px");}).blur(function () {
                if (this.value === '') {
                    label.css("text-indent", "0px");
                }
            });
            label.click(function() {
                var label = $(this); var field;
                var id = this.htmlFor || label.attr('for');
                if (id && (field = document.getElementById(id))) {
                    field.focus();
                }
            });
        }
    });
};

And it would be called like this:

1
2
3
$(document).ready(function() {
    $("label.overlabel").overlabel();
});

I’m wondering whether there are some simplifications to this that a more experienced JQuery user could explain, though. I feel as though it’s still too wordy, and that it spends too much time switching between the DOM elements and the JQuery ones.

In any case, if you are interested in this (public domain) plugin, you can grab a zip here, or just go straight to the Javascript source.

125 Responses to “Overlabel with JQuery”

  1. Abba Says:

    Nice work. Just so you know the comment box on your site breaks the faux columns in ff 1.5 at least.

  2. Scott Sauyet Says:

    Oops. Just upgraded to Wordpress 2 and didn’t even notice that the stylesheet is no longer working. Ugggh.

    Thanks. Gotta find a few minutes…

  3. Jon Lesser Says:

    This is just what I was looking for. Thanks!

  4. Scott Sauyet Says:

    Glad you could use it. If you grab the code from the demo page rather than what’s displayed in the post you will get something that plays better with non-JQuery libraries. (”$” is not used in the global scope.)

  5. Dave Methvin Says:

    Hey Scott, here’s a thought on another way to write it. I can’t say it would be faster, but it gets you thinking about how jQuery chaining can be your friend when it comes to brevity. (Wordpress may mangle this…)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    (function($){
    $.fn.overlabel = function() {
        this.each(function(){
            var label = $(this);
    	$("#"+(this.htmlFor || label.attr('for') || "ID-NOT-FOUND"))
    		.focus(function(){ label.css("text-indent", "-1000px"); })
    		.blur(function(){ this.value || label.css("text-indent", "0px"); })
    		.trigger("focus").trigger("blur")
    		.length && 
    			label.addClass("overlabel-apply");
        });
    }
    })(jQuery);
  6. Scott Sauyet Says:

    Yes, that’s exactly the sort of clean-up I expected more experienced JQuery users could supply. I haven’t tested it yet, but it looks very succinct and will add at least one technique to my personal Javascript repertoire.

    I have one question, though. Why this bit:

    9
    10
    
    		.length && 
    			label.addClass("overlabel-apply");

    instead of just calling addClass() directly. Is there some performance hit?

    Thanks,

    — Scott

  7. Dave Methvin Says:

    I assumed you only wanted the overlabel-apply class on labels that had
    matching form elements, so I had the selector default to #ID-NOT-FOUND if
    the FOR attribute wasn’t present or the ID mentioned in it didn’t exist. The
    selector won’t select anything for that case, the .length will be 0 and the
    chained methods (focus, blur, triggger) won’t apply to any elements. By
    making the addClass dependent on the length being non-zero (it will either
    be 0 or 1 since we’re selecting an ID) the class is only added if there was
    an element matching the ID in the FOR attribute.

    One other thing I should have mentioned is that the trigger of focus/blur on
    each element might interact with fancy form handling such as validators, so
    you’d probably want to do overlabel early in your .ready() handler before
    initializing those kind of functions.

    Thanks for translating this idea to jQuery by the way, I found it in a
    search because I needed this functionality.

  8. Scott Sauyet Says:

    Oh of course, I see. It’s exactly the same technique that I hadn’t used
    before being applied again, but I missed it this time. The technique
    I’ve never used is simply to replace a simple “if” clause with an “||”,
    e.g. replacing this:

    if (this.value === ”) {
    label.css(”text-indent”, “0px”);
    }

    with

    this.value || label.css(”text-indent”, “0px”);

    One other thing I should have mentioned is that the trigger of focus/blur on each element might interact with fancy form handling such as validators, so you’d probably want to do overlabel early in your .ready() handler before initializing those kind of functions.

    I haven’t used it in that environment yet, but will probably do so this
    month, so thanks for the heads-up.

    Thanks for translating this idea to jQuery by the way, I found it in a search because I needed this functionality.

    The translation was pretty easy. But when I went searching, I couldn’t
    find anything. When I posted this entry, several people pointed me to
    other implementations of similar ideas. Google really is only so much
    help…

    Thanks again.

  9. Dave Methvin Says:

    I love Javascript’s || and && operators. First of all, they are
    short-circuit so that they stop as soon as they get a non-false answer, and
    they return the actual value rather than a simple true/false the way C++
    does for example.

    For the purposes of determining truth, a false value is (undefined), (NaN),
    boolean false, numeric 0, or the empty string. No conversion is done on the
    value before checking, so “false” or “0″ do not evaluate to false because
    they are non-empty strings.

    That rewrite above takes advantage of both of those things. At the point
    where it’s run, we know it’s working with a form element such as a text box.
    That means this.value will always be a string, so it will only evaluate to
    false if the string is empty. That means it has to evaluate the label.css()
    to see if the entire statement is true or false, which is just what we want
    for the case where the string is empty.

  10. Scott Sauyet Says:

    Fans of functional languages might run screaming at this use of side effects in a conjunction, but it makes a great deal of sense for shortening up code.

    I use the short-circuited nature of || and && all the time, but I’m coming from a Java background, and often forget the broader nature of true/false in JS. It’s a very nice technique.

  11. Zach Leatherman Says:

    Great plugin!

    You might want to add a textarea to your examples just to comfort the end user that it does indeed work with textareas as well.

    I made a small modification to this script to make it work with JSF-compatible id’s, a la formId:formFieldId, which is supported using the escaping features built into jQuery 1.1.3.

    Use
    var id = this.htmlFor || label.attr(’for’) || “ID-NOT-FOUND”;
    $(”#”+id.replace(/\:/,’\\:’))

    instead of

    $(”#”+(this.htmlFor || label.attr(’for’) || “ID-NOT-FOUND”))

    Hope that helps someone.

  12. ZAP Says:

    Very nice script! Simple, useful, and efficient. Thanks for sharing!

    Question: Is there an easy way to remove the overlabels of specific form fields? I have a form with billing and shipping address sections and a “Ship to Billing” checkbox that calls a JavaScript function that copies the billing info to the shipping fields and disables those fields. This doesn’t cause the overlabels to register that there is now content in each of those fields, however, so the label text stays there and makes the form data very hard to read.

  13. Scott Sauyet Says:

    Very nice script! Simple, useful, and efficient. Thanks for sharing!

    Thanks. I haven’t thought much about this since I wrote it, and the variation proposed by another poster might be a better bet.

    Question: Is there an easy way to remove the overlabels of specific form fields?

    This wasn’t built to be removed, but if your Javascript function can be easily altered then you can simply call focus() then blur() on the form field. In the demo, for instance, you might do

    1
    
           $("#username-field").val("Fred").focus().blur();

    That should work. If you can’t change the JS function, let me know and we’ll see something can be added…

  14. ZAP Says:

    The original version you created is working fine for me, so I’m happy with that. And your suggestion to focus and blur each field worked like a charm. I was even able to chain disabling of each form field after changing the value and removing the overlabel like so: $(”#s1_Name”).val(frm.Name.value).focus().blur().attr(”disabled”,”disabled”);

  15. Scott Sauyet Says:

    Great! I’m glad this worked for you.

    Please let me know if you run into any problems with it.

  16. Scott Sauyet Says:

    Thanks. I can’t really claim much credit, just the conversion of someone else’s technique to jQuery. But I’m glad you like it.

  17. Aristotle Pagaltzis Says:

    Thanks for providing a model to work from. Here’s my version:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    ( function($) {
        $.fn.overlabel = function() {
            this.filter('label[for]').each( function() {
                var label = $( this );
                var id = label.attr( 'for' );
                var field = document.getElementById( id );
     
                if(!field) return;
     
                label.addClass('overlabel-apply');
     
                var hide_label = function() { label.css('text-indent', '-1000px') };
                var show_label = function() { this.value || label.css('text-indent', '0px') };
     
                $( field ).focus( hide_label ).blur( show_label ).each( show_label );
     
                return;
            } );
        };
    } )(jQuery);


    In contrast to Dave Methvin’s variant, this code works without falling back on made-up bogus ID values and is, I believe, much more readable.

    The major win was when it occurred to me that I could remove the duplication between conditionally showing the label right now and conditionally showing the label in the blur handler by using each, because each invokes its function with field assigned to this, thus making the same code reusable for both cases. (Assigning the other closure to hide_label is not necessary, but makes the whole thing read more nicely and look more symmetric.)

    Another minor improvement is the use of filter to avoid manual checks for whether there is a for attribute on the label.

    This is tested and works for me.

    My clean-ups don’t have much to do with jQuery-specific experience, btw – I don’t even have a whole lot of it. I just obsessed over each and every line of code until the last trace of loathsome complexity was gone.

  18. Scott Sauyet Says:

    Perfect!

    This was written because I needed it for a project and didn’t want the overhead of the original technique when I was using JQuery to otherwise simplify my Javascript. It was a naive port of the original, and I was never happy with the code, but I haven’t gone back to clean it up. Although I like Dave Methvin’s shortening of the code, and I learned something from it, I haven’t adopted it in my own use, because it still came across as mysterious.

    Yours is very clean, and I’m very impressed. I think I’ll adopt it for my own use. Is it okay if I post it as the official plug-in version?

    Thanks for sharing it.

  19. Aristotle Pagaltzis Says:

    Yeah, “mysterious” is the first thing I thought about his code too… I just didn’t want to be that forward, heh.

    It’s fine to post mine as the official version – I’d just ask to be credited, since this is essentially a rewrite. But I wouldn’t have gotten to the same place without working off your version, so I’m not going to claim it’s all mine. I dunno – choose a way to handle this that you feel is fair.

    Btw, here’s a jQuery experience issue: turns out that this:

    1
    2
    3
    4
    5
    
    ( function($) {
        $.fn.overlabel = function() {
            // ...
        };
    } )(jQuery);

    … is better written as this:

    1
    2
    3
    4
    5
    
    jQuery.fn.extend( {
        overlabel: function() {
            // ...
        }
    } );
  20. Scott Sauyet Says:

    It’s fine to post mine as the official version – I’d just ask to be credited, since this is essentially a rewrite.

    I certainly wouldn’t do it without giving full credit. The only question to me was whether this excellent rewrite should simply replace my plug-in or whether you would prefer to post an entirely separate one. Either is fine, but I think it’s worth having this version listed on the plug-in page.

    So what is the advantage of the “.extend()” version above?

  21. Aristotle Pagaltzis Says:

    I would post the rewrite separately, to preserve the context for the comments on this post, and then point the plug-in page to the new post, so people looking for such a plug-in aren’t given a choice of two versions when one of them is universally preferable.

    As forextend, mostly it’s just the idiomatic way for jQuery plugins. It does have a small objective advantage in that it’s more declarative. But it forgot that I have $( this ) and $( field ) in the function, and these would have to be written as jQuery( ... ) instead, so I wouldn’t change the style after all.

  22. Scott Sauyet Says:

    I guess the question is whether you would like to post a new plug-in to replace http://jquery.com/plugins/project/overlabel or would prefer that I simply point that one to the code you’ve written. Since I’m going to switch to this code, I don’t see any need to maintain the original version.

  23. Aristotle Pagaltzis Says:

    I could make a page on my site for the plug-in if you think that’s OK?

  24. Scott Sauyet Says:

    Of course. Let me know when it’s done, and I’ll point people there. Perhaps we can simply replace the links on the plug-in page to point there.

  25. Guy Fraser Says:

    Hi All,

    I’ve been fiddling around with the short “chained” version of this script and come up with a new version as follows:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    (function($){
    $.fn.overlabel = function() {
        this.each(function(){
            var label = $(this);
            var id = this.htmlFor || label.attr('for') || "NO-ID";
            $("#"+id.replace(/\:/,'\\:'))
                    .parent().addClass("overlabel-wrapper").end()
    		.focus(function(){ label.css("text-indent", "-1000px"); })
    		.blur(function(){ this.value || label.css("text-indent", "0px"); })
    		.trigger("focus").trigger("blur")
    		.length && 
    			label.addClass("overlabel-apply");
        });
    }
    })(jQuery);

    So, what have I done?

    a) I’ve included the compatibility hack for JSF forms as per Zach’s suggesion - it’s still fast and just extends compatibility with markup used in existing forms.

    b) I’ve replaced “ID-NOT-FOUND” with “NO-ID” - still obvious what it does, but shorter so saves electrons.

    c) Automatically add a class to the element that contains the label/input (which no longer has to be a div) so that the raw HTML doesn’t need to have the class defined.

    This just makes working with some existing forms a lot easier, especially those that place each field in an li or span, etc.

    The CSS becomes:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    .overlabel-apply {
      color:#999;
      cursor:text;
      left:5px;
      position:absolute;
      top:1px; /* I use bold labels hence only 1px, normal weight labels would use 3px */
      z-index:1;
    }
    .overlabel-wrapper {
     position: relative;
    }

    Note: I’ve not floated the wrappers as per the original example just to keep the CSS small. To get the single line form as per the original example, just change the wrapper css to the following:

    1
    2
    3
    4
    5
    
    .overlabel-wrapper {
      float:left;
      margin-right:3px;
      position:relative;
    }

    c) You will no doubt have noticed that I’ve put the styles and their properties in alphabetical order - I find this improves readability when you are in a rush to do something at 5am (as it is here in the UK) and are wading through a HUGE CSS file heh.

    d) With this approach we can remove the “overlabel” class from the labels and the id’s from the divs (which also no longer need to be divs).

    I know the code isn’t as readable to anyone who doesn’t do a lot of chaining, but it’s fast and compact. For projects that need lots of JS, having each component part as compact as possible is really important IMHO.

    You could still include the “overlabel” class on labels if you wanted to use a selector like:

    1
    2
    3
    
    jQuery(function(){
     jQuery("label.overlabel").overlabel();
    });

    But if you’re working with existing form markup you would probably use something more like:

    1
    2
    3
    
    jQuery(function(){
     jQuery("form.myForm label").overlabel();
    });

    So, where next…

    We’ll obviously I’d like to see the chained version become the official version. It’s more compact and more flexible at the same time.

    It might be interesting to see if the formatting of the labels could be based on the formatting of the input/textarea - eg. the font properties, line height and padding could all be taken from the input/textarea and the only thing that the developer would need to change is the colour of the label.

    Comments?

  26. Aristotle Pagaltzis Says:

    How is the chained version “more” flexible? There is nothing about those improvements that makes them hard to incorporate into the clean version:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    ( function( $ ) {
        $.fn.overlabel = function() {
            this.filter( 'label[for]' ).each( function() {
                var label = $( this );
                var id = label.attr( 'for' );
                var field = document.getElementById( id ) ||
                    document.getElementById( id.replace( /\:/, '\\:' ) ); // hack for JSF forms
     
                if(!field) return;
     
                label.addClass( 'overlabel-apply' );
     
                var hide_label = function() { label.css( 'text-indent', '-1000px' ) };
                var show_label = function() { this.value || label.css( 'text-indent', '0px' ) };
     
                $( field ).
                    parent().addClass( 'overlabel-wrapper' ).end().
                    focus( hide_label ).blur( show_label ).each( show_label );
     
                return;
            } );
        };
    } )( jQuery );

    I improved upon the JSF hack here because there’s certainly perfectly good markup that’s not generated by JSF but has colons in IDs; so if the code is to actually “extend compatibility with markup used in existing forms,” it needs to deal with both cases. I also commented the hack so someone who looks at it two years from now will know what the heck that cruft is for.

  27. Scott Sauyet Says:

    I don’t think the “JSF hack” is necessary here. Isn’t that just a workaround for jQuery’s other use of the (perfectly legal) colon character in an id? That is, jQuery would recognize $("#my-id:first-child") as pointing to the element with id “my-id” but only if it is the first child element of its parent. But if you have an element with the id “my-id:first-child”, which is legal XHTML, jQuery’s call above wouldn’t find it. Instead you need to escape the colon with a backslash, and in order to do that in a JS string you need a second backslash escaping the first one. A bit ugly, but at least it leaves us with the flexibility to have CSS-like selectors. But won’t document.getElementById("my-id:first-child") fetch the item with exactly that id anyway without any sort of hack?

    BTW, Aristotle, have you set up your plug-in somewhere yet? I’d really like to point mine to it.

    — Scott

  28. Aristotle Pagaltzis Says:

    Oh! I completely misread what the hack was for. I read it as saying that JSF outputs IDs where the colons are backslashed in the markup – please don’t ask what made me think that, because I have no idea. So yeah, the hack is unnecessary in my version.

    I don’t have a page yet! Sorry. I think I’ll go make one right now, or else it will slip below the fold of my backlog again…

  29. Guy Fraser Says:

    OK, I like the revised readable version more than my updated chained version. It’s far easier to read and understand. Great work Aristotle!

    P.S. Did you spot my “cursor: text” style setting for the label - it ensures that when you mouse over the search box the cursor will be the same as when the box is focussed (just “feels” nicer IMHO).

  30. Guy Fraser Says:

    I forgot to mention - would it be possible to return the jQuery object - this would allow chaining, eg. I might want to do something like this:

    jQuery(”#form3 label”).overlabel().css(”color”,”green”);

    Ideally the jQuery object returned by overlabel() would only include the labels that have actually been processed.

  31. Scott Sauyet Says:

    Ideally the jQuery object returned by overlabel() would only include the labels that have actually been processed.

    Are there other plug-ins that work like this? This would violate my basic assumption that the jQuery object returned is the same one I’ve chosen with my selectors. But I agree that it would be best to return the jQuery object.

  32. Guy Fraser Says:

    Well, there are two options…

    1. Make it clear in docs that returned jQuery obj is filtered to just those labels that are processed. The return would be:

        return this.filter("label.overlabel-apply");

    (or maybe just build a new list within the .each()…?)

    To apply stuff to just the processed labels, the developer could:

        $(whatever).overlabel().whatever();

    The developer could call .end().end() to undo the two filters (label[for] and label.overlabel-apply), eg:

        $(whatever).overlabel().end().end().whatever();

    2. Return the original list prior to any filteres, eg:

        return this.end(); // undo the label[for] filter

    With this option the developer could

        $(whatever).overlabel().filter("label.overlabel-apply").whatever();

    —-

    I’m not sure which would be best. Option 2 would lead to more transparent code, albeit a little wasteful due to the extra filter.

    Note: My example of setting colour to green was terrible because you’d just do that using the CSS for .overlabel-apply heh.

  33. Aristotle Pagaltzis Says:

    Scott: I’m actually reluctant to make a page yet because you have comments on your site and I don’t (yet)! And the discussion here keeps turning up interesting bits. Returning the jQuery object is actually something I thought I should add. But I hadn’t thought about returning a list of only the processed elements, and that is a handy option! As for whether to return the selection filtered or unfiltered – how about letting the user choose?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    ( function( $ ) {
        $.fn.overlabel = function( do_return_filtered ) {
            var selection = this.filter( 'label[for]' ).map( function() {
                var label = $( this );
                var id = label.attr( 'for' );
                var field = document.getElementById( id );
     
                if(!field) return;
     
                label.addClass( 'overlabel-apply' );
     
                var hide_label = function() { label.css( 'text-indent', '-10000px' ) };
                var show_label = function() { this.value || label.css( 'text-indent', '0px' ) };
     
                $( field ).
                    parent().addClass( 'overlabel-wrapper' ).end().
                    focus( hide_label ).blur( show_label ).each( show_label );
     
                return this;
            } );
     
            return do_return_filtered ? selection : selection.end();
        };
    } )( jQuery );

    This way you can pass an optional true argument to the function. If you do, the object you get will contain just the processed nodes; if you call the method without parameters or with a false parameter, the selection remains the same. (All it took to achieve this is changing each() to map() and changing return to return this at the end of the anonymous function.)

    Actually, now that I think about it, there’s some more control we could give the user:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    
    ( function( $ ) {
        $.fn.overlabel = function( arg ) {
            var opt = {
                label_class:   'overlabel-apply',
                wrapper_class: 'overlabel-wrapper',
                hide_css:      { 'text-indent': '-10000px' },
                show_css:      { 'text-indent': '0px' },
                filter:        false
            };
     
            if( 'Object' == typeof arg )
                for( key in arg ) opt[ key ] = arg[ key ];
            else
                opt.filter = !!arg;
     
            var selection = this.filter( 'label[for]' ).map( function() {
                var label = $( this );
                var id = label.attr( 'for' );
                var field = document.getElementById( id );
     
                if(!field) return;
     
                label.addClass( opt.label_class );
     
                var hide_label = function() { label.css( opt.hide_css ) };
                var show_label = function() { this.value || label.css( opt.show_css ) };
     
                $( field ).
                    parent().addClass( opt.wrapper_class ).end().
                    focus( hide_label ).blur( show_label ).each( show_label );
     
                return this;
            } );
     
            return opt.filter ? selection : selection.end();
        };
    } )( jQuery );

    Now the user can either pass true to get back the filtered selection, or false (or just nothing) to get back the original selection – or pass a parameter object to customise any part of the CSS to taste.

  34. Scott Sauyet Says:

    I’d been thinking along the same lines as the last one, adding configuration parameters.

    I don’t personally find any need for the filtered return, but I like the added flexibility for those who do. (My own comment in response to Guy’s last one disappeared — my own damn blog!) I don’t see any good reason to overload the args variable, though. The filter parameter could simply be an attribute of args. That would chop off a few lines and make it easier to document.

  35. Aristotle Pagaltzis Says:

    Hmm, you are right, there isn’t much reason to overload it. The config object should just be another optional parameter, and I shouldn’t have put the filtering flag in there at all. Then I can also unbork the variable names:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    $.fn.overlabel = function( do_return_filtered, override ) {
        var config = {
            label_class:   'overlabel-apply',
            wrapper_class: 'overlabel-wrapper',
            hide_css:      { 'text-indent': '-10000px' },
            show_css:      { 'text-indent': '0px' },
            filter:        false
        };
     
        if( override ) for( key in override ) config[ key ] = override[ key ];

    The rest of the references to opt must be changed, of course, as must the name of the flag variable on the return line. Much nicer.

    It does mean that if you want to pass a config hash, you must say whether you want your selection filtered or not, but if you pass a config hash you’re already taking a verbosity hit anyway, so the extra positional parameter is not a big burden.

  36. Benjam Says:

    You both are having great ideas with this, but one thing I would like to see is an updated demo page.

    I am having difficulties getting this little function to work on my page.

    One thing I noticed, is that one must replace all instances of opt. with config. when using the latest version (posted by Aristotle on 2007-10-05).

    Also, what is the wrapper_class for, and what would be a suitable CSS declaration that would enable this to work?

  37. Benjam Says:

    Oops, forgot to read the rest of that last comment before posting, forgive my config. to opt. statment.

    One other thing I noticed, is that the filter part of the config object is moot now, isn’t it? Due to the do_return_filtered argument?

    Anywho… let me know when I can view an updated demo page.

    Thanks.

  38. Guy Fraser Says:

    The recommended way to do default settings is shown on a jQuery tutorial:

    1
    2
    3
    4
    5
    
     jQuery.fn.foobar = function(options) {
       var settings = jQuery.extend({
         value: 5, name: "pete", bar: 655
       }, options);
     };

    http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery

    Whilst Aristotle’s settings will do much the same thing (and probably be faster) it might be worth sticking to the documented method as more people will be familiar with it….?

  39. Scott Sauyet Says:

    I will try to create an updated version over the weekend. I’ve been letting this play out as Aristotle said he’d be creating a new plugin page for it. At this point, though, even with Aristotle’s rewrite, the whole thing has become a group effort. I will combine all the ideas listed above and create a simple demo.

  40. Damir Secki Says:

    Hello folks!
    great team work!

    I’ve done something on my own but it’s not even remotely similar and useful as what you’ve done boys. I have only one problem with this whole approach…

    If I use this On my log-in form firefox (or the browser) wont be able to remember the values of the fields for me, to log in next time… so next time instead of having already filled fields with my user name and password the fields will be filled with overlabel values… and this is not a very big deal… but its a setback to write the login data all over again…

    are there any workarounds this?

  41. Damir Secki Says:

    ups, never mind… it seems I’ve spoken too soon :)

  42. Scott Sauyet Says:

    Although I never really considered this, it seems to just work, at least the original version. I’ll keep it in mind when I try to put all this together this weekend. But as far as I can tell, that shouldn’t be an issue at all. Firefox puts a value in this field before any of our manipulation. And that manipulation always checks for a value. I’ll have to check if it works in other browsers too.

    Have you tested somewhere and found this not working?

  43. Scott Sauyet Says:

    And I’ve responded too soon! :-)

    Glad it’s working.

  44. Guy Fraser Says:

    Don’t forget the cursor:text in the css for processed labels :)

  45. Scott Sauyet Says:

    I’m afraid I didn’t find the time this weekend to do an update. I will do it as soon as I can find a spare hour or two.

  46. Guy Fraser Says:

    Just been reading this: http://www.learningjquery.com/2007/10/a-plugin-development-pattern

    So the plugin could become something like:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    ( function( $ ) {
     
        // plugin definition
        $.fn.overlabel = function( options ) {
     
            // calculate main options (without metadata)
            var main_opts = $.extend( {}, $.fn.overlabel.defaults, options );
     
            var selection = this.filter( 'label[for]' ).map( function() {
     
                var label = $( this );
                var id = label.attr( 'for' );
                var field = document.getElementById( id );
     
                if ( !field ) return;
     
                // if metadata is present, extend main_opts
                var opts = $.meta ? $.extend( {}, main_opts, label.data() ) : main_opts;
     
                label.addClass( opts.label_class );
     
                var hide_label = function() { label.css( opts.hide_css ) };
                var show_label = function() { this.value || label.css( opts.show_css ) };
     
                $( field ).
                     parent().addClass( opts.wrapper_class ).end().
                     focus( hide_label ).blur( show_label ).each( show_label );
     
                return this;
     
            } );
     
            return opts.filter ? selection : selection.end();
        };
     
        // publicly accessible defaults
        $.fn.overlabel.defaults = {
     
            label_class:   'overlabel-apply',
            wrapper_class: 'overlabel-wrapper',
            hide_css:      { 'text-indent': '-10000px' },
            show_css:      { 'text-indent': '0px', 'cursor': 'text' },
            filter:        false
     
        };
     
    } )( jQuery );

    Things I’ve done:

    1. Non-destructively determine settings (main_opts) when the overlabel function is called, before entering the map() block.

    2. If metadata plugin is available, non-destructively extend main_opts to include element-level settings

    3. Made default settings publicly accessible - you can now easily override the settings via $.fn.overlabel.defaults

    4. Added cursor:text to the show_css to ensure good usability :p

    NB: I’ve not tested the updates heh.

  47. Scott Sauyet Says:

    I’m glad I haven’t found the time to put all this together! :-) This is looking just about perfect.

    By the way, I know that there is no obvious way to format code. This is a mostly unused blog, but when I get some time, I’ll see if I can document how to do it. For now, you might try what I do, which is to add:

    1
    2
    3
    
    <blockquote style="font-size: 125%;"><pre lang="javascript" line="1">
    // code here
    < /pre>< /blockquote>
  48. Guy Fraser Says:

    Found a slight bug and made another tweak based on feedback elsewhere…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    ( function( $ ) {
     
        // plugin definition
        $.fn.overlabel = function( options ) {
     
            // build main options before element iteration
            var opts = $.extend( {}, $.fn.overlabel.defaults, options );
     
            var selection = this.filter( 'label[for]' ).map( function() {
     
                var label = $( this );
                var id = label.attr( 'for' );
                var field = document.getElementById( id );
     
                if ( !field ) return;
     
                // build element specific options
                var o = $.meta ? $.extend( {}, opts, label.data() ) : opts;
     
                label.addClass( o.label_class );
     
                var hide_label = function() { label.css( o.hide_css ) };
                var show_label = function() { this.value || label.css( o.show_css ) };
     
                $( field ).
                     parent().addClass( o.wrapper_class ).end().
                     focus( hide_label ).blur( show_label ).each( show_label );
     
                return this;
     
            } );
     
            return opts.filter ? selection : selection.end();
        };
     
        // publicly accessible defaults
        $.fn.overlabel.defaults = {
     
            label_class:   'overlabel-apply',
            wrapper_class: 'overlabel-wrapper',
            hide_css:      { 'text-indent': '-10000px' },
            show_css:      { 'text-indent': '0px', 'cursor': 'text' },
            filter:        false
     
        };
     
    } )( jQuery );

    1. Renamed “main_opts” to just “opts” - this also fixed a bug on the “return …” line.

    2. Renamed the element-specific opts to “o” - shorter and also seems more visually distinct from the main “opts”

  49. Guy Fraser Says:

    One final mod (I hope!) for readability:

    25
    26
    27
    
                $( field ).
                     parent().addClass( o.wrapper_class ).end().
                     focus( hide_label ).blur( show_label ).each( show_label );

    Becomes:

    25
    26
    27
    
                $( field )
                     .parent().addClass( o.wrapper_class ).end()
                     .focus( hide_label ).blur( show_label ).each( show_label );

    I’ve moved the .’s to make it clearer that parent() and focus() aren’t global functions for anyone doing a cursory glance through the code. Having the “.” at the start of those two lines (rather than the end of the preceding line) just makes it more obvious that it’s a continuation of the chain IMHO.

  50. Guy Fraser Says:

    Hi Scott,

    Did you ever get chance to push this in to SVN and release?

  51. Scott Sauyet Says:

    Hi Guy,

    I don’t have a public SVN server to push this to. I’ve been a bit out of touch with JQuery for the last two months, so I don’t know what’s going on. Is there an SVN server I can use for posting non-official plug-ins?

    But no, I haven’t had any time at all in the last few weeks.

    — Scott

  52. Guy Fraser Says:

    I believe the jQuery site has one (plus associated bug tracker, etc.), but no idea how to use it :s

  53. Mark Montague Says:

    I’ve been trying out the final version of this script, and it works pretty well but seems to have the following bug: if the text field begins with some text in it, the overlabel is shown on top of the text. I can’t quite see how to fix that; anyone else?

  54. Scott Sauyet Says:

    Yes, this looks like a regression. This should fix it:

    25
    26
    27
    
                $( field )
                     .parent().addClass( o.wrapper_class ).end()
                     .focus( hide_label ).blur( show_label ).each( hide_label ).each( show_label      );
  55. Mark Montague Says:

    That did fix it - great! I’m having one further problem with this script, and it seems like a harder one: in Safari 2 (but not Safari 3), if you click on the text of the overlabel, nothing happens. If you click in the blank space next to it, the overlabel disappears and the text input area receives focus, as it should. So it seems that somehow the overlabel is catching the click event instead of the text field. Any ideas?

  56. Scott Sauyet Says:

    Unfortunately, with no Mac to test on, I’m not sure how to chase this down. I have a Win32 version of Safari, but it’s version 3, and everything seems to work there. I wonder if we could create a test case using only CSS and ask the good folks on the CSS-Discuss list…

  57. Guy Fraser Says:

    I’m guessing that the event is not bubbling or for some reason the label is swallowing the click.

  58. Aristotle Pagaltzis Says:

    Aha, that’s why the original function added an onclick handler to the label element. I removed that in my refactor because keeping it made things messier and I didn’t understand what purpose it might possibly serve, seeing as clicking the label should focus the form element anyway. I guess it needs to be added back in… oh well.

  59. Ellen Says:

    I’m a little confused after reading all this … have all the rewrites been incorporated into the plugin? What is the final code that I am supposed to use?

    Thank you

  60. Scott Sauyet Says:

    I’m sorry, I never seem to get back to putting together a decent demo. I think the current state of play is the following:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    ( function( $ ) {
     
        // plugin definition
        $.fn.overlabel = function( options ) {
     
            // build main options before element iteration
            var opts = $.extend( {}, $.fn.overlabel.defaults, options );
     
            var selection = this.filter( 'label[for]' ).map( function() {
     
                var label = $( this );
                var id = label.attr( 'for' );
                var field = document.getElementById( id );
     
                if ( !field ) return;
     
                // build element specific options
                var o = $.meta ? $.extend( {}, opts, label.data() ) : opts;
     
                label.addClass( o.label_class );
     
                var hide_label = function() { label.css( o.hide_css ) };
                var show_label = function() { this.value || label.css( o.show_css ) };
     
                $( field )
                     .parent().addClass( o.wrapper_class ).end()
                     .focus( hide_label ).blur( show_label ).each( hide_label ).each( show_label );
     
                return this;
     
            } );
     
            return opts.filter ? selection : selection.end();
        };
     
        // publicly accessible defaults
        $.fn.overlabel.defaults = {
     
            label_class:   'overlabel-apply',
            wrapper_class: 'overlabel-wrapper',
            hide_css:      { 'text-indent': '-10000px' },
            show_css:      { 'text-indent': '0px', 'cursor': 'text' },
            filter:        false
     
        };
     
    } )( jQuery );

    Please let me know if that doesn’t work for you.

  61. Mike Brittain Says:

    Well done! I’m glad you’re finding good use for it, and extending this technique further than I have.

  62. Nick Carroll Says:

    Hey Scott,

    I fixed the bug that Mark Montague (Comment #55) raised. Safari seems to fire off the form Autofill event after the JQuery ready event. So if you call the overlabel function with:

    $(document).ready(function() {
    $(”label.overlabel”).overlabel();
    });

    Then in Safari, since the Autofill hasn’t added any text to the form input field, the overlabel plugin will think the input fields are empty and display the labels over them. Then Safari triggers the Autofill event and adds the previously entered text (eg username and password) into the form fields. This gives the undesirable effect of overlapping text in the form field.

    To get around this problem you have to call the overlabel plugin with the following:

    $(window).load(function() {
    $(”label.overlabel”).overlabel();
    })

    This waits until the page is fully loaded and Safari’s Autofill event finishes before calling the overlabel plugin.

    Cheers,
    Nick.

  63. Ian Bryce Says:

    I was having trouble with the Label overlapping each other. i’ve over come this by removing in the CSS left:3px and replacing this with padding:0 0 0 3px

    This fixed the problem for both IE and FF whilst using the blueprint CSS framework.

  64. Scott Sauyet Says:

    @Nick, that makes sense. I’ll change it as soon as I get a free moment.

    @Ian, I haven’t seen that issue, but I’ll take a look. It’s certainly a clear enough solution.

  65. Wayne Elgin Says:

    Nice work.

    Have you thought about extending this so that implicit labels also work?
    http://www.w3.org/TR/html401/interact/forms.html#idx-label-1

    I also second the need for a clarifying post or just updating the jQuery plugin page with an up-to-date download link for the script. Parsing through all of the comments confuses me about which direction the current code went.

    -Wayne

  66. Ryan Says:

    To everyone: Thanks for all the hard work. I look forward to using this script.

    I’m using the version from comment #60 and having some problems getting it to work (labels appearing in the top left corner of my screen).

    Would be awesome to have a demo that shows not only the latest version of the script, but also the appropriate markup and css to use.

    Thanks!

  67. Phil Says:

    Nice work everyone :)

    One thought though - it seems as though the assumption has been made that the label will be in the same container as the textbox, so the wrapper is applied to the textbox’s parent rather than the labels parent.

    I’m a bit of a jQuery novice so I won’t get my hands dirty - just my throwing my 2 cents in!

  68. Tim Büthe Says:

    Hi,

    the zip download link (http://scott.sauyet.com/Javascript/Demo/Overlabel/Overlabel.zip) gives a 404

    regards,
    Tim

  69. Nikon Says:

    I would like to see is an updated demo page.

  70. Riad Marrakech Says:

    awesome plugin

  71. Evan Carroll Says:

    Man i wish there was a working demo of the new version.. this isn’t working for me at all.

  72. Evan Carroll Says:

    scratch that the demo is up to date just not the original post

  73. Aurélien Geron Says:

    Hi,

    I just wanted to let you know that I wrote a very similar plugin also based on the overlabel technique, but based on the prototype framework instead of jquery.

    You can download it here:
    http://github.com/ageron/labelinput/

    Cheers!

  74. Aaron Says:

    Great plugin! I’m having one issue though. When you have multiple logins saved for a site and Firefox autofills one of the logins, the overlabel continues to display over the filled-in password. As far as I know, the autofill doesn’t trigger any events on the fields. Anyone know of any good fixes?

    The workaround I’m using right now is to tie to the focus event of the username field and start a check every second for a value in the password field. If it finds one it hides the label. When the username is blurred the check stops. It works but I wish there was a better solution.

  75. Scott Sauyet Says:

    Do you have an example url? I can’t duplicate this. Perhaps at start a call to $(”selector”).focus().blur() in a timeout on startup would do…

  76. Craig Says:

    I looked and what you did and wrote a plugin that’s does the exact same thing in a slightly different way. Instead of moving the label over the input, I chose to hide the label and copy the html() into the input’s value attribute.

    Here’s my version:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    (function($) {
        $.fn.overlabel = function() {
            this.filter('label[for]').each(function() {
                var $label = $(this);
                var $field = $('input[id="' + $(this).attr('for') + '"]');
     
                if(!$field) return;
     
                var hide_label = function() { 
                	if ($field.val() == $label.html() || $field.val() == "")
                	{
                		$field.val(""); 
                		$field.removeClass('overlabel_shown');
                	}
                };
                var show_label = function() {
                	if ($field.val() == $label.html() || $field.val() == "")
                	{
                		$field.val($label.html());
                		$field.addClass('overlabel_shown') 
                	}
                };
     
                $label.hide();
     
                $field.focus(hide_label).blur(show_label).each(show_label);
     
                return;
            });
        };
    })(jQuery);
  77. GouMs Says:

    Hi Guys,

    Nice discussion about best ways to do a watermark using jQuery !
    I’m using a similar pluggin that I wrote myself, and was looking around the web to find a fix for my problem wich is the same than Aaron (post #75).

    Reproduce it as easy as this:
    - Make a login form with overlabel (email + password).
    - Log in and allow firefox to remember your email and password.
    - Log out
    - Reload the page
    - Type the begining of your email address, and select it in the list that firefox is showing.
    –> The password field is automaticaly filled and the label stay over the input value !

    I can’t find the event to use to fix that :s

    Is anyone having an idea?

    Cheers

  78. GouMs Says:

    About my last comment:

    I tried to hang arround with “DOMAttrModified” but I figured out that the value of an input field is actually not a DOM attribute. The actual is only use to set the default value, and is not change when a user or a script update the value of the field.

    So I tried with “DOMControlValueChanged” but nothing conclusive.. I don’t know if this event is really working yet in the common browsers… Does anyone know about it?

    Regards.

  79. Scott Sauyet Says:

    @Craig: This is an interesting alternative. It is slightly simpler, which is nice, but it has one minor hole that I can see: If the user wants to type the same value as is displayed in the label, she’s not going to see it as an entered value but as an overlabeled-style field. This is not a big deal, I imagine, but it could be disconcerting.

  80. Scott Sauyet Says:

    @GouMS: Yes, I see what you’re talking about too. I haven’t found a solution yet, but I’ll keep looking.

  81. GouMs Says:

    @Craig: I haven’t tried your script, but is it working with password fields? I know that it’s one of the major concern about watermark that are not using the overlabel method…

    @Scott: Thanks, let me know if you find anything. By the way it’s very nice to see that more than 2 years after posting this thread, you are still updating the script and helping people to handle it!

    Cheers

  82. Scott Sauyet Says:

    @GouMs: Well, I don’t get to follow the jQuery group regularly; I figure this fairly minor plug-in is at least one way I can give back to the community.

  83. Cheryl Says:

    This is an excellent help to me, looks very stylish and nice. I’m also having the problem with autofilled-passwords causing a label overlap. Could any of you gentlemen give me some kind of workaround here? I just want the labels to disappear when the fields are filled in. I work with PHP (and only cut-and-paste with Jquery and javascript), so some of your posts are kinda over my head. Any help would be appreciated.

  84. Scott Sauyet Says:

    @Cheryl: Is that happening only in Firefox? And only when there are several passwords stored for the field? If so, that’s the issue that several people have pointed out and it’s one for which no one has yet found a solution. We’ll keep looking, though. Sorry.

  85. sunny Says:

    Hi, Can someone give me a step by step on how to do this. As in what files i need to insert which codes in to create the overlabel. im so confused by it all. so something more simple would go better. my email is kumar017@hotmail.com if u want to email it me.

    Thanks. Sunny

  86. Vicky Says:

    Hi guys,
    I’m having a conflict problem with Overlabel and UI Datepicker. When I select the date, the label and the date are meshed together. So it clears when I first click on the input box, but when I go to select a date from the pop-up calendar, the label returns. Any idea on how to fix this? I figured it has something to do with the fact that the input is dynamic and not directly within the input box.

  87. Scott Sauyet Says:

    I haven’t seen this, but it’s not terribly surprising. Do you have a test page somewhere?

    Something like overlabel would make a good extension to the Datepicker, I think. But I don’t know that code at all to suggest how it might best be incorporated.

  88. Scott Says:

    If you’re having issues with jQuery UI Datepicker and using this technique insert “change( hide_label )” before “.focus( hide_label ).blur( show_label ).each( hide_label ).each( show_label );” and it will solve your issues.

  89. Tchat Says:

    Great plugin :)

    Thanks for working :)

  90. Alexander Says:

    hi!

    Maybe this will be helpfull for someone:

    (function ($) {

    $.fn.WaterMark = function (watermarkText, watermarkCSS) {

    return this.each(function () {

    var $M = $(”label[for]=” + $(this).name);

    if ($M.length == 0) {
    $(”")
    .attr(”for”, $(this)[0].name)
    .attr(”innerHTML”, watermarkText)
    .addClass(watermarkCSS)
    .css(”position”, “absolute”)
    .css(”width”, $(this)[0].clientWidth)
    .css(”height”, $(this)[0].clientHeight)
    .css(”padding”, “3px”)
    .insertBefore(”#” + $(this)[0].name);
    }

    var doOnFocus = function () { $(”label[for]=” + $(this)[0].name).fadeOut(”fast”); };

    var doOnBlur =
    function () {

    if (!this.value) {
    $(”label[for]=” + this.name).fadeIn(”slow”);
    }
    };

    $(this)
    .focus(doOnFocus)
    .blur(doOnBlur);
    });

    };

    })(jQuery);

    using:

    $(document).ready(function () {

    $(’#SendText’).WaterMark(”mail us if you have any suggessions”, “some”);

    });

  91. Alexander Says:

    $(””)

    after
    if ($M.length == 0) {

    must be
    $(”")

  92. Alexander Says:

    $(”<label/>”)

  93. Mike Metcalf Says:

    Wrote an alternative jQuery script that removes class dependency and adds a dim state on focus. Click my name for the link.

  94. Scott Sauyet Says:

    @Mike

    I like the dim state a lot. I never considered doing that.

    But I’m not sure what you mean by “the class dependency”. The version that’s been developed here uses CSS for styling. I wouldn’t want to remove that feature.

    I’m also curious as to why you choose to link the label and the input control by DOM ordering (using “prev”) when there is already a semantically meaningful link between them in the label’s “for” tag.

    One more thing, I just realized, too. Yours looks as though it will act very oddly if JS is off. Have you tested that?

  95. Mike Metcalf Says:

    @Scott

    Glad you like the dim state. By class dependency I just meant you don’t need to manually add the overlabel class to the labels you want to use the script on. It works, but I’m definitely a novice when it comes to jQuery. I would be interested to see how you might use your existing plugin to integrate a dim state. I’ve used your plugin many times, so thanks for your work.

    Mike

  96. fha loan limits anne arundel county md jobs Says:

    There may also be a review if the discharge was dishonorable.
    The US Government has also been behind this change
    of scenario as the FHA has its backing and the measures such as those of elimination of
    a mandatory 90-day flipping a house rule and the expansion of the types of homes that
    can now be purchased, take condos for example, have been welcomed with warmth.

    “As far as Fannie Mae and Freddie Mac are concerned, there is a tradeoff there between supporting the higher priced homes and weaning the housing finance system off of unusual limits it was put under during the crisis,” Bernanke said.

  97. Jacquetta Says:

    Pretty part of content. I just stumbled upon your weblog
    and in accession capital to claim that I acquire in fact loved account your weblog posts.
    Any way I will be subscribing in your augment or even I achievement you get right
    of entry to consistently quickly.

  98. guide touristique bresilien paris Says:

    Ces chutes spectaculaires sont en grande partie sur le territoire Argentin mais
    il y a un point de vue plus general du cote du Bresil.

  99. Voyage sri lanka blog 2012 Says:

    Des plages interminables, des ruines intemporelles, des gens
    accueillants, des elephants a ne plus les compter, du surf, des petits prix, des plantations de the et des mets savoureux:
    autant de raisons de partir pour le Sri Lanka.

  100. Brayden Says:

    Relating to Nintendo’s Satoru Iwata, the company would cautiously select appropriate IP and titles” because
    of its smartphone games.

  101. root android online Says:

    You should also treap moving actions in this particular phone with the
    help of inbuilt video recorder. I’m not an skillful, fair any guy who pllayed extensively
    with constellate of these things!root android online

  102. http://violensboksida.bloggplatsen.se/gilla/?url=http://www.pacifichomes.ec/index.php/component/k2/itemlist/user/201525 Says:

    Todo lo que se vende aquí (que es mucho) sale de un taller anexo donde vas a
    poder ver a las artesanas manos a la obra con sus agujas de hilar.

  103. Luxury Beauty Says:

    I blog often and I truly thank you for your content. This great article has truly peaked my interest.
    I am going to bookmark your blog and keep checking for new details about once a week.
    I subscribed to your RSS feed too.

  104. Simone Says:

    Good day I am so happy I found your webpage, I really
    found you by error, while I was researching on Bing for
    something else, Nonetheless I am here now and would just like to say kudos for a remarkable post and
    a all round entertaining blog (I also love the theme/design), I don’t have time to look over it all at the minute but I have bookmarked it and also added in your RSS feeds, so when I have time I will be back to read more, Please
    do keep up the excellent work.

  105. gems.clashclans-hack.com Says:

    If you need to get unlimited gems, gold andd
    elixir without any investing a great deal time, you caan actually liike finding no cost ems on-line through the use of
    thee clash of clsns hack wirh proxy support
    and user-friendly interface. You could have the opportunity of taking pleasure in the game
    and reachuing individuals important elixirs and
    gems even while doing some methods. By turning your focus to your hack
    instrument, you can find noo have to carryy on battling
    during the sport. Savoring it will be even achievable among the various recreation fans.

    Should you havve your pill or Androikd cellular phone, iPad, Personal computer, apple iphone, just about
    everything appears too get the jobb done effectively. The Gem Hack
    wilpl work with any of them. Generating
    Clash of Clans Totally free Gems is free of charge among the
    any lots oof gamers. You can find a hzck instrumen that can bbe used in building COC gems effortlessly and
    complimentary. This will work its most effective reason to suit your needs.
    There iis merely a really have too sit back again and loosen up whilst yoou proceed to keep on building no
    charge gems.
    Gems can be attained around thee recreation by completing Achieveements or clearing obstructions.
    At the tme you extensive difficuilties around the Achievements menu, one example is, ‘clear fifty obstacles’, players are rewarded with
    Gems. When gamers pick up 3200 trophies, thesy will be awarded
    2000 Gems(3715 in the event you depend the Gems awarded by trophies).
    This is the most quantity of gems gamers can generae from achievements, make use oof them properly.

    A different technique to get Gems would be to distinct obstructions,
    that arre a never-ending (albeit slow) source of Gems.
    Road blocks will give Working experiience and wherever among 1 and 6 Gems whenever these are cleared, whilst sometimes they may not give any gems in the slightest
    degree. There may be also a specific obsztacle recognized as the Gem Box, which continually yields twenty five gems when cleared, butt is wayy
    rarer than other regulr obstructions, for example
    trees, and typically spawns about when everfy week.
    A further (despitethe act that confined availability) way for you to gain Gemss wwould be to be 1 insiide of
    the High 20 players from the High 3 Clans. At the end of each two-week
    time period, the very best 3 Clans get paid fifty,000 Gems for 1st, 30,000 Gems for 2nd and 15,
    000 Gems foor 3rd; these totals are divided equally among the best twwenty
    players in the respective Clans.
    Prepare to create the foremost robust clan in the world and protect enemmy territories with
    excellent ability. The Clash of Clanjs hack is correct right here to help
    you receive unlimited gold, endless gems and unrestricted elixir
    so you would do not ever operate outside of methods yet again. The performing hacking process
    hhas long been meticulously produced andd coded by a highly fully commited
    team that have invested lots of hours of labor into it.

    It really works right away and you simply do not will need to be coinsidered a
    desktop computer skilled to utilise it. Jusst plug in your device, join it and allw the
    instrument detect your system. Our software program is thoroughly capable off generating unrestricted methods for huge OSes
    which includes iOS & Android. Whenever you have so a lot gems
    as part of your account, there exists no will
    need to wait foor constructions too complete and limitless gold will make sure you are
    able to upgrade your village, construct defensive structures
    and new troopps devoid of slowing down. The ortiginal recreation appears to have been designed iin a
    way where there is certainly lot of wait time and in order to proceed
    to essentially the most efficient troops of these all, similar to the dark elixir troops you will have to win more battles.
    Instead, we are offering you the Clash of Clans cheats
    thst will unlock them in an instant.
    For players who wish to practical experience the
    sport in all its glory, Clash of Clans hack may be the tactic to go.
    The hacking software very easily detects your platform and
    the next step would be to enter a number for each and every resource that you choose to have.

    As the hacking applications is free of charge to download aand use, players have no resason to worry about running outside
    of gems or gold yet again. You possibly can consistently
    vijsit our website to download the latest verrsions within the course and sustain obtaining resources without utilising a credit card or paying real cash.
    You wiill find no verification process associated ith the software package
    and it truly is made for users like you, who
    want hassle 100 % free fun and infinite assets to beat every clan during the
    map. Witth the guide on the Clash of Clans cheats, it is possible too now
    engage in cllan wars with confidence because
    you will provide the most troops and the methods are designed in a way that the official servers will in no way detect their presence.

    The method features an user pleasant interface which is so easy to navigate
    through and for those peoole of you who are wondering whether itt will be safe, know that it has become tested under
    multiple antigirus as properly as spyware programs beinng proven safe.

    The advantage oof by means of the Clash of Clans hack
    provided in this article is that they do the trick with iOS as perfectly as Android phones aand tablets without
    having to jailbreak or root them. It iis actually aan important factor for users who doesn’t prefer voiding their warranty but would desire
    to get infinite quantitioes of gold, elixir and gems to create a strong clan. It’s time tto play
    the game on your iphone, iPad, Nexus and other Android devices with all of the assets that happen to
    be mandatory stay on top notch for the leaderboard. Have fun with Clash of Clans adventures with our outstanding clash of clans hak annd cheats device.

    This guide will assistance your for Clash of Clans Cheeats and Hack to acquire free
    of charge gems and gold for your game. The hacks and Cheats for totally frfee gems generation on your account allow you a unique ability to add infinite quantity of gems and gold on your Clawh of
    Clans Account. If you ever are fan of gaming therefore
    you are addicted to playing on the net games but you possedss had enough from having to spend
    all those money over the best suited in game item boosts the we have a
    method to make thigs significantly easier for
    you. The latest cheat for Clash of Claans will enabble
    you access to infinite volume of cost-free methods for example gold and gems into yoour COCbattle account.
    This basicalloy means that in the event you use our hack device
    you will do not ever have to spend money once again to play
    Clash of Clans with all its benefits and advantages which you get while you actually spennd money.

  106. star stable star coins Says:

    Good post. I will be experiencing some of
    these issues as well..

  107. mr davis shirts Says:

    Wonderful, what a web site it is! This weblog presents useful information to us, keep it up.

  108. kittchen Says:

    Excellent pieces. Keep posting such kind of info on your site.

    Im really impressed by your blog.
    Hi there, You have performed a great job. I’ll definitely digg it and in my view suggest to my friends.

    I am confident they’ll be benefited from this website.

  109. qorerani.tumblr.com Says:

    Other high-paying industries for Gross sales Managers include financial funding firms, monetary pools,
    funds and apparel, piece goods and notions service provider
    wholesalers.

  110. obama cpa Says:

    As impressive ass these numbers are, Small Enterprise
    Saturday is well defeated bby one other purchasing vacation.

  111. 持久藥 Says:

    對于任何人的情緒波動 威而鋼 效果”雖然很疼 勃金V8,不過敬業的李敏鎬還 威而鋼 效果 是忍著,堅持把戲拍完才去醫治。雖然做演員非常辛苦,但李敏鎬卻很享受 勃金V8 ,“有這么多好的角色讓我詮釋,這么多的朋友支持我 威爾剛,非常幸福。”他還說:“希望新年里能夠演一次陽光大男孩。”齊邦媛考上了遷到四川樂山的武漢大學,一九四五年初,戰場失利,日軍可能進犯四川 威尔刚 是什么,校長訓話:“我們已 威爾剛 經艱辛地?了八年 威而鋼哪裡買,絕沒有放棄的一天,大家都要盡各人的力,教育部命令各校,不到最后一日,弦歌不輟。”如同一九四一年八月十九日張季鸞命名、王蕓生執筆的《大公報》社論:《我們在割稻子》。社論說,“就在最近十天晴空而敵機連連來襲

  112. 催情素 Says:

    到了12點50李健比喻說 陰莖增大膠囊,這種做法相當于俗語所說的“一人感冒,全家吃藥” 陰莖增大膠囊 。其目的是為了對飛機有 日本騰素 可能存在的不安全狀況進行排查波音承諾對其生產飛機的安全運營負責,并將一直致力于保證其現役機隊在運營中保持最高安全標準。國內的航空公司根據需要安排飛機做相應的檢查即可,而且這個時間很充裕,更不會影響到飛行安全 日本騰素。移動互聯網時代,傳統電商的商務市場增速放緩,而且一直面臨著同質化、價格戰等邁不過的坎 威爾康,與此同時社交應用卻始終沒有形成清晰的盈利模式 威爾康 樂威壯藥局,故將兩者相結合的社交化電商應運而生,其中又以微商尤為突出。然而,在微商蓬勃發展的同時,亦不能忽略其缺乏電商生態和缺乏流量監

  113. 威而鋼使用心得 Says:

    廣州為什么不申報多一些呢 威而刚這些人是國家賦役的重要承擔者,其社會地位基本相同。賤 威而刚 籍戶種 新竹藥局犀利士 社會地位低于平民,包括軍戶、錄戶、雜戶、樂戶和丐戶等新中國戶籍制度的變遷。1954 新竹藥局犀利士 年,中國頒布實施第一部憲法,其中規定公民有“遷徙和居住的自由”。1 催情素 N 催情粉 P+ 樂威壯口溶錠哪裡買 z$ 威尔刚 P7 c14天機是目前在我國手機市場上新出現的一個品種,原則上說,應該屬于水貨的一種,因為很多手機愛好者對此還不熟悉,我在這里專門介紹。在外國,比如歐洲和北美,網絡運營商有這樣一種服務:你只 催情素 要在網內開通一個號碼,簽訂使用協議,每個月交納一定數額的話費,交足兩年就可以擁有這部手機,并

  114. 威而剛哪裡買 Says:

    標榜建材行業新高度 性藥這就十分明確的點明了文章的基本思想和中心意義。講的是’《紅樓夢》的哲學,包括講曹雪芹的哲學觀’與’浸透于《紅 性藥 樓夢》文本中的哲學意蘊’。我們現在常說,人要樹立正確的’ 犀利士使用方法 世界觀、人生觀、價值觀’,解決了“三觀”,就是一個純粹的人、有道德的人 。用紅樓夢的哲學視角來看,對于人、人生那還只是肉眼看紅塵,僅是局限于小小的地球、局限于有形的世界,更多的是如何面對色,甚至于只是相,我們不知道(看不到)更廣闊無邊無沿的空和無的境界。而要能看到這個空和無 樂威壯 藥效 ,就必須有天眼、佛眼、法眼、慧眼,有了這樣的視野——大觀視野,也就解決了人的本質問題——從那里來、到哪里去?,“在大觀視野下,生命并非生滅

  115. 迷昏藥 Says:

    并能完善小區的配套騰訊科技訊(陳晴虹)今日,首趟京廣、 威爾剛 京滬 KM/H的車體。為了適應快遞公司白 樂威壯用量 天收貨\晚上分揀、凌晨組織運輸的特點,中國鐵路總公司調整了列車行車時刻表,同時研制了集裝籠進行裝卸作業,將此前兩到三天的收派件流程壓縮到24小時以內對快遞企業來講,電商專列不僅集約化高效運輸的優勢明顯,也更具成本優勢。目前,電商專列設15至19節車廂,每節車廂核定載重在23噸左右。對項目可能產生的危 催情咖啡 害性,她進行了艱難的求證 威爾剛,從一遍遍的模擬實驗到繁瑣的資料收集袁東星教授的一些擔憂 樂威壯用量,在提案中是沒有被具體提到的,但這絕對是一組讓人震驚的數字根據初步估算 催情咖啡,加上翔鷺石化在廈門已經投

  116. 澳洲袋鼠精 Says:

    環境衛生臟亂自知擾亂天理干擾五行,罪行不淺。又悲世人蒙難。欲親下界以降張角。1. 受熱或撞擊后立即引起爆炸的化合物或混合物明 宋應星 《天 增大丸 工開 威而鋼服用 物.火藥》:“凡火藥以硝石硫黃為主,草木灰為輔。硝性至陰,硫性至陽,陰陽兩神物相遇於無隙可容之中,其出也,人物膺之,魂散驚而魄齏粉。” 增大丸 清 和邦額 《夜譚隨錄.烽子》:“予乃取火鎗火藥下鉛子,向婦人發之。然而,剛剛跑了幾步,土黃色護罩便’啪’的一聲煙消云散;緊跟著,以老頭子為中心產生了一場驚天動地的爆炸 威而鋼服用,揚起了一片遮天蔽月的灰塵“吉布森.”回頭看著驚天動地的大爆炸,漢克斯率眾人’啪’的 堅硬持久 一聲跪下來,淚流滿面 堅硬持久。咬咬牙后,率眾人含

  117. 威爾剛成分 Says:

    而公建配套設施大幅增加特別是查禁毒品工作面臨空前的難度和壓力 堅硬持久,突出表現在吸毒人員數量不斷增多 偉哥,一些患有艾滋病、癌癥等嚴重疾病人員和殘疾人、孕婦為 堅硬持久 主的特殊群體涉毒違法犯罪不能及時收戒 催情膏,制約了禁毒執法 犀利士使用 偉哥 方法,影響了社會治安、服務人民群眾和經濟發展的質量有待改進 威而鋼香港價錢。對待群眾冷硬橫推、作風紀律“稀拉松散”等問題不同程序存在,急待加強。黨委成員和派出所長聯系掛牌企業的機制尚存在一些漏洞 犀利士 頭痛,少數企業業主、工程建設項目和招商單位負責人對我縣的治安秩序還不滿意三、加強和改進公 催情膏 安工作的措施 樂威壯口溶錠 心得。中新網10月16日電 威而鋼副作用 據香港

  118. 威而鋼 犀利士 樂威壯 價格 Says:

    半成品38噸我們國家的經濟適用房非常高 ,10%差不多。財富的增長,財富分配給誰了呢?分配給政府或者是老百姓 威而鋼作用 。我們政府的稅收超過10%,差不多20%。小孩們應該多去學學 樂威壯 香港 跆拳道,既可以保護自己又鍛煉了身體。在體博會里全家老小總可以找到適合自己的一項運動,為明天的創意生活鍛煉出健康的身體。主要針對運動健身和機構組織人群,核心項目包括: 室外極限運動廣場和籃球場、游泳館、羽毛球館、健身會所、跆拳道、女子瑜伽館等 。司機很擔心我們將第一口汁液吐在他的車上,還特別停車在路邊讓我們吐掉。因為第一口汁液是血 威而鋼吃過頭 色的,弄到車上洗不掉。第一次吃新鮮檳榔,還蠻恐怖的。隨著市場的發展,紅旗也在幾經變化,到如今 威而鋼作

  119. 性奴粉 Says:

    單日募集規模超過40億 威而鋼香港進入甘孜后,經道孚、爐霍、甘孜、德格過崗嘎金沙江大橋 威而鋼香港 入藏,再經江達、昌都、類烏齊、巴青、索縣、那曲至拉薩。北線相對南線而言,所過地區多為牧區(如那曲地區),海拔更高,人 MAXMAN 口更為稀少,景色更為原始壯麗與南線新都橋至巴塘一段相比,川藏北線新都橋至德格一線 MAXMAN,基本上是沿鮮水河、雅礱江而上,時有草場、峽谷、河水、河原等地形 小叮噹吃威而鋼,不似南線那般高拔和平緩。其中丹巴是嘉絨藏族的主要分布區,塔公草原(也稱毛埡大草原)一帶風光和人文見長 威尔刚 是什么,道孚、爐霍等地民居冠絕康區乃至整個藏區,甘 小叮噹吃威而鋼 孜縣河谷是康區優良的農區 犀利士學名藥,寺院林立,而馬尼干戈、

  120. star stable star coins generator Says:

    You should take part in a contest for one of the highest quality sites online.
    I am going to recommend this site!

  121. Bing Says:

    What’s up Dear, are you actually visiting this web site on a regular basis, if so afterward you will definitely
    obtain pleasant experience.

  122. no credit check loans Says:

    Valuable info. Lucky me I found your site by accident, and I am shocked why this accident didn’t happened earlier! I bookmarked it.

  123. Brianne Coltrin Says:

    Hey, you used to write fantastic, but the last several posts have been kinda boring¡K I miss your super writings. Past few posts are just a bit out of track! come on!

  124. sodium per serving Says:

    Write more, thats all I have to say. Literally, it seems as
    though you relied on the video to make your point. You definitely know what youre
    talking about, why throw away your intelligence on just posting
    videos to your blog when you could be giving us something
    informative to read?

  125. 3 year loans for poor credit Says:

    Yet another thing I would like to talk about is that as opposed to trying to match all your online degree training on days that you complete work (because most people are drained when they go back home), try to receive most of your sessions on the saturdays and sundays and only a few courses in weekdays, even if it means a little time away from your end of the week. This is beneficial because on the week-ends, you will be more rested plus concentrated for school work. Thx for the different ideas I have discovered from your blog.

Leave a Reply

Powered by WordPress