title: Knockout computed and input validation
body: <p>I am fairly new to knockout and am trying to figure out how to put two pieces that I understand together.</p>
  
  <p>I need:</p>
  
  <ol>
  <li>Items that are dependent on each other.</li>
  <li>Input value validation on the items.</li>
  </ol>
  
  <p>Example:</p>
  
  <ul>
  <li>I have <code>startTime</code> in seconds, <code>duration</code> in seconds, and <code>stopTime</code> that is calculated from <code>startTime + duration</code></li>
  <li><code>startTime</code> cannot be changed</li>
  <li><code>duration</code> and <code>stopTime</code> are tied to input fields</li>
  <li><code>stopTime</code> is displayed and entered in <code>HH:MM:SS</code> format</li>
  <li>If the user changes <code>stopTime</code>, <code>duration</code> should be calculated and automatically updated</li>
  <li>If the user changes <code>duration</code>, <code>stopTime</code> should be calculated and automatically updated</li>
  </ul>
  
  <p>I can make them update each other (assume <code>Sec2HMS</code> and <code>HMS2Sec</code> are defined elsewhere, and convert between <code>HH:MM:SS</code> and seconds):</p>
  
  <pre><code>this.startTime = 120; // Start at 120 seconds
  this.duration = ko.observable(0);
  
  // This dependency works by itself.
  this.stopTimeFormatted = ko.computed({
      read: function () {
          return Sec2HMS(this.startTime + parseInt(this.duration()), true);
      },
      write: function (value) {
          var stopTimeSeconds = HMS2Sec(value);
          if (!isNaN(stopTimeSeconds)) {
              this.duration(stopTimeSeconds - this.startTime);
          } else {
              this.duration(0);
          }
      },
      owner: this
  });
  </code></pre>
  
  <p>Or, I can use <code>extenders</code> or <code>fn</code> to validate the input as is shown in the knockout docs:</p>
  
  <pre><code>ko.subscribable.fn.HMSValidate = function (errorMessage) {
      //add some sub-observables to our observable
      var observable = this;
      observable.hasError = ko.observable();
      observable.errorMessage = ko.observable();
  
      function validate(newValue) {
          var isInvalid = isNaN(HMS2Sec(newValue));
          observable.hasError(isInvalid ? true : false);
          observable.errorMessage(isInvalid ? errorMessage : null);
      }
  
      //initial validation
      validate(observable());
  
      //validate whenever the value changes
      observable.subscribe(validate);
  
      //return the original observable
      return observable;
  };
  this.startTime = 120; // Start at 120 seconds
  this.duration = ko.observable(0);
  this.stopTimeHMS = ko.observable("00:00:00").HMSValidate("HH:MM:SS please");
  </code></pre>
  
  <p>But how do I get them working together? If I add the <code>HMSValidate</code> to the computed in the first block it doesn't work because by the time <code>HMSValidate</code>'s <code>validate</code> function gets the value it's already been changed.</p>
  
  <p>I have made it work in the first block by adding another observable that keeps track of the "raw" value passed into the computed and then adding another computed that uses that value to decide if it's an error state or not, but that doesn't feel very elegant.</p>
  
  <p>Is there a better way?</p>
  
  <p><a href="http://jsfiddle.net/cygnl7/njNaS/2/" rel="nofollow">http://jsfiddle.net/cygnl7/njNaS/2/</a></p>