文本输入水印使用自定义bindingHandler

时间:2012-06-07 14:38:11

标签: knockout.js watermark

我一直在尝试创建一个自定义的bindingHandler,我可以使用它来为文本输入字段提供水印行为。

watermark我的意思是:将默认值添加到焦点上删除的文本字段,如果文本字段仍为空,则替换为模糊

我设法让这个工作正如这个jsfiddle所示:http://jsfiddle.net/rpallas/nvxuw/

我对此解决方案有3个问题:

  1. 有没有办法改变它,所以我只需要声明一次水印值?目前我必须将它放在我声明绑定的地方,我还必须初始化可以在viewModel中使用相同的值进行观察 - 否则它将没有初始值。
  2. 有没有更好的方法来获取元素值绑定的基础observable。我目前正在使用allBindingsAccessor抓取它,但这对我来说是错误的。最初我只是使用jquery $(element).val('')来设置值,但这也感觉不对。哪个最好,还是有更好的方法?
  3. 是否有人知道或知道此问题的现有解决方案?我是否正在重新发明轮子?

2 个答案:

答案 0 :(得分: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 :(得分:1)

只要您的应用程序逻辑非常简单,请注意解决方案正在弄乱您的视图模型的值,之前的方法很好,这些值可以是可观察的,并且它们可以具有与之关联的订阅或计算,因此通过更改您更改视图模型的值。这是一个不同的解决方案而不更新您的视图模型

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();
            }
        }
    }
}