How to specify rows and columns of a <textarea > tag using wtforms
Constructing a wtf开发者_StackOverflow中文版orms' 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?
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.
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() }}
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;
}
{{form.text(cols="35", rows="20")|safe}}
is working
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>
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>
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 !
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.
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.)
精彩评论