views:

152

answers:

4

I have a loginbar that can be used to login to 2 different systems depending on what value a user chooses from a dropdown. And then, I provide default values to fill each textbox depending on which login is chosen by the user. However, to make things easier for the user by clearing the default contents when the textbox receives focus, and then refilling it on blur.

 $('#logintype').change(function() {
  if ($(this).val() == 1) {
   $('#loginf').attr('action','login1.php');
   $('#loginf #user').attr('name', 'userid').attr('defaultValue', 'Username').val('Username');
   $('#loginf #pass').attr('name', 'password').attr('defaultValue', 'password').val('password');
  }
  else {
   $('#loginf').attr('action','login2.php');
   $('#loginf #user').attr('name', 'email').attr('defaultValue', 'Email').val('Email');
   $('#loginf #pass').attr('name', 'passed_password').attr('defaultValue', 'password').val('password');
  };
 });

 $('.textbox').focus(function(){
  if ($(this).val() == $(this).attr('defaultValue')) {
   $(this).val('');
  };
 });

 $('.textbox').blur(function(){
  if ($(this).val() == '') {
   $(this).val($(this).attr('defaultValue'));
  };
 });

Is there a more efficient way to accomplish this? I feel like I'm repeating myself and that's never a good thing. I'd also appreciate comments on whether or not this is a good idea in terms of user experience.

+2  A: 

First, what you have is perfectly valid. The only changes I can suggest is to use .data() and $.data() to make it valid (no invalid attributes). You can chaining the .focus() and .blur() handlers to prevent a duplicate selection. Also there's no need for #loginf before another ID selector...they should be unique and just #ID has a shortcut in the jQuery core code.

Also, I changed it around a little bit to make it more extensible so you can add as many as you want with less code as you go, like this:

var types = { "1": { action: "login1.php", 
                     user: { id: "userid", val: "Username" },
                     pass: { id: "password", val: "password" } },
              "2": { action: "login2.php", 
                     user: { id: "email", val: "Email" },
                     pass: { id: "passed_password", val: "password" } } 
            };
$('#logintype').change(function() {
  var type = types[$(this).val()];
  $('#loginf').attr('action', type.action);
  $('#user').attr('name', type.user.id).data('defaultValue', type.user.val).val(type.user.val);
  $('#pass').attr('name', type.pass.id).data('defaultValue', type.pass.val).val(type.pass.val);
}).change();

 $('.textbox').focus(function(){
  if ($(this).val() == $.data(this, 'defaultValue')) $(this).val('');
 }).blur(function(){
  if ($(this).val() == '') $(this).val($.data(this, 'defaultValue'));
 });​

You can give it a try here, personally I just like this style in case you need to add a third option later it makes it very quick/easy to do (though arguably your current method still makes this pretty easy). As you add more though, you'll save more and more code this route over the your current way, but it completely depends on your style, it doesn't matter much either way.

Nick Craver
Only issue is that it doesn't clear on focus when the page first loads. Also, how come you use data for defaultValue but not for the name attribute for instance.Also, I forgot about the ability to chain things like .focus() and .blur() - that already makes it look better.
Radu
@Radu - I just updated, didn't notice the onload bit, it's fixed now (call `.change()` to run the handler on load). Also this allows your inputs to not have any `value` or `name` attributes at the start, so you can remove those from your makrup (I did this in the demo). We're not using attribute here because `defaultValue` isn't a valid attribute (`name` is!), `data` is stored elsewhere on the `$.cache` object. In practice it doesn't matter much that you're using an invalid attribute, I was just trying to make it as clean/compliant as possible :)
Nick Craver
Ah, I wasn't aware it was invalid.
Radu
@Nick - I have my version also.. ;) http://jsfiddle.net/QgdAh
Reigel
@Reigel - It has the issues I addressed above though...you should fix the invalid attributes and the inefficient selectors :)
Nick Craver
@Nick - Ahh I thought `defaultValue` is a javascript and is valid.. :)
Reigel
+3  A: 

You could also use the HTML5 attribute "placeholder", with cross-browser compatibility using Mike Taylor's html5placeholder.jquery.js; it will use native browser support if available: http://github.com/miketaylr/jQuery-html5-placeholder/blob/master/html5placeholder.jquery.js

peol
That's pretty awesome, wasn't aware that this will be included in HTML5. That plugin you linked is also pretty tiny. Will keep this in mind as support for HTML5 grows.
Radu
You shouldn't be afraid of using it, it works perfectly fine already. Browsers like Chrome/Safari/Firefox/Opera (newer versions) already has this implemented natively. :)
peol
A: 

demo

without .data() this can also be achieve as,

$('#logintype').change(function() {
  if ($(this).val() == 1) {
   $('#loginf').attr('action','login1.php');
   $('#user').attr('name', 'userid')[0].defaultValue = 'Username';
   $('#pass').attr('name', 'password')[0].defaultValue= 'password';
  }
  else {
   $('#loginf').attr('action','login2.php');
   $('#user').attr('name', 'email')[0].defaultValue = 'Email';
   $('#pass').attr('name', 'passed_password')[0].defaultValue = 'password';
  };
 });

 $('.textbox').focus(function(){
  if (this.value == this.defaultValue) {
   this.value = '';
  };
 }).blur(function(){
  if (this.value == '') {
   this.value = this.defaultValue;
  };
 });

could also try this one

$('#logintype').change(function() {
    var bol = ($(this).val() == 1);
    $('#loginf').attr('action',bol?'login1.php':'login2.php');
    $('#user').val(bol?'Username':'Email').attr('name', 'userid')[0].defaultValue = bol?'Username':'Email';
    $('#pass').attr('name', bol?'password':'passed_password')[0].defaultValue= 'password';
});

$('.textbox').focus(function(){
    if (this.value == this.defaultValue) {
        this.value = '';
    };
}).blur(function(){
    if (this.value == '') {
        this.value = this.defaultValue;
    };
});
​
Reigel
A: 

Don't retail stale news.

http://plugins.jquery.com/project/placeholder

Riateche