I am trying to create a virtual stock market where I have different modals displaying information about each stock.
But the template renders as such that I am unable to get a unique modal-header for each stock.
Even after clicking on the 'CIPLA' stock I get "Buy HDFC" as the modal header.
Here is my django template.
{% for stock in user.stocks.all %}
<li class="list-group-item">
<b>{{ stock.stock_name }}</b>
<p id="curr">Current price : {{ stock.current_price }}</p>
Bought at : {{ stock.buy_price }}
<button class="btn" id="buy" data-toggle="modal" data-target="#buy-modal">Buy</button>
<!--Modal for buy-->
<div id="buy-modal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Buy {{ stock.stock_name }}</h4>
</div>
<div class="modal-body">
<form method="post" action="/stocks/{{ user.id }}/{{ stock.stock_name }}/buy/" >
{% csrf_token %}
<label for="quantity">Quantity</label>
<input type="number" id="quantity-buy" name="quantity">
<button class="btn" id="confirm-buy" type="submit" >Buy</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
I have ended it with {% endfor %}.
The error is being caused by this line:
<button class="btn" id="buy" data-toggle="modal" data-target="#buy-modal">Buy</button>
As you can see, this line is mapped to data-target="#buy-modal" . This means that the Dom Element with id="buy-modal" gets invoked by it.
Now if you look inside your code, you are creating more than one number of modals(but with same html id).
The root error being the multiple Dom Elements with the same id. If you look at this line:
<div id="buy-modal" class="modal fade" role="dialog">
this line is created n-times inside your Dom(because it's being run inside a loop). This means that there are n-modals with the same ID. This also means that you Dom has n-number of modals with the same id.
Now that's a wrong practice in writing html.
Every time you click on the button:
<button class="btn" id="buy" data-toggle="modal" data-target="#buy-modal">Buy</button>
the html parser looks for the respective data-target in your html. Which clearly are n(since you created n; more than 1). Now the html always invokes the first or any specific modal every time because it parsed only one while it initialized your modal. Hence every time you click on a button, the same modal pops up
So to fix this you have to create modal with different ids and with different button triggers.
Hope this helps. Thanks.
Related
I want to ask you, if you know, is here some point or solution how to do confirm delete item with DeleteView class by Popup bootstrap window. So I will not use template_name, but popup windows on current page.
Thank you so much for everything...!!!
To be more precise
I have this button in my index.html page
<button type="button" class=" ml-1 btn btn-outline-dark my-2 my-sm-0" data-toggle="modal" data-target="#exampleModal">
In
</button>
And here I have modal for deleting
<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">Are you sure to delete this?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
<div class="modal-footer">
Yes
<button type="button" class="btn btn-danger" data-dismiss="modal">No</button>
</div>
</div>
</div>
</div>
</div>
and here is my views.py for delete
class ItemDeleteView(DeleteView):
model = Item
# template_name = 'index.html'
success_url = reverse_lazy('index')
login_url = '/accounts/login/'
def get(self, request, *args, **kwargs):
return self.post(request, *args, **kwargs)
and I don't know what to do. now... thanks
Best option would be Javascript, but you could instead redefine the get method of your DeleteView class :
Add that to your class
def get(self, request, *args, **kwargs):
return self.post(request, *args, **kwargs)
Basically the Deleteview need a post request to get trigger, it is a bit of a hack but works well.
In your template place this in your modal or popup
<form method="POST" action="{% url "your_delete_url_name" %}">
{% csrf_token %}<input type="submit" value="DELETE">
</form>
Do not forget the object id in your URL
so i have modal to confirm delete action, but when the tabel data is null / dont have any data, got have an error because i dont have id to call? but if i have more than 1 data my delete modal code is works perfectly.. an error occurs when I delete the last data in the table.
i have already try :
the error message is :
Undefined variable $listproduct on --> index.blade.php)
Possible typo $listproduct
Did you mean $listproducts?
my loop function is #foreach($listproducts as $listproduct)
this is my button :
<td>
<a href="#" class="btn btn-danger delete"
data-toggle="modal"
data-target="#deleteModal"
productid="{{$listproduct->id}}"> Delete
</a>
</td>
this is my modal :
<!-- Delete Warning Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="Delete" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Delete Contact</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form action="{{ route('products.destroy', $listproduct->id ) }}" method="post">
#csrf
#method('DELETE')
<div class="modal-body">
<label for="id">
<input id="id" name="productid">
</label>
<h5 class="text-center">Are you sure you want to delete this contact?</h5>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-sm btn-danger">Yes, Delete Contact</button>
</div>
</form>
</div>
</div>
</div>
<!-- End Delete Modal -->
this is my script to get ID ( I use this when i write this code :
<form action="{{ url('delete', 'id' ) }}" method="post">
but still not works
) :
$(document).on('click','.delete',function(){
let id = $(this).attr('productid');
$('#id').val(id);
});
this is my Product Controller :
public function destroy($id): RedirectResponse
{
$deleteads = Product::findOrFail($id);
$deleteads->delete();
return redirect('products');
}
and this is my route (iam using Resource):
Route::group(['middleware' => ['auth']], function() {
***Route::resource('products', ProductController::class);***
Route::delete('/selected-products', [ProductController::class, 'deleteSelectedItem'])->name('products.deleteSelected');
});
First, you can't use your own productid attribute in HTML, thus you should use data attribute you save your information.
Second, your form in the modal doesn't get it's action attribute updated and thus only One product ID remains in the action attribute.
Try putting a # in the action first, and then when an item is clicked to be deleted, use JQuery to update your form's action and put the proper URL and the ID of the product.
Your ID should be saved in data attribute like below:
<td>
<a href="#" class="btn btn-danger delete"
data-toggle="modal"
data-target="#deleteModal"
data-productid="{{$listproduct->id}}"> Delete
</a>
</td>
Form in the modal:
<form action="#" method="post" id="delete_product_form">
#csrf
#method('DELETE')
<div class="modal-body">
<label for="id">
<input id="id" name="productid">
</label>
<h5 class="text-center">Are you sure you want to delete this contact?</h5>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-sm btn-danger">Yes, Delete Contact</button>
</div>
</form>
JQuery code for handling the form's action attribute update:
$(document).on('click','.delete',function(){
let id = $(this).data('productid');
$('#delete_product_form').attr('action', '/products/' + id);
});
I need to develop back-end system and using(first time) Flask and mongodb for database. Basically, i need a dynamic table in a webpage with "add" button to add data to the table and "update" button for each row of data. So far, i have managed to load data(for table) from database once page is accessed and add new data to the table and database.
But I can not implement "update" button in each row, because I do not know how to detect which button was clicked in the table. I tried to get it through button value which was assigned to the ID of qualification(any row in table). Below is the table and i used bootstrap modal(which has the "html form" inside) for adding and updating
<table class="table table-condensed">
<thead>
<tr>
<th>Qualification</th>
<th>Calculation of overall result</th>
<th>Minimum Score</th>
<th>Maximum Score</th>
<th></th>
</tr>
</thead>
<tbody>
{% for qual in qualifications %}
<tr>
<td>{{ qual.qualificationName }}</td>
<td>{{ qual.calculation }}</td>
<td>{{ qual.minimumScore }}</td>
<td>{{ qual.maximumScore }}</td>
<td>
<!-- Button trigger modal -->
<form method="post" action="">
<<button type="submit" class="btn btn-danger" data-toggle="modal" data-target="#updateModalCenter"
name="updateBtn" value="{{ qual._id }}">Update
</button>
</form>
<!-- Modal -->
<div class="modal fade" id="updateModalCenter" tabindex="-1" role="dialog" aria-labelledby="updateModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="updateModalLongTitle">Update Qualification</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form method="post" action="{{setupQual/qual._id}}">
<div class="form-group">
<label>Qualification Name</label>
<input type="text" class="form-control" name="qualNameUpdate">
</div>
<div class="form-group">
<label>Calculation of result by average of how many subjects: </label>
<select multiple class="form-control" name="calculationUpdate">
<option>1 subject</option>
<option>2 subjects</option>
<option>3 subjects</option>
<option>4 subjects</option>
<option>5 subjects</option>
<option>6 subjects</option>
<option>7 subjects</option>
<option>8 subjects</option>
</select>
</div>
<div class="form-group">
<label>Minimum Score</label>
<input type="number" class="form-control" name="minScoreUpdate" placeholder="Enter number(s) only">
</div>
<div class="form-group">
<label>Maximum Score</label>
<input type="number" class="form-control" name="maxScoreUpdate" placeholder="Enter number(s) only">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<input type="submit" class="btn btn-primary" value="Save">
</div>
</form>
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
the backend code for adding
#app.route("/setupQual/add", methods = ['POST']) #addding to db from modal
def addQualification():
qualName = request.form['qualName']
calc = request.form['calculation']
minScore = request.form['minScore']
maxScore = request.form['maxScore']
addToDB = {
"qualificationName": qualName,
"calculation": calc,
"minimumScore": minScore,
"maximumScore": maxScore
}
db.qualifications.insert_one(addToDB)
return redirect(url_for('setupQual'))
I tried many ways unsuccessfully and my last code for updating is this:
#app.route("/setupQual/<string: _id>" , methods = ['GET', 'POST']) #loading
from db for modal updating
def loadQualToUpdate():
updateBtnId = request.form['updateBtn']
qualUpdate = "myUni"#delete later, only for testing
updateQualifications = db.qualifications.findOne({
"_id": updateBtnId
})
qualName = request.form['qualNameUpdate']
calc = request.form['calculationUpdate']
minScore = request.form['minScoreUpdate']
maxScore = request.form['maxScoreUpdate']
updateDB = {
"$set": {
"qualificationName": qualName,
"calculation": calc,
"minimumScore": minScore,
"maximumScore": maxScore
}
}
db.qualifications.updateOne(updateQualifications, updateDB)
return redirect(url_for('setupQual'))
Obviously, page should not reload when "update" button is clicked. So, any suggestions to catch the "right" update button in the table using Flask python.
I did it by assigning ID value to hidden input
<input type="hidden" name="id" value="{{ qual._id }}" />
And requested from flask and found data by id and updated on mongodb
I have a get form that works well on one view.
http://myurl.com/myapp/filter_objects/?risk__worktask=1&craft=3
I have another view to export this filtered list to pdf. For now i'm storing the results in session and accessing list from there in my pdf view, but ideally i would like to pass the filter parameters from the GET form directly to the export_to_pdf view.
Is that possible in django ? [ to have a given GET form send to two different urls with two submit buttons ? Would be great !
Thanks !
Here's my form
<form method="get">
<div class="well">
<h4 style="margin-top: 0">Filter Objects</h4>
<div class="row">
<div class="form-group col-sm-4 col-md-3">
{{ filter.form.risk__worktask.label_tag }}
{% render_field filter.form.risk__worktask class="form-control" %}
</div>
<div class="form-group col-sm-4 col-md-3">
{{ filter.form.craft.label_tag }}
{% render_field filter.form.craft class="form-control" %}
</div>
</div>
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-search"></span> Search
</button>
</div>
<div class="well">
<h4 style="margin-top: 0">Filtered Ratings: {{ filter.qs.count }}</h4>
<a href="{% url 'myapp:export_ratings_to_pdf_by_worktask' %}">
<button type="button" class="btn btn-success">Export Filtered List ({{ filter.qs.count }} items)</button>
</a>
</div>
Why don't u use the formaction= tag attribute in your button to override the form action?
<form method="get" action="firstView">
<input ...
<input ...
<button ...>Submit to first view</button>
..
..
<button formaction="{% url 'myapp:secondView' %}" ...>Submit to second view</button>
</form>
It is a HTML5 attribute but it is supported by all the major browsers.
FormAction browser support
I'm using Django and i'm trying to send data in a modal to get informations of an element.
My button to open the modal is :
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#informations">
<span class="glyphicon glyphicon-trash" aria-hidden="true">{{registration_id}}</span>
</button>
And the modal is
<div class="modal fade" tabindex="-1" role="dialog" id="information">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<form method="post" action="{% url 'informations_choices' %}">
{% csrf_token %}
<input type="hidden" name="registration" value=......>
Get info about : ......
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="$('#information').modal('hide');$('#informations_choices').submit()">
Get Info
</button>
</div>
</div>
</div>
</div>
The modal open correctly, but how can transform the "......" into value (by exemple with the {{registration_id}} present in the button ?
Thanks in advance
I am assuming here that the modal is on the same page from the beginning. You can just replace the .... with {{registration_id}}. If you want to make the .... dynamic and changing over the time the person is on the page, you might want to look into javascript frameworks and work with AJAX requests.
If you want to go with plain AJAX you will end up with something like this:
$.ajax({
type: "POST",
url: "/getnewvalue/",
data: { array : items_array },
success: function (data) {
// make the changes to the DOM.
},
error: function(data) {
$("#MESSAGE-DIV").html("Something went wrong!");
}
});