Components
Components are Python classes stored in meld/components either within your application folder or in the base directory of your project.
Combined with a Jinja template, components enable you to create dynamic content without the need to write JavaScript.
The best way to start to understand how components work is to look at an example.
# app/meld/components/counter.py
from flask_meld import Component
class Counter(Component):
count = 0
def add(self):
self.count = int(self.count) + 1
def subtract(self):
self.count = int(self.count) - 1
The class above creates a property named count
and defines the add
and
subtract
functions which will modify the count
property. Combining the use of
properties and functions in this way allows you to customize the behavior of your components.
{# app/meld/templates/counter.html #}
<div>
<button meld:click="subtract">-</button>
<input type="text" meld:model="count" readonly></input>
<button meld:click="add">+</button>
</div>
The template includes two buttons and an input field. The buttons bind to the functions
using meld:click="add"
and meld:click:"subtract"
while the input binds to the
count
property with meld:model="count"
.
Properties
Components store model data for the class using properties
.
class Counter(Component):
count = 0
Data Binding
You can bind a compenent property to an html element with meld:model
. For instance,
you can easily update a property by binding it to an input
element. When a user types
text in the input field, the property is automatically updated in the component.
class Person(Component):
name = ""
---------------------------------------------
<div>
<input meld:model="name" type="text">
<h1>Hello {{ name }}</h1>
</div>
You can use meld:model
on the following elements:
<input type="text">
<input type="radio">
<input type="checkbox">
<select>
<textarea>
Custom events
You can use custom events to call a method in one component from a different component.
Let's extend the counter
component above to listen for a set-count
event, then build
a new component that emits it. To listen for the event, we just need to define a method
on the component and use the @flask_meld.listen
decorator. No changes are needed to
the template.
# app/meld/components/counter.py
from flask_meld import Component, listen
class Counter(Component):
count = 0
def add(self):
self.count = int(self.count) + 1
def subtract(self):
self.count = int(self.count) - 1
@listen("set-count")
def set_count(self, count):
self.count = count
Now let's define a second component SetCount
that will have a text box and a button.
When a user clicks the button, we want to emit an event with the value from the text
box that can be picked up by the counter. To do this, we just use flask_meld.emit
.
# app/meld/components/set_count.py
from flask_meld import Component, emit
class SetCount(Component):
value = 0
def set_count(self):
emit("set-count", count=self.value)
Note that the count
argument to emit
will be passed as a keyword argument to
the listening function. The template for this component is pretty simple,
we just need to define the text box and button and hook them to the Component.
{# templates/meld/set_count.html #}
<div>
<input type="text" meld:model="value"></input>
<button meld:click="set_count">Set Count</button>
</div>
Finally, add {% meld 'set_count' %}
to your page template and run the app!
Pretty simple right? You can use this to create very dynamic user interfaces using pure Python and HTML. We would love to see what you have built using Meld so please share!