Skip to content
Advertisement

is there a way to prevent repeating code in html I’m using bootstrap 4 collapse like 20 times in one page

    <div class="card" style>
      <div class="card-header" id="headingOne">
        <h5 class="mb-0">
          <button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria- 
expanded="true" aria-controls="collapseOne">
                          Collapsible Group Item #1
                      </button>
        </h5>
      </div>
      <!-- Add mx-auto -->
      <div id="collapseOne" class="collapse show text-center mx-auto" aria-labelledby="headingOne" 
 style="width:300px;">
        <div class="card-body">
          <div class="card">
            <div class="card-header text-center" id="headingTwo" style="width:300px;">
              <h5 class="mb-0">
                <button class="btn btn-link collapsed text-center" data- toggle="collapse" data- 
   target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo" style="width:300px;">
                                      Collapsible Group Item #2
                                  </button>
              </h5>
            </div>
            <div id="collapseTwo" class="collapse show" aria-labelledby="headingTwo">
              <div class="card-body">
                Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus wolf moon put a 
                craft beer sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings farm-
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="card">
      <div class="card-header" id="headingThree">
        <h5 class="mb-0">
          <button class="btn btn-link collapsed" data-toggle="collapse" data- target="#collapseThree" 
 aria-expanded="false" aria-controls="collapseThree">
                          Collapsible Group Item #3
                      </button>
        </h5>
      </div>
      <div id="collapseThree" class="collapse" aria-labelledby="headingThree">
        <div class="card-body">
          Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry wolf moon 
          et. Nihil anim keffiyeh helvetica, craft beer labore wes sapiente ea proident. Ad vegan 
        </div>
      </div>
    </div>
  </div>

Hello I have been copying and pasting this like 10-20 times on my code changing the id the header id and the button. I also had been copying and pasting a bunch of other html code (image tag about 20 images) I was wondering if there was a way to stop repeating code (like a function) with pure html css. If not can you do it with plain vanilla js? if not then what are the other ways?

In short

Most important question (A is most important C is least)

  • A) is there a way to prevent repeating code with the collapse code above with just pure HTML/CSS? if yes how?
  • B) is there a way to prevent repeating code with the collapse code above with just pure HTML/CSS/vanilla js? if yes how?
  • C) is there a way to prevent repeating code with the collapse code above with just pure HTML/CSS/angular/react? if yes how?

Advertisement

Answer

You can use a function to repeat how many times you want to duplicate your element, in the following snippet I created a function that will clone .card node using .cloneNode() and iterate a number of times, then modify the ids and attributes using querySelector() on the cloned node, here is a snippet for option A:

function duplicateElement(selector, numOfDuplicates) {
  let element = document.querySelector(selector);
  for(let i = numOfDuplicates; i > 0; i--) {
    let newElement = element.cloneNode(true);

    newElement.querySelector('#headingOne').id = `headingOne-${i}`;
    newElement.querySelector('#collapseOne').id = `collapseOne-${i}`;
    newElement.querySelector('#collapseTwo').id = `collapseTwo-${i}`;
    newElement.querySelector('#headingTwo').id = `headingTwo-${i}`;
    let toggleBtn = newElement.querySelector('[data-target="#collapseOne"]');
    toggleBtn.dataset['target'] = `#collapseOne-${i}`;
    toggleBtn.setAttribute('aria-controls', `collapseOne-${i}`);
    
    let toggleBtn2 = newElement.querySelector('[data-target="#collapseTwo"]');
    toggleBtn2.dataset['target'] = `#collapseTwo-${i}`;
    toggleBtn2.setAttribute('aria-controls', `collapseTwo-${i}`);

    element.after(newElement);
  }
  
}

duplicateElement('.card', 4);
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>


<div class="card">
    <div class="card-header" id="headingOne">
        <h5 class="mb-0">
            <button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne" aria- expanded="true" aria-controls="collapseOne">
                Collapsible Group Item #1
            </button>
        </h5>
    </div>
    <!-- Add mx-auto -->
    <div id="collapseOne" class="collapse show text-center mx-auto" aria-labelledby="headingOne" style="width: 300px;">
        <div class="card-body">
            <div class="card">
                <div class="card-header text-center" id="headingTwo" style="width: 300px;">
                    <h5 class="mb-0">
                        <button class="btn btn-link collapsed text-center" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo" style="width: 300px;">
                            Collapsible Group Item #2
                        </button>
                    </h5>
                </div>
                <div id="collapseTwo" class="collapse show" aria-labelledby="headingTwo">
                    <div class="card-body">
                        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus wolf moon put a craft beer sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings farm-
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

If you are looking for option C solution, it will be a bit complicated if your project is not already using React or other client rendering library or front-end framework, you have to use Webpack with Babel to setup the front-end framework and code-base for your project, here is a working codesandbox sample for on how you might implement your bootstrap front-end using React.

In the following snippet, I created a component function and used Array.map() on array [1, 2, 3, 4, 5] to create 5 components:

import React, { useState } from "react";
import { Collapse, Button, Card } from "react-bootstrap";

import "bootstrap/dist/css/bootstrap.min.css";

import "./styles.css";

function Example() {
  const [open, setOpen] = useState(false);
  const [openLevel, setOpenLevel] = useState(false);

  return (
    <>
      <Card>
        <Card.Header>
          <Button
            onClick={() => setOpen(!open)}
            aria-controls="collapseOne"
            aria-expanded={open}
          >
            Collapsible Group Item #1
          </Button>
        </Card.Header>

        <Collapse className="first-coll" in={open}>
          <Card.Body id="collapseOne">
            <Card>
              <Card.Header>
                <Button
                  onClick={() => setOpenLevel(!openLevel)}
                  aria-controls="collapseTwo"
                  aria-expanded={openLevel}
                >
                  Collapsible Group Item #2
                </Button>
              </Card.Header>

              <Collapse className="second-coll" in={openLevel}>
                <Card.Body id="collapseTwo">
                  Anim pariatur cliche reprehenderit, enim eiusmod high life
                  accusamus wolf moon put a craft beer sapiente ea proident. Ad
                  vegan excepteur butcher vice lomo. Leggings farm-
                </Card.Body>
              </Collapse>
            </Card>
          </Card.Body>
        </Collapse>
      </Card>
    </>
  );
}

export default function App() {
  return (
    <div className="App">
      {[1, 2, 3, 4, 5].map((el, i) => {
        return <Example key={i} />;
      })}
    </div>
  );
}
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement