Zajęcia 12 - formularz dla pracowników

Zajęcia 12 - formularz dla pracowników
Photo by Annie Spratt / Unsplash

W formularzu dodałam prostą walidację obowiązkowych pól. Przez to nie mogłam użyć metody clear_on_submit() na formie, ponieważ ona zadziałałaby za każdym razem po naciśnięciu przycisku Submit . Nie jest to dla mnie pożądane zachowanie, ponieważ ja na kliknięciu Submit najpierw sprawdzam, czy wszystkie wymagane pola są poprawnie wypełnione. W celu wyczyszczenia formularza po wysłaniu formularza, stworzyłam metodę clear_form().

from datetime import date
import streamlit as st
import json
import os

class EmployeeForm:
    def __init__(self, intrest_options, file_name) -> None:
        self.intrest_options = intrest_options
        self.file_name = file_name
        self.form_data = {
            "first_name": "",
            "last_name": "",
            "gender": "",
            "birthday": date.today(),
            "shoe_number": None,
            "mail": "",
            "adress": "",
            "color": "#ff00ff",
            "is_not_vege": False,
            "intrests": []
        }

        self.generete_form()
     
    def generete_form(self):
        with st.form(key="employee-form", border=False):
            self.form_data["first_name"] = st.text_input(label="First name", max_chars=50, placeholder="First name")
            self.form_data["last_name"] = st.text_input(label="Last name", max_chars=50, placeholder="Last name")
            self.form_data["gender"] = st.radio(label="Gender", options=["Male", "Female"], horizontal=True)
            self.form_data["birthday"] = st.date_input(label="Birthday")
            self.form_data["shoe_number"] = st.slider(label="Shoe number", min_value=34, max_value=50)
            self.form_data["mail"] = st.text_input(label="E-mail adress", placeholder="E-mail adress", max_chars=256)
            self.form_data["adress"] = st.text_input(label="Mailing adress", placeholder="Mailing adress", max_chars=500)
            self.form_data["color"] = st.color_picker(label="Pick your favourite color", value="#ff00ff")
            self.form_data["is_not_vege"] = st.toggle(label="Do you eat meat?")
            self.form_data["intrests"] = st.multiselect(label="What are your intrests?", options=self.intrest_options)
               
            submitted = st.form_submit_button(label="Submit")
            
            if submitted:
                if self.validate_form():
                    self.save_employee_data()
                    self.clear_form()
                    st.balloons()

    def validate_form(self):
        errors = []
                
        if not self.form_data["first_name"]:
            errors.append("First name is required.")
        if not self.form_data["last_name"]:
            errors.append("Last name is required.")
        if not self.form_data["mail"]:
            errors.append("E-mail address is required.")
        if "@" not in self.form_data["mail"]:
            errors.append("Invalid e-mail address.")
        if not self.form_data["adress"]:
            errors.append("Mailing address is required.")
        if self.form_data["birthday"] > date.today():
            errors.append("Birthday cannot be in the future.")

        if errors:
            for e in errors:
                st.toast(e, icon="❗️")
            return False

        return True
    
    def clear_form(self):
        st.session_state["first_name"] = ""
        st.session_state["last_name"] = ""
        st.session_state["gender"] = "Male"
        st.session_state["birthday"] = date.today()
        st.session_state["shoe_number"] = 34
        st.session_state["mail"] = ""
        st.session_state["adress"] = ""
        st.session_state["color"] = "#ff00ff"
        st.session_state["is_not_vege"] = False
        st.session_state["intrests"] = []

    def to_dict(self) -> dict:
        return {
            "first_name": self.form_data["first_name"],
            "last_name": self.form_data["last_name"],
            "gender": self.form_data["gender"],
            "birthday": self.form_data["birthday"].isoformat(),
            "shoe_number": self.form_data["shoe_number"],
            "email": self.form_data["mail"],
            "adress": self.form_data["adress"],
            "color": self.form_data["color"],
            "is_not_vege": self.form_data["is_not_vege"],
            "intrests": self.form_data["intrests"]
        }
    
    def save_employee_data(self):
        employee_data = self.to_dict()
        if os.path.exists(self.file_name):
            with open(self.file_name, "r") as db:
                try: 
                    data = json.load(db)
                except:
                    data = []
        else: 
            data = []
        
        data.append(employee_data)

        with open(self.file_name, "w") as db:
            json.dump(data, db, indent=4)

        st.toast('Hooray! Your form is submitted', icon='🎉')
    
st.title("Employee information form") 

with open("interests_list.json", "r") as list:
    intrests = json.load(list)


new_form = EmployeeForm(intrests, "db.json")

W testowaniu przyda się używany przeze mnie plik interests_list.json z przykładowymi zainteresowaniami

[
    "Traveling",
    "Photography",
    "Reading",
    "Cooking",
    "Hiking",
    "Painting",
    "Music",
    "Fitness",
    "Gardening",
    "Writing",
    "Cycling",
    "Swimming",
    "Gaming",
    "Dancing",
    "Crafting",
    "Yoga",
    "Fishing",
    "Volunteering",
    "Technology",
    "Podcasting",
    "Fashion",
    "Martial Arts",
    "Movies",
    "Astronomy",
    "Birdwatching",
    "Blogging",
    "Running",
    "Chess",
    "Investing",
    "Woodworking"
]