---
id: 6915aa2ea2f30176eccd9307
title: Step 49
challengeType: 0
dashedName: step-49
---

# --description--

Use the `oninput` event on `shapeTypeSelect` and set it to `handleShapeSelect`. This will make the function run each time the shape selection changes.

After doing that, you should be able to see the input fields of each shape. But the calculations won't work yet, and that's what you will handle next.

# --hints--

You should set `shapeTypeSelect.oninput` to `handleShapeSelect`.

```js
console.log(initializeApp.toString())
assert.match(initializeApp.toString(), /shapeTypeSelect\.oninput\s*=\s*handleShapeSelect;?/)
```

# --seed--

## --seed-contents--

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="styles.css" />
    <title>Shape Manager</title>
  </head>
  <body>
    <div class="container">
      <div class="text-center mb-8">
        <h1>Shape Manager</h1>
        <p class="subtitle">Calculate areas of geometric shapes</p>
      </div>

      <div class="card">
        <div class="card-header">
          <h2 class="card-title">Shape Calculator</h2>
        </div>
        <div class="card-content">
          <div class="form-group">
            <label for="shape-type" class="label">Shape Type</label>
            <select id="shape-type" class="select">
              <option value="">Select shape type</option>
              <option value="circle">Circle</option>
              <option value="rectangle">Rectangle</option>
              <option value="triangle">Triangle</option>
            </select>
          </div>

          <div id="property-inputs">
          
            <div id="circle-props" class="form-group hidden">
              <label for="radius" class="label">Radius</label>
              <input
                type="number"
                min="0"
                id="radius"
                placeholder="Enter radius"
                class="input"
              />
            </div>
          
            <div id="rectangle-props" class="form-grid hidden">
              <div class="form-group">
                <label for="width" class="label">Width</label>
                <input
                  type="number"
                  min="0"
                  id="width"
                  placeholder="Width"
                  class="input"
                />
              </div>
              <div class="form-group">
                <label for="height" class="label">Height</label>
                <input
                  type="number"
                  min="0"
                  id="height"
                  placeholder="Height"
                  class="input"
                />
              </div>
            </div>
         
            <div id="triangle-props" class="form-grid hidden">
              <div class="form-group">
                <label for="base" class="label">Base</label>
                <input
                  type="number"
                  min="0"
                  id="base"
                  placeholder="Base"
                  class="input"
                />
              </div>
              <div class="form-group">
                <label for="triangle-height" class="label">Height</label>
                <input
                  type="number"
                  min="0"
                  id="triangle-height"
                  placeholder="Height"
                  class="input triangle-height"
                />
              </div>
            </div>
          </div>
        </div>
      </div>

      <div id="result-card" class="card">
        <div class="card-content result-card-content">
          <div id="result-text"></div>
          <div class="result-area"></div>
        </div>
      </div>
    </div>
    <script src="index.ts"></script>
  </body>
</html>
```

```css
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Helvetica Neue", Arial, sans-serif;
  background: linear-gradient(to bottom right, #f8fafc, #f1f5f9);
  color: #334155;
  min-height: 100vh;
  padding: 1rem;
}

.container {
  max-width: 56rem;
  margin: 0 auto;
  padding: 2rem 1rem;
}

.text-center {
  text-align: center;
}

.mb-8 {
  margin-bottom: 2rem;
}

h1 {
  font-size: 2.25rem;
  font-weight: 700;
  color: #1e293b;
  margin-bottom: 0.5rem;
}

.subtitle {
  color: #475569;
}

.card {
  background-color: white;
  border-radius: 0.75rem;
  box-shadow:
    0 10px 15px -3px rgba(0, 0, 0, 0.1),
    0 4px 6px -2px rgba(0, 0, 0, 0.05);
  margin-bottom: 1.5rem;
}

.card-header {
  padding: 1.5rem;
  border-bottom: 1px solid #e2e8f0;
}

.card-title {
  font-size: 1.25rem; 
  font-weight: 600;
}

.card-content {
  padding: 1.5rem;
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

@media (min-width: 768px) {
  .form-grid {
    grid-template-columns: 1fr 1fr;
  }
}

.form-group {
  margin-bottom: 1.5rem;
}

.label {
  display: block;
  font-weight: 500;
  margin-bottom: 0.5rem;
}

.input,
.select {
  width: 100%;
  padding: 0.5rem 0.75rem;
  border: 1px solid #cbd5e1;
  border-radius: 0.375rem;
  font-size: 1rem;
  transition:
    border-color 0.2s,
    box-shadow 0.2s;
}

.input:focus,
.select:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.4);
}

.result-card-content {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.result-icon-container {
  width: 3rem;
  height: 3rem;
  border-radius: 0.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.result-icon {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 9999px;
}

#result-text {
  flex-grow: 1;
}
#result-text h3 {
  font-size: 1.25rem;
  font-weight: 700;
}
#result-text p {
  color: #475569;
  text-transform: capitalize;
}

.hidden {
  display: none;
}

/* Hide the result card until a shape is selected */
#result-card {
  display: none;
  opacity: 0;
  transition: opacity 0.15s ease-in-out;
}

/* Add this class to show the result card */
#result-card.visible {
  display: block;
  opacity: 1;
}
```

```ts
interface Shape {
  type: string;
}

interface Circle extends Shape {
  type: "circle";
  radius: number;
}

interface Rectangle extends Shape {
  type: "rectangle";
  width: number;
  height: number;
}

interface Triangle extends Shape {
  type: "triangle";
  base: number;
  height: number;
}

type Shapes = Circle | Triangle | Rectangle;

const getElement = (id: string): HTMLElement => {
  const el = document.getElementById(id);
  if (!el) throw new Error(`Element not found: ${id}`);
  return el;
};

let shapeTypeSelect: HTMLSelectElement;

let propertyGroups: {
  circle: HTMLElement;
  rectangle: HTMLElement;
  triangle: HTMLElement;
};

let propertyInputs: {
  radius: HTMLInputElement;
  width: HTMLInputElement;
  height: HTMLInputElement;
  base: HTMLInputElement;
  triangleHeight: HTMLInputElement;
};

let resultText: HTMLElement;
let resultCard: HTMLElement;

const chooseShape = (shapeType: string) => {
  Object.entries(propertyGroups).forEach(([name, group]) => {
    if (name === shapeType) {
      group.classList.remove("hidden");
    } else {
      group.classList.add("hidden");
    }
  });
};

const toggleResultCard = (show: boolean) => {
  if (show) {
    resultCard.classList.add("visible");
  } else {
    resultCard.classList.remove("visible");
  }
};

const calculateArea = (shape: Shapes): string => {
  switch (shape.type) {
    case "circle":
      return `Area of Circle: ${(Math.PI * shape.radius ** 2).toFixed(2)}`;
    case "rectangle":
      return `Area of Rectangle: ${shape.width * shape.height}`;
    case "triangle":
      return `Area of Triangle: ${0.5 * shape.base * shape.height}`;
    default:
      const _nonExistent: never = shape;
      return _nonExistent;
  }
};

const clearInputFields = () => {
  document.querySelectorAll("input").forEach((input) => {
    input.value = "";
  });
};

function updateResult() {
  const shape = shapeTypeSelect.value;
  let result: string = "";

  if (shape === "circle") {
    result = calculateArea({
      type: "circle",
      radius: Number(propertyInputs.radius.value),
    });
 } else if (shape === "rectangle") {
    result = calculateArea({
      type: "rectangle",
      width: Number(propertyInputs.width.value),
      height: Number(propertyInputs.height.value),
    });
  } else if (shape === "triangle") {
      result = calculateArea({
        type: "triangle",
        base: Number(propertyInputs.base.value),
        height: Number(propertyInputs.triangleHeight.value),
      });
    }

  resultText.textContent = result;
}

const handleShapeSelect = (e: Event) => {
  e.preventDefault();
  clearInputFields();

  const val = e.currentTarget as HTMLSelectElement;
  if (!val) {
    return "target value not found";
  }

  const hasSelection = Boolean(val.value);
  toggleResultCard(hasSelection);

  chooseShape(val.value);
  updateResult();
};

const handleInput = (e: Event) => {
  const value = Number((e.target as HTMLInputElement).value);

  if (value < 0) {
    alert("Negative values are not allowed.");
    clearInputFields();
  }

  updateResult();
};

const initializeApp = () => {
  shapeTypeSelect = getElement("shape-type") as HTMLSelectElement;

  propertyGroups = {
    circle: getElement("circle-props") as HTMLElement,
    rectangle: getElement("rectangle-props") as HTMLElement,
    triangle: getElement("triangle-props") as HTMLElement,
  };

  propertyInputs = {
    radius: getElement("radius") as HTMLInputElement,
    width: getElement("width") as HTMLInputElement,
    height: getElement("height") as HTMLInputElement,
    base: getElement("base") as HTMLInputElement,
    triangleHeight: getElement("triangle-height") as HTMLInputElement,
  };

  resultText = getElement("result-text") as HTMLElement;
  resultCard = getElement("result-card") as HTMLElement;

  --fcc-editable-region--
  
  --fcc-editable-region--
};

document.addEventListener("DOMContentLoaded", initializeApp);
```
