Richiedlon
Richiedlon

Reputation: 111

Show Hide form elements based on select Flask

I have developed a flask webform for my web project. I need to remove or Deactivate one file upload element base on User selection in select element.

class MyForm(FlaskForm):
    email = StringField('Email')
    fileBase = FileField('Base OBS file:')
    fileObsRover= FileField('Rover OBS file:')
    fileNavRover= FileField('Rover NAV file:')
    password = TextField('Name')
    textarea = IntegerField('Elevation mask angle')
    #radios = RadioField('Frequecies', default='option1', choices=[('option1', 'L1'), ('option2', 'L2'), ('option3', 'L1 and L2')])
    selects = SelectField('Positioning mode', choices=[('0', 'Single Point Positioning'), ('1', 'DGPS/DGNSS'), ('2', 'Kinematic'), ('3', 'Static Positioning')])

I want to delete fileBase file field if user selected Positioning mode as Single Point Positioning before rendering the template.

I have read some articles about Removing fields per instance. But I'm having trouble implementing the same code for my form. Any suggestions are really appreciated.

I have tried using following code

def edit_issue():
    if Myform.selects.data == 'Single Point Positioning':
        del MyForm.fileBase

But the template wont delete when single point positioning selected

Upvotes: 1

Views: 3692

Answers (1)

pjcunningham
pjcunningham

Reputation: 8046

Removing Fields Per-instance is used before a form is rendered and sent to the browser. It looks like that you want to remove the field after it has been sent to the browser and a user has selected a particular option, in which case you will need to use Javascript in the browser to manipulate the form.

An alternative without resorting to Javascript would be to split your form processing into a two step process.

Define three forms as follows:

class PositioningModeForm(FlaskForm):
    selects = SelectField('Positioning mode', choices=[('0', 'Single Point Positioning'), ('1', 'DGPS/DGNSS'), ('2', 'Kinematic'), ('3', 'Static Positioning')])

class SinglePointPositioningForm(FlaskForm):
    email = StringField('Email')
    fileObsRover= FileField('Rover OBS file:')
    fileNavRover= FileField('Rover NAV file:')
    password = TextField('Name')
    textarea = IntegerField('Elevation mask angle')

class OtherPointPositioningForm(SinglePointPositioningForm):
    selected_id = HiddenField()
    fileBase = FileField('Base OBS file:')

Note that OtherPointPositioningForm inherits from SinglePointPositioningForm so it has all the required input fields. OtherPointPositioningForm also has a hidden field to store the selected positioning mode. You don't need this field in the SinglePointPositioningForm as you clearly know the positioning mode.

Step 1.

Send a PositioningModeForm to the browser asking the user what Positioning Mode they want to work on

Step 2

Process the form and internally redirect to either one of two routes depending on the selected Positioning Mode. One route renders a SinglePointPositioningForm whilst the other renders a OtherPointPositioningForm

Upvotes: 1

Related Questions