How to specify rows and columns of a <textarea > tag using wtforms
Asked Answered
P

9

20

Constructing a wtforms' TextAreaField is something like this:

content = wtf.TextAreaField('Content', id="content-area", validators=[validators.Required()])

How can I specify the number of rows and columns associated with this textarea?

Putto answered 8/2, 2011 at 7:53 Comment(0)
G
28

You are not supposed to do it in the place where you declare the widget. You have do it in the template. For eg:

{{form.content(rows='50',cols='100')}}

Need to ensure the rows and cols are specified as a string.

Grigson answered 25/2, 2011 at 11:27 Comment(3)
Me neither. There is some corner case which need resolving.Dyche
I'd recommend turning those ints into strings. I think Jinja2 only takes Strings into it's named variables for the most part.Forename
I think it's a pretty significant limitation of the library that it doesn't specify a way to define these attributes in python.Borstal
C
15

Much simpler; use render_kw argument when creating the field:

port = IntegerField(u"HTTP port", validators=[DataRequired(), NumberRange(1025, 65535)], render_kw={'class': 'form-control'})
mytextarea = TextAreaField(u"Content", render_kw={'class': 'form-control', 'rows': 5})

And then render the file:

{{ field() }}
Cartomancy answered 11/8, 2016 at 17:54 Comment(1)
Best way to do this!Priestly
A
5

There is a tutorial on Flask by nettuts+. Basically, it works like this:

from flask.ext import wtf

class ContactForm(wtf.Form):
    content = wtf.TextAreaField("Content", [validators.Required()])

and in your html:

<form action="" method="post">
    {{ form.content }}
</form>

Instead of specifying the layout in html, you can specify it in your css, for example:

form textarea#content {
     width: 100px;
     height: 100px;
     max-width: 100px;
}
Arbitress answered 20/4, 2013 at 8:15 Comment(1)
This is a nice work around, but it doesn't specifically answer the question of how you do it purely with Flask/Jinja2.Forename
A
4

{{form.text(cols="35", rows="20")|safe}} is working

Anemochore answered 5/11, 2011 at 20:36 Comment(0)
M
3

Here is an example:

<div class="row">
    <div class="col-md-12">
        <div class="form-group">
            {{ wtf.form_field(form.notes, rows=5) }}
        </div>
    </div>
</div>
Mandimandible answered 3/12, 2015 at 0:52 Comment(0)
O
3

I was able to modify the rows and columns via the render_kw tag on the python forms page. When I first saw the definition of this on WTForm's website, I didn't know what it did until seeing other people's examples of using this to modify the class of the form element. So their definition just confused me until I started experimenting with it.

render_kw (dict) – If provided, a dictionary which provides default keywords that will be given to the widget at render time. - https://wtforms.readthedocs.io/en/stable/fields.html

I used this on my forms page.

current_templates_in_library = TextAreaField('current_templates_in_library', render_kw={'rows':'4'})

To add multiple tags and values, just separate them with a comma like this.

render_kw={'class':'myclass','rows':'4'}

Then this was rendered in the HTML. Notice the "rows" attribute there that was added.

<textarea class="form-control" id="current_templates_in_library" name="current_templates_in_library" rows="4" style="z-index: auto; position: relative; line-height: 20px; font-size: 14px; transition: none 0s ease 0s; background: transparent !important;">
rhel6
rhel7
win_2012r2
centos7
</textarea>
Ounce answered 17/1, 2019 at 16:26 Comment(0)
E
1

For convenience, add this macro first.

_formhelpers.html:

{% macro render_field(field) %}
  <dt>{{ field.label }}
  <dd>{{ field(**kwargs)|safe }}
  {% if field.errors %}
    <ul class=errors>
    {% for error in field.errors %}
      <li>{{ error }}</li>
    {% endfor %}
    </ul>
  {% endif %}
  </dd>
{% endmacro %}

Import this macro and code in this way. it should work.

{% from "_formhelpers.html" import render_field %}
<form action="" method="post">
    {{ render_field(form.content,rows=100, cols=100) }}
</form>

Hope it helps !

Emmery answered 27/8, 2014 at 1:48 Comment(0)
L
1

You could simply use this replacement widget that is remembering default values for the rendering:

import wtforms.widgets.core

class TextArea(wtforms.widgets.core.TextArea):
    def __init__(self, **kwargs):
        self.kwargs = kwargs

    def __call__(self, field, **kwargs):
        for arg in self.kwargs:
            if arg not in kwargs:
                kwargs[arg] = self.kwargs[arg]
        return super(TextArea, self).__call__(field, **kwargs)

Now you can add this new widget to your Field:

content = wtf.TextAreaField(
    'Content',
    id='content-area',
    widget=TextArea(rows=50,cols=100),
    validators=[validators.Required()])

You now can render this field without any extra arguments and get a 50x100 textarea.

Lahnda answered 18/11, 2014 at 2:54 Comment(0)
C
-1

I looked at the code and found that Field class defines both __new__ and __init__. __new__ takes a bunch of *args and **kargs. So, you can just pass rows=x cols=y in your TextAreadField creation and it should work. I noticed that wtforms is creating a class called "UnboundField" for such cases, I don't know the implications of that as where this would cause problems, if any. But the next step of creating the TextAreaField are same. (That is control goes to __init__ call as before.)

Cierracig answered 8/2, 2011 at 8:11 Comment(1)
That's what I thought too, but that doesn't work: "an unexpected keyword argument 'rows'"Putto

© 2022 - 2024 — McMap. All rights reserved.