How to get a Table to display in a Popover?

Hi,

I’m new here and to website creation, Javascript etc. I’ve got Popovers working with basic HTML content (fantastic) but I’ve been unable to get a Table to display, even a simple one added to the data-bs-content attribute.

I’ve been trying to use the first solution on this Stackoverflow post (javascript - Putting table into Bootstrap popover - Stack Overflow) but it’s not working (I used a jQuery to Javascript converter, which seems to have converted okay):

I think I’m close but something’s missing. Can anyone help?

// to display Popovers
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'))
var popoverList = popoverTriggerList.map(function (popoverTriggerEl) {
 return new bootstrap.Popover(popoverTriggerEl)
})

//  for the Table
  document.querySelector('[data-bs-toggle=popover]').popover({
  content: document.querySelector('#myPopoverContent').html(),
  html: true
}).click(function() {
  document.querySelector(this).popover('show');
});

The CSS (“display: none” was switched off in the screenshot to show the table)

#myPopoverContent {
  display: none;
  float: right;
}

.popover {
  width: 700px;
}

You might find it easier to use a modal for your situation.

Thanks for the feedback The use is as a lightweight pop-up for extra info on various cells in a table (displaying a summary of information in a small table). I wouldn’t want to use a Modal for this.

The characteristics of a Popover exactly fits the requirements, so I’m hoping there’s a way to make this happen. It doesn’t need to be easy, though I wish it were. This seems to be the only issue that’s in the way of completing this website and getting this in place will be a huge improvement to the user-experience.

I’ll learn whatever JS, jQuery, CSS etc that’s required. Anyone?

Popovers are pretty useful. Have you checked what you have against the BS docs?

1 Like

Edit: Ignore this, I read it wrong, you wanted a table in a popover not a popover in a table. I need more coffee.

javascript:

var popover = new bootstrap.Popover(document.querySelector('.table-popover'), {
  container: 'body'
})

And these attibutes:

1 Like

I do it like this
https://popovers.bss.design/

Javascript

const popover = new bootstrap.Popover(document.querySelector('#pop'), {
	container:'body',
	title:'your title',
	html:true,
	content: (() => document.querySelector('#popoverTable'))
})
2 Likes

My bad, I too thought you meant a table in the popover, but you meant a popover inside a table so yes a Popover would be the best choice then.

One thing I do want to point out that will probably affect how this works is that the StackOverflow you’re trying to mimic is over 6 years old. Bootstrap is quite different from 6 years ago so you won’t want to follow everything that’s there exactly I’m sure.

Looks like the others have this covered so good luck!

1 Like

Oh man, this is perfect, works like a charm. A really truly big thankyou for helping out. Totally wrapped!

Just a couple of hopefully little issues if I may:

    • How to get the table to be non-visible on the page but visible when clicked? I tried display: none in the CSS and .click(function() { this.popover('show'); } at the end of the code you posted, but no luck.
    • How use or replicate linking? There a couple of tables which are repeated (within three Accordians). I understand that the hook would need to be a class rather than an ID but no luck with the code below (bare in mind that I have no idea what I’m doing BTW).
//how to make linkable
// get all of the .pop-sitn-infgun selectors (buttons)
var allPopInfGuns = document.querySelectorAll('.pop-sitn-infgun');

for (i = 1; i < allPopInfGuns + 1; i++) {
    window['popInfGun' + i] = new bootstrap.Popover(allPopInfGuns[i]), {
	container:'body',
	title:'Situations - Combine',
	html:true,
    placement: 'top',
	content: (() => document.querySelector('#table-sitn-infgun'))
})

Thank you (or anyone else) for any help!

Sounds like maybe adding it to an Accordion component would do what you want.

Sry, I may be explaining things very well. I’m referring to the “original” table referenced in the Popover, which is currently sitting at the bottom of the page. I don’t want it visible there, only in the Popover.

With the linking, when just using simple HTML content in the data-bs-content field, I could duplicate the button as a linked component and put it in a couple of other Tables. Being linked of course keeps any changes in synch. But I can’t do that with the this code:
const popover = new bootstrap.Popover(document.querySelector('#pop'), {
because it only picks up one element, with ID ‘pop’ (to reference kuligaposten’s code - name changed in mine).

Maybe a screen recording would be the way to go to make things clearer. I can do that later.

@MrGreggles

HTML markup

// html for the popover table wrap a div around the table
// with a class d-none
<div class="d-none">
	<div class="table-responsive" id="table-sitn-infgun">
		<table class="table">
			<thead>
				<tr>
					<th>Column 1</th>
					<th>Column 2</th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td>Cell 1</td>
					<td>Cell 2</td>
				</tr>
				<tr>
					<td>Cell 3</td>
					<td>Cell 4</td>
				</tr>
			</tbody>
		</table>
	</div>
</div>

If you want to style the popover
CSS

.popover {
  min-width: 276px;
  border-radius: 25px;
}

.popover-header {
  text-align: center;
  background-color: var(--bs-blue);
  color: white;
  border-radius: 25px 25px 0 0;
  border-bottom: 0;
}

Javascript

(function(document) {
	
	"use strict";
	
	let ready = (callback) => {
		if (document.readyState != "loading") callback();
		else document.addEventListener("DOMContentLoaded", callback);
	};

	ready(() => {

		[].slice.call(document.querySelectorAll('.pop-sitn-infgun')).forEach(trigger => {
			new bootstrap.Popover(trigger, {
				container:'body',
				placement: 'top',
				title:'Situations - Combine',
				html:true,
				content: () => document.querySelector('#table-sitn-infgun')
			});
		});
		
	}); // end document.ready

})(document); // End of use strict	

here is an example with tables in a accordion

1 Like

A big thank you once again. I’ve learnt some interesting JS and modern coding style from that code. It (almost) works in that it works for the first clicked button but not with the second button (only the header shows).

Here’s a vid which covers the set up and issue, should you be willing to take a look. :slight_smile:

P.S. Oooh, a really low video res but should be viewable.

You can replace the javascript with this, in the example I used different tables in each popover.

(function(document) {
	
	"use strict";
	
	let ready = (callback) => {
		if (document.readyState != "loading") callback();
		else document.addEventListener("DOMContentLoaded", callback);
	};

	ready(() => {

		[].slice.call(document.querySelectorAll('.pop-sitn-infgun')).forEach(trigger => {
			new bootstrap.Popover(trigger, {
				container:'body',
				placement: 'top',
				title:'Situations - Combine',
				html:true,
				content: () => document.querySelector('#table-sitn-infgun').cloneNode(true)
			});
		});
		
	}); // end document.ready

})(document); // End of use strict	
1 Like

A deep clone - yes, that did it. Thank you! I think the way is clear to get this part of the site finished now. I couldn’t have done without help. I’ll post a quick vid once it’s all in place, likely this weekend.