How to put a custom css role into a function

What I’m trying to do:
I am just at this point trying to get the feel of Python and Anvil, so I copied a You Tube tutorial, which was great and we created a little calculator. However, I wanted to see how I could add custom CSS to it. As such, I have created a custom role called btnround and want to assign this instead of the regular button.

I added this custom CSS to it:

anvil-role-btnround{
  border-radius:50px;
  border: 2px;  
  padding:3px;
}

I want to put it in here

self.btnround = {}
If I put
self.anvil-role-btnround = {}

I get a syntax error
The SyntaxError: cannot assign to operator error is raised when you try to evaluate a mathematical statement before an assignment operator. To fix this error, make sure all your variable names appear on the left hand side of an assignment operator and all your mathematical statements appear on the right.
What I’ve tried and what’s not working:

I want to put it in this code, but as soon as I enter the first one I get the syntax error

Code Sample:

class Form1(Form1Template):
  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)
    chars = ["1", "2", "3", "4", "d", "c",
             "5", "6", "7", "8", "+", "-",
             "9", "0", ".", "*", "/", "="]
    self.anvil-role-btnround = {}
    gp = GridPanel()

    for idx, i in enumerate(chars):
      if i =="=":
        clr = "#2e536e"
      elif i in ["c", "d"]:
        clr = "#ef2e36"
      elif i in ["+", "-", "*", "/"]:
        clr = "#3A3A49"
      else:
        clr = "#EE8A8A"
      if idx < 6:
        row = 'A'
      elif 6<=idx<12:
        row = 'B'
      else:
        row = 'C'
      self.btnround[i] = Button(text=i,
                          font ="Consolas",
                          bold= True,
                          foreground="#FFF",
                          background=clr)
      self.btnround[i].tag.name = i
      self.btnround[i].set_event_handler('click', self.click)
      gp.add_component(self.btnround[i], row=row, col_xs=3, width_xs=1)
    self.add_component(gp)
    
  def click(self, **event_args):
    val = event_args['sender'].tag.name
    if val == "=":
      self.text_box_1.text = eval(self.text_box_1.text)
    elif val =="c":
      self.text_box_1.text = ""
    elif val =="d":
      self.text_box_1.text = self.text_box_1.text[:-1]
    else:
      self.text_box_1.text += val

https://hasty-wry-tiger.anvil.app

Can you help with the right way to put this custom role into this script, many thanks

You set a role on a component, e.g.:

self.btnround.role="btnround"

Will use the CSS that already exists for anvil-role-btnround. You do not need to have self.anvil-role-btnround in your class, that’s just an empty dictionary that isn’t being used, and with an illegal variable name at that (you can’t use dashes in variable names in Python).

Sorry, I should have confirmed I sorted it rather than just delete my reply. I solved it thank you. I just needed to declare it in the script as follows

self.btn[i].role =“btnround”

Many thanks

Ok, so it appears I am not done yet, here is the publshed app

I put in my CSS

.anvil-role-btnround{
  border-radius:50px !important;
  border: 2px;  
  padding:10px !important;
}

Its assigning the class to the wrong place, how do I get it to assign it to the actual button, if I type in Inspect on the browser, its like this:
.btn.btn-default {
border-radius: 50px;
}

You can also apply multiple roles, which is only possible via code:

self.btn[i].role = ["btnround", "role2", "role3"]

Thanks, I tried that and can see it on the div, but its not in the right place, hence the styling is being applied to the space around the button, not the button itself.

Ive published the app here https://hasty-wry-tiger.anvil.app if you do an Inspect Element on it you can see the class is being aplied here (I colour coded the border on the CSS so its easy to see what its doing)

<div style="text-align: center;" class="align-center anvil-spacing-above-small anvil-spacing-below-small left-icon has-text anvil-inlinable anvil-button anvil-component anvil-role-btnround" anvil-role="btnround"></div>

iit needs to be the button which is the inner button class to this.

Right now I don’t have time to clone and look, but maybe you can fix it by knowing that the role applies to the div containing the button, and changing the css to target its child.

Maybe something like this would work:

.anvil-role-btnround > div {

Ok thanks I am playing around so am sure it will click in the end, thanks for the hint, will try that

Unfortunately I havent been able to resolve this yet.

Two bits with your role.

One is that the roles are HTML classes, so you need the period in front of it, e.g.:

.anvil-role-btnround{
  border-radius:50px;
  border: 2px;  
  padding:3px;
}

The other is, as you found, an Anvil “button” is the div and the actual button inside the div. Any CSS roles you create that need to target the HTML button element need to be adjusted to target the child of the div.

.anvil-role-btnround > .btn {
  border-radius:50px;
  border: 2px;  
  padding:3px;
}

You can find examples of button roles in your app’s theme.css (that’s where I grabbed the technique from).

2 Likes

Thank you, you are right, I forgot the period :slight_smile: and thank you it now works YAH you are so kind!

1 Like