text input watermark using custom bindingHandler

knockout.js, watermark

Solution

I think you're use of allbindings is unecessary. In fact I don't think the watermark needs to be aware of the observable at all since that's what a watermark generally does i.e the `placeholder` attribute.

Would this work for you?

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/

Hope this helps.

Problem

I've been trying to create a custom bindingHandler that i can use to give a watermark behaviour to text input fields. By `watermark` i mean: to add default values to text fields that are removed on focus, and replaced on blur if the text field is still empty I have managed to get this to work as demonstrated in this jsfiddle: http://jsfiddle.net/rpallas/nvxuw/ I have 3 questions about this solution: - Is there any way to change it so that I only have to declare the watermark value once? Currently I have to put it on the place where I declare the binding and I also have to initialise the observable with the same value in the viewModel - as it will otherwise have no initial value. - Is there a better way of getting to the underlying observable that the elements value is bound to. I'm currently grabbing it using the allBindingsAccessor, but this feels wrong to me. Originally I was just setting the value using jquery `$(element).val('')` but this also felt wrong. Which is best, or is there a better way? - Does any one have or know of an existing solution to this this problem? Am I re-inventing the wheel?

Original source