Events Reference

NExS apps fire events that you can listen for in JavaScript. Use events to react to app initialization, data updates, view changes, and button clicks.

Listening for Events

Add event listeners to the document:

document.addEventListener("nexsappinit", function(e) {
  // Handle event
  console.log("App initialized:", e.detail.appIndex);
});

Event Detail Object

All events include an event.detail object with event-specific properties. Every event includes:

PropertyTypeDescription
appIndexnumberIndex of the app that fired the event

Available Events

nexsappinit

Fires when an app completes initialization and the API becomes available.

When to use: Initialize your UI, read initial values, set up other event listeners.

Detail properties:

PropertyTypeDescription
appIndexnumberIndex of the initialized app

Example:

document.addEventListener("nexsappinit", function(e) {
  console.log("App", e.detail.appIndex, "is ready");

  // Safe to use API now
  const initialValue = NEXS.app(e.detail.appIndex).view(0).cell("B5").data;
  document.getElementById("display").textContent = initialValue;
});

Important: The API methods (NEXS.app(), .cell(), .setInputs(), etc.) are not available until this event fires.

nexsappupdated

Fires whenever cell values change due to recalculation.

When to use: Update your UI when calculated values change.

Detail properties:

PropertyTypeDescription
appIndexnumberIndex of the updated app

Example:

document.addEventListener("nexsappupdated", function(e) {
  // Read updated values
  const total = NEXS.app(e.detail.appIndex).view(0).cell("B10").text;
  document.getElementById("total").textContent = total;

  // Conditional logic based on results
  const value = NEXS.app(e.detail.appIndex).view(0).cell("B10").data;
  if (value > 1000) {
    document.getElementById("warning").style.display = "block";
  } else {
    document.getElementById("warning").style.display = "none";
  }
});

nexsviewchanged

Fires when the displayed view changes.

When to use: Update navigation indicators, track user progress, show/hide related content.

Detail properties:

PropertyTypeDescription
appIndexnumberIndex of the app

Example:

document.addEventListener("nexsviewchanged", function(e) {
  const currentView = NEXS.app(e.detail.appIndex).setView();
  console.log("Now showing view:", currentView);

  // Update navigation
  document.querySelectorAll(".nav-item").forEach(function(item, index) {
    item.classList.toggle("active", index === currentView);
  });
});

nexsbuttonclick

Fires when a button is clicked in the NExS app.

When to use: Execute custom JavaScript in response to button clicks, integrate with external systems, add custom behavior beyond built-in actions.

Detail properties:

PropertyTypeDescription
appIndexnumberIndex of the app
viewstringName of the view containing the button
cellstringCell address of the button (e.g., “A10”)
textstringDisplay text of the button
datatypestring”string”, “numeric”, or “error”
dataanyRaw value of the button’s cell
extraanyCustom data from button’s extra property (default: null)

Example:

document.addEventListener("nexsbuttonclick", function(e) {
  console.log("Button clicked:");
  console.log("  View:", e.detail.view);
  console.log("  Cell:", e.detail.cell);
  console.log("  Text:", e.detail.text);
  console.log("  Extra:", e.detail.extra);

  // Handle specific buttons
  if (e.detail.cell === "A10") {
    // Custom action for button in A10
    submitToExternalAPI();
  }

  if (e.detail.extra === "download") {
    // Handle buttons with extra: 'download'
    generatePDF();
  }
});

Using the extra Property

Pass custom data to your event handler using the button’s extra property:

Cell content: Download {extra: 'pdf'}

JavaScript:

document.addEventListener("nexsbuttonclick", function(e) {
  if (e.detail.extra === "pdf") {
    downloadAsPDF();
  } else if (e.detail.extra === "csv") {
    downloadAsCSV();
  }
});

Complete Example

<!DOCTYPE html>
<html>
<head>
  <title>Event Handling Example</title>
  <style>
    .status { padding: 10px; margin: 10px 0; border-radius: 4px; }
    .loading { background: #fff3cd; }
    .ready { background: #d4edda; }
    .updated { background: #cce5ff; }
  </style>
</head>
<body>

<h1>Calculator with Events</h1>

<div id="status" class="status loading">Loading app...</div>

<div id="app-container">
  <p>Enter values in the calculator below:</p>
  <script class="nexs"
    src="https://static.nexs.com/js/nexs_embed.js"
    data-nexs-app-url="https://platform.nexs.com/app/YOUR-APP-ID">
  </script>
</div>

<div id="results" style="display:none;">
  <h3>Results</h3>
  <p>Total: <span id="total"></span></p>
  <p>Last updated: <span id="timestamp"></span></p>
</div>

<script>
  // Track initialization
  document.addEventListener("nexsappinit", function(e) {
    console.log("App initialized");

    // Update status
    const status = document.getElementById("status");
    status.textContent = "App ready!";
    status.className = "status ready";

    // Show results section
    document.getElementById("results").style.display = "block";

    // Display initial values
    updateResults();
  });

  // Track updates
  document.addEventListener("nexsappupdated", function(e) {
    console.log("App updated");

    // Update status briefly
    const status = document.getElementById("status");
    status.textContent = "Calculating...";
    status.className = "status updated";

    setTimeout(function() {
      status.textContent = "App ready!";
      status.className = "status ready";
    }, 500);

    // Update displayed results
    updateResults();
  });

  // Track view changes
  document.addEventListener("nexsviewchanged", function(e) {
    const viewIndex = NEXS.app(e.detail.appIndex).setView();
    console.log("View changed to:", viewIndex);
  });

  // Handle button clicks
  document.addEventListener("nexsbuttonclick", function(e) {
    console.log("Button clicked:", e.detail.text);

    if (e.detail.cell === "A15") {
      // Custom handler for specific button
      alert("You clicked the special button!");
    }
  });

  function updateResults() {
    const total = NEXS.cell("B10").text;
    document.getElementById("total").textContent = total;
    document.getElementById("timestamp").textContent = new Date().toLocaleTimeString();
  }
</script>

</body>
</html>

Event Order

When a NExS app loads and the user interacts with it, events fire in this order:

  1. nexsappinit — App is ready (fires once)
  2. nexsappupdated — Initial values loaded
  3. (User changes an input)
  4. nexsappupdated — Recalculation complete
  5. (User clicks a button)
  6. nexsbuttonclick — Button click registered
  7. nexsappupdated — If button action changed values
  8. nexsviewchanged — If button action changed view

Tips

Multiple Apps

When handling multiple embedded apps, check e.detail.appIndex:

document.addEventListener("nexsappupdated", function(e) {
  if (e.detail.appIndex === 0) {
    // Handle first app
  } else if (e.detail.appIndex === 1) {
    // Handle second app
  }
});

Debouncing Updates

If you’re doing expensive operations on update, consider debouncing:

let updateTimeout;
document.addEventListener("nexsappupdated", function(e) {
  clearTimeout(updateTimeout);
  updateTimeout = setTimeout(function() {
    // Expensive operation here
    updateChart();
  }, 100);
});