2012-06-07 1 views
5

텍스트 입력 필드에 워터 마크 동작을 부여하는 데 사용할 수있는 사용자 정의 bindingHandler를 만들려고했습니다. watermark으로사용자 정의 bindingHandler를 사용하는 텍스트 입력 워터 마크

말 : 텍스트 필드에이 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 바인딩 (built-in)이 있음을 알 수 있습니다. 그게 더 좋은 방법일까요? – Robbie

+2

이전 브라우저를 지원하려면이 방법이 좋다고 생각합니다. 새로운 것들을 위해서 단지 자리 표시 자 속성을 사용하십시오. 내부적으로 KO는 입력 값을 설정하기 전에 setTimeout을 사용하기 때문에 setTimeout이 필요합니다. 이것은 KO 코드가 값을 설정하기 전에 코드가 실행 중이 었음을 의미하므로 setTimeout을 다시 사용하여 코드가 실행 마지막에 오도록해야합니다. – madcapnmckay

+0

설명과 도움에 감사드립니다. – Robbie

1

앱 논리가 매우 단순한 한 이전 접근법은 괜찮습니다. 솔루션이 View Model의 값을 망치고 있다는 것을 알아 두십시오.이 값은 관찰 가능하고 구독 또는 계산에 연결할 수 있으므로 값을 변경하여 View Model을 변경하십시오. 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(); 
      } 
     } 
    } 
}