Python Flask WTForms: How can I disable a field dynamically in a view?
Asked Answered
T

4

21

I've been able to implement this change to create Field which is disabled in WTForms. How would I selectively disable a field in my view before rendering it?

Trebuchet answered 7/5, 2013 at 16:45 Comment(1)
You could try form.field(disabled_="disabled") in template. wtforms.simplecodes.com/docs/1.0.4/…Forde
B
25

vim forms.py:

add_time = DateTimeField(

    '添加时间',
    format='%Y-%m-%d %H:%M:%S',
    default=datetime.datetime.now(),
    # I use bs3,and it well add input an attribute disabled
    render_kw={'disabled':''},
    validators=[DataRequired()],
)
Bolster answered 22/1, 2017 at 7:38 Comment(2)
Thanks for this! In my case, the form had already been instantiated, so I just did form.my_field.render_kw = {'disabled': 'disabled'}.Aili
@Aili consider posting that as an answer so the questioner can mark as accepted.Monjo
O
11

It's almost as @Bibhas proposed. If I understand this correctly and you want to disable a field through the html disabled attribute, then the following worked for me:

form.field(disabled=True)

This answer might be a bit late, but if any one else has this problem it might help.

Orthogenic answered 10/10, 2015 at 16:42 Comment(1)
this would be at render time - what if we want to do it at definition time?Callant
P
8

If you're trying to remove a field you could look at the Removing Fields Per-instance in the documentation.

From the docs:

Sometimes, you create a form which has fields that aren’t useful in all circumstances or to all users. While it is indeed possible with form inheritance to define a form with exactly the fields you need, sometimes it is necessary to just tweak an existing form. Luckily, forms can have fields removed post-instantiation by using the del keyword:

class MagazineIssueForm(Form):
    title  = TextField()
    year   = IntegerField('Year')
    month  = SelectField(choices=MONTHS)

def edit_issue():
    publication = get_something_from_db()
    form = MagazineIssueForm(...)

    if publication.frequency == 'annual':
        del form.month`
Penetrance answered 7/5, 2013 at 17:30 Comment(3)
Thanks. But I'm looking to disable the field, not delete it.Trebuchet
Ah sorry - I misunderstood. How do you mean disable? Display it but make it so the field can't be modified?Penetrance
This is very similar to another question, and I wrote a detailed answer there as well: https://mcmap.net/q/659400/-disabled-field-is-considered-for-validation-in-wtforms-and-flaskMultiplicity
C
1

I am using helper functions below. Example usage

 for button in [ttForm.instancesButton,ttForm.propertiesButton,ttForm.idButton,ttForm.labelButton,ttForm.clearButton]:
            self.setInputDisabled(button)
        self.enableButtonsOnInput([ttForm.idButton,ttForm.clearButton],ttForm.itemLabel)
        self.enableButtonsOnInput([ttForm.labelButton,ttForm.clearButton,ttForm.instancesButton], ttForm.itemId)
        self.enableButtonsOnInput([ttForm.propertiesButton], ttForm.itemCount)

helper functions

  def setInputDisabled(self,inputField,disabled:bool=True):
        '''
        disable the given input
        
        Args:
            inputField(Input): the WTForms input to disable
            disabled(bool): if true set the disabled attribute of the input 
        '''
        if inputField.render_kw is None:
            inputField.render_kw={}
        if disabled:
            inputField.render_kw["disabled"]= "disabled"
        else:
            inputField.render_kw.pop("disabled")
            
    def setRenderKw(self,inputField,key,value):
        '''
        set a render keyword dict entry for the given input field with the given key and value
        
        Args:
            inputField(Input): the field to modify
            key(str): the key to use
            value(str): the value to set
        '''
        if inputField.render_kw is None:
            inputField.render_kw={}
        inputField.render_kw[key]=value
        
    def enableButtonsOnInput(self,buttons:list,inputField):
        '''
        enable the given list of buttons on input in the given inputField
        
        Args:
            inputField(Input): the inputField to set the input trigger
            buttons(list): the list of buttons to enable
        '''
        script=""
        for button in buttons:
            script+=f"document.getElementById('{button.id}').disabled = false;"
        self.setRenderKw(inputField,"oninput",script)
Callant answered 21/3, 2022 at 18:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.