Reputation: 43
I'm trying to use Bootstrap's collapse functionality to create a functioning 'Show More' button on a page that I'm working on. The button should show more/hide the body text of a card description.
The problem is that the page content is being generated dynamically and I'm not sure how to use collapse in this context. I understand that I need to link the button to the content that I would like collapsed and shown.
I've tried to follow the Bootstrap documentation on collapsing elements. Unfortunately, as mentioned above, this has not yielded the expected result (Which I presume is due to the dynamic creation of my content).
HTML:
<pre><code>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="carsStyling.css">
<title>Weyland's Cars</title>
</head>
<body>
<div class="row">
<div class="col-md-4">
<h1>Hello World</h1>
<p>Welcome to Weyland's Cars</p>
</div>
</div>
<div id="card-space" class="row">
</div>
<script src="cars.js"></script>
</body>
</html>
JavaScript:
let cars = [];
function carCreator(make, model, colour, image, registrationNumber, price) {
this.make = make;
this.model = model;
this.colour = colour;
this.image = image;
this.registrationNumber = registrationNumber;
this.price = price;
cars.push(this);
}
let volkswagenPolo = new carCreator("Volkswagen", "Polo", "White", "https://source.unsplash.com/random/1920x1080", "ND 123 456", "R125 000");
let chevroletSpark = new carCreator("Chevrolet", "Spark", "Black", "https://source.unsplash.com/random/1920x1080", "ND 654 321", "R112 000");
let renaultClio = new carCreator("Renault", "Clio", "Red", "https://source.unsplash.com/random/1920x1080", "ND 456 789", "R225 000");
let kiaPicanto = new carCreator("Kia", "Picanto", "Grey", "https://source.unsplash.com/random/1920x1080", "ND 987 6546", "R185 000");
let fordFiesta = new carCreator("Ford", "Fiesta", "Orange", "https://source.unsplash.com/random/1920x1080", "ND 123 987", "R295 000");
cars.forEach(car => {
container = document.createElement("div");
container.className = "col-md-3";
card = document.createElement("div");
card.className = "card";
image = document.createElement("img")
image.className = "card-img-top"
image.src = car.image;
info = document.createElement("div");
info.className = "card-body";
title = document.createElement("h4")
title.className = "card-title"
title.innerHTML = car.make;
details = document.createElement("p")
details.className = "body-text"
details.innerHTML = "Model: " + car.model + "</br>" +
"Colour: " + car.colour + "</br>" +
"Registration: " + car.registrationNumber + "</br>" +
"Price: " + car.price;
details.id = "body-text-area"
collapse = document.createElement("a")
collapse.className = "btn btn-primary"
collapse.innerHTML = "Show More"
container.appendChild(card);
card.appendChild(image);
card.appendChild(info);
info.appendChild(title);
info.appendChild(details);
info.appendChild(collapse)
document.getElementById('card-space').appendChild(container);
})
Upvotes: 0
Views: 1665
Reputation: 22295
You have forgotten a lot of things in your code:
1: have a unique identifier for each 'content'
2: put the references useful for the collapse to work:
....a) details.className = 'body-text collapse';
... b) collapse.dataset.toggle = 'collapse'
...... collapse.setAttribute ('role', 'button')
...... collapse.setAttribute ('aria-expanded', 'false')
...... collapse.setAttribute ('aria-controls', 'body-text-area')
3: add the 3 JS libraries in the page!
... - jquery-3.2.1.slim.min.js
... - popper.min.js
... - bootstrap.min.js
otherwise, sorry, but I can not seem to find any logic in your way of coding, so I did it in my own way, I hope it will help you
class Cars {
constructor(ref) {
this.list = []; // do you really need a list ?
this.hmi_ref = ref;
// Bootstap : container type
this.BS = {}
this.BS.container = document.createElement('div');
this.BS.card = document.createElement('div');
this.BS.image = document.createElement('img');
this.BS.info = document.createElement('div');
this.BS.title = document.createElement('h4');
this.BS.details = document.createElement('p');
this.BS.collapse = document.createElement('a');
this.BS.info.appendChild( this.BS.title )
this.BS.info.appendChild( this.BS.details )
this.BS.info.appendChild( this.BS.collapse );
this.BS.card.appendChild( this.BS.image );
this.BS.card.appendChild( this.BS.info );
this.BS.container.appendChild( this.BS.card );
this.BS.container.className = 'col-md-3';
this.BS.card.className = 'card';
this.BS.image.className = 'card-img-top';
this.BS.title.className = 'card-title';
this.BS.details.className = 'body-text collapse';
this.BS.collapse.className = 'btn btn-primary';
this.BS.collapse.dataset.toggle ='collapse'
this.BS.collapse.textContent = 'Show More'
this.BS.collapse.setAttribute('role', 'button');
this.BS.collapse.setAttribute('aria-expanded', 'false');
this.BS.collapse.setAttribute('aria-controls', 'body-text-area');
}
add ( make, model, colour, image, registrationNumber, price)
{
this.list.push( {make, model, colour, image, registrationNumber, price } ) // for list, but why ?
let carID = 'car_' + this.list.length;
this.BS.image.src = image;
this.BS.title.textContent = make;
this.BS.details.id = carID;
this.BS.details.innerHTML = `Model:${model}</br>Colour:${colour}</br>Registration:${registrationNumber}</br>Price:${price}`;
this.BS.collapse.href = `#${carID}`;
let newNode = this.BS.container.cloneNode(true)
this.hmi_ref.appendChild( newNode );
// return carID; ?// ??
}
}
const CardSpace = document.getElementById('card-space');
let myCars = new Cars( CardSpace );
myCars.add('Volkswagen', 'Polo', 'White', 'https://source.unsplash.com/random/1920x1080', 'ND 123 456', 'R125 000');
myCars.add('Chevrolet', 'Spark', 'Black', 'https://source.unsplash.com/random/1920x1080', 'ND 654 321', 'R112 000');
myCars.add('Renault', 'Clio', 'Red', 'https://source.unsplash.com/random/1920x1080', 'ND 456 789', 'R225 000');
myCars.add('Kia', 'Picanto', 'Grey', 'https://source.unsplash.com/random/1920x1080', 'ND 987 6546', 'R185 000');
myCars.add('Ford', 'Fiesta', 'Orange', 'https://source.unsplash.com/random/1920x1080', 'ND 123 987', 'R295 000');
// console.log( myCars.list )
<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="row">
<div class="col-md-4">
<h1>Hello World</h1>
<p>Welcome to Weyland's Cars</p>
</div>
</div>
<div id="card-space" class="row"> </div>
Upvotes: 1