How can I avoid duplicating code in HTML? I find myself utilizing the Bootstrap 4 collapse feature around 20 times on a single 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 duplicating this content multiple times in my code by changing IDs, headers, and buttons. I have also been pasting a large amount of other HTML code (approximately 20 images) and I'm looking for a way to avoid repeating this code, possibly with a function in pure HTML/CSS or plain vanilla JavaScript. If not possible, what are the other possible solutions?

Summary:

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

  • A) Can I prevent repeating the collapse code above with just pure HTML/CSS? If yes, how?
  • B) Can I prevent repeating the collapse code above with pure HTML/CSS and vanilla JavaScript? If yes, how?
  • C) Can I prevent repeating the collapse code above with pure HTML/CSS/angular/react? If yes, how?

Answer №1

After some exploration, I have stumbled upon another solution. This method utilizes the <template> tag in HTML and JSON to access the necessary data.

Utilizing the HTML Template

As explained by MDN:

The HTML Content Template (<template>) element is a mechanism for holding HTML that is not to be rendered immediately when a page is loaded but may be instantiated subsequently during runtime using JavaScript.

Therefore, this approach is perfectly suited for tackling this type of issue.

Resolution

Firstly, you'll need to define the button text and card content within a JSON object. This JSON can either be stored in a separate file (and loaded as shown below) or you can embed the JSON content inside a variable, similar to the demonstration in the JSFiddle.

1. Using a JSON File

data.json

[
   {
      "button" : "Button 1",
      "body"   : "Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt"
    },
    {
      "button" : "Button 2",
      "body"   : "aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat"
    },
    {
      "button" : "Button 3",
      "body"   : "craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS."
    },
    {
      "button" : "Button 4",
      "body"   : "Lorem ipsum dolor sit amet"
    }
]

loadDom function:

function loadDom() {
   //Get the data from data.json

   var xobj = new XMLHttpRequest();
   xobj.overrideMimeType("application/json");
   xobj.open('GET', 'data.json', true);
   xobj.onreadystatechange = function() {
     if (xobj.readyState == 4 && xobj.status == "200") {
        //parse the json
        let dataToLoad = JSON.parse(xobj.responseText);
        //create the cards
        dataToLoad.forEach((card, i) => {
           createCard(i, card["button"], card["body"]);
        });
       }
     };
   xobj.send(null);

}

2. Inline JSON

function loadDom() {
  //Just specify the data that you want...
  var dataToLoad = [ ... ]  // JSON data content here

  //load the data from json and create the cards
  dataToLoad.forEach((card, i) => {
    createCard(i, card["button"], card["body"]);
  });
}

function createCard(id, buttonText, cardBody) { ... } // function code here

<!DOCTYPE html> ... // HTML document structure here

Hopefully, this explanation proves useful! If you encounter any difficulties, feel free to ask for further assistance.

(Credit to @Polygnome's code contribution in the <head> section of the example)

Answer №2

To achieve this in pure HTML/CSS, you would need to utilize server-side rendering with a template language.

If you want to implement this using pure HTML/CSS/JS, ECMAScript 262 introduced template literals that can be effectively utilized:

<script>
    function createCard(id, content) {
        return `<div class="card">
                    <div class="card-header" id="heading-${id}">
                        <h5 class="mb-0">
                            <button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse-${id}" aria-expanded="false" aria-controls="collapse-${id}">Collapsible Group Item #${id}</button>
                        </h5>
                    </div>
                    <div id="collapse-${id}" class="collapse" aria-labelledby="heading-${id}">
                        <div class="card-body">
                            ${content}
                        </div>
                    </div>
                </div>`;
    }
    $(function(){
        $('#cards').append($(createCard('1', "Lorem ipsum")));
        $('#cards').append($(createCard('2', createCard(3, "Dolor sit amnet"))));
    });
</script>

It's important to note that jQuery is used in this example for element selection and insertion, as Bootstrap also relies on jQuery. However, the same can be achieved with pure JS using document.getElementById(...).

You can view a working demonstration of this concept here:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>
    
    <div class="container" id="cards">
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
    
    <script>
        function createCard(id, content) {
            return `<div class="card">
                        <div class="card-header" id="heading-${id}">
                            <h5 class="mb-0">
                                <button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse-${id}" aria-expanded="false" aria-controls="collapse-${id}">Collapsible Group Item #${id}</button>
                            </h5>
                        </div>
                        <div id="collapse-${id}" class="collapse" aria-labelledby="heading-${id}">
                            <div class="card-body">
                                ${content}
                            </div>
                        </div>
                    </div>`;
        }
        $(function(){
            $('#cards').append($(createCard('1', "Lorem ipsum")));
            $('#cards').append($(createCard('2', createCard(3, "Dolor sit amnet"))));
        });
    </script>
  </body>
</html>

Answer №3

If you want to replicate an element multiple times, you can achieve this by creating a function. In the code snippet below, I have demonstrated a method that duplicates the .card node using the .cloneNode() function. This function iterates through the specified number of times, modifies the IDs and attributes of the cloned node using the querySelector() method. Here is an example 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);
... (Additional code continues)

If you are interested in option C, it involves complexities if your project does not already utilize React or another client-side rendering library. You would need to set up Webpack with Babel to establish the front-end framework and codebase for your project. To see a demonstration, check this working codesandbox sample on implementing React with bootstrap.

... (Additional text and code snippets follow)

Answer №4

Building upon Polygnome's response,

To achieve this task in pure JavaScript, you can utilize the following code snippet:

function addCard(id, content) {
  let element = document.querySelector(".card");
  let newContent = document.createTextNode(`<div class="card">
    <div class="card-header" id="heading-${id}">
      <h5 class="mb-0">
        <button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse-${id}" aria-expanded="false" aria-controls="collapse-${id}">Collapsible Group Item #${id}</button>
      </h5>
    </div>
    <div id="collapse-${id}" class="collapse" aria-labelledby="heading-${id}">
      <div class="card-body">
          ${content}
      </div>
    </div>
  </div>`);
  element.appendChild(newContent);
}

Hopefully, this solution proves beneficial!

Answer №5

Response for Question A: Escape the repetition trap in HTML and CSS by utilizing the :nth-child() property. With this tool, you can assign unique CSS styles to identical elements without the need for individual classes or IDs. Simply duplicate the code in HTML and let :nth-child() work its magic. For more information, check out the link here.

Insight on Questions B and C: While I may be a tad late to the discussion, I must acknowledge the insightful answers already provided by fellow users like Chiel, ROOT, Polygnome, and Coder100. Their input offers valuable perspectives on achieving desired outcomes using various languages and frameworks beyond just CSS and HTML.

Wishing everyone a fantastic day!
Best regards,
Om Chaudhary

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

Stripping file extensions from retrieved echo (PHP/HTML)

<?php $files = scandir("signatureforms/"); foreach($files as $index => $filename) { if($index < 2) { continue ;} $extension = pathinfo($filename, PATHINFO_EXTENSION); ?> <button class="signatureformbutton" ...

Using Javascript to efficiently remove elements with AJAX

Currently, I am learning the basics of HTML and focusing on tasks such as login/logout functionality, creating users, and deleting users (only permitted when logged in as an admin). For updating a user password, I have utilized PUT, for creating a user ac ...

Arrange the array depending on the existence of properties in the objects

Is there a way to efficiently organize an array like the following in cases where certain fields are missing? For instance, consider the current array: const users = [ { id: 1, firstname: 'Jerry' }, { id: 2, firstname: & ...

Attempting to update an AJAX field with the returned value, but it only updates after clicking away from it

Image of form utilizing AJAX & JS The current setup involves a maintainer that uses AJAX to update the "Calc" field in response to a number entered in the "Order No" field. The issue is that the "Calc" field does not update immediately after typing in the ...

The "if" statement carries out the identical action each time it is executed

Despite my efforts to toggle the value of the turn variable every time the if statement runs, I keep encountering the same outcome. It appears that turn consistently evaluates as 2. Below is the code snippet in question: $(function() { var turn = 2; ...

Issues with image sizing on mobile devices

After finalizing my header design, I encountered an issue with the mobile version of the website. The images in the header are not responsive and do not adapt well to different screen sizes. I need assistance converting the header design into functional co ...

What is the method for altering a CSS element's keyframe animation while it is currently running?

My little mouse speed detector, although not perfect, provides me with the current mouse speed every 100ms in the variable window.mouseSpeed.t. I decided to implement this feature because I wanted to create a whimsical animation at the bottom edge of the s ...

Can anyone help me with coloring Devanagiri diacritics in ReactJS?

I am currently working on a ReactJS project and I have come across an issue. I would like for the diacritic of a Devanagiri letter to be displayed in a different color than the letter it is attached to. For example: क + ी make की I was wondering ...

Within a container, there are two divs separated by a white bar

Hello everyone, I am in need of creating a unique slideshow for my website and I want to start by splitting a div into two sections using a slightly skewed diagonal line that is either semi-transparent black or solid white. I have searched extensively onli ...

Determine if a specific value is present within an array consisting of multiple objects using Mongoose

In my collection, I have a scenario where I need to utilize the $in operator. Person = { name: String, members: [ {id: String, email: String}... {}] } Currently, I am using the following: Person.find({members: {"$in": [id1]}}) However, I am aware of ...

Responsive height using Material Design Lite

I have a website using MDL, with a prominent header centered on the page. To enhance visibility, I added a background box behind the text. To view the CodePen example, click here. The challenge is to ensure that when the window is resized, such as on a m ...

Utilize PHP to generate a table from data

I successfully created a table using information retrieved from my database, and everything is displaying as intended. However, I am facing an issue where adding a background color applies it to every row in the table. How can I add a background color wit ...

Error in Next.js: Trying to destructure an undefined object in useContext

While attempting to change the state of my cursor in a Next.js app using useContext, I encountered the following error: TypeError: Cannot destructure 'Object(...)(...)' as it is undefined. The goal is to update the state to isActive: true when h ...

Close the material-ui popper when clicking away

I am currently working on implementing a Material UI popper feature that should close when the user clicks outside of it using ClickAwayListener. However, I have been unable to make this functionality work despite trying different approaches. I've att ...

How can Redux help persist input value through re-rendering?

Handling Input Value Persistence in Redux despite Re-rendering? I am currently able to store and save input values, but only the data from one step ago. For example, when I click on the second input field, it displays the value from the first input fiel ...

What is the best method for saving console.log output to a file?

I have a tree structure containing objects: let tree = {id: 1, children: [{id: 2, children: [{id: 3}]}]} My goal is to save all the id values from this tree in a text file, indenting elements with children: 1 2 3 Currently, I am using the following ...

React: Issue with input values not correctly updating across multiple fields when changing state toggles

I am working on a React component that needs to update input values for multiple players independently. However, I am facing an issue where toggling a state causes the first input's value to incorrectly propagate to all other inputs. Additionally, cle ...

Issues with the functionality of jQuery's .load() method are causing

I am encountering an issue for the first time. Inside ajax.html, I have the following code in the header: $(document).ready(function(){ $( "#result" ).load( "/loaded.html" ); }); In the same directory, there is a second page named loaded.html: <d ...

Having trouble getting THREE.Raycaster to intersect with THREE.PointCloud

Currently, I am trying to implement click events on my WebGL based 3D graph library called Graphosaurus. You can take a look at what I have done so far here. I have used this example as a reference. I am wondering if the reason it is not functioning corr ...

Guide to adding a tag in front of a text in HTML with Python

Searching for all the text within the html document and wishing to incorporate a span tag that contains additional information about each text as shown below def recursiveChildren(x): if "childGenerator" in dir(x): for child in x.childGenerator( ...