Help with Elements, Element Placing and how to reference them

HiI did start this code on another thread, so not sure if I should have carried on with the other thread or started a new, as its a slightly different question. So apologies if I should have done that. Here are my questions

1. If I create an element via a function, say a Column Panel or Text Box via code, I want to be able to reference that particular element in another function.

So, if I drag and drop a text box on the properties, I can rename it to something unique and reference that in my argument.

e.g self.repeating_panel_1.items = anvil.server.call('locationQuery', self.text_box_location.text)

But if I create one on a function, there doesnt seem to be a way of making it unique. This is how I am adding the component on the function

self.cp.add_component(self.tb, row=row, col_xs=3, width_xs=2)

How would I go about making each component unique, say traveller_1, traveller_2 etc?

2. If I am adding some components by drag and drop and others by a function, how do I specify the order of them as the one I created by a function is just showing up at the bottom of the page?

Is there any way I can look at an advanced tab that shows the whole page in code, so I can place the code for my created element where I want?

Like this:-
Drag and Drop Element
Drag and Drop Element
My Function Element
Drag and Drop

3. If thats not possible, how do I get my created element to display in a specific element

In my example self.tb (which is a textbox) I would like it to display this inside a drag and drop element named self.column_panel_all_travellers.

Here is my code

  def text_box_travellers_pressed_enter(self, **event_args):
    trav = int(self.text_box_travellers.text)
    trav = trav + 1
    traveller_ages=[]
    for i in range(1, trav):
      if i<=4:
        row ='A'
      elif 5<= i<=8:
        row ='B'
      elif 9<= i<12:
        row ='C'
      else:
        row ='D'
      self.tb = TextBox(bold= True,foreground="#FFF",background="#fff",placeholder=f"traveller{i}",)
      self.tb.role = "form-control"
      self.tb.tag.name = i
      self.cp.remove_from_parent()
      self.cp.add_component(self.tb, row=row, col_xs=3, width_xs=2)
      self.add_component(self.cp)
    pass

Here is the form, once you enter how many travellers, the boxes show at the bottom.

Thanks in advance

You probably want to put your dynamically created components in a list or dictionary, depending on what you’re doing with them later.

If you want dynamically created components to be created somewhere other than the bottom of the page, put a blank flow or column panel (or other container) somewhere on the page, and add them to it instead of the form itself.

1 Like

Hi thanks,

  1. so am I right in saying you cannot follow the same referencing that Anvil drag an drop offers with code created components?

  2. so with my code example, how would I do this, I did create a column panel called column_panel_travellers_all, how can I get those created boxes to go in that column panel specifically?

Yes, you can follow the same referencing, as your own code proves:

It doesn’t matter whether the component referenced by self.tb got there via your code, or via the IDE. You the second line above would be valid in either case. So you definitely can use the same “referencing code” in both cases.

I dont think I am explaining the terms well to say what I want to do, so I want to call self.tb self.text_box_traveller_1

also I want the container it shows in to be an existing one, which is column_panel_travellers_all not a random one.

On that note I’ve just been looking at how Anvils ticketing system works, I think I need to play around with layering my design into parts, and see if that solves my layout issues.

You call add_component on your column panel, not on the form itself. You’re actually already doing that, but you’re forcing your column panel to the bottom of the form by removing it from the parent and readding it. Just call clear() on the column panel before you add new text boxes to it, don’t remove it from the parent. Call clear () on the column panel before the for loop, though, not inside it. Otherwise you’ll only see the last textbox you add to it.

ahhhh. I wondered why when I ran it, the orange bar I created dissapeared. That makes sense now, so I’m removing what I put in.

So I solved it, I didnt need to add the column panel at all, because I already had one.

  def text_box_travellers_pressed_enter(self, **event_args):
    trav = int(self.text_box_travellers.text)
    trav = trav + 1
    traveller_ages=[]
    self.tb = {}
    self.cp.clear()
    for i in range(1, trav):
      if i<=4:
        row ='A'
      elif 5<= i<=8:
        row ='B'
      elif 9<= i<12:
        row ='C'
      else:
        row ='D'
      self.tb[i] = TextBox(bold= True,foreground="#FFF",background="#fff",placeholder=f"traveller{i}",)
      self.tb[i].role = "form-control"
      self.tb[i].tag.name = i
      self.cp.add_component(self.tb[i], row=row, col_xs=3, width_xs=2)
      
    pass
2 Likes