# Flask WTF

***

**1. Create a Simple Form**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField

class MyForm(FlaskForm):
    name = StringField('Name')
    submit = SubmitField('Submit')
```

**2. Form Validation**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, validators

class MyForm(FlaskForm):
    name = StringField('Name', validators=[validators.DataRequired()])
    submit = SubmitField('Submit')
```

**3. Custom Validators**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, validators

class MyForm(FlaskForm):
    name = StringField('Name', validators=[validators.DataRequired(), my_custom_validator])
    submit = SubmitField('Submit')
```

**4. Form Fields with Default Values**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField

class MyForm(FlaskForm):
    name = StringField('Name', default='John Doe')
    submit = SubmitField('Submit')
```

**5. Handling Errors**

```python
@app.route('/', methods=['GET', 'POST'])
def index():
    form = MyForm()
    if form.validate_on_submit():
        # Form is valid
        return redirect(url_for('success'))
    else:
        # Form is invalid
        return render_template('index.html', form=form)
```

**6. Populating Form Data from Model**

```python
class MyModel:
    def __init__(self, name):
        self.name = name

@app.route('/', methods=['GET', 'POST'])
def index():
    model = MyModel('John Doe')
    form = MyForm(obj=model)
    if form.validate_on_submit():
        # Form is valid
        return redirect(url_for('success'))
    else:
        # Form is invalid
        return render_template('index.html', form=form)
```

**7. Using FieldList**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, FieldList, FormField

class ItemForm(FlaskForm):
    name = StringField('Name')

class MyForm(FlaskForm):
    items = FieldList(FormField(ItemForm), min_entries=1)
    submit = SubmitField('Submit')
```

**8. Nested Forms**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, FormField

class SubForm(FlaskForm):
    name = StringField('Name')

class MyForm(FlaskForm):
    subform = FormField(SubForm)
    submit = SubmitField('Submit')
```

**9. File Upload**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, FileField, validators

class MyForm(FlaskForm):
    name = StringField('Name')
    file = FileField('File', validators=[validators.DataRequired()])
    submit = SubmitField('Submit')
```

**10. CSRF Protection**

```python
from flask import Flask, request
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
csrf = CSRFProtect(app)

@app.route('/', methods=['GET', 'POST'])
@csrf.exempt
def index():
    # ...
```

**11. Custom Error Messages**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, validators

class MyForm(FlaskForm):
    name = StringField('Name', validators=[validators.DataRequired(message='Name is required.')])
    submit = SubmitField('Submit')
```

**12. Form Translation**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, validators
from flask_babel import lazy_gettext

class MyForm(FlaskForm):
    name = StringField(lazy_gettext('Name'), validators=[validators.DataRequired()])
    submit = SubmitField(lazy_gettext('Submit'))
```

**13. Conditional Validation**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, validators

class MyForm(FlaskForm):
    name = StringField('Name', validators=[validators.DataRequired(message='Name is required if the checkbox is checked.')])
    checkbox = BooleanField('Checkbox')
    submit = SubmitField('Submit')
```

**14. SelectField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, SelectField

class MyForm(FlaskForm):
    name = StringField('Name')
    choices = [('1', 'Option 1'), ('2', 'Option 2'), ('3', 'Option 3')]
    select_field = SelectField('Select Field', choices=choices)
    submit = SubmitField('Submit')
```

**15. RadioField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, RadioField

class MyForm(FlaskForm):
    name = StringField('Name')
    choices = [('1', 'Option 1'), ('2', 'Option 2'), ('3', 'Option 3')]
    radio_field = RadioField('Radio Field', choices=choices)
    submit = SubmitField('Submit')
```

**16. CheckboxField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, BooleanField

class MyForm(FlaskForm):
    name = StringField('Name')
    checkbox_field = BooleanField('Checkbox Field')
    submit = SubmitField('Submit')
```

**17. HiddenField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, HiddenField

class MyForm(FlaskForm):
    name = StringField('Name')
    hidden_field = HiddenField('Hidden Field')
    submit = SubmitField('Submit')
```

**18. DateField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, DateField

class MyForm(FlaskForm):
    name = StringField('Name')
    date_field = DateField('Date Field')
    submit = SubmitField('Submit')
```

**19. TimeField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, TimeField

class MyForm(FlaskForm):
    name = StringField('Name')
    time_field = TimeField('Time Field')
    submit = SubmitField('Submit')
```

**20. DateTimeField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, DateTimeField

class MyForm(FlaskForm):
    name = StringField('Name')
    datetime_field = DateTimeField('DateTime Field')
    submit = SubmitField('Submit')
```

**21. IntegerField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, IntegerField

class MyForm(FlaskForm):
    name = StringField('Name')
    integer_field = IntegerField('IntegerField')
    submit = SubmitField('Submit')
```

**22. FloatField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, FloatField

class MyForm(FlaskForm):
    name = StringField('Name')
    float_field = FloatField('FloatField')
    submit = SubmitField('Submit')
```

**23. DecimalField**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, DecimalField

class MyForm(FlaskForm):
    name = StringField('Name')
    decimal_field = DecimalField('DecimalField')
    submit = SubmitField('Submit')
```

**24. Form Validation with AJAX**

```python
@app.route('/form-validate', methods=['POST'])
def form_validate():
    form = MyForm()
    if form.validate_on_submit():
        return jsonify({'success': True})
    else:
        errors = form.errors
        return jsonify({'errors': errors})
```

**25. Custom Validation with AJAX**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from werkzeug.datastructures import MultiDict

class MyForm(FlaskForm):
    name = StringField('Name')
    submit = SubmitField('Submit')

    def validate_name(form, field):
        if field.data != 'John Doe':
            raise ValidationError('Name must be John Doe.')

@app.route('/form-validate', methods=['POST'])
def form_validate():
    form = MyForm(MultiDict(request.form, request.files))
    if form.validate():
        return jsonify({'success': True})
    else:
        errors = form.errors
        return jsonify({'errors': errors})
```

**26. Form Submission with AJAX**

```python
@app.route('/form-submit', methods=['POST'])
def form_submit():
    form = MyForm()
    if form.validate_on_submit():
        # ...
        return jsonify({'success': True})
    else:
        return jsonify({'errors': form.errors})
```

**27. Populating Form Data with AJAX**

```python
@app.route('/form-populate', methods=['GET'])
def form_populate():
    data = {'name': 'John Doe'}
    form = MyForm(data=data)
    return jsonify({'success': True, 'form': render_template('form.html', form=form)})
```

**28. HTML5 Validation**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField

class MyForm(FlaskForm):
    name = StringField('Name', validators=[validators.DataRequired(message='Please enter your name.')])
    submit = SubmitField('Submit')
```

**29. Custom Field Widgets**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.widgets import TextArea

class MyTextAreaField(TextArea):
    def __call__(self, field, **kwargs):
        kwargs.setdefault('rows', 10)
        return super(MyTextAreaField, self).__call__(field, **kwargs)

class MyForm(FlaskForm):
    name = StringField('Name')
    description = StringField('Description', widget=MyTextAreaField())
    submit = SubmitField('Submit')
```

**30. Custom CSS Styling**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField

class MyForm(FlaskForm):
    name = StringField('Name')
    submit = SubmitField('Submit')

@app.route('/')
def index():
    form = MyForm()
    return render_template('index.html', form=form)

@app.route('/css')
def css():
    return '''
        .form-control {
            border: 1px solid #ccc;
            border-radius: 4px;
            padding: 6px 12px;
            font-size: 14px;
        }

        .btn-primary {
            background-color: #337ab7;
            border-color: #2e6da4;
            color: #fff;
            padding: 6px 12px;
            font-size: 14px;
        }
    '''
```

**31. Handling Multiple Forms on the Same Page**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField

class Form1(FlaskForm):
    name = StringField('Name')
    submit = SubmitField('Submit Form 1')

class Form2(FlaskForm):
    email = StringField('Email')
    submit = SubmitField('Submit Form 2')

@app.route('/')
def index():
    form1 = Form1()
    form2 = Form2()
    return render_template('index.html', form1=form1, form2=form2)
```

**32. Conditional Field Rendering**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, BooleanField

class MyForm(FlaskForm):
    name = StringField('Name')
    show_email = BooleanField('Show Email')
    email = StringField('Email', render_kw={'disabled': True})
    submit = SubmitField('Submit')
```

**33. File Upload with Multiple Files**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, FileField, validators

class MyForm(FlaskForm):
    name = StringField('Name')
    files = FileField('Files', validators=[validators.DataRequired()])
    submit = SubmitField('Submit')
```

**34. Field Grouping**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, FieldList, FormField

class SubForm(FlaskForm):
    name = StringField('Name')

class MyForm(FlaskForm):
    group = FieldList(FormField(SubForm), min_entries=1, max_entries=3)
    submit = SubmitField('Submit')
```

**35. Dynamic Form Creation**

```python
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, FieldList, FormField

class SubForm(FlaskForm):
    name = StringField('Name')

@app.route('/')
def index():
    form = FlaskForm()
    for i in range(3):
        form.subform_list.append_entry(SubForm())
    return render_template('index.html', form=form)
```

**36. Multi-step Form**

```python
from flask_wtf import FlaskForm, Form
from wtforms import StringField, SubmitField

class Step1Form(FlaskForm):
    name = StringField('Name')
    submit = SubmitField('Next')

class Step2Form(FlaskForm):
    email = StringField('Email')
    submit = SubmitField('Submit')

@app.route('/')
def index():
    return render_template('step1.html', form=Step1Form())

@app.route('/step2', methods=['POST'])
def step2():
    form = Step1Form()
    if form.validate_on_submit():
        # Store the data in the session
        session['name'] = form.name.data
        return redirect(url_for('step2'))
    else:
        return render_template('step1.html', form=form)

@app.route('/step2')
def step2():
    form = Step2Form()
    # Load the data from the session
    form.email.data = session.get('name')
    return render_template('step2.html', form=form)
```
