JQueryでプレースホルダつき入力欄その2

先日、JavaScriptでプレースホルダつき入力欄を作る(JQuery実装)というのを作ったのですが、不具合が見つかったので修正しました。


JQueryでプレースホルダつき入力欄


修正する時に色々と新しいことを覚えたり物思いにふけったりしたのでメモしておきます。

未入力のままsubmitするとおかしくなる

昨日作ったものはテキストボックスからフォーカスが外れたときにvalue属性に値をセットしていたので、submitした時に表示されている文字列がそのまんま送信されてしまいます。これはいけません。
色々と考えたのですが、親要素のformタグを探してonsubmitイベントでテキストボックスのvalueをクリアするという方法しか思いつきませんでした。
でもこれだと直接submitするときはいいけど他のJavaScriptからvalueを参照されたときにはまた同じことが起こるんだよなー。クライアント側での入力チェックとかに支障をきたすなー。うーんうーん。
良い解決策があったら誰か教えてください><

HTML5ではplaceholderという属性が追加されるらしい。

http://b.hatena.ne.jp/vantguarde/20090308#bookmark-12431708

それplaceholder属性でできるよ

↑のブコメを見て知ったのですが、HTML5ではテキストボックスにplaceholder属性というのが追加されてるみたいです。

<input type="text" placeholder="何か入力してね"/>

みたいに書いておくとプレースホルダつきのテキストボックスができあがるみたいです。実際に色んなブラウザでやってみたら、Goole ChromeSafariではもう実装されてるみたいでした。「textareaでもできるのかしらん」と思ったのですがダメでした。

placeholder属性があったら勝手に適用してしまおう

http://b.hatena.ne.jp/twk/20090309#bookmark-12431708

誰かplaceholder属性のある要素を自動的に変換してくれるJavaScriptを書くんだ!

というのを見て「おお、これはいい考えだ」と思ったので書いてみました。

ソースコード

(function($){
  $.fn.placeholder = function(opts){
    
    if(typeof opts == 'string') {
      opts = {word:opts};
    }
    opts = $.extend({
      word: '',
      styleClass: 'placeholder'
    },opts);
    
    return this.each( function() {
      $(this).blur(
        function(){
          if(changed(this)) return;
          $(this).addClass(opts.styleClass).val(opts.word);
        }
      ).focus(
        function(){
          if(changed(this)) return;
          $(this).removeClass(opts.styleClass).val('');
        }
      ).blur();
      
      $(this).parents('form').bind('submit', $(this), function(event){
        event.data.triggerHandler('focus');
      });
      
    });
    
    function changed(elem) {
      if($(elem).val() == ''){
        return false;
      }else if($(elem).val() == opts.word && $(elem).hasClass(opts.styleClass)){
        return false;
      }
      return true;
    }
  };
  
  $(function(){
    $(':text[placeholder]').each(function(){
      $(this).placeholder({
        word: $(this).attr('placeholder'),
        styleClass: 'placeholder'
      });
    });
  });
})(jQuery);