Thymeleaf - How to iterate list of objects in multiple columns of html with Bootstrap 4.5.0+ - spring-mvc

I have the following in Thymeleaf template:
<div class="row col-md-12">
<div th:each="item : ${itemList}">
<div class="col-md-3">
<div class="card custom-card"
style="width: 15rem; display: inline-block">
<div class="card-body">
<h5 class="card-title" th:text="${'item Id - ' + item.id}">Id</h5>
<p class="card-text" th:text="${item.itemname}">Name</p>
<p class="card-text" th:text="${item.itemdescription}">Desc</p>
<a th:href="#{'/createforItemId/' + ${item.id}}"
class="stretched-link btn btn-sm btn-primary mr-2"><i
class="fas fa-rocket mr-2"></i> Start New Discussion</a>
</div>
</div>
</div>
</div>
</div>
I am trying to iterate the itemList in such a way that each row in my html should have 4 cards in 4 columns (12/3).
But currently I am getting only one "Single" column (huge) stacked with my list of objects.
What I am missing here?
I am open for any alternative solution too. Please suggest.

ODD but I got a workaround and is pretty much what I wanted. The following did the trick for me (notice the table without <td></td>):
<table style="width: 100%">
<tr th:each="item : ${itemList}">
<div class="card custom-card text-center mr-2 mt-2 ml-2 mb-2"
style="width: 15rem; display: inline-block">
<div class="card-body">
<h5 class="card-title" th:text="${'item Id - ' + item.id}">Id</h5>
<p class="card-text" th:text="${item.itemname}">Name</p>
<p class="card-text" th:text="${item.itemdescription}">Desc</p>
<a th:href="#{'/createforItemId/' + ${item.id}}"
class="stretched-link btn btn-sm btn-primary mr-2"><i
class="fas fa-rocket mr-2"></i> Start New Discussion</a>
</div>
</div>
</tr>
</table>
I am getting nice looking 4 columns with 4 cards with this css to add rounded borders for the boxes/cards:
.custom-card {
border-radius: 20px;
}
However, I am still waiting for some expert's suggestion here as the solution I came up with looks more like a patch work instead of a clean solution.

You should be able to include the th:each one level up to create 4 cards in a 12 slot row by col-xl-3.
<div class="row">
<div class="col-xl-3" th:each="item : ${itemList}">
<div class="card">
<!-- other stuff -->
</div>
</div>
</div>
It is similar to this later posted question that uses 3 cards instead of 4.
A solution like you have that uses a <div> in the <tr> will have your IDE complain that <div> is not a valid element in that location.
Note that you may still need to constrain the height of the card if they are not of the same size.

Related

How can I make multiple items appear on a bootstrap 5 carousel slide?

I have a bootstrap 5 carousel with controls. My desired output is a slideshow with 2 items per slide and I would like to scroll through one image at a time.
From here:
To here:
The problem with solutions I have found which use the bootstrap grid system like the ones posed on this topic are that they rely on the correct multiple of items to work and they scroll two items per click, not one. A lot of the solutions I have found online are buggy or overcomplicated.
Is there a simple way to achieve this?
you mean like this ?
<div id="carouselExample" class="carousel slide">
<div class="carousel-inner">
<div class="carousel-item active ">
<div class="col-12 row">
<div class="col-6" style="background-color: yellow; height: 10vh;"></div>
<div class="col-6 " style="background-color: blue; height: 10vh;"></div>
</div>
</div>
<div class="carousel-item">
<div class="col-12 row">
<div class="col-6" style="background-color: red; height: 10vh;"></div>
<div class="col-6 " style="background-color: green; height: 10vh;"></div>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExample" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExample" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>

Products Pulled in from JSON not displaying in a grid

I am pulling in content from a JSON file to populate a grid of products for an eCommerce website I'm working on. when the data loads it displays all the products in 1 column or (1 row) instead of in a grid. All the CSS for this part of from default Bootstrap 4 values. I need your assistance to go about this.
Thanks
Here is the code to display them on a page I called "products"
<div class="product container d-flex justify-content-center mt-50 mb-50">
<div class="card">
<div class="card-body">
<div class="card-img-actions"> <img src="{{product.imageUrl}}" class="card-img img-fluid" width="96" height="350" alt=""> </div>
</div>
<div class="card-body bg-light text-center">
<div class="mb-2">
<h6 class="font-weight-semibold mb-2"> <a routerLink="/products/{{product.id}}" class="text-default mb-2" data-abc="true">{{product.title}}</a> </h6>
</div>
<h3 class="mb-0 font-weight-semibold">{{product.price}}</h3>
Available in size: {{product.size}}
<button type="button" class="btn bg-cart"> Buy Now </button>
</div>
</div>
</div>
Then below is what I have on the products.components.html
<app-header></app-header>
<app-item *ngFor="let product of products" [product]= "product"></app-item>
<app-footer></app-footer>
This is the expected result I want to acheive
Here is what I am getting
enter image description here
I think you did not follow the bootstrap principles of how to construct a card grid.
When you put your .container class into the app-item, you will create a new container on each loop, which you don't want I guess. Instead you only want one container and then the cards as columns.
See https://getbootstrap.com/docs/5.1/components/card/#grid-cards
<app-header></app-header>
<div class="container">
<div class="row row-cols-md-3">
<ng-container *ngFor="let product of products">
<app-item [product]="product"></app-item>
</ng-container>
</div>
</div>
<app-footer></app-footer>
And in your app-item you only have columns.
<div class="product col">
<div class="card">
...
</div>
</div>

BULMA: How to get equal width for first column? Only by using a table?

building a web page using Bulma I want to display several events in this way:
<div class="card" style="background: lightgreen;">
<div class="card-header p-4">
<div class="is-flex is-flex-direction-row ">
<div class="has-text-right pr-4 is-one-quarter" style="white-space: nowrap;">
<strong>[1st column]</strong><br/>
See https://codepen.io/baschtl/pen/PobXamm
But I want to have the first column for each "row/line" always have the equal width.
But maybe this would be only possible by using the good, old TABLE element [https://bulma.io/documentation/elements/table/] and not columns or something else, too?
Thanks a lot!
mtemp
You can fix the width of the first column with is-x class which can be is-1 to is-12.
<div class="columns">
<div class="column is-1"></div>
<div class="column"></div>
</div>
I'm not familiar with this framework but this is pretty simple to do in CSS.
You could add a class with width to each first element like this
.width-fix{
width:10rem;
}
Your html (minus white-space:nowrap and added width-fix class):
<div class="card" style="background: lightgreen;">
<div class="card-header p-4">
<div class="is-flex is-flex-direction-row ">
<div class="width-fix has-text-right pr-4 is-one-quarter">
<strong>[1st column]</strong><br/>
Saturday<br /><strong>27th May 2022</strong>
</div>
<div class="pr-4" style="min-width: 80px;">
<strong>[2nd column]</strong><br/>
<a href="#" target="_blank">
<figure class="image is-128x128">
<img class="is-rounded" src="https://bulma.io/images/placeholders/128x128.png">
</figure>
</a>
</div>
Also keep in mind that using table isn't bad if you actually need a table, so you could also consider that.

Bootstrap two column misalignment

I am trying to create a simple two column layout, but for some reason, some of the cells get skipped. (see: https://imgur.com/a/FE2ZwKY). I am using Laravel to get the products from the DB using a foreach loop. The code for one product looks like this:
<div class="col-md-6 mt-4">
<div class="card">
<img src="{{asset('storage/app/public/cover_images/'.$product->cover_image)}}" class="img-fluid" alt="">
<div class="card-content">
<div class="row">
<div class="col-md-6">
<h6 class="text-center">ROMÂNĂ</h6>
<h4 class="mt-4 text-center">
<b>{{$product->name_ro}}</b></h4>
<p>{{$product->desc_ro}}</p>
</div>
<div class="col-md-6">
<h6 class="text-center">ENGLISH</h6>
<h4 class="mt-4 text-center">
<b>{{$product->name_en}}</b></h4>
<p>{{$product->desc_en}}</p>
</div>
</div>
<h5 class="text-center">Pret: <b>{{$product->price}}</b>
</h5>
<hr>
<div class="button-wrapper">
<a href="{{url('/products/'.$product->id.'/edit/')}}">
<button type="submit" class="btn btn-warning">Editeaza</button></a>
<form action="{{ action('ProductsController#destroy', $product->id) }}" method="post">
#csrf
<input name="_method" type="hidden" value="DELETE">
<button type="submit" class="btn btn-danger">Sterge</button>
</form>
</div>
</div>
</div>
The code above is generated for every product there is. Any help is welcome, thanks!
a problem could be, that your <h4> text is not always the same length.
The headlines are pushing the content, and the cards are receiving different height values.
If you set a fixed height for h4, your problem is maybe solved.

Bootstrap 4 center header elements on mobile

Here is my header setup (bootstrap 4):
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="navbar-brand"><img src="..."></div>
</div>
<div class="col-md-6 text-right">
<div class="header-btn-grp">
<div class="header-call-us">Get a Quote, Call Today!</div>
<a role="button" class="btn btn-danger btn-lg header-btn" href="tel:123">Ph : <strong>...</strong></a>
<div class="header-address">XXX</div>
</div>
</div>
</div>
As expected on desktop the logo sits on the left and the button sits on the right.
When on smaller devices I would like the logo and button to align in the center.
I have tried to add a .text-md-center class to both columns but this caused both elements to center in there columns at all widths (desktop and mobile).
What is the correct way to do this?
An alternate to #cwanjt answer is using the text-center. You just then need to use text-md-left and text-md-right to keep the desired alignment on larger widths.
<div class="container">
<div class="row">
<div class="col-md-6 text-md-left text-center">
<div class="navbar-brand"><img src="//placehold.it/140x30"></div>
</div>
<div class="col-md-6 text-md-right text-center">
<div class="header-btn-grp">
<div class="header-call-us">Get a Quote, Call Today!</div>
<a role="button" class="btn btn-danger btn-lg header-btn" href="tel:123">Ph : <strong>...</strong></a>
<div class="header-address">XXX</div>
</div>
</div>
</div>
</div>
https://www.codeply.com/go/Ijl31XHfRT
#TimothyAURA, if I'm understanding you question correctly, it's how to center the content of your header on smaller screens. If that's the case, you can look at the code in this codeply project to get an idea of how to do that. It seems like you have some familiarity with Bootstrap, but here's a reference to Bootstraps utilities for justifying content.
It uses a justify-content-center class for device sized medium and below, and a justify-content-lg-between on larger displays.
<header class="d-flex justify-content-center justify-content-lg-between">
<a class="navbar-brand" href="#">
<img src="http://via.placeholder.com/65x65" alt="">
</a>
<div class="header-btn-grp">
<div class="header-call-us">Get a Quote, Call Today!</div>
<a role="button" class="btn btn-danger btn-lg header-btn" href="tel:123">Ph : <strong>...</strong></a>
<div class="header-address">XXX</div>
</div>
</header>

Resources