Adding SelectQueryField Id attribute in Jinja2 - python

I'm trying to assign Id attribute to the SelectQueryField in Jinja.
The problem is Jinja don't render variable in double curly brackets.
<form method="post" class="form form-inline" >
{{ form.opcje(class="form-control form-select", id="{{user.id}}" ) }}
</form>
output:
<select class="form-control form-select" id="{{user.id}}" name="opcje"><option selected="" value="__None">Wybierz cechÄ™</option><option value="1">Sklepy</option><option value="2">Niemcy</option><option value="3">Holandia</option></select>

Try:
<form method="post" class="form form-inline" >
{{ form.opcje(class="form-control form-select", id=user.id ) }}
</form>
You can use variables inside the first set of {{...}} freely.

Related

How to have radio buttons with Materialize and WTForms?

In Materialize you define the radio group of a radio button using the attribute name, but Flask-WTForms binds the input with an attribute name.
If I have the following in my template:
{{ form.radio1(type='radio', name='group1') }}
{{ form.radio2(type='radio', name='group1') }}
There will be an error:
TypeError: html_params() got multiple values for keyword argument 'name'
And if we don't add the name, the radios won't work as radios, just as checkboxes, as expected.
How can i get around this?
This is my form class:
class AbcForm(FlaskForm):
field1 = HiddenField('Field1')
field2 = HiddenField('Field2')
and then at runtime I'll dynamically add the radios, here's a simplification:
class F(AbcForm):
pass
setattr(F, radio1, BooleanField('Radio1')
setattr(F, radio2, BooleanField('Radio2')
form = F(field1=x, field2=y)
You can't set the name attribute in your field, wtforms already does that for you.
Use the RadioField instead of HiddenField:
from wtforms import RadioField
from flask_wtf import Form
class YourForm(Form):
radio_group = RadioField('label', choices=[('value','description'),('value_two','some other description')])
(...)
Then, in your endpoint:
#route('/your/route')
def your_endpoint():
your_form = YourForm()
(...)
return render_template('/your/template.html', form=your_form)
Finally, in your template:
<form action="#">
{% for subfield in form.radio_group %}
<p>
{{ subfield }}
{{ subfield.label }}
</p>
{% endfor %}
</form>
This generates the following code:
<form action="#">
<p>
<input id="radio_group-0" name="radio_group" type="radio" value="value">
<label for="radio_group-0">description</label>
</p>
<p>
<input id="radio_group-1" name="radio_group" type="radio" value="value_two">
<label for="radio_group-1">some other description</label>
</p>
</form>
Which, given materialize is included in the template, will render the radio buttons properly as shown in this plunker.

Flask hidden input doesn't get set in template

So I'm trying to pass a value from a Jinja2 template back to my Python code. I'm trying to do this with a hidden input. My form class is this:
class TrueOrFalseForm(flask_wtf.FlaskForm):
choice = RadioField(choices=[('True', 'TRUE'), ('False', 'FALSE')], validators=[validators.InputRequired()])
hidden = HiddenField()
submit = SubmitField('Submit')
And my form is this:
<form autocomplete="off" action="" method="post">
{{ form.hidden_tag() }}
<div style="text-align: center">
<div style="display: inline-block">
{{ form.choice }}
{{ form.hidden(value="{{ result }}") }}
{{ form.submit(class_="btn btn-primary btn-lg") }}
</div>
</div>
</form>
result is a string that I'm passing when rendering the template.
When checking the value of form.hidden.data, though, it comes back as ''. The tag also renders as <input id="hidden" name="hidden" type="hidden" value="">.
I've also tried doing value={{ result }} instead of value="{{result}}" but that makes Jinja throw a TemplateSyntaxError.
Any idea on how to do this?
EDIT:
I'm overwriting result every time I call the function.
This is my route function:
#app.route('/', methods=['GET', 'POST'])
def home():
form = forms.TrueOrFalseForm()
x = random.randint(-100, 100)
y = random.randint(-100, 100)
statement_str = generate_statement_string(2)
tree = BinTree.build_tree(statement_str)
statement_result = BinTree.solve_tree(tree, x, y) # result gets overwritten here
if form.validate_on_submit():
if not flask_login.current_user.is_anonymous:
# same as the else, except with some sql, not relevant
else:
if form.choice.data == form.hidden.data:
flask.flash('Correct!')
else:
flask.flash('Incorrect!')
return flask.render_template('home.html', x_value=str(x), y_value=str(y), statement=statement_str,
result=str(statement_result), form=form)
{{ form.hidden(value="{{ result }}") }} is already in templating syntax with the outer double curly brackets. Therefore, you should just be able to plainly write the result variable, like this: {{ form.hidden(value=result) }}
EDIT
Replace {{ form.hidden_tag() }} with {{ form.csrf_token() }} as well as doing what is in my original answer.
You may also have to instantiate the form with form = forms.TrueOrFalseForm(request.form). Some forms behave weirdly if you don't do that.
Since you're using {{ form.hidden_tag() }} in your template, you do not need to explicitly render the hidden form field. It will be included in the hidden_tag() call.
You can set the value of the hidden field in your views before rendering the template.
views.py
form.hidden.data = result
return render_template("index.html",form=form)
index.html
<form autocomplete="off" action="" method="post">
{{ form.hidden_tag() }}
<div style="text-align: center">
<div style="display: inline-block">
{{ form.choice }}
{{ form.submit(class_="btn btn-primary btn-lg") }}
</div>
</div>
</form>
My proposal is:
<input type="hidden" id="locphoto" value="{{ mbrs.photoName|safe }}" />
Previous answer are correct but I think they need some correction putting safe in variable jinja:

List item template Django

I'm dealing creating a template on Django to show a list of items with 2 buttons that make actions.
My form class it's:
class AppsForm(forms.Form):
def __init__(self, *args, **kwargs):
policiesList = kwargs.pop('policiesList', None)
applicationList = kwargs.pop('applicationList', None)
EC2nodesList = kwargs.pop('amazonNodesList', None)
super(AppsForm, self).__init__(*args, **kwargs)
self.fields['appsPolicyId'] = forms.ChoiceField(label='Application Policy', choices=policiesList)
self.fields['appsId'] = forms.ChoiceField(label='Application', choices=applicationList)
self.fields['ec2Nodes'] = forms.ChoiceField(label='Amazon EC2 Nodes', choices=EC2nodesList)
Now, I do the form with:
<form method="post" action="" class="form-inline" role="form">
<div class="form-group">
{% for field in form %}
{ field.label }}: {{ field}}
{% endfor %}
</div>
{% csrf_token %}
<input type="submit" class="btn btn-default btn-success" name="deployButton" value="Deploy"/>
<input type="submit" class="btn btn-default btn-danger" name="undeployButton" value="Undeploy"/>
And the result it's:
Application Policy - Choicefield ; Application - Choicefield ; Amazon EC2 Nodes - Choicefield [Button Deploy] [Button Undeploy]
And what I'm looking for it's a way to render the form and show the list like this:
Application Policy - Choicefield ; Application - Choicefield [Button Deploy] [Button Undeploy]
Amazon EC2 Nodes - Choicefield [Button Deploy] [Button Undeploy]
<more items if I add them in forms.py...>
How I can get the proper way to render like that?
Thanks and regards.
You just need to change the code a bit is all:
{% for field in form %}
{ field.label }}: {{ field}}
<input type="submit" class="btn btn-default btn-success" name="deployButton" value="Deploy"/>
<input type="submit" class="btn btn-default btn-danger" name="undeployButton" value="Undeploy"/>
<br />
{% endfor %}
So this will create a new line for each of the field.label and field variables with their own button. One thing to caution against though, if you try and assign ID's to the buttons they will have to be different or you'll get errors. Also, submission may be a bit weird with code such as this but it depends on the rest of your application. Either way, this will give you the desired format.

Flask WTF-forms adding select and textarea

I am trying to make a flask form which produces the following HTML:
<input type="text" name="title" class="field">
<textarea class="field"></textarea>
<select name="status">
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
So far, since I am new to python, I got this far.
{% from "forms/macros.html" import render_field %}
<form method="POST" action="." class="form">
{{ render_field(form.title, class="input text") }}
My question is, have I got this correct so far for the title field, and assuming I have, could someone please explain how I can get a textarea and selectfield? I have read the docs and I am finding it almost impossible to get my head around it.
In my opinion it's better to define the form not in the template but in the controller.
Example form definition :
class CommentForm(Form):
language = SelectField(u'What You Want', choices=CAN_BE_FILLED_LATER_ON)
code = TextAreaField()
All you need later on is to -
Initialize the form by:
comment_form = CommentForm()
Passing it to the template:
return render_template('post_show.jinja2.html', comment_form=comment_form)
Render the form in the template:
<div class="form-group" id='cg-{{comment_form.email.id}}'>
{{comment_form.email.label(class='col-lg-2 control-label',for=comment_form.email.id)}}
<div class="col-lg-9">
{{comment_form.email(class='form-control')}}
<span class="help-block" id='hl-{{comment_form.email.id}}'></span>
</div>
</div

multiple file upload django

I know how to mutiple file upload in djnago. I use:
<form enctype="multipart/form-data" action="" method="post">
{% csrf_token %}
<p>Press control to upload more than image at same time</p>
<input type="file" name="myfiles" multiple>
<input type="submit" name="upload" value="Upload">
</form>
but what I want is a single file upload, but permit user to click in a"+" button and automatic create a new file upload, permit user upload mutiple files. like attach a file in hotmail.
You're looking for a FormSet - a set of multiple forms, and some JavaScript to populate new forms.
https://docs.djangoproject.com/en/dev/topics/forms/formsets/
Here are some references to JS code that will help dynamically build the HTML for new forms:
Dynamically adding a form to a Django formset with Ajax
Setting up the formsets is easy (it's documented everywhere), but you might want help with the JS part:
I actually use a different method to dynamically add forms. I set up a hidden div with formset.empty_form which comes with easily replaceable __prefix__es in its attributes:
var form_count = {{ formset.total_form_count }};
$('#add_form').click(function() {
var form = $("#empty_form").html().replace(/__prefix__/g, form_count);
$('#forms').append(form);
form_count++;
$('#id_form-TOTAL_FORMS').val(form_count);
});
<div id="empty_form" style="display:none;">
{{ formset.empty_form.as_p }}
</div>
<div id="add_form">Add another form</div>
<form id="forms">
{{ formset.management_form }}
{% for form in formset %}
{{ form.as_p }}
{% endfor %}
</form>

Categories