I have a form with select field in my web app. The form is about creating questions that user can later answer. I have form that if you want to create select field question you will be asked to select options for that question and create new ones. For this I am using TomSelect with create option enabled. But when I try to submit my form I have an error that say that my created options are not a valid choice. I tried to update the choices in validate_option function and pre_validate but it didnt work
This is my model:
class Questions(db.Model):
__tablename__ = 'questions'
id = db.Column(db.Integer(), primary_key=True)
question = db.Column(db.String(120))
label = db.Column(db.String(20), unique=True)
type = db.Column(db.String(20))
answers = db.relationship('Answers')
status = db.Column(db.String(20))
groups = db.relationship('Groups', secondary='question_groups', backref='questions')
options = db.relationship('SelectOptions', secondary='questions_select_options', backref='questions')
in_passport = db.Column(db.Boolean())
is_unique = db.Column(db.Boolean())
required = db.Column(db.Boolean())
class SelectOptions(db.Model):
__tablename__ = 'select_options'
id = db.Column(db.Integer(), primary_key=True)
answer = db.Column(db.String())
class QuestionsSelectAnswers(db.Model):
__tablename__ = 'questions_select_options'
id = db.Column(db.Integer(), primary_key=True)
question_id = db.Column(db.Integer(), db.ForeignKey('questions.id', ondelete='CASCADE'))
select_option_id = db.Column(db.Integer(), db.ForeignKey('select_options.id', ondelete='CASCADE'))
This is my form:
class QuestionForm(FlaskForm):
label = StringField(_('Label'), validators=[DataRequired()], render_kw={"placeholder": _('Label')})
question = StringField(_('Question'), validators=[DataRequired()], render_kw={"placeholder": _('Question')})
type = SelectField(_('Type'), validators=[DataRequired()], choices=[('boolean', 'Boolean'), ('date', 'Date'), ('datetime', 'DateTime'), ('file', 'File'), ('integer', 'Integer'), ('radio', 'Radio'), ('select', 'Select'), ('string', 'String'), ('range', 'Range'), ('textarea', 'Text Area')], render_kw={"placeholder": _('Type')})
options = SelectMultipleField(_('Option for select type question'), choices=[('', '')], validators=[Optional()], render_kw={'placeholder': _('Select or type to create options for question')})
aggregaten = SelectMultipleField(_('Available aggregaten'), choices=[('', '')], render_kw={"placeholder": _('Select Aggregat(s)')})
form_type = HiddenField()
question_id = HiddenField(default="")
question_groups = SelectMultipleField(_('Question groups'), choices=[('', '')], validators=[Optional()], render_kw={"placeholder": _('Select group(s) for question')})
required = BooleanField(_('Required?'))
passport = BooleanField(_('Add to passport'))
is_unique = BooleanField(_('Unique'))
submit = SubmitField(_('Submit'))
def validate_label(self, value):
if self.form_type.data != 'edit':
question = Questions.query.filter_by(label=value.data).first()
if question is not None:
flash('Question with this label already exists. Please use different label', 'danger')
raise ValidationError('Please use different label')
I tried to update choices in validate_option but it didnt work. I still got an error that said that option are not valid.
def validate_options(self, field):
if field.data:
self.options.choices = [(choice, choice) for choice in field.data]
Ok I figured it out, Im posting it if anyone has similar problem. This did work for me.
I used this 'custom' field I made to just overwrite pre_validate