views:

627

answers:

4

Hi!

I have some bug with the following page: http://jsbin.com/agedu/ Source code with some comments: http://jsbin.com/agedu/edit

The problem is that when typing something and doing the query to display search results, if I go back to the search page in my browser (Firefox 3.5 but it's the same thing with IE8) there isn't my search terms anymore.

It's replaced by grey text. This grey text that I only want to have when there isn't any filled text.

When I remove the jQuery code, if I do some search and press "go back" button on my browser the filled text is still present.

And even with this example page: http://mucur.name/system/jquery_example/

If I write some text, load some other URL in the address bar, and then press go back button, the filled text is still present, while it's not with my code.

So my question is: do you have any idea how to keep this text if filled?

There should be a way to detect if the input is filled and avoid replacing text if so.

It may come from browsers and how they deal with JavaScript but I'm not sure about it.

A: 

The inputdynvalue() function explicitly forces the textbox text when called, even if the textbox is non-empty.

Fix it like so:

 (function($) {
    $.fn.inputdynvalue = function(options) {
        var opts = $.extend({},
        $.fn.inputdynvalue.defaults, options);
        return this.each(function() {
            var hvalue = opts.htext;
            switch (opts.htext) {
            case 'title':
                hvalue = $(this).attr('title');
                break;
            case 'value':
                hvalue = $(this).attr('value');
                break;
            }
            if (this.value === '') {
              $(this).attr('value', hvalue).addClass(opts.hclass)
            }
            $(this).unbind('focus blur').bind('focus',
            function() {
                if (this.value === this.title) {
                    this.value = '';
                    $(this).removeClass(opts.hclass);
                }
            }).bind('blur',
            function() {
                if (this.value === '') {
                    this.value = this.title;
                    $(this).addClass(opts.hclass);
                }
            });
        });
    };
    $.fn.inputdynvalue.defaults = {
        htext: 'title',
        hclass: 'hint'
    };
})(jQuery);

The key is the lines:

        if (this.value === '') {
          $(this).attr('value', hvalue).addClass(opts.hclass)
        }

which replace the un-conditional overwrite from before.

The fixed version can be seen at http://jsbin.com/ikipi.

Stobor
I don't think so. setText is called when user clicks on the radio button.
SolutionYogi
@SolutionYogi: you're right, I misread that.
Stobor
Aha. Fixed: http://jsbin.com/ikipi
Stobor
There is still a problem with your version. Go to your page, enter some text in Google text box, hit Ok. Go back. 'Wikipedia' is not greyed out.
SolutionYogi
Same thing as Kennethj:Thanks but I noticed some bug, when typing "blablabla" in Google input and checking "Spanish" for Wikipedia, if I do my Google search then go back "blablabla" will still be there but "Spanish Wikipedia" will not be greyed out and if I click on radio buttons it doesn't change anymore. But that's a beginning...
Mark
A: 

When you initialize your plugin, you were setting resetting the value of the inputs, I just refactored a bit and added the following check:

        if (this.value === '' || this.value === hvalue){
          $(this).attr('value', hvalue).addClass(opts.hclass);
        }

I separated that operations from your focus event connection chain.

Now it will only set the default value (hvalue) and the default gray class (hclass) if the element value is '' or it has the default value.

Check your snippet here.

CMS
This still doesn't solve the problem posted by the author.
SolutionYogi
If selecting "French", then clicking in order to type, the grey text isn't removed as before. It should work as before except keeping search input when going back with browser.
Mark
A: 

Tested in IE8 and FF

This is copied from the source and modified.

I made a ghosted text control in plain old js a while back, looking at it in jQuery makes me want to go back and rewrite it.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt; 
<html xml:lang="fr" xmlns="http://www.w3.org/1999/xhtml" lang="fr"> 

<!--

  Created using http://jsbin.com
  Source can be edited via http://jsbin.com/oxeye/edit

-->

<head> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt; 
<style type="text/css"> 
   .hint { 
    color: #C0C0C0; 
} 
</style> 

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
 <title>Test</title>
</head> 
<body> 

<form action="http://www.google.com/search?&amp;q="&gt; 
 <div class="saisie"> 
  <input type="text" id="lr_text" name="q" title="Google" />  
  <button type="submit">OK</button> 
 </div> 
 <div class="options"> 
  <label for="lang_en"><input type="radio" checked="checked" id="lang_en" name="lr" title="English Google" />English</label> 
    <label for="lang_fr"><input id="lang_fr" type="radio" name="lr" title="French Google" />French</label> 
  <label for="lang_de"><input id="lang_de" type="radio" name="lr" title="German Google" />German</label> 
  <label for="lang_es"><input id="lang_es" type="radio" name="lr" title="Spanish Google" />Spanish</label> 

 </div> 
</form> 
<form method="post" action="http://en.wikipedia.org/wiki/Special:Search?search="&gt; 
 <div class="saisie"> 
  <input type="text" id="wikipedia_text" name="champ_wikipedia" title="Wikipedia" /> 
   <button type="submit">OK</button> 
 </div> 
 <div class="options"> 
 <label for="wik_en"><input type="radio" checked="checked" name="wikipedia" id="wik_en" title="English Wikipedia" />English</label> 
  <label for="wik_fr"><input type="radio" name="wikipedia" id="wik_fr" title="French Wikipedia" />French</label> 
 <label for="wik_de"><input type="radio" name="wikipedia" id="wik_de" title="German Wikipedia" />German</label> 
 <label for="wik_es"><input type="radio" name="wikipedia" id="wik_es" title="Spanish Wikipedia" />Spanish</label> 
 </div> 
</form> 

<script type="text/javascript">
    $(document).ready(function() {
        function setText() {
            var kf = this.title.split('|');
            if (kf.length < 0) return;
            if ($('#' + this.name + '_text').hasClass('hint')) {
                $('#' + this.name + '_text').val(kf[0]).addClass('hint');
            }
            $('#' + this.name + '_text').attr('title', kf[0]);
        }

        $("input[type='text']").inputdynvalue();
        $("input[type='radio']").click(setText);
    });

(function($) {
    $.fn.inputdynvalue = function(options) {
        var opts = $.extend({},
        $.fn.inputdynvalue.defaults, options);
        return this.each(function() {
            var hvalue = opts.htext;
            switch (opts.htext) {
                case 'title':
                    hvalue = $(this).attr('title');
                    break;
                case 'value':
                    hvalue = $(this).attr('value');
                    break;
            }
            //if value == title change class to 'hint'
            if ($(this).attr('value') == $(this).attr('title')) {
                $(this).addClass(opts.hclass);
            }
            $(this).attr('value', hvalue).unbind('focus blur').bind('focus',
            function() {
                if (this.value === this.title) {
                    this.value = '';
                    $(this).removeClass(opts.hclass);
                }
            }).bind('blur',
            function() {
                if (this.value === '') {
                    this.value = this.title;
                    $(this).addClass(opts.hclass);
                }
            });
        });
    };

    $.fn.inputdynvalue.defaults = {
        htext: 'value', //changed to value
        hclass: 'hint'
    };
})(jQuery);
$(document).ready(function() {
    //Set hint
    $("input[type='text']").blur();
});
</script>
<script type="text/javascript">
                 var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
                 document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
    var pageTracker = _gat._getTracker("UA-1656750-13");
    pageTracker._trackPageview();
</script></body></html>
x13
Thanks but I noticed some bug, when typing "blablabla" in Google input and checking "Spanish" for Wikipedia, if I do my Google search then go back "blablabla" will still be there but "Spanish Wikipedia" will not be greyed out and if I click on radio buttons it doesn't change anymore. But that's a beginning...
Mark
Mark, if you want to be able to grey out the text depending upon the radio button state, you will have to take an entirely different approach. Let me try to code a solution for that.
SolutionYogi
Yes that's what I want, your above solution didn't work, I hope you will find something. Thanks for your help.
Mark
+1  A: 

Wow, it took a long time to debug this one, I think you should use the val method instead of using the 'value' attribute.

Anyway, the problematic line is this

$(this).attr('value', hvalue).addClass(opts.hclass).unbind('focus blur').bind('focus',

In the above line, when you assign the attribute 'value', you are actually changing the value of the text box. You should change it only if it's non empty.

I changed your code a little bit to use val() method everywhere and it works as you expected.

Working demo: http://jsbin.com/ihegu/

[Notice how the demo correctly greys out 'Wikipedia' text when you search something on Google and click on the back button.]

 (function($) { 
    $.fn.inputdynvalue = function(options) 
    { 
        var opts = $.extend({}, 
        $.fn.inputdynvalue.defaults, options); 
        return this.each(function() 
            { 
            var hvalue = opts.htext; 
            switch (opts.htext) 
            { 
                case 'title': 
                    hvalue = $(this).attr('title'); 
                    break; 
                case 'value': 
                    hvalue = $(this).val();
                    break; 
            } 

            //Modify the text value ONLY if it's non empty. 
            if($(this).val() === '')
            {
               $(this).val(hvalue);
            }  

            //If title and value is same, apply the grey text class.
            if($(this).val() === this.title)
            {
               $(this).addClass(opts.hclass);
               //Why do you unbind the event?
            };

            $(this).bind('focus', 
            function() { 
                if ($(this).val() === this.title) { 
                    $(this).val('');
                    $(this).removeClass(opts.hclass); 
                } 
            });

            $(this).bind('blur', 
            function() { 
                if ($(this).val() === '') { 
                    $(this).val(this.title);
                    $(this).addClass(opts.hclass); 
                } 
            }); 
        }); 
    }; 
    $.fn.inputdynvalue.defaults = { 
        htext: 'title', 
        hclass: 'hint' 
    }; 
})(jQuery); 
$(document).ready(function() { 
    $("input[type='text']").inputdynvalue(); 
});
SolutionYogi
I forgot to mention it should work as before, which means when clicking on radio buttons it changes grey text if input is empty, it doesn't with your code but I will look at it.
Mark
That was because I had commented out the radio button click handler to debug the problem. Try this:http://jsbin.com/ihegu/
SolutionYogi
Same thing noted as before:when typing "blablabla" in Google input and checking "Spanish" for Wikipedia, if I do my Google search then go back "blablabla" will still be there but "Spanish Wikipedia" will not be greyed out and if I click on radio buttons it doesn't change anymore.
Mark
To answer your question I used to unbid the event in order to reset the event handler but if it's buggy feel free to remove it ;-).
Mark
Note: I added a few source comments so I edited the links of my question.
Mark