Skip Navigation

[Resolved] Bootstrap 4 carousel with several (post) columns on each slide

This thread is resolved. Here is a description of the problem and solution.

Problem:
The native Bootstrap Carousel will display on each slide one piece of information (we could easily rebuild that in a View loop, but it would always display one post each slide).
What if we want a column structure in each slide, each column representing one post?

Solution:
You would work with 2 post types.
- A "Slides" Post Type (those are the "containers" which hold the columns, hence, the Bootstrap 4 slide items).
- A "Display" post type where you store the information you want to display in each column of each slide (traditionally that would be the posts you want to display in the slider).

The Slides post type is a parent to the Display post type, where you can exactly that many Display posts to a Slide, as you will have columns in each slide.
For example, a 3 column slide means you will have max 3 child Display Posts each Parent Slide Post.

After creating the posts and connections, create a View where you query Slides, and output a raw View loop where you generate the HTML for the Bootstrap 4 slides.
Note that the View LOOP will repeat what is inside the wpv-loop shortcode and hence, you will add the Bootstrap HTML adequately wrapping that Loop and adding IN the loop only the HTML for the slides, but not their content (columns and Display post information). Pay attention to pass a active class by default to the first slide!

The loop of this view should look something like this:

<wpv-loop>
            [wpv-item index=1]
              <div class="carousel-item active">
                //insert Child View here
              </div>
            [wpv-item index=other]
              <div class="carousel-item ">
                //insert child view here
              </div>
          </wpv-loop>

Now create another view for the Display post type, add a query filter to display the Display Posts that are a child to the post set in the parent view, and add in this View loop the HTML for EACH Display Post.
This means, the columns and post Display information is inserted in this loop, which also should be returned raw.

This view is now inserted to the View displaying Slides.
That is the type you will query in the View where you build the slides.

When now the slides view is inserted to a page, you'll see a slider that each slide has N columns (as many you chose to have) each displaying particular post data.

Follow the thread below in detail for a real-life example with the code for the loops, particularly https://toolset.com/forums/topic/boostrap-4-carousel-is-not-working/#post-1301915

This support ticket is created 5 years, 5 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- - 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00
- - - - - - -

Supporter timezone: Asia/Ho_Chi_Minh (GMT+07:00)

This topic contains 6 replies, has 2 voices.

Last updated by Tcoffee 5 years, 5 months ago.

Assisted by: Beda.

Author
Posts
#1301879

I am trying to: create a team member section thumbnail carousel using bootstrap 4 and views

Link to a page where the issue can be seen:hidden link

I expected to see: hidden link

Instead, I got: only the values, the carousel is not working: hidden link

My view look like this:

[wpv-layout-start]
	[wpv-items-found]
<div class="container my-4" id="team-carousel">
        <!--Carousel Wrapper-->
        <div id="multi-item-example" class="carousel slide carousel-multi-item" data-ride="carousel">  
      <div class="controls-top">
         <a class="btn-floating controls-left" href="#multi-item-example" data-slide="prev"><i class="fa fa-chevron-left"></i></a>
         <a class="btn-floating controls-right" href="#multi-item-example" data-slide="next"><i class="fa fa-chevron-right"></i></a>
      </div>
         <!--Slides-->
      <div class="carousel-inner" role="listbox">
         <div class="carousel-item active" id="home-team">
               <div class="row">
	<!-- wpv-loop-start -->
		<wpv-loop>
                        <div class="col-md-4">
                            <div class="card mb-2">
                                <a href="[wpv-post-url]">
                               [types field='profile-picture' title='%%TITLE%%' alt='%%ALT%%' size='full' class='card-img-top'][/types]
                                <div class="card-body">
                                    <h4 class="card-title">[wpv-post-title]</h4>
                                    <p class="card-text">[types field='specialization'][/types]</p>
                                </div>
                                </a>
                            </div>
                        </div>
		</wpv-loop>
	<!-- wpv-loop-end -->
          </div>
           </div>
         </div>
          </div>
	[/wpv-items-found]
	[wpv-no-items-found]
		<strong>[wpml-string context="wpv-views"]No items found[/wpml-string]</strong>
	[/wpv-no-items-found]
[wpv-layout-end]
#1301905

I see there are many JS errors (around 25) in the console.
I would suggest trying to resolve those because I see many errors related to precisely Bootstrap and dependencies.
It seems something is blocking core scripts from loading, as you can see in the errors list

Most of the errors seem because of the theme and the revslider plugin.
I see the slider is working but not as expected, it slides one image in place of 4 all the way of the slider.

I think after resolving the errors, this will look better.

Also, when you manipulate core Bootstrap Code like that (substitute the usually manually crafted content with a View loop) I suggest to check the "Disable the wrapping DIV around the View" checkbox under the View loop, so you can be certain ONLY the HTML is returned you need, as otherwise, an entire DIV with data from the loop is passed to the structure, and that can break the carousel.

Locally this works fine, but you need to properly dissect the code and add wpv-item index ShortCodes to pass the right active class as well to the Bootstrap.
(note, this is a very minimal example)

[wpv-layout-start]
  [wpv-items-found]
    <!-- wpv-loop-start -->
      <div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
        <div class="carousel-inner">
          <wpv-loop>
            [wpv-item index=1]
              <div class="carousel-item active">
                THIS[wpv-post-featured-image]
              </div>
            [wpv-item index=other]
              <div class="carousel-item ">
                THIS[wpv-post-featured-image]
              </div>
          </wpv-loop>
        </div>
  
        <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
          <span class="carousel-control-prev-icon" aria-hidden="true"></span>
          <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
          <span class="carousel-control-next-icon" aria-hidden="true"></span>
          <span class="sr-only">Next</span>
        </a>
      </div>
    <!-- wpv-loop-end -->
  [/wpv-items-found]

  [wpv-no-items-found]
    <strong>[wpml-string context="wpv-views"]No items found[/wpml-string]</strong>
  [/wpv-no-items-found]
[wpv-layout-end]

Note, the carousel is made in the example of Bootstrap with relatively big images, so if you use the Featured Image as I did above it will not look as good as the Bootstrap example which uses big images.

Please let me know if I missed something crucial.

#1301911

Hi,
I had checked the console and I can't see any javascript dependencies for this to work : hidden link

Regarding view, I had actually used the following code with index:

[wpv-layout-start]
	[wpv-items-found]
 <div class="container my-4" id="team-carousel">
        <!--Carousel Wrapper-->
        <div id="multi-item-example" class="carousel slide carousel-multi-item" data-ride="carousel">
      <div class="controls-top">
         <a class="btn-floating controls-left" href="#multi-item-example" data-slide="prev"><i class="fa fa-chevron-left"></i></a>
         <a class="btn-floating controls-right" href="#multi-item-example" data-slide="next"><i class="fa fa-chevron-right"></i></a>
      </div>
      
            <!--Slides-->
            <div class="carousel-inner" role="listbox">
	<!-- wpv-loop-start -->
	<wpv-loop wrap="2" pad="true">
		[wpv-item index=1]
		<!--First slide-->
                <div class="carousel-item active" id="home-team">
                    <div class="row">
			 <div class="col-md-4">
                            <div class="card mb-2">
                                <a href="[wpv-post-url]">
                                [types field='profile-picture' title='%%TITLE%%' alt='%%ALT%%' size='full' class='card-img-top'][/types]
                                <div class="card-body">
                                    <h4 class="card-title">[wpv-post-title]</h4>
                                    <p class="card-text">[types field='specialization'][/types]</p>
                                </div>
                                </a>
                            </div>
                        </div>
                       </div>
                        </div>
		[wpv-item index=other]
			<div class="carousel-item" id="home-team-two">
              <div class="row">
               <div class="col-md-4">
                            <div class="card mb-2">
                                <a href="[wpv-post-url]">
                                [types field='profile-picture' title='%%TITLE%%' alt='%%ALT%%' size='full' class='card-img-top'][/types]
                                <div class="card-body">
                                    <h4 class="card-title">[wpv-post-title]</h4>
                                    <p class="card-text">[types field='specialization'][/types]</p>
                                </div>
                                </a>
                            </div>
                        </div>
			</div>
		</div>
	</wpv-loop>
	<!-- wpv-loop-end -->
	[/wpv-items-found]
	[wpv-no-items-found]
		<strong>[wpml-string context="wpv-views"]No items found[/wpml-string]</strong>
	[/wpv-no-items-found]
[wpv-layout-end]

After making it this way I got the current output, but still not what I'm looking for.

can you help me on this, please let me know what I'm missing?

#1301915

Well, I saw that jquery was not loaded and many errors are related to jquery on the screen.
Not only font awesome, but something around 23 errors where visible, now only 11 remains, related to font awesome and other woff files.

As I elaborated, Bootstrap uses images fitting the container of the slider, as you can see here hidden link

Your image is not wide enough to cover the slider area, and something seems to produce a second loop.
I tested Bootstrap carousel as shown above, and it works, can you try that code and then complete it with content as required?

We cannot help crafting HTML - but we can surely analyse and help to find the issue or report a bug if there is one.
Right now, with the proposed code of Bootstrap 4 doc, and enabling Bootstrap 4 in Toolset, and loading a Theme that does not overwrite it, it works.

It does not seem to me that your code, even if outside a view, would work. See, I understand that instead of one big slider item as the default of Bootsrap 4 shows in the example, you want to use cards in a column structure and slide hence several items each slide item.
This requires some additional things wich could not be done with native Bootstrap out of the box like that, unless of course you hardcode the loops.

Natively, not using Views to produce the "loop" in the Bootstrap Carousel you'd do this:

<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
  <div class="carousel-inner">
    <div class="carousel-item active">
      [wpv-post-featured-image]
    </div>
    <div class="carousel-item">
      [wpv-post-featured-image]
    </div>
    <div class="carousel-item">
      [wpv-post-featured-image]
    </div>
  </div>
  <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true">Back</span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true">Forward</span>
    <span class="sr-only">Next</span>
  </a>
</div>

The problem is, as you can notice, Bootstrap 4 by default will assume a certain width of the content.
Carousels don’t automatically normalize slide dimensions. As such, you may need to use additional utilities or custom styles to appropriately size content.

That said, it's possible to insert the below structure to a Carousel, but here we get a second loop:

<div class="row">
    <div class="col-sm">
      One of three columns
    </div>
    <div class="col-sm">
      One of three columns
    </div>
    <div class="col-sm">
      One of three columns
    </div>
</div>

Those Columns will align next to each other as expected within each one slide.

Now we can populate each of the columns with a single post item - but here you have a problem because you build already one loop (the actual slide) with the view and that is your single post, not every single column, but each set of single columns in a slide represents a post, in the View, since its within the loop.

What you can do is build a Parent Post "Slides", and use that Post to create the slides - then, every single item that you want to display (grouped by 3) would be your current post type.

You should assign each of your current posts to a particular parent "slide", where a maximum is 3 (or as many you plan to display in each slide).
Then you create a View, that shows all slides, and in that View you add the code for the Bootstrap carousel.
But instead of populating the Loop with the Columns and single items, here you'd insert a second view.

This other View should query all posts that are a child to the parent slide of the parent View, and produce the Columns with single Posts in the loop.
Since there will be maximally 3 (or your chosen amount) of child posts, the view will always return the right amount of columns.

This view, inserted to the parent view loop, will produce the 3 column setup with each column a post.
The parent view will produce the slide, which has its content from the View in the loop.

Both views should have the checkbox "Disable the wrapping DIV around the View" checked, and I would suggest, to begin with minimal setup as shown below, and then gradually add HTML to it

In the parent View loop:

[wpv-layout-start]
  [wpv-items-found]
    <!-- wpv-loop-start -->
      <div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
        <div class="carousel-inner">
          <wpv-loop>
            [wpv-item index=1]
              <div class="carousel-item active">
                //insert Child View here
              </div>
            [wpv-item index=other]
              <div class="carousel-item ">
                //insert child view here
              </div>
          </wpv-loop>
        </div>
   
        <a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
          <span class="carousel-control-prev-icon" aria-hidden="true"></span>
          <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
          <span class="carousel-control-next-icon" aria-hidden="true"></span>
          <span class="sr-only">Next</span>
        </a>
      </div>
    <!-- wpv-loop-end -->
  [/wpv-items-found]
 
  [wpv-no-items-found]
    <strong>[wpml-string context="wpv-views"]No items found[/wpml-string]</strong>
  [/wpv-no-items-found]
[wpv-layout-end]

In the Child View:

[wpv-layout-start]
	[wpv-items-found]
	<!-- wpv-loop-start -->
<div class="row">
		<wpv-loop>
    			<div class="col-sm">
      				What you want to display for each item (Bootstrap Card with Image etc)
    			</div>
		</wpv-loop>
</div>
	<!-- wpv-loop-end -->
	[/wpv-items-found]
	[wpv-no-items-found]
		<strong>[wpml-string context="wpv-views"]No items found[/wpml-string]</strong>
	[/wpv-no-items-found]
[wpv-layout-end]
#1301925

hi,
i didn't understand this portion completely:

What you can do is build a Parent Post "Slides", and use that Post to create the slides - then, every single item that you want to display (grouped by 3) would be your current post type.

You should assign each of your current posts to a particular parent "slide", where a maximum is 3 (or as many you plan to display in each slide).

Can you please give an example

#1301927

Sure, you would create another post type "Slides".
That is the type you will query in the View where you build the slides.

That Slide Post type is a parent to the current post of which you display data in your current code (let's assume those are native posts)
Those posts should all be the child to the proper parent post of type Slide.
Each Slide post would hence have 3 child post if you want a 3 column output, or 4, if it should be 4 columns, etc.

You can read more about post relationships here:
https://toolset.com/documentation/post-relationships/

You need a One To Many relationship between the Slide and posts, where the "many" (posts) parts are limited to the number of columns each slide you need (3 in your case)
In that relationship, Slider Post type is the parent and the child is the post of which you want to show content in each slide (for each col) which I assumed to be posts.

#1303341

My issue is resolved now. Thank you!