Building a custom shadowDOM with a dynamic bootstrap dropdown menu using JavaScript

As I work on developing a Chrome extension, I found myself in need of incorporating the split-button feature provided by Bootstrap within a shadow DOM. Despite my efforts, I have not been able to find clear guidelines on how to achieve this. Can anyone provide insights on creating a shadow DOM that integrates the necessary Bootstrap CSS, JS, and Popper JS files?

I attempted the following approach but unfortunately, the button did not appear:

const shadowHost = document.getElementById('my-shadow-host');
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });

  // HTML for Bootstrap button and dropdown menu
const bootstrapButtonAndDropdown = `
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <div class="btn-group">
    <button type="button" class="btn btn-primary">Bootstrap Button</button>
    <button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      <span class="sr-only">Toggle Dropdown</span>
    </button>
    <div class="dropdown-menu">
      <a class="dropdown-item" href="#">Action</a>
      <a class="dropdown-item" href="#">Another action</a>
      <a class="dropdown-item" href="#">Something else here</a>
      <div class="dropdown-divider"></div>
      <a class="dropdown-item" href="#">Separated link</a>
    </div>
  </div>
`;

  // Inject Bootstrap components into the shadow root
  shadowRoot.innerHTML = bootstrapButtonAndDropdown;

  // Set up an event listener for the button inside the Shadow DOM
  const buttonInsideShadowDom = shadowRoot.querySelector('.btn-primary');
  buttonInsideShadowDom.addEventListener('click', () => {
    alert('Button inside Shadow DOM clicked!');
  });

class SplitButton extends HTMLElement {
  constructor() {
    super();
    this.render();
  }

  render() {
    this.attachShadow({ mode: "open" });
    this.shadowRoot.innerHTML += template;
  }
}

window.customElements.define("split-button", SplitButton);

Trying to call the split button:

const button = document.createElement('split-button');

However, the button appears as null.

Answer №1

Your code has been revised for clarity. Please note that you will not be adding multiple listeners, so there is no need for addEventListener

<split-button></split-button>
<script>
  customElements.define("split-button", class extends HTMLElement {
    constructor() {
      super().attachShadow({
        mode: "open"
      }).innerHTML = `<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <div class="btn-group">
    <button type="button" class="btn btn-primary">Bootstrap Button</button>
    <button type="button" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      <span class="sr-only">Toggle Dropdown</span>
    </button>
    <div class="dropdown-menu">
      <a class="dropdown-item" href="#">Action</a>
      <a class="dropdown-item" href="#">Another action</a>
      <a class="dropdown-item" href="#">Something else here</a>
      <div class="dropdown-divider"></div>
      <a class="dropdown-item" href="#">Separated link</a>
    </div>
  </div>`;
      this.shadowRoot.querySelector('.btn-primary').onclick = () => alert('Button inside Shadow DOM clicked!');
    }
  });

</script>

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

Error 404 encountered while attempting to access dist/js/login in Node.JS bootstrap

I currently have a web application running on my local machine. Within an HTML file, I am referencing a script src as /node_modules/bootstrap/dist/js/bootstrap.js. I have configured a route in my Routes.js file to handle this request and serve the appropri ...

What is the best way to retrieve a particular variable from an ng-repeat loop?

I'm currently working on a task where I have an ng-repeat loop that generates multiple dropdowns. Each dropdown is associated with a unique ID generated by the controller for reference purposes. The issue I am facing is that when a user selects an op ...

Apply a specific image layout once the drop event occurs

I have a container with 5 image pieces that need to be dropped into another container to complete the image. Once an image is dropped, I want to apply the style "position:absolute" so that it sticks to the previous image in that container. Although I have ...

- Aligning list items using UL bullet style

I'm having trouble aligning my ul dropdown with the rest of my menu. Even after removing the Bullet from my ul dropdown, it still maintains its position (I expected it to move all the way to the left side of the page). I've attempted various st ...

Incorporating YouTube links into calendar events for each specific date

Our team is currently developing an online class website where our client wants to incorporate recorded classes. These recorded classes will be uploaded to YouTube in unlisted format and then linked to specific calendar dates. I will share the code for the ...

Positioning the footer to sit at the bottom of my webpage, leaving a pleasing margin at the top

One technique I frequently use to ensure my footer stays at the bottom of my page is by utilizing an empty div. Here's how the code looks: <body> <div id="canevas"> <article>My website's content</article> ...

An issue arises when attempting to initialize an AngularJS global variable using a REST service

I am looking to establish a global variable called httpTimeout that will be initialized at the beginning. This variable will contain a Long value retrieved from a synchronous Rest Service call and will be utilized in various services. ( function () { &apo ...

Invalid file name detected during the download process

Below is the Javascript code I currently use to download a pdf: var link = document.createElement('a'); link.innerHTML = 'Download PDF file'; link.download = "Report.pdf"; link.href = 'data:application/octet-stream;base64 ...

Issue with the JQuery Lightbox 2 Plugin

I'm currently in the process of developing a gallery using jQuery Lightbox 2 (visit the plugin page here). I am encountering an issue where the navigation entries remain visible even when an image is selected (view example here). The navigation is cre ...

React typescript props not appearing as potential defined, even after implementing the '?' optional operator and '| undefined'

I've noticed that my linter has suddenly stopped flagging potentially undefined properties passed into my React components. For instance: interface BooleanTypeObject { prop1: true } interface MyComponentProps { disable ...

Activating a function on a click or item selection in React using Office UI Fabric's

<div> <CommandBar areNamesVisible={false} areIconsVisible={true} items={[ { name:"James Towns", className:"noHoverEffect", }, { key:"Info", icon:"Contact", onItemClick={this.handlePanel} ...

Updating input value using v-model in Vue.js does not reflect changes

I'm struggling with formatting numbers that I input in an HTML text box. I have a function that is supposed to format the number when I click out of the input box, but the updated value is not reflected in the v-model. The function is working correct ...

Using jQuery, transform JSON into an array

After running my PHP code, I have the following result: $result = '[{"MFG_NAME":"ABC","CONCATED_MKT_SHARE":"01-MAR-14|0.59"},{"MFG_NAME":"XYZ","CONCATED_MKT_SHARE":"01-MAR-14|0.87"},{"MFG_NAME":"ABC","CONCATED_MKT_SHARE":"01-APR-14|0.25"},{"MFG_ ...

The jQuery Modal Dialog functions properly on the initial page load, but fails to work on subsequent pages unless manually refreshed

So, I've encountered an issue with my jQuery modal dialog. It's set up to remind non-registered users to sign up when they try to access user-only actions. Oddly enough, the dialog functions perfectly after a page refresh on THAT specific page. H ...

Reveal a segment of a picture

Is there a way to display only a section of an image using either jQuery or another JavaScript method? For example: image: [ ] [ -------- ] [ - - ] [ - part - ] [ - - ] [ -------- ] [ ...

Slice an interactive div

I am currently working on setting up a horizontal sliding div for a menu. The layout consists of a left DIV that remains visible at all times, and a sliding DIV that appears horizontally when the menu is activated. My HTML code looks like this. <div id ...

Div element obstructing the ability to view markers

Issue with a positioned DIV over Google Maps: The DIV is causing accessibility problems for the map, taking up the entire width when it should stop at the green square borders. Interaction with the map is limited to the very bottom after the green square. ...

Execute a batch operation or transaction within a Cloud Firestore onCreate trigger

Imagine a scenario where I have a collection of vendor documents in firestore: vendors : { vendor1: { id: "vendor1", name: "John", shopId: "shop1" }, vendor2: { id: "vendor2", name: "Mary", shopId: "shop2" } } Additionally ...

What steps can be taken to properly display dateTime values in a data table when working with JavaScript (VueJS) and PHP (Laravel)?

I am facing an issue where I am unable to save user inputted date-time values from a modal into a data table. Despite receiving a success message, the dateTime values are not being added to the table. My payload only displays the state and approval fields ...

What steps can I take to ensure my header appears perfectly aligned? (HTML/CSS)

My header on my website is all messed up with the links appearing incorrectly. I suspect it's an issue with style.css, so I attempted to modify the style.css file but had no luck. I have very limited experience with .css and cannot seem to figure out ...