HTML Components¶
Introduction¶
In JustPy components are Python classes. All HTML components inherit from either the Div or Input component. The Input component itself inherits from the Div component.
The reference will describe primarily the Div component and the Input component.
It would be helpful to read the HTML Components chapter in the tutorial first.
Div Component¶
Introduction¶
The Div component is the basic container component of JustPy. It is a component that can contain other components. It can of course, contain components that themselves are container components.
Attributes¶
General¶
Attributes can be set as keywords when an element is created.
They can also be set anytime after the element is created (except for delete_flag
which needs to be set at creation).
text¶
- Type:
string
- Default:
""
(the empty string)
The text
attribute will always be rendered as the first child of the component. If you want a Div (or any container component) instance to render multiple texts in different locations, encompass the text in another container component and add that component to the Div at the location you want.
If you want to render an HTML Entity use the HTMLEntity component or set the html_entity
attribute to True
.
import justpy as jp
def entity_test():
wp = jp.WebPage()
jp.Space(num=3, a=wp)
jp.HTMLEntity(entity='à',a=wp, classes='text-lg')
jp.Span(text='à',a=wp, classes='text-lg', html_entity=True)
jp.Space(num=5, a=wp)
jp.HTMLEntity(entity='á',a=wp, classes='text-xl')
jp.Span(text='á',a=wp, classes='text-xl', html_entity=True)
jp.Space(num=5, a=wp)
jp.HTMLEntity(entity='∃',a=wp, classes='text-2xl')
jp.Span(text='∃',a=wp, classes='text-2xl', html_entity=True)
jp.Space(num=5, a=wp)
jp.HTMLEntity(entity='©', a=wp, classes='text-3xl')
jp.Span(text='©', a=wp, classes='text-3xl', html_entity=True)
jp.Space(num=5, a=wp)
return wp
jp.justpy(entity_test)
Info
The Space component can be used to insert spaces. It creates a Span with num
repeats of the html entity ' '.
classes¶
- Type:
string
- Default:
""
(the empty string)
The classes to attach to the element. Usually Tailwind classes, but may be any classes you define. Basically equivalent to the class
attribute of HTML tags.
import justpy as jp
def classes_test():
wp = jp.WebPage()
d = jp.Div(text='Classes Example', a=wp)
# Assign Tailwind classes to d
d.classes = 'text-5xl text-white bg-blue-500 hover:bg-blue-700 m-2 p-2 w-64'
return wp
jp.justpy(classes_test)
style¶
- Type:
string
- Default:
""
(the empty string)
The CSS to attach to the element. Basically equivalent to the style
attribute of HTML tags.
import justpy as jp
def style_test():
wp = jp.WebPage()
for size in range(1,101):
jp.Div(text=f' {size}', style=f'font-size: {size}px; color: red', a=wp, classes='inline cursor-pointer', size=size,
click='self.size *= 2; self.style=f"font-size: {self.size}px; color: green";')
return wp
jp.justpy(style_test)
components¶
- Type:
list
- Default:
[]
Holds the list of child elements in the Div. Strictly speaking these are not components, they are elements, instances of components. When the Div is rendered, the elements are rendered according to their place on the list, starting with the first.
In the following example, the Div elements will show up in a different order each time the page is loaded because main_div.components
is shuffled.
import justpy as jp
import random
def shuffle_test():
wp = jp.WebPage()
main_div = jp.Div(classes='flex flex-wrap m-2 p-2 ', a=wp)
for i in range(1,101,1):
jp.Div(text=f'Div {i}', a=main_div, classes='m-2 p-2 text-xl text-white bg-blue-500')
random.shuffle(main_div.components)
return wp
jp.justpy(shuffle_test)
events¶
- Type:
list
- Default:
[]
When an element is bound to an event, the event name (of type string) is added to events
. You can use events
to check which events the element will respond. Also, by removing an event name from the list, you will disable the element responding to that event.
allowed_events¶
- Type:
list
- Default:
['click', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave', 'input', 'change', 'after', 'before', 'keydown', 'keyup', 'keypress', 'focus', 'blur']
If an event name is not in allowed_events
, JustPy will generate an error if you try to bind to that event.
You can use the add_event
method to add an allowed event to the list.
additional_properties¶
- Type:
list
- Default:
[]
JustPy does not pass all the JavaScript event properties by default since in most cases they are not needed. If you need additional properties from the JavasScript event, use the additional_properties
attribute. In the example below, more fields are added to msg
.
import justpy as jp
def my_click(self, msg):
print(msg)
self.text = 'I was clicked'
def event_demo():
wp = jp.WebPage()
wp.debug = True
d = jp.Div(text='Not clicked yet', a=wp, classes='w-48 text-xl m-2 p-1 bg-blue-500 text-white')
d.on('click', my_click)
d.additional_properties =['screenX', 'pageY','altKey','which','movementX','button', 'buttons']
return wp
jp.justpy(event_demo)
inner_html¶
- Type:
string
- Default:
""
(the empty string)
Used to to set the HTML of an element directly.
import justpy as jp
def inner_html_test():
wp = jp.WebPage()
for i in range(1,11):
jp.Div(inner_html=f'<span style="color: orange">{i}) Hello!</span>', a=wp, classes='m-2 p-2 text-3xl')
return wp
jp.justpy(inner_html_test)
If inner_html
is not the empty string, it will override any other content of the element
show¶
- Type:
boolean
- Default:
True
If set to False
, the element is not rendered. See here
set_focus¶
- Type:
boolean
- Default:
False
If set to True
, the element will have focus when the page is rendered.
If multiple elements have the set_focus
attribute set to True
, the results will be unpredictable. The last element to be rendered by Vue will have focus.
import justpy as jp
# Try not using this event handler and see what happens
def my_blur(self, msg):
self.set_focus = False
def focus_test():
wp = jp.WebPage()
in1 = jp.Input(classes=jp.Styles.input_classes, placeholder='Input 1', a=wp, blur=my_blur)
in2 = jp.Input(classes=jp.Styles.input_classes, placeholder='Input 2', a=wp, blur=my_blur)
in3 = jp.Input(classes=jp.Styles.input_classes, placeholder='Input 3', a=wp, blur=my_blur)
in4 = jp.Input(classes=jp.Styles.input_classes, placeholder='Input 4', a=wp, blur=my_blur)
# Set focus on third Input element
in3.set_focus = True
return wp
jp.justpy(focus_test)
children¶
- Type:
list
- Default:
[]
When an element is created, can be used to create its children also. Useful if you like defining elements in a hierarchical way.
New in version 0.10
import justpy as jp
def children_test():
wp = jp.WebPage()
div_classes = 'm-2 p-2 bg-blue-500 text-white text-lg'
span_classes = 'm-2 p-2 bg-blue-500 text-yellow-700 text-xl'
jp.Div(children=[jp.Div(classes=div_classes, children=
[jp.Span(text='s1', classes=span_classes), jp.Span(text='s2', classes=span_classes)])
,jp.Div(text='d2', classes=div_classes), jp.Div(text='d3', classes=div_classes), jp.Div(text='d4', classes=div_classes)], a=wp)
return wp
jp.justpy(children_test)
animation¶
- Type:
string
- Default:
""
(the empty string)
Set the animation of the element. Uses animate.css
Control the speed of the animation by adding classes:
Class Name | Speed Time |
---|---|
slow |
2s |
slower |
3s |
fast |
800ms |
faster |
500ms |
For more information and additional options consult the animate.css documentation
import justpy as jp
import random
input_classes = "m-2 bg-gray-200 appearance-none border-2 border-gray-200 rounded w-64 py-2 px-4 text-gray-700 focus:outline-none focus:bg-white focus:border-purple-500"
def animate(self, msg):
self.d.delete_components() # remove all components from d
directions = ['Up', 'Down', 'Left', 'Right']
html_entity = False
for letter in self.text_to_animate.value:
if letter == ' ':
letter = ' '
html_entity = True
jp.Div(animation=f'fadeIn{random.choice(directions)}', text=letter, html_entity=html_entity,
classes='rounded-full bg-blue-500 text-white text-6xl', a=self.d)
html_entity = False
def animation_test():
wp = jp.WebPage()
text_to_animate = jp.Input(a=wp, classes=input_classes, placeholder='Enter text to animate', value='Animation Demo!', input='return True')
animate_btn = jp.Button(text='Animate!', click=animate, classes='w-32 m-2 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded', a=wp)
animate_btn.text_to_animate= text_to_animate
d = jp.Div(classes='flex items-center justify-center', style='height: 500px', a=wp)
animate_btn.d = d
return wp
jp.justpy(animation_test)
id¶
- Type:
string
- Default: Nothing assigned
If you need to identify an element use the name
attribute (or any other attribute you choose), NOT the id
attribute. JustPy assigns a unique id to elements that are associated with events and uses it to identify which event handler to run.
It is advised not to change an element's id
or assign it an id
delete_flag¶
- Type:
boolean
- Default:
True
If set to False
, element is not deleted when a page which it is on closes. In addition, non of its child components will be deleted.
If you create an element that will be used on more than one page, set the value to False
.
event_propagation¶
- Type:
boolean
- Default:
True
The current version of JustPy supports only event bubbling. Events originate in the innermost child and bubble up through the parents unlessevent_propagation
is set to False
.
import justpy as jp
def event_propagates():
wp = jp.WebPage()
main_div = jp.Div(classes='flex flex-wrap m-2 p-2 ', a=wp, click='self.text="main div clicked"')
for i in range(1,10):
jp.Div(text=f'Div {i}', a=main_div, classes='m-2 p-2 text-xl text-white bg-blue-500', click='self.text="clicked"')
return wp
@jp.SetRoute('/no_propagation')
def event_does_not_propagate():
wp = jp.WebPage()
main_div = jp.Div(classes='flex flex-wrap m-2 p-2 ', a=wp, click='self.text="main div clicked"')
for i in range(1,10):
jp.Div(text=f'Div {i}', a=main_div, classes='m-2 p-2 text-xl text-white bg-blue-500',
event_propagation=False, click='self.text="clicked"')
return wp
jp.justpy(event_propagates)
vue_type¶
- Type:
string
- Default:
'html_component'
The Vue component to couple with the Python class. Used by the front end of the framework.
If you change this, the component will not be rendered correctly
When you develop components that require a Vue component as well, you will need to set this attribute in the Python class
html_tag¶
- Type:
string
- Default:
'div'
The HTML tag that corresponds to the component. If you change it, the component may not render correctly.
If you change this, the component may not be rendered correctly
class_name¶
- Type:
string
- Default:
'Div'
The class (component) name of the element. Should be considered read only
Global HTML attributes¶
Div supports some HTML global attributes. Please review the Common Attributes section in the Tutorial.
Methods¶
def delete(self)
Remove references to the object from JustPy internal data structures to allow garbage collection.
def on(self, event_type, func)
Bind a function to an event
def remove_event(self, event_type)
Remove and event from the element's allowed events
def has_event_function(self, event_type)
Returns True
if the element has the specified event
async def update(self)
Updates just the element, not the whole page. The element is updated on all pages specified in the attribute pages
.
See Simple Message Board
remove_page_from_pages(self, wp: WebPage)
Remove a page from pages
def add_page(self, wp: WebPage)
and def add_page_to_pages(self, wp: WebPage)
Add a page to pages
def set_model(self, value)
Set the model value
async def run_event_function(self, event_type, event_data)
Run an event function. This method takes two arguments in addition to self
. The first is the event type. The second, is the dictionary we want passed as the second positional argument to the event handler. This is what we usually designate as msg
in our event handler examples in the tutorial. See example here
@staticmethod def convert_dict_to_object(d)
Takes the dictionary created by convert_object_to_dict
and returns an object. Can be used to make independent copies of objects.
def __len__(self)
len(c)
returns the number of direct children the element c
has
def add_to_page(self, wp: WebPage)
Adds the element to a page
def add_attribute(self, attr, value)
Adds an attribute that will be part of the dictionary created by convert_object_to_dict
def add_event(self, event_type)
and def add_allowed_event(self, event_type)
Add an allowed event to the element
def add_scoped_slot(self, slot, c)
Relevant to Quasar and other Vue based frameworks or components.
def to_html(self, indent=0, indent_step=0, format=True)
Returns an HTML representation of the element
def react(self, data)
Executes just before the element is rendered. It is just pass
for Div and is meant to be overridden by components that inherit from Div
def convert_object_to_dict(self)
Converts the element to a dictionary in the format the can be sent to the frontend to be rendered.
def add_component(self, child, position=None, slot=None)
Add a component at the specified position.
def delete_components(self)
Use to empty a container element like Div. Does not delete the text
attribute
def add(self, *args)
Add all arguments as child elements after the current child elements
def add_first(self, child)
Add a child element before all other child elements
def remove_component(self, component)
Remove a child element
def get_components(self)
Get child elements as a list
def first(self)
Get first child element
def last(self)
Get last child element
def model_update(self)
Override as necessary. See example here