Example: Tip Calculator

This example walks through building a simple tip calculator app from scratch.

Download the example spreadsheet to follow along or upload directly to NExS.

Live Demo

Try changing the Bill Amount, Tip Percentage, or Number of People to see the calculations update instantly. You can also open the Tip Calculator app in a new window.

What We’re Building

A restaurant tip calculator that:

  • Takes a bill amount and tip percentage as inputs
  • Calculates the tip and total
  • Optionally splits the bill among multiple people

Step 1: Create the Excel Spreadsheet

Open Excel, rename the first worksheet to Calculator, and create this layout:

Calculator

A B
1 Tip Calculator
2
3 Bill Amount $50.00
4 Tip Percentage 18%
5 Number of People 1
6
7 Tip Amount =B3*(B4/100)
8 Total =B3+B7
9 Per Person =B8/B5

The tip percentage in B4 is a whole number (18, not 0.18), so the tip formula divides it by 100. That makes it easy to type, and easy to set from buttons or a custom page.

Formatting

  • A1:B1: Merged
  • B3, B7, B8, B9: Currency, 2 decimals ($#,##0.00)
  • B4: Custom format 0"%", which shows the whole number 18 as 18% in Excel
  • B5: General
  • A1 and the labels in A3:A9: Bold
  • Optional: Add borders and background colors

Step 2: Create the NExS.app Worksheet

Create a new worksheet named NExS.app (the name isn’t case-sensitive):

A B C
1 app Tip Calculator
2 view Calculator!A1:B9
3 editable Calculator!B3, Calculator!B4, Calculator!B5

Step 3: Upload and Test

  1. Save as .xlsx
  2. Upload to platform.nexs.com
  3. Test by changing the bill amount and tip percentage

Step 4: Embed on Your Website

<!-- Replace this UUID with your own app's ID if building from scratch -->
<script class="nexs"
  src="https://static.nexs.com/js/nexs_embed.js"
  data-nexs-app-url="https://platform.nexs.com/app/59c0b001-81fc-4ac5-85ec-30b21f1626c6">
</script>

Custom UI with Declarative API

Use the same workbook to drive your own interface. Every control is bound with the nexs__input class (see the Declarative API Reference):

  • Bill amount: a text input bound to B3. On its own it would show the cell’s raw value (50), so a short nexsappupdated listener shows the formatted value ($50.00) instead.
  • Tip percentage: four radio buttons that share cell B4, with values 15, 18, 20, and 25. The selected button’s value is sent to B4, and the matching button is checked when B4 changes. Because B4 holds a whole number, no script is needed.
  • Split between: a number input bound to B5.

Try It

This custom UI is connected to the Live Demo app at the top of this page, so a change here also shows up in the spreadsheet view above.

Tip Calculator

Tip Percentage
Each Person Pays
Tip:  |  Total:

The Code

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Tip Calculator</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
      max-width: 400px;
      margin: 40px auto;
      padding: 20px;
    }
    h1 {
      color: #333;
      text-align: center;
    }
    .card {
      background: #f8f9fa;
      border-radius: 12px;
      padding: 24px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    }
    .field {
      margin-bottom: 20px;
    }
    .field-label {
      display: block;
      font-weight: 600;
      margin-bottom: 8px;
      color: #555;
    }
    .field input[type="text"],
    .field input[type="number"] {
      width: 100%;
      padding: 12px;
      font-size: 18px;
      border: 2px solid #ddd;
      border-radius: 8px;
      box-sizing: border-box;
    }
    .field input:focus {
      border-color: #4a90d9;
      outline: none;
    }
    .tip-options {
      display: flex;
      gap: 10px;
    }
    /* Radio buttons styled as buttons: the input is hidden, the label is the button */
    .tip-option {
      flex: 1;
      position: relative;
      padding: 12px;
      font-size: 16px;
      text-align: center;
      border: 2px solid #ddd;
      border-radius: 8px;
      background: white;
      cursor: pointer;
    }
    .tip-option:hover {
      border-color: #4a90d9;
    }
    .tip-option input {
      position: absolute;
      opacity: 0;
      pointer-events: none;
    }
    .tip-option:has(input:checked) {
      background: #4a90d9;
      color: white;
      border-color: #4a90d9;
    }
    .tip-option:has(input:focus-visible) {
      outline: 2px solid #333;
      outline-offset: 2px;
    }
    .results {
      background: #4a90d9;
      color: white;
      border-radius: 8px;
      padding: 20px;
      text-align: center;
    }
    .results .label {
      font-size: 14px;
      opacity: 0.9;
    }
    .results .amount {
      font-size: 36px;
      font-weight: bold;
      margin: 5px 0;
    }
    .results .detail {
      font-size: 14px;
      opacity: 0.8;
    }
  </style>
</head>
<body>

<h1>Tip Calculator</h1>

<div class="card">
  <div class="field">
    <label class="field-label" for="bill">Bill Amount</label>
    <input type="text"
           id="bill"
           class="nexs__input"
           data-nexs-cell-addr="B3"
           placeholder="$0.00">
  </div>

  <!-- Radio buttons: all share cell B4, and the selected value is sent -->
  <div class="field">
    <span class="field-label">Tip Percentage</span>
    <div class="tip-options">
      <label class="tip-option">
        <input type="radio" name="tip" class="nexs__input"
               data-nexs-cell-addr="B4" value="15"> 15%
      </label>
      <label class="tip-option">
        <input type="radio" name="tip" class="nexs__input"
               data-nexs-cell-addr="B4" value="18" checked> 18%
      </label>
      <label class="tip-option">
        <input type="radio" name="tip" class="nexs__input"
               data-nexs-cell-addr="B4" value="20"> 20%
      </label>
      <label class="tip-option">
        <input type="radio" name="tip" class="nexs__input"
               data-nexs-cell-addr="B4" value="25"> 25%
      </label>
    </div>
  </div>

  <div class="field">
    <label class="field-label" for="people">Split Between</label>
    <input type="number"
           id="people"
           class="nexs__input"
           data-nexs-cell-addr="B5"
           min="1"
           value="1">
  </div>

  <div class="results">
    <div class="label">Each Person Pays</div>
    <div class="amount">
      <span class="nexs__output_formatted" data-nexs-cell-addr="B9"></span>
    </div>
    <div class="detail">
      Tip: <span class="nexs__output_formatted" data-nexs-cell-addr="B7"></span>
      &nbsp;|&nbsp;
      Total: <span class="nexs__output_formatted" data-nexs-cell-addr="B8"></span>
    </div>
  </div>
</div>

<!-- NExS app (handles calculations) -->
<!-- Replace this UUID with your own app's ID if building from scratch -->
<script class="nexs"
  src="https://static.nexs.com/js/nexs_embed.js"
  data-nexs-app-url="https://platform.nexs.com/app/59c0b001-81fc-4ac5-85ec-30b21f1626c6">
</script>

<script>
  // Text inputs receive the cell's raw value (50). After each update,
  // show the formatted text instead ($50.00), except while the user is typing.
  document.addEventListener('nexsappupdated', () => {
    document.querySelectorAll('input[type="text"].nexs__input').forEach(input => {
      if (input !== document.activeElement) {
        input.value = NEXS.cell(input.dataset.nexsCellAddr).text.trim();
      }
    });
  });
</script>

</body>
</html>

To hide the spreadsheet view and show only your custom controls, wrap the NExS script in <div style="display:none;">. See Hiding the NExS App.

Enhancements

Add Preset Tip Buttons

In Excel, add buttons below the results that set common tip percentages:

A B
10
11 [15%] [18%]
12 [20%] [25%]

Cell A11 content: 15% {setInputs: ['B4', 15]}

Cell B11 content: 18% {setInputs: ['B4', 18]}

And so on for A12 and B12.

NExS.app update: extend the view to row 12 and add the buttons:

A B C
2 view Calculator!A1:B12
3 editable Calculator!B3, Calculator!B4, Calculator!B5
4 buttons A11:B12

Add Rounding Options

Add a checkbox to round the per-person amount up to the nearest dollar:

A B
10 Round up? 0

Formula in B9:

=IF(B10=1, CEILING(B8/B5, 1), B8/B5)

NExS.app:

A B C D
inputs B10 checkbox

Complete NExS.app

With both enhancements (the Round up? checkbox in row 10 and the buttons in rows 11–12):

A B C D
1 app Tip Calculator
2 mode open
3 view Calculator!A1:B12
4 name Calculator
5 backgroundColor white
6 editable Calculator!B3, Calculator!B4, Calculator!B5
7 inputs B10 checkbox
8 buttons A11:B12

What You Learned

  • Creating a basic NExS app from a spreadsheet
  • Configuring editable cells
  • Using the Declarative API for custom styling, including radio buttons that share one cell
  • Adding buttons with setInputs action
  • Using checkbox inputs

Next Steps