Page
Page class can be used to combine multiple widgets into a single page. A dictionary is returned with entries containing values from input widgets. These entries are labelled with the widget message if no key is provided.
Basic use
Basic use of Page class. You can customize the submit button text passing a string to the run method. The default value is 'Next'.
from abstra.forms import Page
contact = (
Page()
.read("What is your name?")
.read_email("What is your email?")
.run()
)
name = contact["What is your name?"]
email = contact["What is your email?"]
# Alternative way to use values
# name, email = contact.values()
Custom keys
You can provide custom keys for each widget. These keys will be used to label the entries in the dictionary returned by the run method.
from abstra.forms import Page
contact = (
Page()
.display("Address information")
.read("Address", key="address")
.read("City", key="city")
.read("State", key="state")
.read("Zip Code", key="zipcode")
.run("Send")
)
address = contact["address"]
city = contact["city"]
state = contact["state"]
zipcode = contact["zipcode"]
Custom buttons (actions)
You can provide custom buttons (actions) to the run method. The default value is 'Next'.
from abstra.forms import Page
contact = (
Page()
.read("Contact's name", key="name")
.read_email("Contact's email", key="email")
.run(actions=["Add more", "Finish"])
)
if contact.action == "Finish":
# Do something
pass
else:
# Do something else
pass
Reactive pages
You can create pages with dinamic content using the reactive decorator. This decorator will make the render function reactive, allowing you to use the read and display methods to interact with the user.
from abstra.forms import reactive
@reactive
def render(p):
name = p.read("What is you name?")
age = p.read_number("What is your age?")
if age is not None and age > 60:
p.display("You are eligible for the senior discount")
render.run()
Page validation
You can pass a validate function to the run method in your page in order to validate it. This function receives a partial result and can return either a boolean (True for valid and False for invalid) or a string with an error message to show the user.
def validate(partial):
if partial.get("email") is None:
return False
if partial.get("email").endswith("@abstracloud.com"):
return True
return "You must be an Abstra member to use this form"
Page().read_email("Email", key="email").run(validate=validate)
Steps
You can allowing back and forth navigation by using our run_steps function.
from abstra.forms import run_steps, Page
page1 = (
Page()
.display("Bio information")
.read("What is your name?", key="name")
.read("What is your email?", key="email")
)
page2 = (
Page()
.display(" information information")
.read("Address", key="address")
.read("City", key="city")
.read("State", key="state")
.read("Zipcode", key="zipcode")
)
page3 = (
Page()
.display("Payment information")
.read("Credit card number", key="cc_number")
.read("Expiration date", key="cc_expiration")
.read("Security code", key="cc_security_code")
)
steps_response = run_steps([page1, page2, page3])
page1_response = steps_response[0] # Use the first page response
city = steps_response["city"] # Directly access a page item by key
Functions and dynamic pages
Adding functions to run_steps
will execute those functions on forward direction.
Adding reactive pages will allow you to dynamically use previous steps as inputs
from abstra.forms import run_steps, Page
page1 = Page().read("What is your name?", key="name")
# Functions can be added to the steps list
def do_something(page1_response):
# Responses will be accessible as dicts
name = page1_response['name']
# The return value of the function will be passed forward
return dict(nickname="Dr. " + name)
# Reactive pages will start with previous responses
def render(function_response):
if 'nickname' in function_response:
return Page().display(f"Hello {function_response.get('nickname')}")
page2 = Page().reactive(render)
steps_response = run_steps([page1, do_something, page2])