Let us know when the information on a different tab is updated

I have multiple tabs and I want to indicate when a change occurs on another tab that the user hasn't clicked. For example, if the user hits the run button while on the Data pane, I would like the Errors tab to change to red to show that there was a change on that tab as well. How can I achieve this? Conversely, if they're on the error tab, the Data tab should turn red. Also, once the tab is clicked, I want to remove the red color. Any assistance would be appreciated!

Desired Output

https://i.sstatic.net/BozhN.png

runCode = () => {
   document.getElementById("dataOutput").innerHTML = "Paragraph changed!";
   document.getElementById("errorOutput").innerHTML = "Error Occurred";
 }
.fab {
  width: 60px;
  height: 60px;
  background-color: #A7C0CD;
  border-radius: 50%;
  box-shadow: 0px 3px 15px rgba(0,0,0,0.2);
  transition: all 0.1s ease-in-out;
  font-size: 15px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  color: white;
  text-align: center;
  line-height: 58px;
  float: right;
  margin: 8px;
  z-index: 5000;
  position: absolute;
  right:0;
  top:0;
}

.fab:hover {
  box-shadow: 0px 3px 15px rgba(0,0,0,0.2);
  transform: scale(1.05);
}
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  </head>
    <!-- Visual appearance -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap/dist/js/bootstrap.min.js"></script>
  <body>

<div class="fab" id="runCode" onclick="runCode();">RUN</div>
        <ul class="nav nav-tabs">
          <li class="active"><a data-toggle="tab" href="#data">Data</a></li>
          <li><a data-toggle="tab" href="#error">Errors</a></li>
        </ul>

        <div class="tab-content">
          <div id="data" class="tab-pane fade in active">
            <div id="dataOutput"></div>
          </div>
          <div id="error" class="tab-pane fade">
            <div id="errorOutput"></div>
          </div>
        </div>

  </body>
</html>

Answer №1

Utilizing MutationObservers, I believe I have successfully achieved your desired outcome. Although it may require some restructuring, the essence should be clear:

// To reuse our tabs, we store a reference to them
const data = document.getElementById("dataOutput");
const error = document.getElementById("errorOutput");
const runCode = () => {
  data.textContent = "Paragraph changed!";
  error.textContent = "Error Occured";
};

// Remove the 'changed' class from clicked tabs
const tabs = document.querySelector('.nav-tabs');
tabs.onclick = ({ target }) => target.classList.remove('changed');

// Watch for mutations in our output elements
new MutationObserver(observe).observe(data, { childList: true });
new MutationObserver(observe).observe(error, { childList: true })

function observe(mutations) {
  const target = mutations[0].target;
  // Extract the name of the changed tab by removing 'Output' from the target's id
  const tabName = target.id.slice(0, target.id.indexOf('O'));
  const tab = document.querySelector(`a[href="#${tabName}"]`);
 
  // Add the 'changed' class to the corresponding tab if it's not currently active
  if (!target.parentNode.classList.contains('active')) {
    tab.classList.add('changed');
  }
}
 
.fab {
  width: 60px;
  height: 60px;
  background-color: #A7C0CD;
  border-radius: 50%;
  box-shadow: 0px 3px 15px rgba(0,0,0,0.2);
  transition: all 0.1s ease-in-out;
  font-size: 15px;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  color: white;
  text-align: center;
  line-height: 58px;
  float: right;
  margin: 8px;
  z-index: 5000;
  position: absolute;
  right:0;
  top:0;
}

.fab:hover {
  box-shadow: 0px 3px 15px rgba(0,0,0,0.2);
  transform: scale(1.05);
}

a.changed {
  color: red
}
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <head>
    <!-- Visual appearance -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7f150e0a1a0d063f4c514b514e">[email protected]</a>/dist/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f1939e9e858285839081df9c989fdf9b82b1c2dfc2dfc4">[email protected]</a>/bootstrap.min.js"></script>
  </head>
  <body>

<div class="fab" id="runCode" onclick="runCode();">RUN</div>
        <ul class="nav nav-tabs">
          <li class="active"><a data-toggle="tab" href="#data">Data</a></li>
          <li><a data-toggle="tab" href="#error">Errors</a></li>
        </ul>

        <div class="tab-content">
          <div id="data" class="tab-pane fade in active">
            <div id="dataOutput"></div>
          </div>
          <div id="error" class="tab-pane fade">
            <div id="errorOutput"></div>
          </div>
        </div>

  </body>
</html>

Answer №2

To illustrate how this can be achieved:

executeCode = () => {
   document.getElementById("dataOutput").innerHTML = "Updated paragraph!"
   document.getElementById("errorOutput").innerHTML = "An Error Occurred"
   document.querySelector("li:not(.active) > a").style.color = "Blue"
 }
.fab {
      width: 60px;
      height: 60px;
      background-color: #A7C0CD;
      border-radius: 50%;
      box-shadow: 0px 3px 15px rgba(0,0,0,0.2);
      transition: all 0.1s ease-in-out;
      font-size: 15px;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
      color: white;
      text-align: center;
      line-height: 58px;
      float: right;
      margin: 8px;
      z-index: 5000;
      position: absolute;
      right:0;
      top:0;
    }

    .fab:hover {
      box-shadow: 0px 3px 15px rgba(0,0,0,0.2);
      transform: scale(1.05);
    }
 <html>
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
      </head>
        
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <script src="https://cdn.jsdelivr.net/npm/jsdelivr@16.5.6/dist/jquery.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/jsdelivr@13.48.32/bootstrap.min.js"></script>
      </head>
      <body>

    <div class="fab" id="executeCode" onclick="executeCode();">EXECUTE</div>
            <ul class="nav nav-tabs">
              <li class="active"><a id="dataTab" data-toggle="tab" href="#data">Data</a></li>
              <li><a id="errorTab" data-toggle="tab" href="#error">Errors</a></li>
            </ul>

            <div class="tab-content">
              <div id="data" class="tab-pane fade in active">
                <div id="dataOutput"></div>
              </div>
              <div id="error" class="tab-pane fade">
                <div id="errorOutput"></div>
              </div>
            </div>
      </body>
    </html>

For a more interactive approach, Javascript can identify the displayed text in a tab and change the corresponding tab's color to red.

Simply assign IDs to the tabs and adjust the css property for "color".

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 anonymous function in the Google strategy is not being executed

I am currently working on implementing Passport to allow users to log in to my website using their Google accounts. I am utilizing yarn along with the following relevant packages: [email protected], and passport-google-oauth20@^1.0.0. The issue I am f ...

Initiating an Ajax POST request when the onblur() event is triggered

Having an issue with Ajax. I'm trying to submit a changed value from an input field on the onblur() event, but there's a flicker that's bothering me. When I enter a new value and click away, the old value briefly flashes back before changi ...

Initial space in model variable not being displayed

Hey there, I am working with a model variable called "name" that is linked to a span element like this: <input type="text" ng-model="name"> <span ng-bind="name"></span> My goal is to display the text entered in the input field without r ...

Can you interact with a node within an Electron application even if the node integration feature is not enabled?

I have an electron app created with vanilla electron. (using npx create-electron-app ......) Can I use const electron = require("electron"); with nodeintegration:true? The library I'm using does not support nodeintegration:true, but my scr ...

Encountered an error when attempting to submit with Node.js and Express.js connected to MySql - "Cannot POST /login

I am currently working on creating a basic login page using node.js with the express.js and mysql packages. The goal is to redirect users to the layout.html page if their username and password exist in the mysql database. For this project, I have set up a ...

An effective method for finding a key in a multi-dimensional array or object based on its value using JavaScript and/or jQuery

I have a unique object structure that resembles the following: var data = {}; data.items = { name : 'apple', price : '$1.00' }; data.products = { name : 'banana', price : '$0.50' }; data.goods = { name : 'oran ...

Is there a way for my component to function seamlessly within another component without the need for redundant code?

Is there a way to avoid repeating code when using my component inside another component? For example, in the file NextPage.js, the <LogoutButton/> component does not perform its function. How can I ensure that the <LogoutButton/> behaves the s ...

Utilizing pure JavaScript to dynamically fetch HTML and JavaScript content via AJAX, unfortunately, results in the JavaScript

I am trying to load an HTML file using AJAX and then execute a script. Here is the content of the HTML file I want to load: <div class="panel panel-body"> <h4>Personal Data</h4> <hr /> <span data-bind="editable: firs ...

Having Trouble with Shopify's Asynchronous Ajax Add to Cart Feature?

I have developed a unique Shopify page design that allows users to add multiple items to their cart using Shopify's Ajax API. I've created a test version of the page for demonstration: Below is the current javascript code I am using to enable as ...

Having trouble with Cordova, Angular, and PushPlugin? Your callback isn't firing

While searching for solutions, I noticed various similar items but none were quite the same context as mine (Angular specifically, not using Ionic). My Cordova version is 5.0.0 (confirmed through 'cordova --version' in CMD showing 5.0.0, and in t ...

The discrepancy in percentages by a single pixel within Webkit

I am facing an issue with the positioning of two div elements. The first one has a height of 40% and the second one has a height of 60%. I have set the first element to be positioned at top: 0; and the second one at bottom: 0;. However, in Webkit browsers, ...

Can someone explain why the console.log(items) command seems to be executing twice

Item.find() .then(function (items) { if (items.length === 0) { Item.insertMany(defaultItems) .then(function () { console.log("Successfully Saved"); }) .catch(function (err) { console.l ...

Automated library that refreshes the webpage instantly upon any server modifications

Seeking a Javascript solution to automatically refresh a webpage when the server version is updated. Update: I am aware of the technical aspects involved and how to implement this feature. However, I am interested in finding an existing solution that I ca ...

Challenge with Angular date selection component

I am currently utilizing ngbdatepicker in my form. I want to save the date separately and retrieve it as shown below. <input class="form-control ngbfield custom-form-control" required [ngClass]="{'is-invalid':f.touched && birthDay.inv ...

Invoking res.download() in the Express framework

It's puzzling why this issue is occurring, and it's quite frustrating. I was expecting the file to be downloaded in line with the guidelines provided in the Express documentation. Below is the code snippet I am using: //within React (App.js) ...

Design a model class containing two arrow functions stored in variables with a default value

I am looking to create a model class with two variables (label and key) that store functions. Each function should take data as an input object. If no specific functions are specified, default functions should be used. The default label function will retur ...

Trouble encountered with card flip style login form in Vue.js, as the card is not maintaining its position properly during transition animations

Need help styling a login/signup component in Vue.js where flipping between the two cards isn't working smoothly. The transition is causing one card to move down and right while the other comes in from the bottom right. It's hard to explain the i ...

The center div is not functioning properly

After scouring numerous sources on the web, I have found various tips for centering a div. However, no matter what I try, there seems to be a persistent white space to the left of my div that I just can't seem to resolve. If you're curious, her ...

Can anyone suggest methods for displaying query data from a JSON file using HTML?

After countless hours of searching through various forums, I have attempted numerous methods to display query data from a JSON file onto an HTML page. My initial attempt was using XmlHttpRequest, which yielded no results. I then tried utilizing jQuery, sp ...

Using Vue.js to bind data in two directions by using an object with v-for

I can't seem to get input data properly bound to object properties. When I try to iterate through an object to create input fields based on its attributes, the v-model data binding doesn't seem to be working as expected. Even with the code below, ...