1

I am programming a panel using jquery, you can see it here: http://www.taoktalk.com/socialapps/baidu/taozhe/ My logics are:

  1. When i click each of the buttonset, the defaut value of the input element changed;
  2. Each time when focus in the input element, the value was cleared;
  3. If blur out without type anything, the default value was reset back, but if typed some words, the words is the value.

Method 'inputWithDefValue' implements the logic 2 and 3. But logic 1, when i click the button set, the evnet 'focus' and 'blur' was bind incrementally, so the 'defVal' variable was not correct. How to fix this, thanks.

For debug, I use 'alert(defVal);' in focus evnet.

Javascrip Code:

$(function() {
    $( "#tabs" ).tabs();

    var selectedTab = ''
    $( "#tabs" ).bind( "tabsselect", function(event, ui) {
        //selectedTab = ui.panel.id;
    });
    $( "#goods" ).buttonset();
    $( "#shop" ).buttonset();

    var defaultInputVal = '';
    $('input[type=radio]').bind('click', function(){
            switch (this.id){
                case 'goods-url':
                    defaultInputVal = '输入宝贝网址';
                    break;
                case 'goods-name':
                    defaultInputVal = '输入宝贝名称';
                    break;
                case 'goods-id':
                    defaultInputVal = '输入宝贝编号';
                    break;
                case 'shop-url':
                    defaultInputVal = '输入店铺网址';
                    break;
                case 'shop-nick':
                    defaultInputVal = '输入店铺名称';
                    break;
            }
            $('input.input-search').val(defaultInputVal);  //set default value of input.input-search element
            $('input.input-search').inputWithDefValue(defaultInputVal);  //excute inputWithDefValue method every time after click
        });


    //excute inputWithDefValue method without click buttonset
    $('input#input-goods').inputWithDefValue('输入宝贝网址');
    $('input#input-shop').inputWithDefValue('输入店铺网址');
});

$.fn.extend({
    inputWithDefValue: function(defVal){
        this.bind('focus', function(){
            alert(defVal);   //for debug purpose 
            if ($(this).val() == defVal) {
                $(this).val('').css({
                    'color': 'black'
                });
            }
        });

        this.bind('blur', function(){
            if ($(this).val() == '') {
                $(this).val(defVal).css({
                    'color': '#969696'
                });
            }
        });

    }
});

2 Answers 2

2

I'm afraid your code needs quite heavy refactoring. With your current implementation, on each radio button click you bind newer and newer functions to the blur and focus events - and that is only one of your problems (though the heaviest one).

As you very nicely put your requirements into an ordered list, it's clear that you need to bind to three events: click on the buttons, focus and blur on the input fields. This is a good indication that you'll have to implement the following functions (without the need of using $.fn.extend):

$('input[type=radio]').on('click', function() { ... });
$('input.input-search').on('focus', function() { ... });
$('input.input-search').on('blur', function() { ... });

So a proper approach would be to declare your defaultInputVal one time, as an object instead of a single string, like this:

var defaultInputVal = {
  goods-url  : '输入宝贝网址',
  goods-name : '输入宝贝名称',
  ...
};

Based on the id of any input field, you can easily get the default value for the given field. The above mentioned three function should run along the lines:

$('input[type=radio]').on('click', function() { 
  $('input.input-search').val(defaultInputVal[$(this).attr('id')]);
});

$('input.input-search').on('focus', function() {
  var selected_radio_id = $('input[type=radio]:checked').attr('id');
  if ($(this).val() == defaultInputVal[selected_radio_id]) {
    $(this).val('').css({
      'color': 'black'
    });
  }
}).on('blur', function() {
  var selected_radio_id = $('input[type=radio]:checked').attr('id');
  if ($(this).val() == '') {
    $(this).val(defaultInputVal[selected_radio_id]).css({
      'color': '#969696'
    });
  }
});

Code is untested but should point you in the right direction. There is still a lot of room for improvement, like not littering the global namespace with variables, but this is probably the first step you need to take.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you man. If direction is wrong, efforts are in vain.I'll try your direction.
0

Change your extend method to this one

$.fn.extend({
    setAsDefault: function(defValue, undefined) {
        this.each(function() {
            var valueToUse = (defValue === undefined) ? this.value : defValue;
            this.defaultValue = valueToUse;
            this.value = valueToUse;
        });
    },
    revertToDefault: function(optionalValue) {
        return this.bind('focus', function() {
            if (this.value == this.defaultValue) {
                $(this).val('').css({
                    'color': 'black'
                });
            }
        }).bind('blur', function() {
            if (this.value == '') {
                $(this).val(this.defaultValue).css({
                    'color': '#969696'
                });
            }
        }).setAsDefault(optionalValue);
    }
});

It creates two methods, one that extends the object to react on the blur and focus events, and one to allow you to set the default value.

For the initialization use

$('input.input-search').revertToDefault('输入宝贝网址');

and for your radio buttons use

$('input.input-search').setAsDefault(defaultInputVal);

Full working demo at http://jsfiddle.net/gaby/FETcS/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.