Getting user feedback in conditionally rendered forms

Hi all, I recently built a simple app that takes user text as input, generates a response, and then asks for user feedback. There are two options for rendering the user feedback form:

  1. Render feedback form simultaneously with everything else.
    Pro: The text can be captured in a variable when the form is submitted.
    Con: It doesn’t look as slick.

  2. Render feedback form only if the user submits something.
    Pro: Looks and feels great.
    Con: The form renders fine but its contents are lost.

I’d really like to go with Option 2 but it’s impossible to access the contents of the form on the backend. Here is a code snippet that illustrates the problem:

import streamlit as st
import time

with st.form('input_form'):
    query = st.text_area('Ask a question')
    submitted_input = st.form_submit_button('Submit question')
    print(query) # works fine

if submitted_input:
    with st.spinner(text='This may take a moment...'):
        time.sleep(2) # simulate generating a response
    st.text("That's a good question! I think that...") # simulated response
    
    with st.form('feedback_form'):
        feedback = st.text_input('What did you think of this answer?')
        submitted_feedback = st.form_submit_button('Submit feedback')
        print(feedback) # empty string

To turn this into Option 1 simply remove the if submitted_input guard.

Does anyone have a workaround or at least some insight into why this doesn’t work? Thanks.

Hi @intalentive i think what you can do is to add a callback to your submit button and you can create a container to store the input_form and feedback_form eg.

container_1 = st.container()
container_1.empty() 
container_2 = st.container()
container_2.empty()

def create_feedback():
    with container_2:
        with st.form('feedback_form'):
            feedback = st.text_input('What did you think of this answer?')
            submitted_feedback = st.form_submit_button('Submit feedback')

with container_1:
    with st.form('input_form'):
        query = st.text_area('Ask a question')
        submitted_input = st.form_submit_button('Submit question', on_click = create_feedback)
        print(query) # works fine

    if submitted_input:
        with st.spinner(text='This may take a moment...'):
            time.sleep(2) # simulate generating a response
        st.text("That's a good question! I think that...") # simulated response
1 Like

Thanks for your response! I was really hoping that this would work, but when I add a print statement as follows, I still get the empty string.

def create_feedback():
    with container_2:
        with st.form('feedback_form'):
            feedback = st.text_input('What did you think of this answer?')
            submitted_feedback = st.form_submit_button('Submit feedback')
            print(feedback) # nothing!

Hi @intalentive, you get an empty string because the form feedback button causes a refresh and your print statement line is not encountered.

Here’s are small modifications to @mliu code:

import streamlit as st
import time

container_1 = st.container()
container_1.empty() 
container_2 = st.container()
container_2.empty()

def print_fdbk():
    print(st.session_state.fbk)
    st.session_state.qry = ""

def create_feedback():
    with container_2:
        with st.form('feedback_form'):
            feedback = st.text_input('What did you think of this answer?', key='fbk')
            submitted_feedback = st.form_submit_button('Submit feedback', on_click=print_fdbk)

with container_1:
    with st.form('input_form'):
        query = st.text_area('Ask a question', key='qry')
        submitted_input = st.form_submit_button('Submit question', on_click = create_feedback)
        print(query)

    if submitted_input:
        with st.spinner(text='This may take a moment...'):
            time.sleep(2) # simulate generating a response
        st.text("That's a good question! I think that...") # simulated response

Hope this helps…

Cheers

1 Like

Fantastic, thank you! This works perfectly.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.