2012-06-07 58 views
5

我一直在試圖創建一個自定義綁定處理器,我可以使用它來給文本輸入字段添加水印行爲。使用自定義綁定處理器的文本輸入水印

通過watermark我的意思是:添加默認值到文本中的焦點刪除字段,以及模糊替換文本字段仍然是空

我設法得到這個工作,因爲在此的jsfiddle證明:http://jsfiddle.net/rpallas/nvxuw/

我對這個解決3個問題:

  1. 有沒有辦法改變它,這樣我只需要聲明一次水印值?目前我必須把它放在聲明綁定的地方,我還必須在viewModel中使用相同的值初始化observable,否則它將沒有初始值。
  2. 有沒有更好的方法來獲取元素值綁定到的基礎觀察值。我目前正在使用allBindingsAccessor來抓取它,但是這對我來說感覺不對。本來我只是使用jquery $(element).val('')設置值,但這也感覺不對。哪個最好,還是有更好的方法?
  3. 有沒有人知道或解決這個問題的現有解決方案?我重新發明了車輪嗎?

回答

14

我認爲你使用allbindings是不必要的。事實上,我認爲水印根本不需要知道可觀測數據,因爲這就是水印通常所做的,即placeholder屬性。

這會適合你嗎?

ko.bindingHandlers.watermark = { 
    init: function (element, valueAccessor, allBindingsAccessor) { 
     var value = valueAccessor(), allBindings = allBindingsAccessor(); 
     var defaultWatermark = ko.utils.unwrapObservable(value); 
     var $element = $(element); 

     setTimeout(function() { 
      $element.val(defaultWatermark);}, 0); 

     $element.focus(
      function() { 
       if ($element.val() === defaultWatermark) { 
        $element.val(""); 
       } 
      }).blur(function() { 
       if ($element.val() === '') { 
        $element.val(defaultWatermark) 
       } 
      }); 
    } 
}; 

http://jsfiddle.net/madcapnmckay/Q5yME/1/

希望這有助於。

+1

啊,這是幾乎正是我之前,我改變它使用allBindingsAccessor。嘗試設置初始值時,我錯過了'setTimeout'。你能否簡要解釋爲什麼這是必需的?另外,你知道有沒有更好的方法?或者你認爲這是一個好的(足夠的)方法(就整個解決方案而言)?例如,我注意到有一個hasfocus綁定(內置)。這可能是一個更好的方法嗎? – Robbie

+2

我認爲這種方法很好,如果你想支持舊瀏覽器。對於新的只使用佔位符屬性。 setTimeout是需要的,因爲內部KO在設置輸入值之前使用setTimeout。這意味着您的代碼在KO代碼設置值之前運行,因此您需要setTimeout來再次確保您的代碼在執行過程中最後出現。 – madcapnmckay

+0

非常感謝您的解答和幫助。 – Robbie

1

只要您的應用程序邏輯非常簡單,請注意解決方案正在混淆您的View Model的值,這些值可以是可觀察的,並且它們可以具有訂閱或計算關聯到它,通過改變你的視圖模型來改變你的值。這是不更新您的視圖模型不同的解決方案

ko.bindingHandlers.fakePlaceHolderWhenNeedIt = { 
    init: function (element, valueAccessor, allBindings, vm) { 
    if (!Modernizr.input.placeholder) { 
     var placeHolderVal = $(element).attr("placeholder"); 

     if (placeHolderVal != null || placeHolderVal != '') { 

      var $element = $(element); 
      var value = valueAccessor() 
      var valueUnwrapped = ko.utils.unwrapObservable(value); 


      $element.keyup(function() { 
       var inputValue = $(this).val(); 
       var $watermark = $(this).prev('.ie-placeholder'); 
       if (inputValue == null || inputValue == '') { 
        $watermark.show(); 
       } 
       else { 
        $watermark.hide(); 
       } 
      }); 

      var display = valueUnwrapped != null || valueUnwrapped != '' ? "block" : "none"; 
      var left = $element.position().left; 
      var top = $element.position().top; 
      var paddingLeft = $element.css('padding-left'); 
      var paddingRight = $element.css('padding-right'); 
      var paddingTop = $element.css('padding-top'); 
      var paddingBottom = $element.css('padding-bottom'); 

      var height = $element.css('height'); 
      var placeHolder = '<div class="ie-placeholder" style="position:absolute;left:' + left + ';top:' + top + ';padding-top: ' + paddingTop + ';padding-bottom: ' + paddingBottom + ';padding-left: ' + paddingLeft + ';padding-right: ' + paddingRight + ';height: ' + height + ';line-height:' + height + ';display:' + display + ';">' + placeHolderVal + '</div>'; 

      $(placeHolder).click(function() { $element.focus(); }).insertBefore(element); 
     } 
    } 
}, 
update: function (element, valueAccessor, allBindings, vm) { 
    if (!Modernizr.input.placeholder) { 
     var placeHolderVal = $(element).attr("placeholder"); 

     if (placeHolderVal != null || placeHolderVal != '') { 
      var $element = $(element); 
      var value = valueAccessor() 
      var valueUnwrapped = ko.utils.unwrapObservable(value); 

      var $watermark = $element.prev('.ie-placeholder'); 
      if (valueUnwrapped == null || valueUnwrapped == '') { 
       $watermark.show(); 
      } 
      else { 
       $watermark.hide(); 
      } 
     } 
    } 
} 
相關問題