Pregunta

I've created a JSFiddle to help demonstrate my question: http://jsfiddle.net/jeffreyrswenson/CrYWn/5/

Here's what I'd like to see:

  • Messages should not appear when page loads.
  • Messages should appear when submit button is pushed.
  • Messages should appear after input value is changed and user leaves element. (Tabs or clicks to next field)
  • Messages should appear after user leave an input without changing.(For example a field is required and the user tabs through the field, but doesn't enter a value. I'd like the validation message to appear when this happens.)

The first four work as I'd expect. Is the last item possible and if so, what do I need to change to enable that behavior?

HTML:

<label>First name:
<input data-bind='value: firstName' />
</label>
<br/>
<label>Last name:
    <input data-bind='value: lastName' />
</label>
<br/>
<button type="button" data-bind='click: submit'>Submit</button>
<br/>
<span data-bind='text: errors().length'></span> errors

ViewModel:

var viewModel = function () {
       ko.validation.configure({
           decorateElement: true,
           registerExtenders: true,
           messagesOnModified: true,
           insertMessages: true,
           parseInputAttributes: true,
           messageTemplate: null
       });

       this.firstName = ko.observable().extend({
           required: true
       });
       this.lastName = ko.observable().extend({
           required: true,
           pattern: {
               message: 'Hey this doesnt match my pattern',
               params: '^[A-Z0-9]+$'
           }
       });

       this.submit = function () {
           if (this.errors().length == 0) {
               alert('Thank you.');
           } else {
               this.errors.showAllMessages();
           }
       };
       this.errors = ko.validation.group(this);
   };
¿Fue útil?

Solución

You just need to use the standard valueUpdate option of the value binding where you can specify additional events to trigger your property change and with that the validation.

So you just need to add the valueUpdate: "blur" setting on your bindings:

<label>First name:
    <input data-bind='value: firstName, valueUpdate: "blur"' />
</label>
<br/>
<label>Last name:
    <input data-bind='value: lastName, valueUpdate: "blur"' />
</label>

Demo JSFiddle.

Otros consejos

In my case, I needed the value to update after key down because I was making some fields visible if the input had a value. I wanted the underlying value to update but didn't want the validation to show until the user tabbed to the next input.

A bit of CSS and a couple of bindings is what worked for me:

CSS:

div.validationWrapper.standard-focus.has-focus .validationMessage 
{
    display: none;
}

HTML:

<div class="validationWrapper standard-focus" data-bind="css: { 'has-focus': MyObservableHasFocus() }">
    <input class="standard-focus" type="text" data-bind="hasFocus: MyObservableHasFocus, value: MyObservable, valueUpdate: 'afterkeydown'" />
</div>

Knockout:

self.MyObservable = ko.observable('').extend({/* Your validation here */});
self.MyObservableHasFocus = ko.observable(false);

The result is an observable that updates it's value after key up and shows the validation message after it loses focus.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top