JSFiddle - React, Tailwind, and code Playground

by Ben South

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h4 data-bind="visible: people().length > 0">
  There are <span data-bind="text: people().length"></span> people below:
</h4>

<h4 data-bind="visible: people().length < 1">
  There is nothing to be shown!
</h4>

<p>Display Buttons <input type="checkbox" data-bind="checked: showButtons" /> </p>
<p>Display Add Name Input <input type="checkbox" data-bind="checked: showInput" /> </p>

<div class="people" data-bind="visible: people().length > 0">
  <ul data-bind="foreach: people">
    <li>Name of person <span data-bind="text: $index"></span> is: <span data-bind="text: $data"></span></li>
  </ul>
</div>

<div class="name-input" data-bind='fadeVisible: showInput'>
  <input type="text" data-bind='value: nameToAdd' />
  <button data-bind="click: addPerson">Add Person</button>
</div>


<div class='buttons-container' data-bind='fadeVisible: showButtons'>
  <button data-bind="click: removePerson">Remove Person</button>
  <button data-bind="click: clearArray">Remove everyone</button>
</div>

CSS

.people-header {
  max-width: 300px;
  padding: 2px;
  background-color: #CFCFCF;
  margin-bottom: 10px;
}

.people {
  max-width: 325px;
  padding: 2px;
  background-color: #CBCBCB;
  margin-bottom: 20px;
}

.name-input {
  max-width: 325px;
  margin-bottom: 10px;
}

JavaScript

function AppViewModel() {
  var self = this;
  self.showButtons = ko.observable(false);
  self.showInput = ko.observable(false);
	self.nameToAdd = ko.observable("");

  self.people = ko.observableArray(["Ben","Steve","Connor"]);

  self.addPerson = function() {
  	if(self.nametoAdd != ""){
    	self.people.push(self.nameToAdd());
      self.nameToAdd("");
    }
  };

  self.removePerson = function() {
    self.people.pop();
  };

  self.clearArray = function() {
    self.people.removeAll();
  };
}

ko.bindingHandlers.fadeVisible = {
  init: function(element, valueAccessor) {
    // Initially set the element to be instantly visible/hidden depending on the value
    var value = valueAccessor();
    $(element).toggle(ko.utils.unwrapObservable(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable
  },
  update: function(element, valueAccessor) {
    // Whenever the value subsequently changes, slowly fade the element in or out
    var value = valueAccessor();
    ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut();
  }
};

ko.applyBindings(new AppViewModel());