Search code examples
htmlcssknockout-3.0

How to bind a toggle button using knock out


I have written the below code to see the working of Toggle Button. But it seems the data bind is not working.

Below is the HTML code

  <div>
        <label class="switch">
            <input type="checkbox" id="toggle123" data-bind="click:isToggleTrueOrFalse" />
            <span class="slider round"></span>
        </label>
    </div>

Below is the Style

<style>

         .switch {
            position: relative;
            display: inline-block;
            width: 60px;
            height: 34px;
        }

        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            -webkit-transition: .4s;
            transition: .4s;
        }

            .slider:before {
                position: absolute;
                content: "";
                height: 26px;
                width: 26px;
                left: 4px;
                bottom: 4px;
                background-color: white;
                -webkit-transition: .4s;
                transition: .4s;
            }

        input:checked + .slider {
            background-color: #2196F3;
        }

        input:focus + .slider {
            box-shadow: 0 0 1px #2196F3;
        }

        input:checked + .slider:before {
            -webkit-transform: translateX(26px);
            -ms-transform: translateX(26px);
            transform: translateX(26px);
        }

        /* Rounded sliders */
        .slider.round {
            border-radius: 34px;
        }

            .slider.round:before {
                border-radius: 50%;
            }


    </style>

Below is the script

<script>
    self.isToggleTrueOrFalse = ko.computed(function () {
        if (document.getElementById('toggle123').checked) {
            // return true;
            console.log("true");
        }
        else {
            console.log("false");
        }
    }, self);
</script>

My requirement is when clicking on the toggle button I have to get the true or false in the console. Currently only false is coming in console.

Also I have tried using

<script>
        this.toggleAssociation1=function () {
            var checkBox = document.getElementById("toggle123");
            if (checkBox.checked == true)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    </script>

and

<input type="checkbox" id="toggle123" data-bind="click:toggleAssociation1" />

but it also did not work.

Will click event work for this. Or shall we have to use any other event.

Can some one help me on this.


Solution

  • You're using the wrong bindings for what you're trying to achieve. The click binding is used to call functions that perform some action. Observables and Computed Observables on the other hand are meant to hold values.

    What you need is the checked binding (https://knockoutjs.com/documentation/checked-binding.html). And once you use this you won't need the following bit of code -

    var checkBox = document.getElementById("toggle123");
      if (checkBox.checked == true){
         return true;
      }
      else{
         return false;
      }
    

    Here's the way to use checked binding:

    function viewmodel(){
      var self = this;
      self.isToggleTrueOrFalse = ko.observable();
      
      //to check the value whenever it updates, we can subscribe to the observable like this:
      self.isToggleTrueOrFalse.subscribe(function(latestValue){
        console.log(latestValue);
      });
    }
    
    ko.applyBindings(viewmodel());
    .switch {
    	position: relative;
    	display: inline-block;
    	width: 60px;
    	height: 34px;
    }
    
    .switch input {
    	opacity: 0;
    	width: 0;
    	height: 0;
    }
    
    .slider {
    	position: absolute;
    	cursor: pointer;
    	top: 0;
    	left: 0;
    	right: 0;
    	bottom: 0;
    	background-color: #ccc;
    	-webkit-transition: .4s;
    	transition: .4s;
    }
    
    .slider:before {
    	position: absolute;
    	content: "";
    	height: 26px;
    	width: 26px;
    	left: 4px;
    	bottom: 4px;
    	background-color: white;
    	-webkit-transition: .4s;
    	transition: .4s;
    }
    
    input:checked+.slider {
    	background-color: #2196F3;
    }
    
    input:focus+.slider {
    	box-shadow: 0 0 1px #2196F3;
    }
    
    input:checked+.slider:before {
    	-webkit-transform: translateX(26px);
    	-ms-transform: translateX(26px);
    	transform: translateX(26px);
    }
    
    
    /* Rounded sliders */
    
    .slider.round {
    	border-radius: 34px;
    }
    
    .slider.round:before {
    	border-radius: 50%;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
    <div>
      <label class="switch">
        <input type="checkbox" id="toggle123" data-bind="checked:isToggleTrueOrFalse" />
        <span class="slider round"></span>
      </label>
    </div>