Custom Bootstrap Checkbox in Jinga2/Flask - python

I have the following WTF form
class config_reports(FlaskForm):
test2use = SelectMultipleField('Choose Test(s):', [DataRequired()], choices=[('', '')])
display_cuts = BooleanField('Display Proficiency Cuts?', default = True)
submit = SubmitField('Run Report')
and now I'm trying to fancy up my checkbox to use the example found here, https://getbootstrap.com/docs/4.0/components/forms/, which uses this code
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck1">
<label class="custom-control-label" for="customCheck1">Check this custom checkbox</label>
</div>
Within my jinga2 template file, I'm trying the following. Some of the style is applied, but my checkbox isn't clickable. Any advice on how to properly apply the styling here?
<div class = 'col'>
<div class="formwrapper">
<form method="POST" action="{{url_for('config_tools.config_reader')}}">
<div class="form-field">
{{form2.test2use.label}}
{{form2.test2use (class="form-control", required=False)}} <br>
<div class="custom-control custom-checkbox">
{{form2.display_cuts.label(class="custom-control-label")}}
{{form2.display_cuts (class="custom-control-input") }}<br>
</div>
{{form2.submit(class = "btn btn-primary")}} <br><br>
</div>
</form>
</div>
</div>

Related

Django UserCreationForm and Bootstrap Forms Layouts

I am trying to extend the UserCreationForm using a Bootstrap layout style for the field username. After the input tag in the registration form, I would like to add a div element like an example that I have readapted from the Bootstrap page: i.e. suggesting the user to enter the same username as the company domain.
Let's focus to the bare minimum. The form readapted from Bootstrap is:
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
<div class="col-auto">
<div class="input-group">
<input type="text" name="username" class="form-control" placeholder="your.username" id="id_username">
<div class="input-group-text">#company.domain.com</div>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
Which produces the following:
For the moment, I am using only {{form.as_p}} in my html template file:
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
{{form.as_p}}
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
And I don't know how to add the <div class="input-group-text">#company.domain.com</div> part embedded in a <div class="input-group">...</div> block.
My actual forms.py is a bit more complex, but readapted for this minimum example it contains the widget attributes as follows:
class SignupForm(UserCreationForm):
username = forms.CharField(label="",
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'your.username'}))
class Meta:
model = User
fields = (
'username',
)
Without additional libraries, is there a way to extend the widget attributes? Is it even possible to use {{form.as_p}} as I am currently doing or should I use another method?
If you want to use only {{ form.as_p }} with bootstrap then you need to install django-bootstrap.
Install it using pip:
pip install django-bootstrap4
After installation, add it in INSTALLED_APPS in settings.py file.
INSTALLED_APPS = [
'bootstrap4',
]
And in templates, you need to load it.
{% load bootstrap4 %}
{% bootstrap_messages %}
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
{% csrf_token %}
{% bootstrap_form form %} # added `form` here. we don't need to use with as_p.
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
This is the way you can use bootstrap along with {{ form.as_p }}
OR
Try another way:
Simply you can use {{ form.username }} inside an input tag in template.
For Example:
<input type="text" value="{{ form.username }}">
<form class="row gy-2 gx-3 align-items-center method="POST" action="{% url 'register' %} ">
<div class="col-auto">
<div class="input-group">
<input type="text" name="username" class="form-control" placeholder="your.username" id="id_username" value="{{ form.username }}"> #Added here
<div class="input-group-text">#company.domain.com</div>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>

Is there anyway to know at which card "add comment" has clicked using flask

I'm trying to add a comment section to my web app however, I want to know which book its "add comment" has clicked I'm thinking about getting the book's ID.
Here is my python
#app.route("/comment", methods=["GET", "POST"])
def comment():
if request.method == "POST":
if not request.form.get("comment"):
return apology("must provide comment", 400)
book = request.form.get("book_id")
print(session["user_id"])
print(book)
id = session["user_id"]
print(id)
user = db.execute("SELECT username FROM users WHERE id=?", id)
db.execute("INSERT INTO comment (comment, user,book_id) VALUES(?, ?,?)", comment, user,book)
return render_template ("index.html")
else:
return render_template ("comment.html")
Here is my html code
<form action="/comment" method="get">
<div class="container">
<div class="row g-3">
{% for book in books %}
<div class="col-12 col-md-6 col-lg-4">
<div class="card">
<img src="{{book.volumeInfo.imageLinks.smallThumbnail}}">
<div class="card-body">
<h5 style="color:red" class="card-title">{{book.volumeInfo.title}}</h5>
<p style="color:blue" class="card-text">{{book.volumeInfo.authors}}</p>
<p style="visibility:hidden" class="card-text">{{book.id}}</p>
<input name="book" style="visibility:hidden" class="form-control mx-auto w-auto" name="book_id" value="{{book.id}}" type="text">
More Info
<button value="{{book.id}}" class="btn btn-primary">add comment</button>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
This HTML element
<input name="book" style="visibility:hidden" class="form-control mx-auto w-auto" name="book_id" value="{{book.id}}" type="text">
has two different values for attribute name, please try removing one of them, that is
<input name="book_id" style="visibility:hidden" class="form-control mx-auto w-auto" value="{{book.id}}" type="text">
and then write if you can access book_id properly in your Flask application. As side if you need to have input invisble to user you might use type="hidden" rather than tinker with styling, in this case
<input name="book_id" value="{{book.id}}" type="hidden">

django create template with multiple input field

I am trying to create a template which would take input items like item, quantity and unit price and render a pdf report of it with total price. Also i want the input to be on tabular form and add the lines dynamically by clicking + icon or something.
My folder structure is:
Project
|__ app
|__ template
|__ app.html
I am extending app.html from base.html which inherits bootstrap. Tried the below code but can't figure out how to do it.
{% extends 'base.html' %}
{% block head %}
{% endblock %}
{% block body %}
<div class="panel panel-default">
<div class="panel-body">
<div id="all_fields">
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<input type="text" class="form-control" id="Itemquantity" name="Itemquantity[]" value="" placeholder="Item Quantity">
</div>
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<input type="number" class="form-control" id="Quantity" name="Quantity[]" value="" placeholder="Quantity">
</div>
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<input type="number" class="form-control" id="Unitprice" name="Unitprice[]" value="" placeholder="Unit Price">
</div>
</div>
<div class="col-sm-3 nopadding">
<div class="form-group">
<div class="input-group">
<div class="input-group-btn">
<button class="btn btn-success" type="button" onclick="all_fields();"> <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> </button>
</div>
</div>
</div>
</div>
<div class="clear"></div>
</div>
<div class="panel-footer"><small>Press <span class="glyphicon glyphicon-plus gs"></span> to add another form field :)</small>, <small>Press <span class="glyphicon glyphicon-minus gs"></span> to remove form field :)</small></div>
</div>
{% endblock %}
If you want dinamic you should go to Javascript instead of Django, because Django is server side, django only will process your data after new request... so you can do it from scratch setting up one ajax to connect to your django while User is interacting with your page and create this new inputs based in something from server... or your inputs will be just generated in your HTML and only after sended to your backend will be hanlded by django (you will have to create your own logic)
Probabily there is any lib that already do that for your.
I do recommend to setup your javascript to dinamic create ids and new inputs, setup all inside one form tag, send this form to your backend, capture it in your post request and handle if... if you receive 5 inputs so it means there i 5 new itens...

HTML form is not taking in a date value on desktop, but is on mobile

I'm creating a form. I've created a mobile block that renders on mobile and a desktop block that renders on desktop. There are several fields in this form, and it's working fine with the exception of the date field where I want someone to put in a date. On the mobile block, the date field is taking in a value perfectly. On the desktop block, it is not taking in any value. I end up getting this error when rendering the desktop version:
ValueError: time data '' does not match format '%Y-%m-%d'
The HTML looks like this (I've eliminated a big chunk of the fields in the form for simplicity, let me know if you need to see more of the HTML):
<form method="POST">
<div class="mobile-only">
<div class="form-group row">
<div class="col-12 col-md-2 col-lg-4">
<label for="start-date" class="col-form-label">
<h4>Start Date: <sup class="required">(required)</sup></h4>
</label>
</div>
<div class="col-12 col-md-10 col-lg-4">
<input type ="date" maxlength="10" class="form-control" id="start-date" name="start-date" placeholder="MM/DD/YYYY">
</div>
</div>
<div class="row">
<div class="col-3 col-md-1">
<button class="green-button link-text" type="submit" id="submit" type="submit">Save</button>
</div>
<div class="col-3 col-md-1">
<button class="green-button">Cancel</button>
</div>
</div>
</div>
The above code works fine on mobile, below is what is rendered on desktop, and gives me the above referenced error:
<div class="desktop-only">
<div class="form-group row">
<div class="col-lg-1">
<label for="start-date" class="col-form-label">
<h4>Start Date: <sup class="required">(required)</sup></h4>
</label>
</div>
<div class="col-lg-3">
<input type ="date" maxlength="10" class="form-control" id="start-date" name="start-date" placeholder="MM/DD/YYYY">
</div>
</div>
<div class="row">
<div class="col-3 col-md-1">
<button class="green-button link-text" type="submit" id="submit" type="submit">Save</button>
</div>
<div class="col-3 col-md-1">
<button class="green-button">Cancel</button>
</div>
</div>
</div>
</form>
Also, in case it's relevant, I'm using Bootstrap 4 and the backend is a Flask App with Python. Any idea what the issue is?
your placeholder indicates to user this format:
placeholder="MM/DD/YYYY"
but then elsewhere in the code you are expecting:
format '%Y-%m-%d'
which is your error, if you trying to upload to database you should use YYYY-MM-DD as this is international standard, then in your front end convert to MM/DD/YYYY.
If you asking for input of MM/DD/YYYY, you need to convert it to YYYY-DD-MM

Receiving HTML request from Bootstrap <button>

<form method="post" class="form-horizontal" role="form">
<div class="btn-group col-sm-3">
<button id="typeSelect" type="button" name="reportType" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
People <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>
...
</li>
...
</ul>
</div>
<div class="form-group">
<label for="inputName" class="col-sm-2 control-label">Name</label>
<div class="col-sm-3">
<input type="text" class="form-control" id="inputName" placeholder="Name" name="name" value="{{name}}" onblur="isEmpty(this)">
</div>
</div>
</form>
I have two inputs in my form and I am trying to get the input in my Python code.
report_type = self.request.get('reportType')
name = self.request.get('name')
name is working correctly, but report_type will always be None.
What is the correct way to retrieve the selection in a button (Bootstrap)?
According to the button element specifications:
A button (and its value) is only included in the form submission if the button itself was used to initiate the form submission.
You will have to find another way to pass the value of the button. You could, for example, store the value in a hidden field.

Categories