Dynamic Component Lifecycle
PYUI 6.0 introduced using components dynamically. Now you can add and remove components dynamically from Python Runtime.
This page covers
- How to register and unregister custom nodes in PYUI Python Runtime
- Adding and Removing Components
- Adding and Remving custom HTML content
Adding and Removing custom node in PYUI
PYUI allows to register or un-register nodes to Python Runtime if they are created dynamically. This are internally used in Component class but you might need it separately many times, mostly while working with custom syscalls.
Registering a Unmanged Node
self.pyui.RegisterUnmanagedNode(id,tag)
# Example
self.pyui.RegisterUnmanagedNode("dyn_node","div")
Un-Registering a Unmanaged Node
self.pyui.UnRegisterUnmanagedNode(id)
# Example
self.UnRegisterUnmanagedNode('dyn_node')
Note: Un-register function automatically cleans callbacks associated with the given id
Adding Component to UI
-
For adding Component to UI. The component must be well defined inside the
Componentsfolder.If notPYUIwill fail to createComponentinstanceExample Component:
<ComponentFile text="Default text" place="Default Placeholder"> <Text id='' innerText='{text}'></Text> <Input placeholder='{place}'></Input> </ComponentFile> -
Make a
Componentinstancec = Component('component_path_without_extension_relative_to_component_folder') # Example c = Component(self.pyui,'form') c = Component(self.pyui,'dash/admin')
Try to use POSIX style path, if not used PYUI auto converts it internally to keep the app cross platform.
-
Adding Components to UI
-
Appending at end: Use
c.appendComponent()to add the component to end of the parent id.new_id = c.appendComponent('parent_id') # defaults will be usedor,
# props supplied new_id = c.appendComponent('parent_id', text='Hello World',place="New Placeholder")You can use
new_idas baseidfor thecomponent. Just like statically dynamically all the components getname mangledwith thisnew_id. See Reusing Layouts using Components to know how to reference the inner elements -
Adding to Top of parent id: Use
c.addComponentTop()to add component to top of the parent id.new_id = c.addComponentTop('parent_id') -
Adding component after a element: Use
c.addComponentAfter()to add a component after a certain element.new_id = c.addComponentAfter('preceeding_id')
-
Deleting a Component
Use c.removeComponent(), where c is a component instance (see above) to remove components from UI.
Example
c.removeComponent('component_id')
# use the id returned during the creation of the thread to remove component
Note: This function can remove nodes even if it is not a Component so this can be reused in general to remove any ID from UI.
Adding custom HTML to UI
PYUI 0.6 have loosened the strictness of direct HTML usage for better DX and considering how often users might need to add arbitary objects to UI. But, directly mutating HTML might be still harmfull as it is not verified by Compiler. So a safety approach is implemented by making HTMLObject class.
generator,id_of_obj = HTMLObject(self.pyui,tag_name,innerContent,**attributes)
# Example
generator,id_obj = HTMLObject(self.pyui,'p','Inner text',hidden=True)
This do not add the content to UI. To add this to UI you need to send a syscall
-
Make Send JSON
toSend = {'parent_id':parentID/preceeding ID,'html_to_add':generator(),"mode":mode}- parent_id: Stores the parent id/preeceeding element id to which the Element is added.
- html_to_add: This is the html string to be added. Use the generator function returned by
HTMLObject. -
mode: Where to add the element
- append: Added to the end of the parent id
- top: Added to the TOP of the parent id
- after: Added after a given preeceeding ID
-
Send the Syscall
self.pyui.sendSyscall('ADD_NODE_END',json.dumps(toSend))
Few important notes
-
In
HTMLObjectwhen thegenerate()function is called only then the given node id is registered, it is done so that there are no dangling nodes made until you actually push the html to layout. -
It is not strictly said that you can't add element inside element but it is better to not write InnerHTML manually and it is better to chain
HTMLObjects. We will see this in next section. -
When
generate()is called the node is auto-registered withPYUI Python Runtime, you are free to use them usingElementclass or using other ways to reference the node. -
However if the
Nodeis deleted later you need to manually Unregister the node usingPYUI'sfunction (we will see it soon). -
The adding of custom HTML is intentally made bit elongated to make users use the
Componentas they are much safer. However for small cases like addingoptionto `selector', creating new component is a overkill and there this method is much more suitable.
Chaining HTMLObjects
Let us understand this using a example. For example we need to add button and a p inside a div and add the whole thing to UI
-
First start from inner Nodes and build up. First make the
buttonand thepgen_btn,id_btn = HTMLObject(self.pyui,'button','Click ME') gen_p,id_p = HTMLObject(self.pyui,'p','Click here for magic!!!') # this generates the total html also registers the ID gen_innerhtml = gen_btn() + gen_p() -
Make DIV and add the created HTML
gen_div,id_div = HTMLObject(self.pyui,'div',gen_innerhtml) -
Send the syscall as done before to add the div to the UI
Note: As soon as you generate the html and store it in gen_innerhtml the nodes are registered if you do not directly or indirectly push them to UI using syscall then those nodes will be dangling with no UI counterpart.
Removing HTML Contents
You can delete a HTML node using REM_NODE syscall and then use self.pyui.UnRegisterUnmangedNode(id) to clean the callbacks
-
Send the
REM_NODEsyscall to clean the node from UI.toSend = {'id':id_to_delete} self.pyui.sendSyscall('REM_NODE',json.dumps(toSend)) -
Unregister the Node
self.pyui.UnRegisterUnmanagedNode('id')