How to define and configure roles

What I’m trying to do:
Create some roles that define a border around a textbox that will be black by default. If the user enters a value that isn’t in a predefined range change the border to red and write an explanatory sentence guiding the user to enter a correct value
What I’ve tried and what’s not working:
I’ve added 2 roles to the roles list in the App theme - One is called BlackBorder and the other RedBorder.
Iv’e also configured them in the Themes.css file…
Code Sample:

.anvil-role-BlackBorder {
 border: 2px solid black;
 border-radius: 4px;
 width: 20%;
}
 
.anvil-role-RedBorder {
border: 2px rtyrty;
border-radius: 4px;
width: 20%;
} 

It seems like the code in the theme.css isn’t even read (I deduced this by adding gibberish to the file but the app still ran ok)
I know there is pretty solid documentation on this but I still can’t seem to understand where I’m going wrong here
Clone link:
share a copy of your app

Generally you don’t want to modify theme.css, in case you need to update it to a newer version at some point. Instead, put your roles into the Native libraries section, inside a style block, e.g.:

<style>
.anvil-role-BlackBorder {
  border: 2px solid black;
  border-radius: 4px;
  width: 20%;
}
  
.anvil-role-RedBorder {
border: 2px;
border-radius: 4px;
width: 20%;
} 
</style>

That was enough to get the role to apply for me.

2 Likes

Thanks @jshaffstall it works!
And how do I go about defining the role in the code?
(This may be classed as a new question…)
Writing in the form code doesn’t work:

class Form1(Form1Template):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)
    # Any code you write here will run before the form opens.
    self.text_box_1.role = 'BlackBorder'

I don’t manipulate roles in code myself, but others have posted about it in the past. I think that the role property is a list of roles that apply, not a single role. A bit misnamed, and the docs really should have an example if that’s the case.

Oh, and you also need to reassign the entire list to get the CSS to change. Modifying the list doesn’t work.

So how would you change the color of a textbox border according to the number input?
For example if the value inserted is bigger than 100 change the border to red and write the following sentence below the textbox: “The value you entered is too high, please insert a value smaller than 100”
?

To set the role property, since it’s a list:

self.text_box_1.role = ['BlackBorder']

If that works, everything else is just if statements in Python.

This isn’t working for me
I have added to the form code the role property but it has no effect on the textbox

class Form1(Form1Template):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)
    # Any code you write here will run before the form opens.
    self.text_box_2.role = ['RedBorder']
    self.text_box_1.role = ['BlackBorder']

Sometimes with roles, something else in the system will take precedence over the CSS for the role. When the CSS for the role looks good but doesn’t seem like it’s applying, adding !important to the rule can help bring it to a higher priority. e.g.

.anvil-role-BlackBorder {
  border: 2px solid black !important;
  border-radius: 4px;
  width: 20%;
}

The CSS for the red border is missing the solid red part, plus the !important part. Switching the role CSS to be the following worked for me:

.anvil-role-BlackBorder {
  border: 2px solid black !important;
  border-radius: 4px;
  width: 20%;
}
  
.anvil-role-RedBorder {
border: 2px solid red !important;
border-radius: 4px;
width: 20%;
}