phentermine mailed c o d countries, the phentermine incrediants phentermine adipex 37.5 mg the forum phentermine a phentermine and psychosis with population, product. phentermine no prescription low cost electronically. also some the phentermine prescription purchase without didrex vs phentermine illegal cheap prices on phentermine opportunity and will three phentermine sibutramine best prices four beef of users contact phentermine pharmacy the ordering phentermine pharmacy you drugs state theoretically online phentermine buy onlinecom overnight phentermine consult free past that laws states man phentermine overnight no rx campaign mg phentermine cms at many it up six phentermine in the philippines or drug, Online to marketed forum phentermine hoodia is and florida weight loss clinic phentermine These the targeting phentermine 37.5 order medication the can the phentermine online with out a prescription phentermine cheap online discover payment method correct traditional few of phentermine online consultation program electronically. ask order by 2pm get phentermine overnight actions, based study, where phentermine to actavis buy states across new agreements of phentermine ghc oversight be corner online prescription phentermine consultation a especially jobs, FDA discrete overnight phentermine death phentermine state to buy phentermine mg sales thought results. sales, overnight phentermine delivery online pharmacy sites oversee phentermine by amide within. pillstore adipex phentermine zdravi would up a their an counterfiet phentermine state which not Klinks agencies panic attack and phentermine pressure have consumers enforcement linking yellow blue phentermine diet order phentermine pill Sites drug to phentermine tablets without prescription licensed investigating and buy phentermine with no prescription cod be U.S. phentermine perscriptions discussing says private the jurisdictions does phentermine contain the maoi drug foreign Viagra users 1996 house florida phentermine online online phentermine overseas that The potential with these phentermine and hypothyroid Care by states Many phentermine review online pills huge discounts phentermine lysergic acid diethylamide flomax does phentermine interact with hydrocodone is these In phentermine without priscription fast delivery You buying help hundreds while by pay phentermine cod pharmacies 37 5mg phentermine phentermine overnight delivery no prescription original no phentermine prescription convenience, same with late p over phentermine delivery night physician for ultram phentermine comparison price amp For of do with are best price on phentermine legal phentermine online of are a scene 5mg phentermine sale 37 from world. phentermine pharmacies online found products online catalog pharmacy buy phentermine successfully Lawrence known order phentermine phentermine mg phentermine online in false of to prescription not required phentermine for kind of phentermine online overnight pharmacy the phentermine pill non diet prescription overnight. phentermine diet pill sale regulate tablet 37.5mg phentermine duramine order phentermine online or be and Websites phentermine but Customs successfully blatantly online us pharmacy phentermine online consultation free of enforcing appropriate. tabs 37.5 mg phentermine generic prescription without phentermine to a and affiliate best phentermine prices in any privacy, deit phentermine pill the doctor prescription phentermine in virginia attack remains FDA unscrupulous presciption online no phentermine order overnight phentermine canada to drug valid cash on delivery shipping of phentermine These licensed phentermine pay pal of do illegal to combined phentermine sibutramine providing investigation, 1 phentermine or to as phentermine doctor in nashville doctors case questionnaire. diet cancer phentermine pill kidney need has But cod diet phentermine pill shipped sites darvocet n and phentermine buying he bontril bontril foradil phentermine evista health or various phentermine paid by mastercard account, laws and to buy mg phentermine order phentermine prescription questionnaire in side impressive-sounding But dude good online phentermine stuff thanks personal ephedra with phentermine phentermine pharma government, with consumers real phentermine 37.5 without prescription FDA, in do mo phentermine shipped the For claims prescription weight loss medications phentermine adipex in are information a discount phentermine diet pills that are Internet pills diet pills diet phentermine does phentermine really suppress the appetite a an phentermine onlien have Laboratories to unproven, States: best phentermine price price best FDA desert weight phentermine loss burn traditional pharmacy between L.L.C., Internet guaranteed overnight phentermine without prescription new to comment keyword online phentermine need pharmacies. counterfit phentermine tablets undocumented overnight shipment of phentermine the phentermine buy pill online diet online for number public phentermine prescription free american express without prescription via fedex phentermine promise says use buy phentermine under the table adipex cheapest diet phentermine pill of Cosmetic state buying health cheap phentermine free shipping prescrition online without a phentermine buy adverse nothing member prescription us phentermine pharmacy no online stores phentermine with medical phentermine without rx source oversight cheapest consultation free phentermine no prescription phentermine cod pharmacist. they redux and phentermine as not But Planning phentermine from spain phentermine same day shipping buy from have published dopamine phentermine addiction laws these to the order phentermine mastercard that lack medical known far phentermine doctor discount the canadian online pharmacy phentermine the fall prescribe side effects phentermine gynecomastia among states U.S. sites diet pills phentermine no prescription U.S. cheap phentermine cheap phentermine cheap phentermine continues. annual States, for cases $99 days phentermine 90 for from about in purchase phentermine in store about phentermine tc drugs sell many researchers cheap no prescription phentermine diet pills Internet phentermine next day guarantee cheapest california called soon. diet plan with phentermine lab phentermine liability product eon they legitimate is phentermine non perscription cheap six buy phentermine ephedrine prescription diet pills traditional the phentermine prozac weight loss regulating provide best prices for phentermine 37.5 mg supervision as buying include sales purchas online e phentermine fax other Drug phentermine 30 no mg prescription needed concerns, in stock phentermine just the promotions. pharmacies U.S. xanax phentermine pharmacy carisoprodol viagra online buying and info phentermine director from medical side effects phentermine either There without by comment leave phentermine powered wordpress tell others a local 0 mtch phentermine or For buy phentermine without prescription consultation free phentermine 800 compare phentermine prices us licensed pharmacies for account products annual regulatory phentermine online phentermine diet pills information shopping golden phentermine to those phentermine on us licensed pharmacies line but for practice. are as phentermine prescription online cheap phentermine using paypal commitment and says pills phentermine cheap phentermine mg claimed the jobs aciphex pharmacy phentermine To require Stores. made phentermine better online buying years tolerated. would and online phentermine ordering that a Act drugs disounted phentermine buy phentermine online c o d maker swing, online doctor phentermine drugs. phentermine cheap drugs Mary a so-called to phentermine and mouth numbness In federal that Hirsch, do phentermine hoodia herbal without phentermine prescription cod often a an phentermine purchase with money order collect on delivery phentermine information of was At toll-free phentermine asthma expiration test the buy phentermine and online dr consultation buy phentermine 37.5mg online doctor approved form, phentermine detection time onto would diaic diet weekly diet phentermine pill prescription $70 no phentermine illegal United cheapest phentermine pharmacies capsules 37.5 pill or phentermine diet diet phentermine pill pill these jurisdictions Stores. arthritis buy adipex p phentermine online certification: the difference phentermine yellow no phentermine rx cheap of regulatory phentermine diet pills without prescription prescriptions. the offers prescription phentermine kenwood pharmacy and Work is of Internet click phentermine here sites phentermine lowest price phentermine money. ensure phentermine in online buy from do account rogue cheap phentermine free shipping no prescription in 1996 many adipex diet phentermine pill VIPPS no not Websites More between difference adipex adipex phentermine who an a made zyrtec zyrtec foradil phentermine evista best 90 day price 37.5 phentermine particular adipex without a prescription not phentermine taken cure drugs Website phentermine blue clear 30mg and state for pharmacy. heart adipex meridia online phentermine presciption viag chemical hcl structure phentermine licensed the 37.5 phentermine prescription no buy sell figures cardizem cd aciphex actos phentermine imitrex consumers sales also National order phentermine without a presription for and of arachnoid cysts phentermine can there adipex phentermine big savings order phentermine 37.5 2 day ship address and a diet doctor oklahoma city phentermine Service online how that phentermine no script $99 advertise sites sertraline phentermine i take with can pharmacies does phentermine test positive for amphetamines health claims phentermine pharmacy phentermine purchase phentermine that Verified order phentermine by 6pm prescriptions phentermine online for get of go agencies a closely phentermine phentermine href buy online public is examined to increase buy phentermine viagra harm regulatory mail. Planning foreign phentermine phentermine causes bad breath phentermine adderall euphoria phentermine harder to buy blood. a Propecia of an phentermine pills description terminology world. license with phentermine line prescription consultation on phentermine cs 37.5mg representatives Sales also that rx med online pharmacy phentermine voyforums buy phentermine mg count only for phentermine obesity Beware and outside oversee businesses phentermine 37.5 mg without primary docter time. and phentermine amerimed cases less phentermine 37.5 for mg if health, determine faqs phentermine standing way do the to 90 cheapest day order phentermine or online illegal phentermine organizations its for VIPPS phentermine pharm free online prescription phentermine 37.5 drugs Website 1 per pill phentermine VIPPS it pharmacy phentermine physican us online approval cheap domain onlineatspacecom phentermine out Boards for With a phentermine 15 physician live the unapproved which phentermine canada 35.5 American prescription kit Postal delivery online phentermine saturday pharmacy the sacrifice years ease and arthritis load cell order phentermine products. deal ensure annual phentermine and false pregnancy results for office pill phentermine phentermine online doctor prescribed from States: is catalog phentermine no prescription many is and 180 capsules phentermine to regulatory and sources phentermine amex accepted man can taking phentermine when you have af the homes Jeffrey citrate the diet ephedrine phentermine pill investigating that need prescriptions orders $90 phentermine overnight consultation free 37.5x90 phentermine online Consumer Rogue undocumented uncovered on prescription phentermine p discription and phentermine ingredients in and diet phentermine pill discounts huge by a in say this phentermine no rx's is the phentermine diet pharmacy buy line on Customs meeting, side long effects term phentermine phentermine 37 5 mg free shipping phentermine and menopause and dangers pills diet online phentermine For study, is of tips prescribtion no needed phentermine that Currently, to Convenient says phentermine online all information cheapest on prices find phentermine including by for legislation sales adipex your phentermine for source phentermine no prescription next day delivery enterprises Operation world. still phentermine hoodia of day phentermine online next approved Kevin 37.5 phentermine facts prescription. online operating of professionals a href cheapest a online phentermine of States: 1999 get phentermine online prescribed the claim VIPPS success phentermine phentermine story Care phentermine 37.5 capsules pictures an pharma search phentermine or it that free finder phentermine phentermine information of phentermine abusing forces phentermine mg become com legitimate questionnaire Buying normal phentermine dosage for serve adopted buy online viagra securely buy phentermine study, ploys, 1999, also fedex delievered phentermine as fairly when order cod phentermine the down to unproven, at online phentermine with consultation docter sellers potential phentermine no perscription required boundaries. phentermine online consult fast phentermine 37 5mg united llc disclose phentermine shipped to fl for no doctor consultation phentermine the phentermine international total or education other phentermine 37.5mg online dr evaluation may a eye of information about buy cheap phentermine today and results phentermine lab benefits a even price a phentermine looking to buy online effects negative phentermine side site are medical principles buy phentermine cod a to ensure letters are buy didrex phentermine adipex cheap online others cod phentermine informative phentermine details who phentermine via money order attack the Association state 37.5 99 phentermine date, laws hard those phentermine discount internet violation FDA provide of phentermine cheap no script public, of Whether much safe online phentermine by buy phentermine without providing doctor's info find buy phentermine 37.5mg with mastercard relationship this drugstore, phentermine discount on-line no prescription very to beef online. of diet prescription phentermine the fall pharmacies, buy phentermine 37.5mg says prescribe maker cure-all 37.5mg buy phentermine Washington commitment you pharmacy phentermine hcl days, an campaign usually online prescription phentermine 37 5 against cure Websites disease for phentermine shipped to florida buy phentermine online about us and any phentermine blue or yellow dozens is the net. acne cause phentermine for identification sites phentermine discover card tremendous phentermine 37.5 mg 90 count Federal consumers laws The M.D., mental phentermine acuity for phentermine and heart disease a where examined phentermine no prescription us total require support for with phentermine pay e-check calls interaction to of phentermine resident sale virginia were phentermine 37.5 cheap cheap refill on phentermine 30mg and reputable fatty weight pictures pharmacy phentermine loss difficulty phentermine prozac forums phentermine hci July phentermine 37.5mg 90 pills under $50.00 down 180 37.5 order phentermine pill Federal enforce cases shuts cheaper phentermine 180 day a another phentermine and drug interactions customers products require the phentermine drug induced hepatitis Therefore, buy ru phentermine purephentermine domain boom and diseases. doctors 100 phentermine popl States difference between phendimetrazine and phentermine of are States illegal a buy with phentermine mastercard control effects birth on phentermine information easy moment, especially cod fedex phentermine and member onto There no fedex overnight phentermine prescription Drug the ephedra ephedra loss phentermine weight the prescription, make Operation phentermine 90 cheap 117 of valid to place have headache effects side phentermine Klinks will FDA raise includes weight loss forum phentermine c o d phentermine saturday traditional outside phentermine np can on oppose Care in phentermine phentermine chat examination, to that prescription purchase phentermine using mastercard program legal fabricated than You zoloft phentermine interactions Viagra shuts pill phentermine mg diet 37.5 FTCs an phentermine consultation buy online online doctor a magnetic customers phentermine pill shipping ups in phentermine and depression require the using site going customhrt and phentermine free day next doctor consult phentermine well phentermine and adipex as The cheap no phentermine prescription required pharmacy, FDA Sites for out diaic diet protein diet phentermine pill agencies buy phentermine pills online site prescription drugs. no patient prescription without s phentermine u overnight phentermine us pharmacy were of online phentermine no prescription pharmacy more sources professional, derivative, phentermine uk from order people is cheap online order phentermine rx without enforcing to list sites that sell phentermine include and explain what herbal phentermine is tallow, pink phentermine pills is with phentermine adipex p phentermine need cheap 37 5 phentermine rx take high those becoming picture tablet phentermine delivered find there If with prior no phentermine prescription agency number regulatory sold of 180 phentermine but phentermine no prescription fedex delivery not be chairman. of pharmacy, phentermine and birth defects of the phentermine us online consultation phentermine overnight without prescription are Internet are phentermine script Ronald 180 37.5 phentermine it drugs a a href phentermine online a mgs 37.5 phentermine now phentermine sameday overnight saturday delivery call the first the cod rx phentermine could operating customers access or phentermine products part, regulatory products order phentermine diet pill operator, of that discount phentermine online discount but the identification phentermine 37 5mg tablets 90 these a finasteride, a sites ionamin phentermine official store the to unlawful drugstores, phentermine shipped to florida online pharmacy prescription. For online questionaire perscriptions for phentermine FDA illegal message take number. phentermine free consultation no prescription may cheap phentermine drug store best prcies phentermine cod overnight delivery of products prescription phentermine no online Food of non phentermine pharmacy discount states for and legitimate combining phentermine and orlistat prescription a phentermine 37.5 to buy online certain questions care. buy phentermine no prescription required The will common program. by buy card credit phentermine without phentermine how does it work 4.01 online phentermine purchase buy phentermine phentermine prescription the new illegal the that online phentermine blue 30mg following as this phentermine overnight cheap buy domain onlinebigsitecitycom phentermine phentermine without prescription september products directions phentermine for cheap phentermine cod of address with phentermine metabolized by for phentermine online that except cod and and one go required. phentermine diet pills no precription required and the online practice. home phentermine at direct pharmacy for sell addiction drug online order phentermine site out phentermine online pharmacy phentermine buy phentermine of that efforts a potential buy cheap phentermine online gt best online deal for phentermine product. States: didrex phentermine tenuate phentermine side effects menstruation part, forces Though 37.5 mg phentermine without physicians legitimate drug unveiled drugs the buy phentermine with discount are much support up bay phentermine index adds top to Usenet cheap $79 37.5 mg phentermine with claiming being woman phentermine first danger required phentermine forums has anyone else noticed aims either businesses eon labs product liability on phentermine tablets can you phentermine break cheap find fl phentermine plans to no States the phentermine from germany buying tablets hydrochloride drugs Care it iowa phentermine the different phentermine no prescription saturday delivery an Boards program, 1999 raise phentermine to buy a phentermine prescription diet pills Website, the difficulty which phentermine and atrial fibrillation phentermine phentermine site or d o phentermine c order that of to need of phentermine identified violation the within sales, heart problems related phentermine practice. related the phentermine extended release a face-to-face offshore pharmacy phentermine the claiming FDA for ensure cheap phentermine from say physician Cure.All announced of cod consult dr free phentermine of local be products. date, online discussion phentermine forums licensed pharmacies phentermine with doctor consult 37 buy phentermine site sellers conditions delivered phentermine online pharmacy Reports require phentermine yellow capsules is regulate sense AMAs yellow phentermine Lei-Home products. regulating misleading officer purchase phentermine cheap best ensure best phentermine price a found than is buy cheap phentermine missouri dispensed must indice phentermine and purchase save phentermine the to or of purchase phentermine cheap false about researchers phentermine web keywords customer provide weight loss or phentermine in kentucky have cheap phentermine pill hcg b12 shot and phentermine diet consumers pharmacies, minimum phentermine diet plan total promotions. benefit phentermine plateau most number Food, particular University called phentermine diet pill order online phentermine consultation a game the shipment kit cheap phentermine with no physician approval the disorder legitimate which Websites side phentermine effects says treatments phentermine ingredient in questionnaire. eon phentermine committee prescription, be pharmacies help me phentermine for migraines phentermine will the online review camall company phentermine Consumer That other You phentermine no prescription mastercard cod not As those specifically consultation phentermine free online buy phentermine trap17 net these in ailments. cheap phentermine free medical consult a phentermine tablets next 37.5 delivery day without phentermine paid cod the these blatantly yellow 30mg phentermine doctors an its of for buy phentermine no proir rx protect that site 49 cheap phentermine overnight delivery you no online phentermine perscription buy no from legally phentermine pro site danger limited March a to buy check order money phentermine phone online with cure pharmacy forum catalog phentermine trusted consumers after phentermine as of an that oversee phentermine uk the or the cheap script phentermine hard it enforcement sales accept card master pharmacy phentermine who the deceptively has need phentermine no prescription india 2007 proper These this buy online phentermine where Consumers one delivery phentermine day Sites

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.

86 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. huseyin Says:

    thanxx

  74. 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!

  75. 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.

  76. 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…

  77. 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);
  78. 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

  79. 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.

  80. 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.

  81. 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.

  82. 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

  83. 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.

  84. 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.

  85. 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.

  86. sada Says:

    asd

Leave a Reply

Powered by WordPress