0

I'm trying to display a section that depends on whether one of two radio buttons is selected using knockout's virtual elements with an if statement. The observable isn't being set properly to the value and is blank, so the virtual element is ignored and the inside is always displaying.

HTML

<table style="width:100%" class="table table-striped table-condensed">
<input type="radio" name="aSelect" value="value1" data-bind="checked: aType"/> value1
<input type="radio" name="aSelect" value="value2" data-bind="checked: aType"/> value2
</table>

<!-- ko if: aType() == "value1"-->
    <div> THIS SHOULD ONLY SHOW IF VALUE1 RADIO SELECTED</div>
<!-- /ko -->

JAVASCRIPT

function BindingViewModel() {
        var self = this;
        self.aType = ko.observable("value1");
}
$(function () {
    ko.validation.init();
    ko.applyBindings(new BindingViewModel());
});

The elements need to be unloaded from the DOM, so visible and hidden bindings won't do, as they only show/hide elements. Any thoughts?

EDIT: Removing ko.validation.init(); and taking the applyBindings outside of the $(function(){}); applies a slight fix. I am able to use the virtual element once, but if I click on a radio button again, it doesn't update. I am using knockout 3.4.0 and knockout.validation 2.0.3.

EDIT 2: Removing the table tag allowed the virtual element to work if the applyBindings is outside of the $(function(){});

EDIT 3: Applying a solution from here fixed it: Bootstrap CSS table-striped not working with knockout if binding. Essentially, I need a tr and td tag inside the virtual element.

EDIT 4: tbody tag may also fix, depending on your circumstance: Knockout Error: Cannot find closing comment tag to match

zwhu
  • 41
  • 3
  • Day 312: "The diaries of a dev going psycho" continues :D You structure is kind of bad, start by binding against the body element of the html, so that you know where context is applied and then make a showMyDiv observable and bind the if comment syntax against it, and then manage that observable over a simple boolean – MKougiouris Sep 23 '22 at 13:26
  • Also. do you need the "worst way to work without knockout ever" aka comment binding? can't you reform the html a bit to account for the model instead and have a simple div binded on it? Comment parser alone is 4 times slower than normal html template for ko – MKougiouris Sep 23 '22 at 13:28

1 Answers1

0

You have few mistakes, but your approach is good :) I've introduced a new computed function in ViewModel isVisible and use it in data-bind.

function BindingViewModel() {
    let self = this;
    self.aType = ko.observable("value1");
    self.isVisible = ko.pureComputed(function() {
        return self.aType() === "value1";
    });
}
// ko.validation.init(); - this was NOT working for me
let app = new BindingViewModel();
ko.applyBindings(app);

And then use new function to display/hide your DIV. I've removed KO comments binding and add data-bind to DIV, but feel free to change it back.

<div data-bind="visible: isVisible"> THIS SHOULD ONLY SHOW IF VALUE1 RADIO SELECTED</div>

See an example here

Aleksej Vasinov
  • 2,662
  • 28
  • 29