R

ReflexKR

Reflex-Dokumentation

Die Komponentenwerkstatt: Reflex' 100 Bibliotheksbausteine

·

Kursüberblick

Layout

·

Box

·

Flex

·

Stack

·

Grid

·

Container

·

Section

·

Center

·

Spacer

·

Separator

·

Card

·

Inset

·

Aspect Ratio

·

Fragment

Typografie

·

Text

·

Heading

·

Link

·

Code

·

Markdown

·

Blockquote

·

Quote

·

Strong

·

Em

·

Kbd

Formulare

·

Button

·

Input

·

Text Area

·

Checkbox

·

Switch

·

Radio Group

·

Select

·

Slider

·

Form

·

Upload

Datenanzeige

·

Badge

·

Avatar

·

Icon

·

Callout

·

List

·

Data List

·

Code Block

·

Progress

·

Spinner

·

Scroll Area

·

Moment

Auf- und Zuklappen

·

Tabs

·

Accordion

·

Segmented Control

Overlays

·

Tooltip

·

Popover

·

Hover Card

·

Dialog

·

Alert Dialog

·

Drawer

·

Dropdown Menu

·

Context Menu

·

Toast

Dynamisches Rendern

·

Cond

·

Match

·

Foreach

·

Auto Scroll

Medien

·

Image

·

Audio

·

Video

Tabellen und Datengrids

·

Table

·

Data Table

·

Data Editor

Diagramme

·

Area Chart

·

Bar Chart

·

Line Chart

·

Composed Chart

·

Pie Chart

·

Radar Chart

·

Radial Bar Chart

·

Scatter Chart

·

Funnel Chart

·

Treemap

·

Sankey Chart

·

Error Bar

Diagrammbausteine

·

Axis

·

Cartesian Grid

·

Chart Tooltip

·

Legend

·

Label

·

Reference

·

Brush

Andere Diagrammbibliotheken

·

Plotly

·

Pyplot

HTML-Elemente

·

HTML

·

HTML Text

·

HTML Layout

·

HTML Forms

·

HTML Media

·

HTML Tables

·

SVG

Weitere Werkzeuge

·

Theme

·

Skeleton

·

Clipboard

·

Html Embed

·

Script

·

Memo

Die Komponentenwerkstatt: Reflex' 100 Bibliotheksbausteine
HTML-Elemente

HTML Forms

rx.el.fieldsetrx.el.formrx.el.labelrx.el.legendrx.el.meterrx.el.optgrouprx.el.optionrx.el.outputrx.el.progressrx.el.selectrx.el.textarea

Offizielle Doku

Werkstattauftrag

Café-Bestellformular: Getränke aus einer nach Sorten gruppierten Liste, Abholart per Radio, Sonderwünsche mehrzeilig, und nach dem Bestellen eine Zusammenfassung.

Das sind die HTML-Elemente rund um Formulare: form sammelt Eingaben, fieldset ist ein Gruppierungskasten mit dem Titel legend, zur Auswahl gibt es select·optgroup·option, für mehrzeilige Eingaben textarea und zum Anzeigen von Werten meter·progress·output. Sie sind leichter als die Radix-Formularkomponenten (rx.select, rx.text_area) und nutzen direkt das eingebaute Verhalten des Browsers.

rx.el.label(
    "Size ",
    rx.el.select(
        rx.el.option("Small", value="s"),
        rx.el.option("Medium", value="m"),
        rx.el.option("Large", value="l"),
        default_value="m",
        border="1px solid gray",
        padding="2px 6px",
    ),
)

Props ausprobieren

meter ändert die Farbe, je nachdem, ob der Wert in einem guten oder schlechten Bereich liegt. low·high sind die Bereichsgrenzen, optimum legt fest, welche Seite gut ist.

Props ausprobieren

value

65

low

30

high

80

optimum

90

rx.el.div(
    rx.el.meter(value=65, min=0, max=100, low=30, high=80, optimum=90, width="260px", height="20px"),
    rx.el.progress(value=65, max=100, width="260px"),
    display="flex",
    flex_direction="column",
    gap="10px",
)
Liegt optimum unter low, gelten niedrige Werte als gut, liegt es über high, hohe Werte. progress ist nur ein Fortschrittsbalken und ändert die Farbe nicht.

Props ausprobieren

placeholder

rows

resize

disabled

read_only

rx.el.textarea(
    placeholder="Write a note",
    rows="4",
    resize="vertical",
    disabled=False,
    read_only=False,
    border="1px solid gray",
    border_radius="6px",
    padding="6px 8px",
    width="280px",
)
rows ist die Zahl sichtbarer Zeilen. resize ist eine CSS-Eigenschaft und legt fest, ob Nutzer die Größe an der Ecke ziehen dürfen.
PropWerteStandardVerwendung
on_submit (form)Event-Handlerkeiner (verhindert nur das Absenden)Bekommt ein dict mit den Werten je name
reset_on_submit (form)True / FalseFalseLeert die Felder nach dem Absenden
no_validate (form)True / FalseFalseSchaltet die Browserprüfung von required·pattern ab
html_for (label, output)Element-idkeinerVerknüpftes Eingabefeld. Ein Klick aufs Label springt dorthin
disabled (fieldset, select, option, optgroup)True / FalseFalseSchaltet alle Eingaben darin ab
value / on_change (select, textarea)String / EventkeinerGesteuerte Eingabe. default_value für ungesteuert
multiple size (select)bool / GanzzahlFalse / keinerMehrfachauswahl, Zahl sichtbarer Zeilen
label (optgroup)StringkeinerGruppentitel
rows cols max_length (textarea)GanzzahlkeinerGröße und Zeichenbegrenzung
auto_height enter_key_submit (textarea)True / FalseFalseHöhe wächst mit dem Text, Absenden mit Enter
value min max low high optimum (meter)Zahlmin=0 max=1Messwert innerhalb eines Bereichs
value max (progress)Zahlmax=1Fortschritt. Ohne value eine „läuft noch“-Anzeige

rx.el.form und on_submit

Beim Klick auf den Absende-Button übergibt on_submit die Werte der Eingabefelder als dict mit name als Schlüssel. Checkboxen kommen nur eingeschaltet als "on" an. Auch ohne on_submit verhindert rx.el.form das Standard-Absenden des Browsers (Neuladen der Seite). Mit reset_on_submit=True werden die Felder nach dem Absenden geleert.

    class HtmlFormSignupState(rx.State):
        submitted: dict[str, str] = {}
    
        @rx.event
        def handle_submit(self, form_data: dict):
            self.submitted = {key: str(value) for key, value in form_data.items()}
    
    
    rx.el.div(
        rx.el.form(
            rx.el.input(name="email", type="email", placeholder="Email", required=True, border="1px solid gray", padding="4px 8px"),
            rx.el.select(
                rx.el.option("Weekly", value="weekly"),
                rx.el.option("Monthly", value="monthly"),
                name="plan",
                border="1px solid gray",
                padding="4px",
            ),
            rx.el.label(rx.el.input(type="checkbox", name="news"), " Send news"),
            rx.el.button("Sign up", type="submit", padding="4px 12px", border="1px solid gray", border_radius="6px"),
            on_submit=HtmlFormSignupState.handle_submit,
            reset_on_submit=True,
            display="flex",
            gap="8px",
            flex_wrap="wrap",
            align_items="center",
        ),
        rx.el.ul(
            rx.foreach(HtmlFormSignupState.submitted, lambda kv: rx.el.li(rx.el.code(kv[0]), " = ", kv[1])),
            margin_top="10px",
        ),
    )

    fieldset, legend, label

    fieldset fasst zusammengehörige Eingaben mit einem Rahmen zusammen, legend ist der Titel dieser Gruppe. Mit disabled=True auf dem fieldset sind alle Eingaben darin abgeschaltet. label umschließt ein Eingabefeld oder wird über html_for mit dessen id verknüpft. Ein Klick auf ein verknüpftes Label setzt den Cursor ins Feld.

    Delivery
    Gift wrap (sold out)
    rx.el.div(
        rx.el.fieldset(
            rx.el.legend("Delivery", font_weight="bold"),
            rx.el.label(rx.el.input(type="radio", name="ship", value="pickup", default_checked=True), " Pickup"),
            rx.el.label(rx.el.input(type="radio", name="ship", value="courier"), " Courier"),
            border="1px solid gray",
            border_radius="6px",
            padding="8px 12px",
            display="flex",
            gap="12px",
        ),
        rx.el.fieldset(
            rx.el.legend("Gift wrap (sold out)", font_weight="bold"),
            rx.el.label(rx.el.input(type="checkbox"), " Wrap it"),
            rx.el.label("Message ", rx.el.input(id="htmlforms_gift_msg", border="1px solid gray")),
            disabled=True,
            border="1px solid gray",
            border_radius="6px",
            padding="8px 12px",
            display="flex",
            gap="12px",
            opacity="0.6",
        ),
        rx.el.label("Coupon", html_for="htmlforms_coupon", margin_right="8px"),
        rx.el.input(id="htmlforms_coupon", placeholder="Click the label", border="1px solid gray", padding="2px 6px"),
        display="flex",
        flex_direction="column",
        gap="10px",
        align_items="start",
    )

    select, optgroup, option

    option ist ein wählbarer Eintrag, optgroup fasst Einträge unter einem label-Titel zusammen. Einträge mit disabled sind nicht wählbar. Mit value und on_change hält der State den gewählten Wert. Mit multiple=True und size wählt man in der ausgeklappten Liste per Strg·Shift mehrere Einträge.

    You picked: soup

    class HtmlFormSelectState(rx.State):
        dish: str = "soup"
    
        @rx.event
        def change_dish(self, value: str):
            self.dish = value
    
    
    rx.el.div(
        rx.el.select(
            rx.el.optgroup(
                rx.el.option("Soup", value="soup"),
                rx.el.option("Salad", value="salad"),
                label="Starters",
            ),
            rx.el.optgroup(
                rx.el.option("Pasta", value="pasta"),
                rx.el.option("Steak (sold out)", value="steak", disabled=True),
                label="Mains",
            ),
            value=HtmlFormSelectState.dish,
            on_change=HtmlFormSelectState.change_dish,
            border="1px solid gray",
            padding="4px",
        ),
        rx.el.p("You picked: ", rx.el.strong(HtmlFormSelectState.dish)),
        rx.el.select(
            rx.el.option("Red"),
            rx.el.option("Green"),
            rx.el.option("Blue"),
            rx.el.option("Black"),
            multiple=True,
            size=3,
            border="1px solid gray",
            width="120px",
        ),
        display="flex",
        flex_direction="column",
        gap="8px",
        align_items="start",
    )

    textarea: Senden mit Enter und automatische Höhe

    Reflex' rx.el.textarea hat zwei Attribute, die es in HTML nicht gibt. Mit enter_key_submit=True sendet Enter das Formular ab, und Shift+Enter bricht die Zeile um. Mit auto_height=True wächst die Höhe mit dem Text (zusammen mit min_height verwenden). enter_key_submit lässt sich nicht mit on_key_down kombinieren.

      class HtmlFormChatState(rx.State):
          messages: list[str] = []
      
          @rx.event
          def send(self, form_data: dict):
              text = str(form_data.get("message", "")).strip()
              if text:
                  self.messages = [*self.messages, text][-4:]
      
      
      rx.el.div(
          rx.el.ul(
              rx.foreach(HtmlFormChatState.messages, lambda m: rx.el.li(m, white_space="pre-wrap")),
              list_style_type="disc",
              padding_left="1.5em",
          ),
          rx.el.form(
              rx.el.textarea(
                  name="message",
                  placeholder="Type and press Enter",
                  enter_key_submit=True,
                  auto_height=True,
                  max_length=200,
                  min_height="40px",
                  width="100%",
                  border="1px solid gray",
                  border_radius="6px",
                  padding="6px 8px",
              ),
              on_submit=HtmlFormChatState.send,
              reset_on_submit=True,
          ),
          max_width="360px",
      )

      output, meter, progress

      output ist der Platz für ein Rechenergebnis; in html_for stehen, durch Leerzeichen getrennt, die ids der beteiligten Eingabefelder. meter ist ein Messwert mit festem Bereich wie die Festplattenbelegung, progress der Fortschritt einer Aufgabe. Ohne value zeigt progress „läuft noch“ an.

      + = 5

      class HtmlFormOutputState(rx.State):
          a: int = 2
          b: int = 3
      
          @rx.event
          def change_a(self, value: float):
              self.a = int(value)
      
          @rx.event
          def change_b(self, value: float):
              self.b = int(value)
      
          @rx.var
          def total(self) -> int:
              return self.a + self.b
      
      
      rx.el.div(
          rx.el.p(
              rx.el.input(id="htmlforms_a", type="number", value=HtmlFormOutputState.a, on_change=HtmlFormOutputState.change_a, width="60px", border="1px solid gray"),
              " + ",
              rx.el.input(id="htmlforms_b", type="number", value=HtmlFormOutputState.b, on_change=HtmlFormOutputState.change_b, width="60px", border="1px solid gray"),
              " = ",
              rx.el.output(HtmlFormOutputState.total, html_for="htmlforms_a htmlforms_b", name="total", font_weight="bold"),
          ),
          rx.el.label("Disk ", rx.el.meter(value=0.7, low=0.5, high=0.8, optimum=0.2, width="160px")),
          rx.el.label("Loading ", rx.el.progress(width="160px")),
          display="flex",
          flex_direction="column",
          gap="8px",
      )

      Auftrag erledigt

      Die Getränke sind mit optgroup gruppiert, die Menge ist eine Zahleneingabe, die Abholart ein Radio im fieldset und die Sonderwünsche ein textarea. Nach dem Absenden schreibt der State die Zusammenfassung in output.

      Your order
      Pickup
      class HtmlFormOrderState(rx.State):
          summary: str = ""
      
          @rx.event
          def place_order(self, form_data: dict):
              qty = form_data.get("qty") or "1"
              note = str(form_data.get("note", "")).strip() or "none"
              self.summary = f"{qty} x {form_data.get('drink')} ({form_data.get('size')}), {form_data.get('pickup')}. Note: {note}"
      
      
      rx.el.div(
          rx.el.form(
              rx.el.fieldset(
                  rx.el.legend("Your order", font_weight="bold"),
                  rx.el.select(
                      rx.el.optgroup(rx.el.option("Latte"), rx.el.option("Mocha"), label="Coffee"),
                      rx.el.optgroup(rx.el.option("Green tea"), rx.el.option("Chai"), label="Tea"),
                      name="drink",
                      border="1px solid gray",
                      padding="4px",
                  ),
                  rx.el.select(rx.el.option("Small"), rx.el.option("Large"), name="size", border="1px solid gray", padding="4px"),
                  rx.el.input(name="qty", type="number", min=1, max=9, default_value=1, width="60px", border="1px solid gray", padding="4px"),
                  display="flex",
                  gap="8px",
                  flex_wrap="wrap",
                  border="1px solid gray",
                  border_radius="6px",
                  padding="8px 12px",
              ),
              rx.el.fieldset(
                  rx.el.legend("Pickup", font_weight="bold"),
                  rx.el.label(rx.el.input(type="radio", name="pickup", value="for here", default_checked=True), " For here"),
                  rx.el.label(rx.el.input(type="radio", name="pickup", value="to go"), " To go"),
                  display="flex",
                  gap="12px",
                  border="1px solid gray",
                  border_radius="6px",
                  padding="8px 12px",
              ),
              rx.el.textarea(name="note", placeholder="Notes for the barista", rows=2, border="1px solid gray", border_radius="6px", padding="6px 8px"),
              rx.el.button("Order", type="submit", padding="6px 14px", border="1px solid gray", border_radius="6px", background=rx.color("indigo", 3)),
              on_submit=HtmlFormOrderState.place_order,
              display="flex",
              flex_direction="column",
              gap="10px",
          ),
          rx.el.output(HtmlFormOrderState.summary, display="block", margin_top="10px", font_weight="600"),
          max_width="420px",
      )

      Werkstattnotizen

      • on_submit von rx.el.form bekommt ein dict {name: Wert}. Jedes Eingabefeld bekommt einen name.

      • Mit fieldset + legend gruppieren, mit disabled am fieldset alles auf einmal abschalten. label per html_for mit der id verknüpfen.

      • select mit option · optgroup, gesteuert per value + on_change. Mehrfachauswahl mit multiple · size.

      • enter_key_submit · auto_height bei textarea sind Komfort-Attribute von Reflex.

      • meter ist ein Messwert, der über low · high · optimum die Farbe wechselt, progress der Fortschritt, output ein Rechenergebnis.

      ← Zurück

      HTML-Elemente · HTML Layout

      Weiter →

      HTML-Elemente · HTML Media

      Über neue Lektionen informiert werden

      Wir schicken dir eine E-Mail, wenn dieser Kurs neue Lektionen bekommt oder ein Folgekurs erscheint.

      Erhoben: deine E-Mail-Adresse · Zweck: Hinweise auf neue Lektionen oder den Start dieses Kurses · Speicherdauer: bis du die Löschung verlangst. Keine andere Nutzung, keine Weitergabe. Antworte einfach auf eine Benachrichtigung, dann löschen wir sie sofort.

      Fragen & Antworten

      Frag alles zu dieser Lektion. Fragen aus allen Sprachversionen dieser Seite erscheinen hier gemeinsam.

      Wird als reiner Text angezeigt, ohne Links oder Formatierung.

      R

      ReflexKR

      Python und Reflex zum Anfassen. Alle Beispiele wurden mit Reflex 0.10.0 ausgeführt und geprüft.

      ReflexKR ist kostenlos und ohne Werbebanner. Wenn es dir geholfen hat, kannst du es mit einem Kaffee unterstützen. ☕ Spendier uns einen Kaffee

      Hinweis zu Affiliate-Links
      한국어English日本語简体中文EspañolDeutsch

      © 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

      Built with Reflex