Changing CSS style programmatically

Hey all,
Do you know if there is a good way to change the CSS style of a particular programmatically through Anvil?
For example, I’d like to press a button and have one of the rectangles in my “map” turn red. Or, depending on the user input, have one of the rectangles turn red if it corresponds to a particular number.

Here’s a clone of my app:

Thanks

FYI, that’s a live link to your app, not a clone link. So people can run it through that link, but not see the code.

Back to the original question, in Anvil you can change component properties via code. I don’t know how you’re making the map, though, so can’t comment on exactly what to use.

You can also change Anvil component roles via code, which can change component colors.

If there are no Anvil component properties that work, you can always modify the HTML elements directly using the Javascript bridge, e.g.:

node = anvil.js.get_dom_node(self.somecomponent)
node.id = "someid"

Look up how to change the CSS style you’re interested in via Javascript, and use the node you get from get_dom_node as your object to make the Javascript calls on.

2 Likes

The map is an export from Figma into HTML and CSS.

Then the Javascript bridge is going to be your best bet, I think.

Maybe I misunderstand what you have written, but I think what I’m looking for is almost the reverse of this, because the element whose CSS property I want to change is not an Anvil component, but rather an element in a linked CSS file, for example… when I press the (Anvil component) button Submit, I want to change this element on page from a white text to a gray text:

.enter-apartment-number {
background-color: var(–color-gray-100);
}

That is just a CSS element in a style sheet that I uploaded into my Assets folder (called component4.css) and it is referenced by the custom HTML I added to this form. Is there a way to change that property by pushing the (Anvil component) button?

Anything you can do with Javascript, you can do with one of anvil.js, anvil.js.window, or anvil.js.window.document. That includes targeting specific elements that are not Anvil components, or changing CSS for classes, etc.

1 Like

I am not sure I did it right because the returned “node” I get with your code is:
<HTMLDivElement proxyobject>

Do I then embed some JavaScript in the HTML like:

proxyobject.addEventListener('click', () => {
    const element = document.querySelector('.demo');
    element.style.backgroundColor = 'red';
});

You can do it like this in your Anvil Form.


from anvil.js.window import document

def submit_button_click(self, **event_args):
      element = document.querySelector('.demo')
      element.style.backgroundColor = 'red'
2 Likes

Would this still be possible if Tailwind is used?

Tailwind works by defining a series of CSS classes you use. You can add/remove those classes from HTML elements using Javascript the same as any other CSS classes.

1 Like

Is it possible to reference CSS elements on external stylesheets? In other words, CSS files that I might have in my Assets folder, or that are being used in other forms?

You’d load those in your Native Libraries section. After that, use them like any other CSS.

Is there a way to use the document.querySelector() on a Form before it appears?
When I try to add the code:

      element = document.querySelector('.demo')
      element.style.backgroundColor = 'red'

to the __init__() function of the form, I get
AttributeError: 'NoneType' object has no attribute 'style'

When I add it to a button_click function, it works fine.

You can use anvil.js.get_dom_node(self) to get the DOM node of the Form before it appears. Then use query selectors on that to get children nodes, e.g. js.get_dom_node(self).querySelector(".content")

2 Likes

Perfect, that works!

Thanks for all the responses.

One more question:
I loaded all the CSS files for the app into Native Libraries, however it seems I can only reference the CSS elements on the currently opened form.
When I try to change the style of an element that is not currently being referenced by the HTML of the open form, I get an error:

AttributeError: 'NoneType' object has no attribute 'style'

That error means you’ve tried to fetch something and gotten the value None back, meaning it couldn’t find it. If you’re trying to get an element that isn’t on the page, that would make sense.

1 Like

Would it be possible to use anvil.js.get_dom_node() inside a Module? ie, run a function to change an element on a particular form if some conditions are satisfied?

I don’t see why not. If you try it and run into problems, create a new post for it and post the sample code you’re using.