Pergunta

Almost there, just need the popover to appear only after submit button is clicked and the field has an alert class added to it.

Note: Hover only works for isValid is true in the binding handler, otherwise testing for not true requires a click rather than a hover :S

http://jsfiddle.net/hotdiggity/UUb4M/

HTML:

<input data-bind="value: lastName, popover: isValidField" data-placement="below" data-title="Alert" data-content="We have identified this information is incorrect and must be updated."/>

JS:

self.lastName = ko.observable().extend({ required: true });
self.isValidField = ko.observable();
this.submit = function () {
    if (self.errors().length === 0) {
        alert('Thank you.');
    } else {
        self.errors.showAllMessages();
        self.isValidField(self.lastName.isValid());
    }
};

Binding:

ko.bindingHandlers.popover = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor(),
            valueUnwrap = ko.unwrap(value),
            allBindings = allBindingsAccessor(),
            isValid = allBindings.value;
        if (isValid) {
            $(element).popover({
                trigger: "hover"
            });
        } else {
            $(element).popover("hide");
        }
    },
    Update: //See jsfiddle link above (the same code)
Foi útil?

Solução

Here is a working version for you. The popover will appear only if the validation for the lastName field is not met and only when the submit button is clicked. It will go away if the user types something into the lastName field. See this updated fiddle

The update function of a binding handler creates dependencies on observables that it accesses, so essentially the update of a binding handler will be triggered when that observable is changed. In your case, I did it with the isValidField observable. See notes in the code

var viewModel = function () {
    var self = this;
    self.lastName = ko.observable().extend({ required: true });
    self.isValidField = ko.observable();

    // once the popover is shown, we want it to go away if the user types something
    // into the lastName field. We do this by triggering the popover binding handler
    // by changing the value of isValidField
    self.lastName.subscribe(function(val){          
        if(val && val.length > 0){ self.isValidField(true); }
    });

    // need to create your errors object
    self.errors = ko.validation.group(self);

    this.submit = function () {
        if (self.errors().length === 0) {
            alert('Thank you.');
        } else {
            self.errors.showAllMessages();

            // change the value of isValidField to trigger the popover binding handler's
            // update
            self.isValidField(self.lastName.isValid());
        }            
    };      
};

ko.bindingHandlers.popover = {

    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor(),
            valueUnwrap = ko.unwrap(value);

        if (valueUnwrap === false) {
            $(element).popover('show');
        } else {
            $(element).popover("destroy");
        }
    }
};
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top