Grab Bubble-groups and move them in the DOM?

Plugin geeks / Bubble reverse-engineers,

What are the limits to manipulating the DOM from within a plugin?


I want to create a CSS grid and populate it with Bubble elements.

I created a plugin that:

  1. creates an HTML element, gives it a display: grid;
  2. iterates over a list of texts, trying to find an element on the page with that text as an id.

That works, the CSS works and its displayed properly.

This is the dashboard of a team. When I switch teams, that team might have different amounts widgets – one of the sources is a repeating group.

I might go from teamA with the following widgets:

  • gauge
  • rg_item1
  • rg_item2

to teamB:

  • gauge
  • rg_item1

However, rg_item2 still shows up in teamB’s dashboard.

I tried a few approaches that didn’t work:

  • destroy rg_item2 → I hoped that Bubble would look in the DOM, realize that the item was not there and recreate it, but it doesn’t.
  • move rg_item2 back to its original parent → I hoped that Bubble would just re-establish the connection, but it doesn’t.

Any ideas?

1 Like

I’m curious as to why you would try and manipulate the DOM and not just use internal conditions?

If team B then this. If team A then this?

I did a poor job explaining myself. Maybe this loom explains it a bit better:

1 Like

Sounds like an interesting project.

I probably misunderstood what you were wanting to do.

I had read it and thought you wanted to show/hide certain elements if Team A was logged in…and hide/show elements if Team B was logged in.

This was why I thought using JavaScript to write internal conditions would be a good approach.

Hope you get it working the way you want.

Maybe I don’t fully understand what you’re trying to accomplish.

But why are you creating a new HTML element? Can’t you just throw all of the elements in a group in the editor, then update the CSS on that parent group adding a rule display: grid !important;

I tried that in a few different ways and it wouldn’t let me, it would wipe the extra styling.

But I only tried this with Classify’s style tag, not with an actual class.

@rico.trevisan You shouldn’t have a problem modifying the DOM to manipulate elements on the page. Removing an element entirely from the DOM is likely going to cause you trouble (or at least additional work). Showing or hiding is easier to deal with, however it could cause browser memory or performance issues with large amounts of data.

Remember you can use the Toolbox plugin - Run Javascript in a workflow to manipulate the DOM as well (you don’t need a plugin). We do this often for specialized functionality such as custom drag and drop. jQuery should be your best friend and is probably the fastest and simplest method since it is already included with Bubble.

let items = document.querySelectorAll('#rg_reordercontacts > div')

items.forEach(item => {
  $(item).prop('draggable', true)
  $(item).attr('dropzone', true)

  item.addEventListener('dragstart', dragStart)
  item.addEventListener('drop', dropped)
  item.addEventListener('dragenter', cancelDefault)
  item.addEventListener('dragover', cancelDefault)
})

Consider the above javascript using a DOM selector to target all children items in a Bubble RG with the id “#rg_redordercontacts” so that we can add drag/drop capabilities.

Try with just the regular ID attribute, and add a CSS rule to your page header.

For example, make your id gridGroup

Then add this to your page header

<style>
#gridGroup {
display: grid !important;
}
</style>

And you can also conditionally update the element’s ID to easily remove/change the CSS.

1 Like

I think I finally figured it out with all native elements, no plugins. It’s a bit convoluted, but it works.

demo: https://nocode-to-knowcode.bubbleapps.io/version-test/grid
video: CleanShot 2024-10-30 at 08.42.47 · CleanShot Cloud

editor: Nocode-to-knowcode | Bubble Editor

The challenge is in the CSS selector – Bubble always adds an extra group between the grid (a Bubble RG) and the elements you add. So, if you have to target the parent that has an ID that you created.

You can use nested CSS to target them:

#target {
  gap: 20px !important;

  div {
    grid-area: auto / span 2;
  }

  div:has(#target-item-2) {
    background-color: pink;
    grid-area: 1 / auto / span 3 /  span 3;
  }

  div:has(#target-item-5) {
    background-color: cyan;
    grid-area: span 2 /  auto;
  }
}

Yes, you can also target them based on their position by using the classes of the auto-generated divs.

2 Likes