How to: Flask Python / WTForms Adding dynamic field - python

How we can generate fields dynamically in flask with wtf forms without using java script DOM to add fields like here in this link:
http://formvalidation.io/examples/adding-dynamic-field/
for example adding a field or when we delete the field to delete a set on database like in the images down here.
Form with one row:
Form with one row
Form with multiple rows:
Form with multiple rows
{{ form.hidden_tag() }}
{{ form.Book }}
{{ form.ISBN }}
{{ form.Price }}
<button type="button" class="btn btn-default addButton">
<i class="fa fa-plus"></i>
</button>
<button type="submit" class="btn btn-default">Submit</button>
And my python class form
class BookForm(FlaskForm):
isbn = StringField("ISBN",[validators.DataRequired("Please enter your ISBN number.")])
title = StringField("Titile",[validators.DataRequired("Please enter your Book Title.")])
price = FloatField("Price")
I saw some people proposing some class_ thing but i didn't understand that.

Related

Populate textarea field using WTForms

As I understand it, if you want to populate a textarea you place the text between the textarea tags. However I am using WTForms. How can I pre-populate the form from views or in my template?
FORM
class ModuleSectionForm(FlaskForm):
title = StringField('Section Title', validators=[DataRequired()])
description = TextAreaField('Description', validators=[DataRequired()])
submit = SubmitField('Add Section')
VIEW
#modules.route('/update_section/<name>/<title>', methods=['GET', 'POST'])
def update_section(name, title):
form = ModuleSectionForm()
module = Module.objects(title=name).first()
section = None
for sect in module.sections:
if sect.title == title:
section = sect
#if form.validate_on_submit():
#save data
return render_template('modules/update_section.html', section=section, form=form)
TEMPLATE
<form method="post" action="{{ url_for('modules.update_section', name=name) }}">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.title.label(class="form-control-label") }}
{{ form.title(class="form-control", value=section.title) }}
</div>
<div class="form-group">
{{ form.description.label(class="form-control-label") }}
{{ form.description(class="form-control", default=section.description) }}
</div>
<div class="form-group">
{{ form.submit(class="btn btn-secondary shadow") }}
</div>
</form>
This can be done by just assigning the text to display beforehand (in the view, for instance).
Try edit your view (update_section) this way:
+ form.description.data = 'text you want to display'
And your template as follows:
- {{ form.description(class="form-control", default=section.description) }}
+ {{ form.description(class="form-control") }}
Mind you, there's an alternative way, which is to specify the placeholder attribute (but I guess is not what you want to do here).
Typically with WTForms (let's assume you're using Flask and Bootstrap here), you'll use the value attribute of the input to pre-populate a form field. Note that pre-populating a field is distinct from providing a 'placeholder', which is just an ephemeral hint. So usually we pre-populate like this:
<div class="form-group row">
<label for="form_subject" class="col-sm-2 col-form-label">Subject</label>
<div class="col-sm-7">
<input class="form-control" id="form_framework" name="form_framework"
value="{{ instruct.Subject }}">
</div>
</div>
With Flask and Bootstrap, the name attribute is required to pass the value back to the Controller upon submission, the value attribute is used to pre-populate the field from the object - in this case, our controller has passed in an object called instruct, which has an attribute Subject.
But you have to be aware that different kinds of inputs in WTForms have different attributes, and this is left as a fun challenge for the developer to figure out.
TextArea doesn't have a value attribute, so in order to pre-populate the field, you have to provide the value between the tags, like so (again, using Bootstrap here in case any of these tags are unfamiliar):
<div class="form-group row">
<label for="form_longish_text"
class="col-sm-2 col-form-label">Longish Text</label>
<div class="col-sm-7">
<textarea class="form-control" rows="3"
id="form_longish_text"
name="form_longish_text">{{ instruct.LongishText }}
</textarea>
</div>
</div>

How to store this html data back to another database

Here I iterate data from my database in mongodb i just want that when my add to cart button is clicked it gets stored into another database named cart and gets displayed on another page
{% for data in product_data %}
<div class="shop-item" >
<span class="shop-item-title" id="title-item">{{ data.title }}</span>
<input type="image" class="shop-item-image" id="image-item" src={{ data["img_file"] }} onclick="takethatpage();">
<div class="shop-item-details">
<span class="shop-item-price" id="price-item">{{ data["price"]}}</span>
<button class="btn btn-primary shop-item-button" type="button">ADD TO CART</button>
</div>
</div>
{% endfor %}
I will not spoon feed but let me tell you the approach for it.
Firstly you would need an API implemented at the server end to accept products to be added to the cart for the respective user.
Secondly, for your template there needs to be an AJAX request fired each time the person click on the add to cart button.

Django - Conditional Rendering In Templates

I need some help conditionally rendering data in a modal pop up window on my site.
What I want to do:
When the user clicks on the "make reservation" button, I want to display this in the modal window
<h3 style="margin-top:20px;">Choose dates</h3>
<div style="margin-top:20px;" class="pick-dates-div">
<form method="GET" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="form-btn save btn btn-default">Make A Reservation</button>
</form>
<button style="margin-top: 25px;" class="btn-primary btn-block btn-lg" data-toggle="modal"
data-target="#inquiryModal">More
Questions ?</button>
</div>
Then the user can pick the dates from the date picker and press the "make a reservation" button ( which is a GET request ), the page refreshes and I want to display only this in the same modal window :
<h1>Start Date: {{ date_start }}</h1>
<h1>End Date: {{ date_end }}</h1>
<h1>Price Per Day: ${{ price_per_day }}$</h1>
<h1>Total: ${{ total_price }}$</h1>
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button href="www.facebook.com" type="submit" class="form-btn save btn btn-default">Confirm Reservation</button>
</form>
After that the user submits the form ( POST request ) and I want to display a text :
<h3> Thank you for your reservation </3>
What would be the ideal way to achieve this ?
Thank you stack
The ideal way to achieve this is by using JavaScript.
One of the many methods this could be achieved is by rendering all the three views inside separate containers in a modal and then hiding the next two using javascript.
You can use element.style.display = 'none' to hide and
element.style.display = 'block' to show the content inside the element container.
Once the user clicks on "make reservation" button, hide/show the required containers to achieve the desired result.
Do not forget to secure your website by using proper validation on the server end. Hope that helps!

Django: forms.ChoiceField doesnt refresh after new page loading

In my Django App, I wrote a form with a forms.ChoiceField . The choice should be a list of items that are changing every couple of minutes in my DB. I would like to have the current list of items in a drop-down button when I reload the page.
My code works good except the forms.ChoiceField does not update. To update I have to restart the Django server.
I don't know what i am missing, Can you help me ? It must be something small.
from forms.py
class BookingForm(forms.ModelForm):
make_list_of_tuple = lambda list_machine : [tuple( [i,i]) for i in list_machine]
MACHINES= tuple( QA_machine_DB.objects.values_list('QAmachine',flat=True))
CHOICE_QA_MACHINES= make_list_of_tuple(MACHINES)
QAmachine= forms.ChoiceField(choices=CHOICE_QA_MACHINES)
class Meta():
model= QA_machine_DB
fields= ['QAmachine', 'owner', 'comments','status']
# http://nanvel.name/2014/03/django-change-modelform-widget
widgets = {
'owner':forms.TextInput(attrs={'placeholder':'owner'}),
'comments':forms.TextInput(attrs={'placeholder':'comments'}),
'status': forms.RadioSelect( choices=[('busy','busy'),('free','free')])}
from the template
<form class="form-group" method="post" novalidate >
{% csrf_token %}
<table >
<td>
{{ BookingForm.QAmachine}}
</td>
<td>
{{ BookingForm.owner.errors }}
{{ BookingForm.owner}}
</td>
<td>
{{ BookingForm.comments.errors }}
{{ BookingForm.comments}}
</td>
<td>
{% for radio in BookingForm.status %}
{{ radio }}
{% endfor %}
</td>
</table>
<input type="submit" class="btn btn-success" value="submit status change" style="float: right;" >
Tank you in Adavance
No, anything defined at class level will only be evaluated once, when the class is first imported.
You could do this in the __init__ method, but a better approach is to use the field that is meant for getting choices from querysets: ModelChoiceField.

How to set up an article input function based on forms in Django

New to Django.
I am trying to build a blog of my own, so I will need to input an article with max_length = 5000 or some other number; I don't want to use the admin system directly, instead I want to input the article and submit it to the server.Right now I am trying to use forms.
The question is I didn't find a solution to this huge amount of character inputs.
Any hint to this?
The form:
<form name="input" method="POST">
<li>The title:{{ form.name }}</li>
<li>The body: <textarea cols='20' rows='20'>{{ form.text }}</textarea> </li>
<input type="submit" value="Submit">
</form>
UPDATE:
I solved this issue by deleting the textarea tag wrapping {{ form.text }};
{{ form.text }} itself implements a textarea tag.
And in my view code:
text = forms.CharField(widget=forms.Textarea)

Categories

Resources