Validating a dropdown input which is triggering something else

110 views Asked by At

I have an input, a <select> of <option>s, and depending on which one is selected, I want some more input fields to appear. This is what it looks like in js:

protectionInput: ko.computed({
    read: function () {
        return "";
    },
    write: function (value) {
        if (value == "Primary") {
            viewModel.enhancementVisible(true);
            viewModel.individualVisible(false);
        } else if(value == "IP14" || value == "IP16") {
            viewModel.enhancementVisible(false);
            viewModel.individualVisible(true);
        } else {
            viewModel.enhancementVisible(false);
            viewModel.individualVisible(false);
        }
    },
})

Problem is, I also need this to be a required field so that one of the options is selected. For my other inputs have got this (using ko-validation) which works:

someInput: ko.observable().extend({
    required: true,
}),

But when I add it to the above computed one it always evaluates as invalid even after having selected an option.

Any ideas? Happy to restructure if I've done this in a silly way. Thanks in advance for any help!

PS, this is what the markup looks like:

<div class="form">
    <label>Type of protection</label>
    <select data-bind="value:protectionInput" required>
        <option value="" disabled selected hidden>Please select an option</option>
        <option>Primary</option>
        <option>FP12</option>
        <option>FP14</option>
        <option>FP16</option>
        <option>IP14</option>
        <option>IP16</option>
    </select>
    <label>Enhancement factor</label>
</div>
<div class="form" data-bind="visible: enhancementVisible">
    <input type="number" data-bind="value:enhancementInput" required min="0" max="100" />
</div>
<div class="form" data-bind="visible: individualVisible">
    <label>Individual factor</label>
    <input type="number" data-bind="value:individualInput" required />
</div>
1

There are 1 answers

1
Jason Spake On BEST ANSWER

It's a little unclear how your code is set up, but I think you'd be better off restructuring your computed as an observable and using a subscription instead. That way you can use the validation on the observable, and still update the other properties when the value changes. I've had to make some assumptions about your view model for this example so if your properties aren't on the root of your view model you'll have to replace the "self" references.

self.protectionInput = ko.observable("").extend({ required: true });

self.protectionInput.subscribe(function(value){
  if (value == "Primary") {
      self.enhancementVisible(true);
      self.individualVisible(false);
  } else if(value == "IP14" || value == "IP16") {
      self.enhancementVisible(false);
      self.individualVisible(true);
  } else {
      self.enhancementVisible(false);
      self.individualVisible(false);
  }
});