0

I am creating a form to find other group members, where all members belongs to departments. Some department, but not all, departments have an internal id that can be used to identify each member. Each department also has a different term for this internal member id. Department A calls it "personal identifier," department B calls it "unique id," etc. In the database departments table, the member_id_term field stores what the department calls the internal member id. In the members table in the database, the internal_id stores the member's internal_id if they belong to a department with the internal_id system.

On the first page of the form, the user selects the department, and on the second page of the form, if the user has selected a department that uses internal member ids, they are asked to put the internal member id.

My strategy was to create a variable in views.py called member_id_term and set it to 0 if there is no form.dept.data, but to set member_id_term to form.dept.data.member_id_term when form.dept.data exists. Then, in input_find_member.html, I would conditionally display the input field for internal_id if member_id_term exists.

Problem: I don't have access to form.dept.data until I submit the form. How can I access this value before submitting the form?

Here is the code I currently have. It throws an error on member_id_term = 0 if not form.dept.data else form.dept.data.member_id_term and says that form.dept.data is none.

forms.py

class FindMemberForm(Form):
    name = StringField(
        'name', default='', validators=[Regexp('\w*'), Length(max=50),
                                        Optional()]
    )
    internal_id = StringField('internal_id', default='', validators=[Regexp('\w*'), Length(max=55)])
    dept = QuerySelectField('dept', validators=[DataRequired()],
                            query_factory=dept_choices, get_label='name')

views.py

@main.route('/find', methods=['GET', 'POST'])
def get_officer():
    form = FindMemberForm()
    member_id_term = 0 if not form.dept.data else form.dept.data.member_id_term

    if form.validate_on_submit():
        return redirect(url_for('main.get_gallery'), code=307)
    return render_template('input_find_member.html', form=form)         

{% extends "base.html" %}
{% block content %}

and here is input_find_member.html

<div role="main">
    <div class="hero-section no-sub">
        <div class="hero">Find a Member </div>
    </div>
</div>

<div class="container" role="main">

  <form action="{{ url_for('main.get_member') }}" method="post" class="form">
  {{ form.hidden_tag() }}
      <div class="row form-group">
        <div class="col-xs-12">
            <ul class="nav nav-pills nav-justified thumbnail setup-panel">
                <li class="active"><a href="#step-1">
                    <h4 class="list-group-item-heading">Step 1</h4>
                    <p class="list-group-item-text">Department Information</p>
                </a></li>
                <li class="disabled"><a href="#step-2">
                    <h4 class="list-group-item-heading">Step 2</h4>
                    <p class="list-group-item-text">Member Info </p>
                </a></li>
            </ul>
        </div>
    </div>
    <div class="row setup-content" id="step-1">
        <div class="col-xs-12">
            <div class="col-md-12 well text-center">
                <h2><small>Select Department</small></h2>
                <div class="input-group input-group-lg col-md-4 col-md-offset-4">
                {{ form.dept(class="form-control") }}
                </div>

                {% for error in form.dept.errors %}
                <p>
                  <span style="color: red;">[{{ error }}]</span>
                </p>
                {% endfor %}

                <br>
                <button id="activate-step-2" class="btn btn-primary btn-lg">Next Step</button>
            </div>
        </div>
    </div>
    <div class="row setup-content" id="step-2">
        <div class="col-xs-12">
            <div class="col-md-12 well text-center">
                <h2><small>Do you know the member's name?</small></h2>
                <div class="input-group input-group-lg col-md-4 col-md-offset-4">
                  {{ form.name(class="form-control") }}
                  {% for error in form.name.errors %}
                      <p><span style="color: red;">[{{ error }}]</span></p>
                  {% endfor %}
                </div>

                {% if member_id_term %}
                    <h2><small>Do you know the member's {{ member_id_term }}?*</small></h2>
                    <div class="input-group input-group-lg col-md-4 col-md-offset-4">
                    {{ form.internal_id(class="form-control") }}
                    {% for error in form.internal_id.errors %}
                        <p><span style="color: red;">[{{ error }}]</span></p>
                    {% endfor %}
                    </div>
                {% endif %}
                <br>
                <button id="activate-step-3" class="btn btn-primary btn-lg">Next Step</button>
            </div>
        </div>
    </div>
  </form>
</div>

I've already read these pages
Flask WTForms: how do I get a form value back into Python?
Get data from WTForms form
populate WTForms select field using value selected from previous field

Thanks for reading!

ByteByByte
  • 303
  • 1
  • 2
  • 11
  • 1
    You can't do this in a single server-side view because, as you've observed, you need information which has yet to be provided. A server-side solution to would be to first render a form that collects the required information, on submit redirect the user to another form to collect the rest of the information. A less clunky solution would be to hide the dependent fields initially and use javascript to re-label and reveal them once the reuired information has been input. – snakecharmerb Apr 20 '19 at 16:35
  • I agree with @snakecharmerb You can also use Ajax for that matter. – Sanjay Mangaroliya Dec 12 '19 at 04:46

0 Answers0