For loop and active state in UI

May 20, 2020 Amrish Kushwaha...
twitterlinkedinreddit
For loop and active state in UI

One of the common patterns or UI elements is a list of items with an active state in one of the element and when you click on a different item, that item goes in the active state. This article will explain how to implement this kind of UI element.

Logic: way to develop

Pseudo HTML skeleton

<div (click)="set current index as selected index"
   for-loop="iterate over each elements of array"
   class.active="selectedIndex is equal to currentIndex">
	<div>item[i]</div>
</div>

In order to implement it, you will need:

  • for loop which loops through array
  • click event for every element
  • active state will be set to that element which are clicked, in this case I am using active class.

Example :

  • in Angular
  • in React
  • in Plain Javascript

Example: for loop and active state in angular

demo.component.html

<div class="list-container" *ngIf="listOfItems">
  <div
    class="item"
    (click)="setIndex(i)"
    [class.active]="selectedIndex === i"
    *ngFor="let item of listOfItems; let i = index"
  >
    <span>{{item.num}}</span>
    <p>{{item.content}}</p>
  </div>
</div>

demo.component.css

.item {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  padding: 16px;
  color: green;
  cursor: pointer;
}

.item span {
  border: 1px solid green;
  height: 40px;
  width: 40px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.active span {
  background-color: green;
  color: white;
}
.active p {
  font-weight: 600;
}

demo.component.ts

import { Component, OnInit } from "@angular/core";

@Component({
  selector: "app-demo",
  templateUrl: "./demo.component.html",
  styleUrls: ["./demo.component.css"]
})
export class DemoComponent {
  listOfItems = [
    {
      num: 1,
      content: `I am Item #1`
    },
    {
      num: 2,
      content: `I am Item #2`
    },
    {
      num: 3,
      content: `I am Item #3`
    }
  ];

  INITIAL_INDEX = 0;
  selectedIndex = this.INITIAL_INDEX;

  constructor() {}

  ngOnInit() {}

  setIndex(item) {
    this.selectedIndex = item;
  }
}

That's all

Here is the result:

Example: for loop and active state in react

listItems.js

import React, { useState } from "react";

export default function ListItems() {
  const listOfItems = [
    {
      num: 1,
      content: `I am Item #1`
    },
    {
      num: 2,
      content: `I am Item #2`
    },
    {
      num: 3,
      content: `I am Item #3`
    }
  ];
  const INITIAL_INDEX = 0;
  const [selectedIndex, setIndex] = useState(INITIAL_INDEX);

  return (
    <div className="list-container">
      {listOfItems.map((item, index) => {
        return (
          <div
            className={`item ${selectedIndex === index ? "active" : ""}`}
            key={item.num}
            onClick={() => setIndex(index)}
          >
            <span>{item.num}</span>
            <p>{item.content}</p>
          </div>
        );
      })}
    </div>
  );
}

and its style.css

.item {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  padding: 16px;
  color: green;
  cursor: pointer;
}

.item span {
  border: 1px solid green;
  height: 40px;
  width: 40px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.active span {
  background-color: green;
  color: white;
}
.active p {
  font-weight: 600;
}

and the result is

Example: for loop and active state in plain HTML, CSS and Javascript

html

<div class="list-container" id="listContainer">
  <div class="item active">
    <span>1</span>
    <p>I am Item #1</p>
  </div>
  <div class="item">
    <span>2</span>
    <p>I am Item #2</p>
  </div>
  <div class="item">
    <span>3</span>
    <p>I am Item #3</p>
  </div>
</div>

css

.item {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  padding: 16px;
  color: green;
  cursor: pointer;
}

.item span {
  border: 1px solid green;
  height: 40px;
  width: 40px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.active span {
  background-color: green;
  color: white;
}
.active p {
  font-weight: 600;
}

and javascript

const listContainer = document.getElementById("listContainer");

const items = listContainer.getElementsByClassName("item");

for (let i = 0; i < items.length; i++) {
  items[i].addEventListener("click", function () {
    let current = listContainer.getElementsByClassName("active");
    current[0].className = current[0].className.replace(" active", "");

    this.className += " active";
  });
}

Here is the result:

I hope that you like the article.

Keep coding and keep learning and keep building stuffs...