Changing CSS using jQuery inside an iFrame?

Hey all,

What is the way to change CSS elements programmatically inside of iFrames?

I have the following in my form_init method:

    mySpacer = Spacer()
    self.column_panel_1.clear()
    self.column_panel_1.add_component(mySpacer)

    # Create an iframe element and set the src
    iframe = jQuery("<iframe width='100%' height='800px' frameBorder='0'>").attr("src","./_/theme/component50.html")
        
    # Append the iframe to a container in our form
    iframe.replaceAll(get_dom_node(mySpacer))

    #change the CSS style to hidden
    element = anvil.js.get_dom_node(mySpacer).querySelector(".div30")
    element.style.visibility = 'hidden'

However I get the attribute error: 'NoneType' object has no attribute 'style'

If I tried changing the line to:
element = anvil.js.get_dom_node(iframe).querySelector(i)

I get : get_dom_node expected an anvil Component or DOM node, (got jQuery)

Since the spacer is the component which is displaying the iframe, that should be the one I use get_dom_node() on, right?

This replaces the spacer with the iframe. The iframe is now contained inside the column panel that used to contain the spacer. The spacer no longer exists.

Ah, so should I use get_dom_node(self.column_panel_1) ?

That at least would exist.

I’m not sure the rest of it would work, though, since you’re trying to drill down into an iframe. You might do some Google searches on how to change the CSS in an iframe from the parent. The examples I’ve seem are significantly different from what you’re trying (not saying what you’re trying won’t work, but if it doesn’t don’t be surprised).

I tried using:

element = anvil.js.get_dom_node(self.column_panel_1).querySelector('.mydiv')

but I get

'NoneType' object has no attribute 'style'

I followed some of the suggestions here: like so:

element = anvil.js.get_dom_node(self).frames[0].contentDocument.getElementById('.mydiv')
#element = anvil.js.window.frames[0].contentDocument.getElementById(i)
element.style.visibility = 'hidden'

but I get

'HTMLDivElement' object has no attribute 'frames'

(same with the commented-out line below it.)

The link you posted shows:

document.frames[0].contentDocument...

You’re trying frames on the DOM node of the form, not the document. In Anvil, to get to the document, you use anvil.js.window.document. So something like:

anvil.js.window.document.frames[0].contentDocument...

would be the equivalent.

I tried this, too.

element = anvil.js.window.document.frames[0].contentDocument.getElementById('.mydiv')
print(element)

gives me:

'HTMLDocument' object has no attribute 'frames'

and I believe “document” is directly in “anvil.js”, but after trying:

element = anvil.js.document.frames[0].contentDocument.getElementById('.mydiv')

I get:

module 'document' has no attribute 'frames'

I don’t know which of the techniques shown actually works, so it’s hard to say why something doesn’t work in Anvil.

Maybe try the post marked as a solution in the link you posted? It uses JQuery, which you can import in Anvil as from anvil.js.window import jQuery and then use like you’d use $ in regular JQuery, e.g. jQuery(anvil.js.get_dom_node(iframe)).css(...)

Just tossing ideas out there, since as I say I don’t know the code that would work outside of Anvil. If you want to isolate it you could create a mockup in HTML/CSS/Javascript and get it working there, then try to port that Javascript to Anvil.

1 Like

Well, after a lot of trial and error (probably just patiently reading the documentation would have been a better choice), I’ve got it working.

This page was helpful.

Here is my solution:

 element = anvil.js.document.querySelector("iframe").contentWindow.document.querySelector('.mydiv')
 print(element)
 element.style.visibility = 'hidden'
1 Like