Validation message not appearing

120 views Asked by At

On adding ko validation extender to dynamic objects it is not displaying the error message when showAllMessages() is called. There is also no span tag added below the respective controls which will show the error message.

I also like to show the error message just below the control as soon as the object is added to observable array.

Please find the fiddle
http://plnkr.co/edit/PUgxqrarDeaabDxUwgLO?p=preview

JavaScript

var schedule = function() {


var self = this;
  self.name = ko.observable();
  self.startDate = ko.observable();
  self.endDate = ko.observable();

  // Add validation
  self.name.extend({required: {message: 'Name Required'}});
  self.startDate.extend({required: {message: 'Start Date Required'}});
  self.endDate.extend({required: {message: 'End Date Required'}});
}

var viewmodel = {
  model: {
    lookups: {
      grandSlams: ["Australian Open", "French Open", "Wimbledon", "US Open"]
    },
    schedules: ko.observableArray(),
    status: ko.observable()
  },
  actions: {
    addSchedule: function() {
      console.log('Add Called');
      viewmodel.model.schedules.push(new schedule());
      viewmodel.model.status('Edited');
      console.log(viewmodel.model.schedules().length);
    },
    saveSchedule: function(){
      console.log('Save Called');
      var errors = ko.validation.group(viewmodel.model.schedules, { deep: true });
      if (errors().length > 0) {
          console.log(errors());
          errors.showAllMessages();
          hasError = true;
      }
      viewmodel.model.status('Saved!!!');
    }
  }
};

$(function() {
  ko.validation.init({
            insertMessages: true,
            messagesOnModified: true,
            grouping: {
                deep: true,        //by default grouping is shallow
                observable: true    //and using observables
            }
        });
  ko.applyBindings(viewmodel);
});

HTML

<!DOCTYPE html>
<html>

  <head>
    <script data-require="jquery@*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script data-require="[email protected]" data-semver="2.2.1" src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
    <script data-require="knockout-validation@*" data-semver="1.0.2" src="//cdnjs.cloudflare.com/ajax/libs/knockout-validation/1.0.2/knockout.validation.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <h1>Knockout Validation!</h1>
    <button data-bind="click: actions.addSchedule">Add Schedule</button>
    <button data-bind="click: actions.saveSchedule">Save Schedule</button>
    <h3>Schedules</h3>
    <table>
      <thead>
        <tr>
          <th>Grand Slams</th>
          <th>Start</th>
          <th>End</th>
        </tr>
      </thead>
      <tbody data-bind="foreach:model.schedules">
        <tr>
          <td style="width:250px">
            <select data-bind="options: $root.model.lookups.grandSlams, optionsCaption:'Select...'"></select>
          </td>
          <td style="width:250px">
            <input type="text" data-bind="value: startDate" />
          </td>
          <td style="width:250px">
            <input type="text" data-bind="value: endDate" />
          </td>
        </tr>
      </tbody>
    </table>
    <h3 data-bind="text: model.status"></h3>
  </body>

</html>
1

There are 1 answers

0
tcigrand On BEST ANSWER

Updated example

You're missing the value binding on the select element. It should be

<select data-bind="value: name, options: $root.model.lookups.grandSlams, optionsCaption:'Select...'"></select>

Updated viewmodel if you want to validate on addSchedule (you can probably remove this.actions.showErrors() from save now, I left it just in case)

var viewmodel = {
  model: {
    lookups: {
      grandSlams: ["Australian Open", "French Open", "Wimbledon", "US Open"]
    },
    schedules: ko.observableArray(),
    status: ko.observable()
  },
  actions: {
    addSchedule: function() {
      console.log('Add Called');
      viewmodel.model.schedules.push(new schedule());
      viewmodel.model.status('Edited');
      this.actions.showErrors();
      console.log(viewmodel.model.schedules().length);
    },
    showErrors: function() {
      var errors = ko.validation.group(viewmodel.model.schedules, { deep: true });
      if (errors().length > 0) {
          console.log(errors());
          errors.showAllMessages();
          hasError = true;
      }
    },
    saveSchedule: function(){
      console.log('Save Called');
      var errors = ko.validation.group(viewmodel.model.schedules, { deep: true });
      this.actions.showErrors();
      viewmodel.model.status('Saved!!!');
    }
  }
};