Calculating the total of selected values in Checkboxes and Selectors using KnockoutJS

I have already created this using jQuery. You can view it on JSFiddle: JSFiddle

HTML:

<div class="container">
    <header>
         <h3>The Crazy Things We'll Do for Money</h3>
        <div class="small"><em>An elegant way to test Knockout JS that you're considering.</em>
        </div>
    </header>
    <ul>
        <li>
            <input type="checkbox" name="services" value="150" id="srv" />
            <span>Throw knives at us while we're strapped on a turntable ($150)</span>
        </li>
        <li>
            <input type="checkbox" name="services" value="200" id="srv" />
            <span>Watch us get chased by bulls ($200)</span>
        </li>
        <li>
            <input type="checkbox" name="services" value="799.50" id="srv" />
            <span>Watch us in a straight jacket immersed in a pool of electric eels and try to escape Houdini style. ($799.50)</span>
        </li>
    </ul>
    <hr/>
    <div class="marginise">
    <strong>I want to help with your hospital bills</strong>
        <select id="donate" name="donate">
            <option value="0">No Thanks</option>
            <option value="100">$100</option>
            <option value="300">$300</option>
            <option value="500">$500</option>
        </select>
        <p><strong>Donations</strong>: <span id="blah"></span>
        </p>
    </div>
    <div class="est">
         <h4>Total</h4>
         <span id="serviceTotal"></span>
    </div>
    <div class="f">These Events / Entertainment Services are not real. Unfortunately.</div>
</div>

jQuery:


function outputValue() {
    mathUsage();
    var donValues = $("#donate").val(); 
    $("#blah").html(numeral(donValues).format('$0,0[.]00'));
}
var $cap = $('input[name="services']; 

function mathUsage() {
    var total = $("#donate").val(); 
    $cap.each(function () {
        if (this.checked) total = parseFloat(total) + parseFloat(this.value);
    });
    $("#serviceTotal").text(numeral(total).format('$0,0[.]00'));
}

$("select").change(outputValue);
outputValue();

$cap.click(mathUsage);

I am looking to recreate this using knockoutJS so I can reduce the amount of HTML markup. Any suggestions on the best approach?

There are similar examples out there like this one on Fiddle that show how to output checkbox values in an array. I was thinking of utilizing a similar method to calculate a sum but unsure of where to begin or which syntax to use.

Answer №1

To start, it's important to assign each checkbox its own unique id and name:

<ul>
        <li>
            <input type="checkbox" name="knives" value="150" id="knives" data-bind="checked: knives" />
            <span>Throw knives at us while we're strapped on a turn table ($150)</span>

        </li>
        <li>
            <input type="checkbox" name="bulls" value="200" id="bulls" data-bind="checked: bulls"  />
            <span>Watch us get chased by Bulls ($200)</span>

        </li>
        <li>
            <input type="checkbox" name="eels" value="799.50" id="eels" data-bind="checked: eels" />
            <span>Watch us in a straight jacket immersed in a pool of electric Eels and try to get out of it Houdini style. ($799.50)</span>

        </li>
    </ul>

Next, create the view model with the following structure:

var viewModel = function() {
    var self = this;
    self.knives = ko.observable(false);
    self.bulls = ko.observable(false);
    self.eels= ko.observable(false);

    self.total = ko.computed(function() {
      var totalCost = 0;
      if (self.knives())
        totalCost += 150;
      if (self.bulls())
        totalCost += 200;
      if (self.eels())
        totalCost += 799.50;    
      return totalCost; 
    });
};

ko.applyBindings(new viewModel()); 

This sets up the basic structure for your view model. You can expand on it by adding more properties for other services or organizing the values differently. The customization is up to you.

Answer №2

To achieve the desired result, you can use the following code:

var DataModel = function(name, age) {
    this.name = ko.observable(name);
    this.age = ko.observable(age);
 
    this.total = ko.computed(function() {
        
        return parseFloat(this.name())  + parseFloat(this.age());
    }, this);
};
 
ko.applyBindings(new DataModel("John", "25")); 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-3.2.0.js"></script>
<div class='liveExample'>   
    <p>Name: <input data-bind='value: name' /></p> 
    <p>Age: <input data-bind='value: age' /></p> 
    <h2> <span data-bind='text: total'> </span></h2>  
</div>

For a live example, view this Fiddle.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The links located beneath the iframe/span element are unclickable

My latest creation is a static advert ticker positioned at the bottom of the window. It's contained within an <iframe> for easy placement on other websites. I added a <span> around the <iframe> to keep it fixed at the bottom of the s ...

Using AngularJS to dynamically populate a dropdown menu from a JSON object

I am a beginner to Angular and currently facing my first significant challenge. The JSON object below is the address data retrieved from a third-party API and added to $scope.AddressData in a controller: $scope.AddressData = [{ "Address1":"South Row", ...

Setting the height of a div tag in CSS/HTML5 to match the current height of the browser window

Is there a way to make the height of my div tag always equal to the height of the browser's window, so it adjusts automatically when the browser is resized? I have tried using .class { height: 100%; } But this doesn't work. I've learne ...

Tips on refreshing the D3 SVG element following updates to the dataset state in a React application

Hey everyone, I'm currently experimenting with D3.js and React in an attempt to build a dynamic dancing bargraph. Can anyone provide guidance on how to reload the D3 svg after updating the dataset state within REACT? Feel free to check out my codepen ...

What is the best way to delay Angular for 5 seconds before initiating a page transition?

Just a quick inquiry - is there a way to have Angular wait for 5 seconds before redirecting to a different page? I attempted to implement this functionality within my function, but it doesn't appear to be functioning as expected: setTimeout(() => ...

Activate a particular panel within the leftPanel using PDFNet Webviewer

When using disableElements in the setQuickBarPanelContents() function, I am able to remove 2 of the 3 panels from the leftPanel: setQuickBarPanelContents() { this.instance.disableElements(['notesPanel', 'notesPanelButton', &apos ...

Click event to verify, delete, and include class identifier in angular13

Looking to enhance functionality by dynamically adding and removing the 'active' class to 'li a' elements on click. While the current code performs well when clicking from top to bottom, it fails to work in reverse order. component.htm ...

Utilizing Freebase Suggest, is there a way to refine a field by the choice of another field?

When utilizing Freebase Suggest (), and having a field that chooses between Country or State, how can I make another "City" field filter to only display cities within that selected Country or State? In addition, if a user selects "New York" as their State ...

Trigger a page refresh in jQuery upon database update

On my webpage, I display data that is inserted into a MySQL database. I am interested in having the view page automatically update whenever a new record is added to the database. It's worth noting that the data may be inserted from a different user an ...

performing a GET request directly from a <script> element in the index.html file

I am currently developing an application that utilizes Angular.js on the client side and Node Express on the server side. On my server side, I am using a staticAsset module. Within my index.html file, I have a lengthy list of JavaScript files that need t ...

Why does the data in useState only update after clicking the button for the second time?

When utilizing useState to set a value, I noticed that it only updates upon clicking the button for the second time. Why does this occur? const DropDownMenu = ({ element, segmentEnd, segmentStart }) => { const [open, setOpen] = React.useState(false); ...

The outcome of AES encryption varies when comparing Node JS with C# programming languages

In a particular scenario, I need to encrypt and transmit text using the AES 256 algorithm. The decryption process will be handled by client-side C# code. Here is the encryption code in JavaScript: const crypto = require('crypto'); algorithm = ...

What steps do I need to take in Bootstrap 5 to add a search icon to the navbar that reveals a search box beneath it when clicked?

I've made progress on the navbar design Now, I'm looking to add a search icon next to the login button. Clicking on the search icon should reveal a search box below the navbar, similar to the image shown below. My transparent navbar has a relati ...

Ways to verify if a web URL is contained within an HTML textbox

In the process of developing a frontend form for WordPress, I have incorporated a basic HTML textbox for users to input a web URL. My goal now is to ensure that the entered value is indeed a valid URL and not just arbitrary text. Is there a way to perfor ...

Using jQuery to attach events and trigger them

Within my code, I have the following scenarios: $("#searchbar").trigger("onOptionsApplied"); And in another part of the code: $("#searchbar").bind("onOptionsApplied", function () { alert("fdafds"); }); Despite executing the bind() before the trigge ...

Unable to use the ordered tag correctly in typing

Please review the HTML and CSS Code provided below: HTML : <ol> <li>Test</li> <li> <ol> <li>Sub-Chapter</li> <li>Sub-Chapter</li> </ol> < ...

Unequal spacing between the edges of two background images

I am attempting to create two distinct "layers" of background on my webpage by encapsulating the content within a div element. Strangely, the background set for the div is being clipped before it reaches the edge of the screen, while the one designated as ...

Mastering the utilization of componentDidMount and componentDidUpdate within React.js: a comprehensive guide

I am facing an issue. I need to find an index based on a URL. All the relevant information is passed to the components correctly, but I encounter an error after loading: Cannot read property 'indexOf' of undefined The JSON data is being transmi ...

Event handlers for textboxes in Visual Web Developer are a crucial component for

Having some difficulty with textboxes - ideally, I would like my second textbox to clear whenever the text in my first textbox changes. Currently, it only clears on postback but is there a way to achieve this without needing a postback for each character ...

Mysterious symbols appearing in text/html encoding on Firefox

When I retrieve a text/html content from a ".txt" file using jquery.ajax(), everything works fine in other browsers except for Firefox. In Firefox, I see strange characters like ... This is my code: $.ajax({ url: "menuProcesso.txt", ...