Sabai
Sabai

Reputation: 1599

How to make JavaScript find value of input on focus, clear if it's default and keep if it's new data?

I've spent too many hours trying to figure this, and I've found parts of the answer here on Stackoverflow but still can't get this working.

What I want to do is control all input elements sitewide with some JS/jQuery. When a user focuses on the input, if the value is the same as when the page loaded, clear it, if it's been altered, keep it. Then on blur, if the field is empty, return the default value.

What I have so far is this:

var input = document.getElementsByTagName('input');

$('input, textarea').focus(function() {
    value = $(this).val();

    for (var i=input.length-1; i >= 0; i--) {           
        if(value == input[i].value){
            $(this).attr("value","");   
        }   
    }
});
$('input, textarea').blur(function() {
    if($(this).val()=="") {
        $(this).val(value);
    }
});

This partly works, it just keeps clearing the inputs though, whether they have been changed or not. I'm guessing I am storing the initial values wrong.

Upvotes: 0

Views: 5561

Answers (6)

natedavisolds
natedavisolds

Reputation: 4295

You just need to store a default value first, then reference it on blur and focus.

$('input, textarea').each(function() {
        var $this = $(this);
        $this.data('defaultValue', $this.val()); // stores the default value

        $this.focus( function() {
            if ($this.val() == $this.data('defaultValue')) { 
                $this.val(""); 
            }
        });

        $this.blur( function() {
            if ($this.val() == "") { 
                $this.val( $this.data('defaultValue') ); 
            }
        });
});

With a second look, I think that we don't even need the data store.

$('input, textarea').each(function() {
        var $this = $(this),
            defaultValue = $this.val(); // stores the default value

        $this.focus( function() {
            if ($this.val() == defaultValue) { 
                $this.val(""); 
            }
        });

        $this.blur( function() {
            if ($this.val() == "") { 
                $this.val(defaultValue); 
            }
        });
});

Upvotes: 1

japrescott
japrescott

Reputation: 5015

this line is the bad guy

if(value == input[i].value){

since getElementsByTagName returns a HTMLCollection, changes to the dom are also in your input variable. Thus, value will always be input[i].value, since your getting the value of the same input elem, which of course are the same!

use jquery data method to save the value within the element. and on blur, retrieve it again to make the comparison.

like this;

var handlers={
    focus: function() {
        var elm=$(this),
            value=elm.val(),
            old=elm.data("placeholder");
        if (typeof old==="undefined"){
            elm.data("placeholder", value);
            old=value;
        }
        if (old==value){
            elm.val("");
        }
    },
    blur:function() {
        var elm=$(this);
        if( elm.val() == "" ) {
            elm.val( elm.data("placeholder") );
        }
    }
};
$('input, textarea').each(function(i, elem){
    $(elem).
        focus(handlers.focus).
        blur(handlers.blur);
});
//not tested, should work!

Upvotes: 4

jzilla
jzilla

Reputation: 1703

this does it all: http://jsfiddle.net/uUzY3/4/

$(function() {
    $("input").each( function () {
        $(this).data('initialValue', $(this).val());
    }).bind('focus', function() {
        if ($(this).val() == $(this).data('initialValue'))
            $(this).val("");
    });
});

Upvotes: 0

aepheus
aepheus

Reputation: 8187

So, issue 1 - that collection in input is by reference, so when your inputs are updated, they are also are updated in the collection, thus the value always appears to be the default.

What I would recommend is rather than storing the default values that way, store them as part of the element. On load you can loop through the elements and add the values to a "default" attribute. You could also add the default attribute server-side which would be better.

Something like this:

<input type='text' default='myval' value='myval'/>
var jInput = $('input');
if(jInput.val() == jInput.attr('default'))
...

I'm sure you get the idea.

Upvotes: 0

nrabinowitz
nrabinowitz

Reputation: 55678

I think @japrescott is correct, but you have another issue as well - in the block:

$('input, textarea').blur(function() {
    if($(this).val()=="") {
        $(this).val(value);
    }
});

...the variable value isn't defined in scope.

Upvotes: 0

SiburNY
SiburNY

Reputation: 139

this what I use on my Search box:

<input name="q" value="Search here ..." onfocus="if(this.value == 'Search here ...') this.value = '';" onblur="if(this.value == '') this.value = 'Search here ...';">

Upvotes: 0

Related Questions