JackTheKnife
JackTheKnife

Reputation: 4144

Knockout: Change CSS visibility based on observable value

I'm trying to set CSS class with display: none attribute for Knockout observable which has no value assigned.

HTML code:

    <div class="userParent actionHandle dragHandle">
        <span class="userName" data-bind="text: userName"></span><span class="userDOB" data-bind="text: userDOB"></span><span class="userGender" data-bind="text: userGender"></span>
    </div>  

and Knockout constructor:

    this.userName = ko.observable('');
    this.userDOB = ko.observable('');
    this.userGender = ko.observable('');    

then I clear values

    this.userName('');
    this.userDOB('');
    this.userGender('');

at that point I want to append CSS which will set/add display: none to all user* classes.

I have followed solutions from those two questions

but without luck.

My code for CSS changes looks like

self.CssBind = function (k) {

var CssBind = '';

if (self.userName() === '') {
     CssBind = 'none';
}
if (self.userDOB() === '') {
     CssBind = 'none';
}
if (self.userGender() === '') {
     CssBind = 'none';}

 return CssBind;
});

and changed HTML

 <div class="userParent actionHandle dragHandle">
        <span class="userName" data-bind="text: userName, style: {display $root.CssBind}"></span><span class="userDOB" data-bind="text: userDOB, style: {display $root.CssBind}"></span><span class="userGender" data-bind="text: userGender, style: {display $root.CssBind}"></span>
    </div>  

I think there must be something easy what I have missed.

Upvotes: 0

Views: 946

Answers (1)

Tomalak
Tomalak

Reputation: 338118

Use a computed property instead of a function (also use more a relatable property name – "CssBind" means absolutely nothing)

self.everythingIsFilledIn = ko.pureComputed(function () {
    return self.userName() > '' && self.userDOB() > '' && self.userGender() > '';

    // or, for short
    // return self.userName() && self.userDOB() && self.userGender();
});

and in the view:

<div class="userParent actionHandle dragHandle" data-bind="visible: everythingIsFilledIn">
    <span class="userName" data-bind="text: userName"></span>
    <span class="userDOB" data-bind="text: userDOB"></span>
    <span class="userGender" data-bind="text: userGender"></span>
</div> 

Use the visible binding if you want to show or hide elements based on some truth value. There is no need to fiddle with the CSS binding for such a simple task.

Upvotes: 1

Related Questions