Set key,values for iteritem in for loop - jinja2

How can I iterate over the element {{ dict.r0t0p1 }} using the for-loops I have established?
The desired end result of the <input.. line is next. In the example line the key is r0t0p1, and I need the corresponding value, where in this case the loop value of both r and t are 0, but they change for each input line.
<input type="text" id="r0t0p1" name="r0t0p1" value="{{ dict.r0t0p1 }}"></input>
So the same values of r and t for the id and the name attributes are required for the dict key to produce the dict value.
{% for r in range(rounds)%}
{% for t in range(tables)%}
<input type="text" id="r{{r}}t{{t}}p1" name="r{{r}}t{{t}}p1" value="{{ dict.r0t0p1 }}"></input>
{%endfor%}
{%endfor%}
I tried using a set command to define cell but got the following error. So it looks like nesting loop indices won't work.
{% set cell = r{{r}}t{{t}}p1 %}
TemplateSyntaxError: expected token 'end of statement block', got '{'

Try this maybe:-
{% for r in range(rounds)%}
{% for t in range(tables)%}
{% set cell = 'r'+r|string+'t'+t|string+'p1' %}
<input type="text" id="{{ cell }}" name="{{ cell }}" value="{{ dic[cell] }}"></input>
{%endfor%}
{%endfor%}

Related

Value iteration in HTML

Description
I want to make this view work,
I'm using a loop for this table, I managed to do a loop for the input part of the id.
The input id has followed the increment according to the number of iterations
Problem
However, I also want variables like input id to apply in the value input.
Ex,
Iteration 1 > <input id="id-sensor-1" type="text" value="{{ variable-loopindex1 }}">
Iteration 2 > <input id="id-sensor-2" type="text" value="{{ variable-loopindex2 }}">
Iteration 3 > <input id="id-sensor-3" type="text" value="{{ variable-loopindex3 }}">
I'm using Python Flask and HTML Template. How do I get the conditions I want to work? Or is there any other solution? I'm at a loss to search for the keywords. Thanks
Store variables in an iterable object, such as variables:
{% for variable in variables %}
<input id="id-sensor-{{loop.index0}}" type="text" value="{{ variable }}">
{% endfor %}

Showing QuerySelectMultipleField as checkbox

I'm new in flask. When you use QuerySelectMultipleField in the jinja2 it shows as a drop-down select-box. but I don't like the drop-down and I prefer the options to be visible permanently without drop-down like checkbox. Is it possible?
Lets assume you have a queryselectmultiplefield for a field named 'answer'
{% for item in form.answer %}
<div>
<input type="checkbox" name="{{ item.name }}" value="{{ item.data }}">
{{ item.label }}
</div>
{% endfor %}

How to dynamically render Vue.js directives in custom Django template tags

I created a custom template tag in Django called text_field
#register.inclusion_tag('form_field_tags/text_field.html')
def text_field(field, prefix=None, field_type=None, attr=None, **kwargs):
return {
'field': field,
'prefix': prefix,
'field_type': field_type,
'placeholder': '',
'attrs': parse_attrs(attr)
}
Where parse_attrs is a function that takes as input something like this class=form-control mb-4, v-model=property_name.
{% text_field form.property_name attr="class=form-control mb-4, v-model=property_name" %}
parse_attrs then create a dictionary of HTML attribute and value that can be looped over, so in my text_field.html i can loop over all the attrs passed in from the text_field custom template tag
<label >
{% if field.field.required %}
<strong> {{ field.label }} <span> * </span> </strong>
{% else %}
{{ field.label }}
{% endif %}
</label>
<input
{% if field_type == "password" %}
type="password"
{% else %}
type="text"
{% endif %}
{% for attr, val in attrs.items %}
{{ attr }} = {{ val }}
{% endfor %}
name="{% if prefix %}{{prefix}}-{% endif %}{{ field.name }}"
placeholder="{{ placeholder }}"
id="{% if prefix %}{{prefix}}-{% endif %}{{ field.name }}"
{% if field.field.required %}
required="required"
{% endif %}
{% if field.value %}
value="{{ field.value }}"
{% endif %}>
However, when I try to refresh the browser and see the rendered output what I get is
<input type="text" class="form-control mb-4" name="property_name" placeholder="" id="property_name" required="required">
instead of this
<input type="text" v-model="property_name" class="form-control mb-4" name="property_name" placeholder="" id="property_name" required="required">
Any thoughts on how to go about this?
So I realized that the browser I was using (Firefox Dev) wasn't showing the v-model directive when viewed with the browser inspector nevertheless if you look at the HTML that gets sent in the browser through the network tab, the v-model directive is definitely there so Vue.js would recognize it.

Form not posting all checked input checkboxes

I am trying to post all checked input checkboxes. The input field is generated by django's for loop as shown below.
From what I have found so far, the below should be working. I believe the issue may be in the fact that the input fields are generated through the forloop, if so, how can I get around this? For each value add to list and post with js?
index.html
{% for q in list %}
{% if forloop.last %}
<form method="POST" name="selectedchecks"> {% csrf_token %}
<div class="qblock">
<label class="pure-material-checkbox">
<input class="selectedchecks" type="checkbox" name="choices[]" value="{{ q }}">
<span>
<p>{{ q }}</p>
</span>
</label>
</div>
</form>
{% endif %}
{% endfor %}
views.py
if request.method == 'POST':
selected_list = request.POST.getlist('choices[]')
What happens is that only the first value of {{ q }} is returned if the first checkbox is selected, if any other checkbox apart from the first is selected, nothing is returned (empty list). Selecting all checkboxes also only returns the first value.
It should POST all selected checkbox values.
Any help is appreciated!
UPDATE
The problem was that the form was being re-initialized for every loop iteration. Setting the <form> tag before the loop fixed the issue!

How to draw inputs without the id attribute using WTForms?

In my flask application I have to draw a form multiple times on the same page. This leads to the problem where I have multiple input fields with the same id on the page. E.g.:
class ChannelForm(flask_wtf.Form):
name = StringField('name')
together with this template:
<form>
{{ form.name }}
</form>
...
<form>
{{ form.name }}
</form>
lead to two input elements with the same id:
<input id="name" name="name" value="" type="text">
Is there an official way to disable adding the id attribute?
Quick n' dirty:
I've found that the following works well: instead of using the field directly, I wrap them in a jinja macro:
{% macro render_field(field) %}
<label>
<span>{{ _field.label.text }} </span>
{{ field(id=False, **kwargs) }}
</label>
{% endmacro %}
which can be used like this:
{% from "_formhelpers.html" import render_field %}
{{ render_field(form.name) }}
The trick here is to pass id=False when rendering the field.
using the meta object:
_Auto = object()
class NoIdAttributeMeta(DefaultMeta):
"""
Surpresses rendering the `id' attribute.
"""
def bind_field(self, form, unbound_field, options):
"""
Raises TypeError in case 'id' is given as a positional arg when constructing a field.
If this happens, make this code smarter or pass `id' as a keyword arg.
"""
# we check `id' at rendering time and if it is still _Auto, do not render it
unbound_field.kwargs.setdefault('id', _Auto)
return super().bind_field(form, unbound_field, options)
def render_field(self, field, render_kw):
if field.id is _Auto:
field.id = False
return super().render_field(field, render_kw)
class MyForm(flask_wtf.Form):
Meta = NoIdAttributeMeta
or be pragmatic:
You could also add a different prefix to each instance of your form and therefore you'd have unique ids:
my_form = MyForm(prefix="form1")
pass
I think you can pass a custom id to the field constructor like this:
<form>
{{ form.name(id_='yourId') }}
</form>
...
<form>
{{ form.name(id_='yourId2') }}
</form>
You don't need id=False because you already can set id when you call render_field()
{% macro render_field(_field) %}
<label>
<span>{{ _field.label.text }} </span>
{{ _field(**kwargs) }}
</label>
{% endmacro %}
Usage:
{{ render_field(field, id=False) }}
Explaination:
Because you have ****kwargs**, you can make the id=False and that would be more dymanic. You can choose when to remove ID.
Hope this help for those who have googled this solution