All Delete buttons are attached to the first row - python

I have the following code where it display some data in rows, there's "Delete" button with each button.
in my case the "Delete" button will always delete the first row in the list, even if I try to delete something in the middle or end the last row from the list, the first row gets deleted.
not sure why all buttons are associated with the first row while they're in FOR loop.
Update#1: I did some tests and I can see that each button is aware of the correct data for it's own row, but after I click the button it hits data-target="#deleteLocation" and this new section "#deleteLocation" is always aware of the first row only.
routes.py
#org_settings.route("/locations", methods=["GET"])
def locations():
form = LocationForm()
page = request.args.get("page", 1, type=int)
locations = (
Location.query.filter_by(user_id=current_user.id)
.order_by(Location.name.asc())
.paginate(page=page, per_page=5)
)
return render_template(
"settings/locations.html",
title="Locations",
locations_tab="active",
locations=locations,
form=form,
)
#org_settings.route("/locations/<int:location_id>/delete", methods=["GET", "POST"])
#login_required
def delete_location(location_id):
location = Location.query.get_or_404(location_id)
if location.organization != current_user:
abort(403)
db.session.delete(location)
db.session.commit()
flash("Your location has been deleted!", "info")
return redirect(url_for("org_settings.locations"))
locations.html
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Location Name</th>
<th scope="col">Latitude</th>
<th scope="col">Longitude</th>
<th scope="col">Address</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{% for location in locations.items %}
<tr>
<td>{{ location.name }}</td>
<td>{{ location.latitude }}</td>
<td>{{ location.longitude }}</td>
<td>{{ location.address }}</td>
<td>
<button type="button" class="btn btn-danger btn-sm" data-toggle="modal" data-target="#deleteLocation">
<i class="bi bi-trash-fill" style="font-size:18px; color: rgb(255, 255, 255);"></i>
</button>
<!-- Bootstrap Modal -->
<div class="modal fade" id="deleteLocation" data-backdrop="static" data-keyboard="false" tabindex="-1"
aria-labelledby="deleteLocationLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteLocationLabel">Delete Location</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Are you sure you would like to delete this location?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<form action="{{ url_for('org_settings.delete_location', location_id=location.id) }}"
method="POST">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</div>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>

I solved it by adding the ID of the row {{ location.id }} to the id of html section
data-target="#deleteLocation-{{ location.id }}"
as below
<button type="button" class="btn btn-danger btn-sm" data-toggle="modal"
data-target="#deleteLocation-{{ location.id }}">
<i class="bi bi-trash-fill" style="font-size:18px; color: rgb(255, 255, 255);"></i>
</button>```
<div class="modal fade" id="deleteLocation-{{ location.id }}" data-backdrop=" static" data-keyboard="false"
tabindex="-1" aria-labelledby="deleteLocationLabel" aria-hidden="true">

Related

How do I pass the value from the inside of a for loop ( jinja2 ) to a bootstrap modal to display it in side the modal body?

How do I pass the value from the inside of a for loop ( jinja2 ) to a bootstrap modal to display it in side the modal body?
here is my views.py file:
if request.method == 'GET':
driver = get_network_driver(device.napalm_driver)
with driver(device.IP_address, device.username, device.password) as device_conn:
interfaces = device_conn.get_interfaces()
context = {
'device': device,
'interfaces': interfaces,
}
return render(request, 'network/interface_list.html', context)
Please note that the the device_conn.get_interfaces() method returns a nested dictionary.
Here is the html template:
{% extends 'base/base.html' %}
{% block title %}iNet Interface List{% endblock %}
{% block content %}
<div class="section">
{% include 'network/include/interface_list_header.html' %}
{% if messages %}
{% for message in messages %}
{% if message.tags == 'success' %}<div class="alert alert-success" role="alert">
{{ message }}
</div>{% elif message.tags == 'error' %}<div class="alert alert-danger" role="alert">
{{ message }}
</div>{% endif %}
{% endfor %}
{% endif %}
<div class="card mx-auto shadow rounded">
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col" style="text-align:center">Interface Name</th>
<th scope="col" style="text-align:center">Admin status</th>
<th scope="col" style="text-align:center">Protocol</th>
<th scope="col" style="text-align:center">Description</th>
<th scope="col" style="text-align:center">MAC Address</th>
<th scope="col" style="text-align:center">Last Flapped</th>
<th scope="col" style="text-align:center">Turn On/Off Port</th>
<th scope="col" style="text-align:center">Edit Description</th>
</tr>
</thead>
<tbody>
{% for interface_name, interface in interfaces.items %}
<tr>
<form action="{% url 'get_interfaces' device.id %}" method="post" id="{{ interface_name }}">
{% csrf_token %}
<input type="hidden" value="{{ interface_name }}" name="interface_name" />
<input type="hidden" value="{{ interface.is_enabled|yesno:'False,True' }}" name="enable" />
</form>
<td style="text-align:center">{{ interface_name }}</td>
<td style="text-align:center">{% if interface.is_enabled %}<i class="fa-solid fa-check text-success"></i>{% else %}<i class="fa-solid fa-xmark text-danger"></i>{% endif %}</td>
<td style="text-align:center">{% if interface.is_up %}<i class="fa-solid fa-check text-success"></i>{% else %}<i class="fa-solid fa-xmark text-danger"></i>{% endif %}</td>
<td style="text-align:center">{{ interface.description }} </td>
<td style="text-align:center">{{ interface.mac_address }}</td>
<td style="text-align:center">{{ interface.last_flapped }}</td>
<td style="text-align:center"><button class="btn common-button btn-primary" type="submit" form="{{ interface_name }}" value="Submit">{% if interface.is_enabled %}Turn Off{% else %}Turn On{% endif %}</button></td>
<!-- Modal Trigger button -->
<td style="text-align:center"><i class="fa-regular fa-clipboard"></i></td>
<!-- Modal container -->
<div class="modal fade viewModal" id="editDesc{{ interface_name }}" tabindex="-1" role="dialog" aria-labelledby="editDescLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 style="font-size: 20px;" class="modal-title" id="editDescLabel">View Console Output</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<textarea>{{ interface.description }}</textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
I wish to show the {{interface.description}} of the selected interface in the textarea so that I can edit it later. Any help would be appreciated.
My issue is - I am able to fetch {{interface.description}} outside the bootstrap modal, however I am unable to fetch the same thin inside the bootstrap modal. Eventhough both of them are inside the for loop.

Flask form not submitting but working under another scenario

I have flask website in progress, but the SubmitField is not doing anything whenever I click it.
I followed the similar method in submitting a much smaller form, it worked, but this is not working.
routes.py
from flask.scaffold import _matching_loader_thinks_module_is_package
from slotinfo import app
from flask import render_template,request,redirect
from slotinfo.models import Item
from slotinfo.models import Projects
from slotinfo.forms import AddProjectForm, ReserveSlotForm
from slotinfo import db
from slotinfo.models import Projects
#app.route('/')
#app.route('/home')
def home_page():
form = AddProjectForm()
return render_template('home.html',form=form)
#app.route('/rack1')
def rack_one():
items = Item.query.filter_by(rack_number=1)
form = AddProjectForm()
rform = ReserveSlotForm()
return render_template('rack1.html',items=items,form=form,rform=rform)
#app.route('/rack2')
def rack_two():
items2 = Item.query.filter_by(rack_number=2)
form = AddProjectForm()
return render_template('rack2.html',items=items2,form=form)
#app.route('/rack3')
def rack_three():
items3 = Item.query.filter_by(rack_number=3)
form = AddProjectForm()
return render_template('rack3.html',items=items3,form=form)
#app.route('/witbe1')
def wit_rack1():
items4 = Item.query.filter_by(rack_number=4)
form = AddProjectForm()
return render_template('rack4.html',items=items4,form=form)
#app.route('/addproject', methods=['GET','POST'])
def add_project():
form = AddProjectForm()
name=form.projectname
name2 = request.form['projectname']
x=Projects(projname=name2)
db.session.add(x)
db.session.commit()
return redirect(request.referrer)
#app.route('/reserve',methods=['GET','POST'])
def reserve_r1():
rform1=ReserveSlotForm()
name = request.rform1['reserver_name']
# if form1.validate_on_submit():
# name=form1.reserver_name
print(name)
return redirect(request.referrer)
In the above code, the rack1.html is the page where I am creating the form for submission. Also in the base.html , I used a smaller form it worked and its used in the function add_project(). But when I try to do the same for the rack1.html it does not submit anything. I use the function reserve_r1()
rack1.html
{% extends 'base.html' %}
{% block title %}
Rack 1 Page
{% endblock %}
{% block content %}
<br>
<div class="container-fluid">
<div class="jumbotron-fluid">
<div class="card" id = "rack-table1" style="color: black;">
<div class="card-header">
<h3>Storm Rack One</h3>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<h4 class="card-title">Details of the rack</h4>
</div>
<div class="col">
<button class="btn btn-outline btn-success float-right badge-pill" style="margin-left: 5px;" data-toggle="modal" data-target="#reserveslot">Reserve</button>
<button class="btn btn-outline btn-danger float-right badge-pill" style="margin-bottom: 2px;">Release</button>
</div>
</div>
<br>
<table class="table table-hover table-light table-bordered" style="color: black;">
<thead style="text-align: center;">
<tr style="text-align: justify;">
<th scope="col" style="width: 8rem;">Rack Number</th>
<th scope="col" style="width: 8rem;">Slot Number</th>
<th scope="col" style="width: 10rem;">Project</th>
<th scope="col">Name</th>
<th scope="col" style="width:5rem;">Days</th>
<th scope="col" style="width:12rem;">Date of Reserving</th>
</tr>
</thead>
<tbody>
{% for item in items %}
<tr style="text-align: justify;">
<td>{{item.rack_number}}</td>
<td>{{item.slot_number}}</td>
<td>{{item.project}}</td>
<td>{{item.name}}</td>
<td>{{item.days_taken}}</td>
<td>NA</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<div id="reserveslot" class="modal fade" style="color: black;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<!-- <button type="button" class="close" data-dismiss="modal">×</button> -->
<h4 class="modal-title" style="text-align: left;">Reserve Slot</h4>
</div>
<div class="modal-body">
<form method="POST" action = "{{url_for('reserve_r1')}}">
{{rform.rack_number.label()}}
{{rform.rack_number(class="form-control",placeholder="1-4")}}
{{rform.slot_number.label()}}
{{rform.slot_number(class="form-control",placeholder="1-4")}}
{{rform.project_Name.label()}}
{{rform.project_Name(class="form-control",placeholder="Project for reserving")}}
{{rform.reserver_name.label()}}
{{rform.reserver_name(class="form-control",placeholder="Who is reserving the slot ?")}}
{{rform.days_reserve.label()}}
{{rform.days_reserve(class="form-control",placeholder="For how many days ?")}}
{{rform.description.label()}}
{{rform.description(class="form-control",placeholder="Why do you need this slot ?")}}
{{rform.submit_slot(class="btn btn-lg btn-block btn-primary") }}
<br>
</form>
</div>
<div class="modal-footer" style="text-align: center;">
<button type="button" class="btn btn-primary" data-dismiss="modal" style="text-align: center;">Close</button>
</div>
</div>
</div>
</div>
</div>
<style>
.divider{
width:7px;
height:auto;
display:inline-block;
}
</style>
{% endblock %}
Remove the extra spaces around the action attribute.
<form method="POST" action="{{url_for('reserve_r1')}}">

How do i make a functioning Delete confirmation popup in Django using Bootstrap4 Modal

My views.py file looks like this.
def deleteOrder(request, pk):
order = Order.objects.get(id=pk)
if request.method=="POST":
order.delete()
return redirect('/')
context = {"item":order}
return render(request, 'accounts/delete.html', context)
My delete.html file is this. If there is a way to get rid of it or use part of it's code in the delete popup then kindly assist.
{% block content %}
<br>
<div class="row">
<div class="col-md-6">
<div class="card card-body">
<p>Are you sure you want to delete "{{item}}"?</p>
<form action="{% url 'delete_order' item.id %}" method="POST">
{% csrf_token %}
<a class="btn btn-warning" href="{% url 'home' %}">Cancel</a>
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</div>
</div>
</div>
{% endblock %}
My urls.py file looks like this.
urlpatterns = [
path('delete_order/<str:pk>', views.deleteOrder, name="delete_order"),
]
Bootstrap Delete Popup i need help applying.
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
My Home page made of a table which contains a Delete column for deleting each row.
<table class="table table-sm">
<tr>
<th>Product</th>
<th>Date Ordered</th>
<th>Status</th>
<th>Update</th>
<th>Delete</th>
</tr>
{% for order in orders %}
<tr>
<td>{{ order.product }}</td>
<td>{{ order.date_created }}</td>
<td>{{ order.status }}</td>
<td><a class="btn btn-sm btn-info" href="{% url 'update_order' order.id %}">Update</a></td>
**<td><a class="btn btn-sm btn-danger" href="{% url 'delete_order' order.id %}">Delete</a></td>**
</tr>
{% endfor %}
</table>
The Line that i have added ** asterisks(intentionally) is the one i want to modify so that when i click on Delete button, a Bootstrap delete popup modal gets triggered.
Try this.
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<a class="btn btn-sm btn-danger" href="{% url 'delete_order' order.id %}">Delete</a>
</div>
</div>
</div>
</div>
<table class="table table-sm">
<tr>
<th>Product</th>
<th>Date Ordered</th>
<th>Status</th>
<th>Update</th>
<th>Delete</th>
</tr>
{% for order in orders %}
<tr>
<td>{{ order.product }}</td>
<td>{{ order.date_created }}</td>
<td>{{ order.status }}</td>
<td><a class="btn btn-sm btn-info" href="{% url 'update_order' order.id %}">Update</a></td>
<td><a class="btn btn-sm btn-danger" href="#" data-toggle="modal" data-target="#exampleModal">Delete</a></td>
</tr>
{% endfor %}
</table>
--- UPDATE ---
url.py, most common use is urls.py
Your pk should to be int not str
urlpatterns = [
path('delete_order/<int:pk>', views.deleteOrder, name="delete_order"),
]

How can i reduce the table width or make the table responsive for chrome?(Django/Python deployed web-app)

This is the code for the page that is being viewed in those images, is there any changes that need to be made to make it more responsive in a mobile chrome browser?
<!---To Display Timetable Entries----->
<div class="container"><br>
<span style="font-family:'Futura';font-weight:bold;"><h2>TimetableMatch</h2></span>
<hr>
<div style="overflow-x:auto;">
<table class="table table-dark">
<thead>
<tr>
<th>Module</th>
<th>Day</th>
<th>Time</th>
<th>Area</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for entry in entrys %}
<tr>
<td>{{ entry.module }}</td>
<td>{{ entry.day }}</td>
<td>{{ entry.time }}</td>
<td>{{ entry.location }}</td>
<td><a class="btn btn-info" href="../edit/{{ entry.id }}">Edit</a>
<br>
<br>
<a class="btn btn-danger" href="../delete/{{ entry.id }}">Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="row">
<div class="col-md-4 col-lg-2">
<a class="btn btn-primary" href="../add_entry/">Add Timetable Entry</a>
<br>
<br>
<a href="{% url 'homepage' %}">
<button type="button" class="btn btn-primary btn-xs"> Back to home</button></a>
<a href="{% url 'index' %}">
<br>
<br>
<button type="button" class="btn btn-primary">Logout</button> </a>
</div>
</div>
</body>
IOS chrome browser
Laptop chrome browser

flask template jinja not looping as expected

I have a flask app with a template inside which I have a loop using jinja syntax. The problem is I don't know why the row[5] is not changing while others are working fine. The <p>{{ row[5] }}</p> is not looping probably in that div nested inside the td tag. The data sent to the page should be looped for 4 times. {{ row[5] }} this keeps giving me the value of the first loop. The code is as following:
{% for row in data %}
<tr>
<td>{{ row[2] }}</td>
<td>{{ row[1] }}</td>
<td>{{ row[3] }}</td>
<td>
<button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#myModal">Backup</button>
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<p>{{ row[5] }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</td>
<td>Backup</td>
</tr>
{% endfor %}
Even though the data does not matter here. Since someone asked , I will put it here. Data is something like:
data=((1,2,3,4,5,6,7,8),(1,2,3,4,5,6,7,8))
This is the way I render the template:
#app.route('/home')
def home(methods=['GET']):
cursor = conn.cursor()
cursor.execute("SELECT * from hosts_custom;")
data = cursor.fetchall()
print data
return render_template('index.html',data=data)
It turns out it's the id and the target stay the same all the time. So when I click on the button it keeps jupping to the myModal target. Thanks everyone for your help!
Solution
The solution I use is pretty simple.
<button type="button" class="btn btn-info btn-sm" data-toggle="modal" data-target="#myModal{{ loop.index }}">Backup</button>
<div id="myModal{{ loop.index }}" class="modal fade" role="dialog">

Categories