Prevent duplicate components from interacting with one another in Angular

My Tabs component has its own variables and functions, and it works perfectly. However, I encountered an issue when trying to place multiple tab components on the same page. Whenever I change the value of one tab, it also affects the other tab component.

This is the code for my tab component:

@Component({
  selector: 'sys-tab',
  styleUrls: ['./shared/sys.css'],
  template: `
    <div class="tabs">
      <div *ngFor="let tab of tabs; let i = index" (click)="selectTab(tab)">
        <input id="tab-{{i+1}}" type="radio" name="radio-set" class="tab-selector-{{i+1}}" [checked]="i===0"/>
        <label for="tab-{{i+1}}" class="tab-label-{{i+1}}">{{tab.title}}</label>
      </div>
      <div class="content">
         <ng-content></ng-content>
      </div>
    </div>
  `,
})

export class TabView {
  tabs: TabViewContent[] = [];
  addTab(tab: TabViewContent) {
    if (this.tabs.length === 0)
      tab.active = true;
    this.tabs.push(tab);
  }

  selectTab(tab) {
    this.tabs.forEach((tab) => {
      tab.active = false;
    });
    tab.active = true;
  }
}

@Component({
  selector: 'sys-tab-content',
  styleUrls: ['./shared/sys.css'],
  template: `    
      <div class="content-2" [hidden]="!active">
        <ng-content></ng-content>
      </div>
   `
})
export class TabViewContent {

  active: boolean;

  @Input() title: string;

  constructor(tabs: TabView) {
    tabs.addTab(this);
  }

}

The tab component works well with this implementation:

<sys-tab>
  <sys-tab-content title="Principal">
   Content 1
  </sys-tab-content>
  <sys-tab-content title="Complementar">
   Content 2
  </sys-tab-content>
</sys-tab>

However, issues arise when using multiple tab components like this:

<sys-tab>
      <sys-tab-content title="Principal">
         Content 1
      </sys-tab-content>
     <sys-tab-content title="Complementar">
           Content 2
       </sys-tab-content>
    </sys-tab>
<sys-tab>
      <sys-tab-content title="Principal">
         Content 3
      </sys-tab-content>
     <sys-tab-content title="Complementar">
           Content 4
       </sys-tab-content>
    </sys-tab>

Changing the value of the first component also changes the value of the second, and vice versa.

Answer №1

In order to ensure uniqueness, it is important to assign distinct names to each group of input[radio]:

name="{{id}}-radio-set"

Additionally, make sure that all controls have unique values for the id and for attributes.

Here is an example of how this can be implemented:

let nextId = 0;

@Component({
  selector: 'sys-tab',
  template: `
      ...
        <input id="{{id}}-tab-{{i+1}}" ... name="{{id}}-radio-set" .../>
        <label for="{{id}}-tab-{{i+1}}" ...></label>
      ...
  `,
})
export class TabView {
  id = `tabview-${nextId++}`;

Check out this Plunker Example for reference.

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

Using Angular's [ngIf], [ngIfElse], and [ngIfElseIf] functionalities enables dynamic content rendering

Currently, I have the following code snippet: <ng-container *ngIf="someCondition"> <ng-template [ngIf]="cd.typedType === 'first'" [ngIfElse]="Second"> <div class="row"> fir ...

Enhancing this testimonial slider with captivating animations

I have designed a testimonial slider with CSS3 and now I am looking to enhance it by adding some animation using Jquery. However, I am not sure how to integrate Jquery with this slider or which plugins would work best for this purpose. Can anyone provide g ...

Error code 70006 encountered in Typescript when attempting to reference a type as "any"

Currently, I am working on a React project that involves using TypeScript. This is quite new to me, and I have encountered a type error in one of my components... let dragStart = (e) => { let transferringData = e.dataTransfer.setData("text", e.tar ...

What methods can be used to accomplish this effect using CSS and/or Javascript?

Is there a way to achieve the desired effect using just a single line of text and CSS, instead of multiple heading tags and a CSS class like shown in the image below? Current Code : <h2 class="heading">Hi guys, How can i achieve this effect using j ...

The issue of not being able to add data to the client is encountered in a local setup involving Socket.io, MSSQL

I have a large dataset that needs to be retrieved from a SQL server using Node.js and then broadcasted to clients in real-time using Socket.IO. I've been successful in fetching the data, but the UI on the client side isn't updating. Although I c ...

Is it possible to determine the location of the "phantom image" while moving an object?

Is there a method to retrieve the location of the ghost image when an element is dragged? This is how the scenario is set up: <div id="test" v-on:dragstart="dragStart" v-on:drag="dragging" draggable="true" v-on:drop="drop" v-on:dragover="allowDrop"> ...

It is not possible to change the maximum height of a Popover in Material UI

I am currently working with the Popover component in material-ui, but I am facing an issue modifying the max-height property that is calculated as max-height: calc(100% - var). I have attempted different solutions such as using className and override, but ...

Hide the navigation menu when a page link is selected

Within my Angular 8 application, a fixed navigation bar is positioned at the top of the screen. Upon hovering over a dropdown nav link, a menu will appear for the user to explore. However, when a user clicks on one of these menu links, Angular Routing is ...

Errors were encountered while parsing providers in SystemJS with angular2-in-memory-web-api

Having some trouble integrating angular2-in-memory-web-api into my project. Progress has been made, but now encountering (SystemJS) Provider parse errors: (...). Not sure what I'm missing, everything compiles fine and no 404 errors are showing up, so ...

Show the JSON data from the server in a table format

Is there a way to neatly display data received from an Ajax response within a table format? Below is the structure of the table: <table data-toggle="table" data-show-columns="true" data-search="true" data-select-item-name="toolbar1" id="menu_table"> ...

Guide on incorporating finos/perspective into an Angular 8 project using https://perspective.finos.org/

I am looking for guidance on incorporating Finos/Perspective Datagrid into my Angular 8 application. I need to input data in JSON format and have it output as a Datagrid. Any sample code or examples would be greatly appreciated. You can find the GitHub re ...

Performance of Angular4 UI decreases with a large amount of data objects

https://i.sstatic.net/PdmFk.jpg The table above displays an array of objects, typically containing 50-60 items. As the item count increases, elements like transition animations and click events become slower. However, I have observed that when filtering t ...

The type '{} is not compatible with the type 'IProps'

In my current project, I am utilizing React alongside Formik and TypeScript. The code snippet below demonstrates my usage of the withFormik Higher Order Component (HOC) in my forms: import React from 'react'; // Libraries import........ import { ...

Display Bootstrap Modal Box automatically when Angular 8 App Loads

I am facing an issue with launching a modal dialog on page load in my Angular 8/Visual Studio project. While it works perfectly fine with the click of a button, I am unable to make it load automatically on page load. I have tried using *ngIf but it doesn&a ...

Disable the default marker in Mapbox Geocoder

As a newcomer in the world of ReactJS and Mapbox GL JS, I am working on a project where I have successfully integrated a map with Geocoder, Navigation Controls, and Markers based on locations from a JSON file. However, I encountered an issue - whenever I s ...

I'm having trouble managing state properly in Safari because of issues with the useState hook

Encountering Safari compatibility issues when updating a component's state. Though aware of Safari's stricter mode compared to Chrome, the bug persists. The problem arises with the inputs: https://i.sstatic.net/WSOJr.png Whenever an option is ...

Facing a blank page with no errors displayed during the HTML rendering process in Angular version 6

One of the most frustrating aspects of working with Angular is the lack of information provided when there is a render error in an HTML page. Instead of specifying which page the error is in, Angular defaults to the route page and provides no further detai ...

Discover the method of connecting to a unique JavaScript trigger while utilizing IJavaScriptExecutor

In our web application, we have an event called timelineEventClicked that is created by a custom trigger. canvas.addEventListener('click', function (evt) { evt.stopImmediatePropagation(); var mousePos = ge ...

Extracting web search result URLs using Puppeteer

I'm currently facing an issue with the code I've written for web scraping Google. Despite passing in a specific request, it is not returning the list of links as expected. I am unsure about what might be causing this problem. Could someone kindly ...

What is the process for generating an array of objects using JavaScript?

I am struggling to create an array of objects using JavaScript and facing errors with new lines added where I need to split the messages and collect row numbers. The row numbers should be comma-separated if it is a repetitive error message. I found a solu ...