handling ajax and jquery in django template - django

I am trying to load page in two parts.
second part is only render when user click on 'show more details'
<script>
$(document).ready(function(){
$('#toggle_details').click(function(e){
e.preventDefault();
if ($(this).hasClass('up')){
$(this).removeClass('up').addClass('down');
$('#toggle_text').html('Show More Details');
}
else {
$(this).removeClass('down').addClass('up');
$.ajax({
url: 'some_url_returning_json',
data: $(this).serialize(),
processData: false,
dataType: "json",
success: function(data) {
$( '.name' ).html(data.name);
$( '.lname' ).html(data.lname);
alert(data.name);
}
})
$('#toggle_text').html('Hide Details');
}
$('#details').slideToggle("slow");
return false;
});
$('#details').hide();
});
</script>
and my html is :
<div class="ad-grp-tbl creative-tbl custom-tbl">
<table width="100%">
<tr>
<th>Status:</th>
<td id='status'>{{ status }}</td>
</tr>
</table>
<table width="100%" id="details">
<tr>
<th>Name:</th>
<td id="name" >{{data.name}}</td>
</tr>
<tr>
<th>Last Name:</th>
<td id ="lname">{{ data.lname}}</td>
</tr>
</table>
<table>
<tr>
<th class="tog">
<span id="toggle_text" style="color:blue;font-weight:bold">Show More Details</span>
<span class="down" id="toggle_details"></span>
</th>
<td></td>
</tr>
</table>
</div>
So Basically I am not able to load the json return value in the template.
hw can i fix it. or my approach for solving the problem is wrong.
Thanks.

I show you an example:
def post_ajax(request):
TOTLE = 5
OFFSET = int(request.GET.get('offset', 0))
END = OFFSET + TOTLE
if OFFSET + 1 >= Post.objects.count():
LOADED = "已经全部加载完毕"
return HttpResponse(LOADED)
posts = Post.objects.filter(pub_time__lte=timezone.now())[OFFSET:END]
json_list = []
for post in posts:
t = get_template('blog/ajax_post.html')
html = t.render(Context({'post': post}))
# print(html)
json_list.append({
'html': html,
})
data = json.dumps(json_list)
return HttpResponse(data, content_type="application/json")
Is this you need?

Ajax + JQuery will get response and should put data appropriately in the page. Template of original page doesn't have much role to play.
However, you have to implement separate url+view+template that will handle the ajax request. You can use existing view but need to handle for ajax request (i.e. just to send part of html, likely using another template).
The template for ajax response should send only the relevant part of html and not the entire html page.

In the HTML you have ids set but you are using the class selector.
It should be:
$( '#name' ).html(data.name);
$( '#lname' ).html(data.lname);
instead of:
$( '.name' ).html(data.name);
$( '.lname' ).html(data.lname);
. is the class selector and # is the id selector.
You can try using Firebug or Chrome Dev Tools to see that the above returns the items.

Related

Creating clickable table that sends selected row data as a post request to a flask route

Sample code:
--------------------Start Code------------------
`
<tr>
<th>Year</th>
<th>Month</th>
<th>Day</th>
</tr>
<tr>
<td>2000</td>
<td>January</td>
<td>24</td>
</tr>
</table>
<button type="submit" class="x" formaction="/" formtarget="_blank">send data</button>
`
--------------------End code------------------
I want the user to select a row in the table.
And once they select the row the data from the row is sent to a route in my flask application.
Basically the whole row needs to be clickable so maybe the onclick attribute might work?
Example of flask route:
#app.route('/',methods=['POST','DELETE','GET']) def table(): return render_template('table.html')
Thanks so much!
Put an onclick on each row and get it's child by using getElementByTagsName (how to get a td value of a table using javascript)
Then put a fetch to post the selected data on the route you want to process the data.
HTML
<table>
<tr>
<th>Year</th>
<th>Month</th>
<th>Day</th>
</tr>
<tbody>
<tr onclick = "gen(this)">
<td>2000</td>
<td>January</td>
<td>25</td>
</tr>
<tr onclick = "gen(this)">
<td>2003</td>
<td>February</td>
<td>24</td>
</tr>
</tbody>
</table>
Javascript
<script type="text/javascript" charset="utf-8">
function gen(e){
var year = e.getElementsByTagName("td")["0"].innerText
var month = e.getElementsByTagName("td")["1"].innerText
var date = e.getElementsByTagName("td")["2"].innerText
var list = {
year: year,
month: month,
date: date
}
fetch(`${window.origin}/print`, {
method: "POST",
credentials: "include",
body: JSON.stringify(list),
cache: "no-cache",
headers: new Headers({
"content-type": "application/json"
})
})
}
</script>
Python
#app.route("/print", methods = ["post"])
def printer():
data = request.get_json()
print(data)
return "hey"

How to get table row values in a javascript function from a dynamically created table using for loop in django?

So basically, I am passing a context from views to my template.
In my template I am using 'for loop' to view the context in a tabular form and also attaching a button for every table row.
When that button is clicked, I want to call a javascript function(that has ajax call).
I need to get values of row elements for that particular row to use in my function.
My view function:
def asset_delivery(request):
deliverylist = Delivery.objects.filter(status='Added to Delivery List')
context = {'deliverylist': deliverylist}
return render(request, 'gecia_ass_del.html', context)
So far I tried passing those values as parameters in the following way.
My html template table:
<table class="table">
<thead style="background-color:DodgerBlue;color:White;">
<tr>
<th scope="col">Barcode</th>
<th scope="col">Owner</th>
<th scope="col">Mobile</th>
<th scope="col">Address</th>
<th scope="col">Asset Type</th>
<th scope="col">Approve Asset Request</th>
</tr>
</thead>
<tbody>
{% for i in deliverylist %}
<tr>
<td id="barcode">{{i.barcode}}</td>
<td id="owner">{{i.owner}}</td>
<td id="mobile">{{i.mobile}}</td>
<td id="address">{{i.address}}</td>
<td id="atype">{{i.atype}}</td>
<td><button id="approvebutton" onclick="approve({{i.barcode}},{{i.owner}},{{i.mobile}},{{i.address}},{{i.atype}})" style="background-color:#288233; color:white;" class="btn btn-indigo btn-sm m-0">Approve Request</button></td>
</tr>
{% endfor %}
</tbody>
</table>
The table is displayed perfectly but the button or the onclick or the function call does not seem to work.
My javascript function:
<script>
function approve(barcode2, owner2, mobile2, address2, atype2){
console.log('entered approved');
var today = new Date().getFullYear()+'-'+("0"+(new Date().getMonth()+1)).slice(-2)+'-'+("0"+new Date().getDate()).slice(-2);
$.ajax({
type:'POST',
url: 'deliveryupdate/'+barcode+'/',
dataType: 'json',
data:{
barcode: barcode2,
owner: owner2,
mobile: mobile2,
address: address2,
atype: atype2,
status:'Authority Approved',
statusdate: today,
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
beforeSend: function() {
console.log('before send');
},
success: function(){
console.log("success log");
swal("Success!","Asset request has been approved","success");
},
error: function(){
console.log("error");
}
});
}
</script>
I checked the browser logs and it looks like the function is not getting executed, meaning the problem lies with the function call or the button. Please help.
The code is working on my end. I have reduced the function to:
function approve(){console.log('entered approved');}
without any parameters and 'entered approved' is logged to the console. Check if you are setting the correct parameters and if the console throws an error. Simplify your function and add the parameters one by one in order to troubleshoot this.

Django template data update using ajax

I am trying to update my data periodically (10 seconds) on a Django template using ajax scripts. I am relatively new in front-end development.
Using other articles, I am able to do so. But everytime page refreshes, multiple threads for page refreshing are created and update requests are doubled every 10 secods.
Following is my django template snippet:
<body id="page-top">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr class="table-info">
<th style="text-align:center">Parameter</th>
<th style="text-align:center">A</th>
<th style="text-align:center">B</th>
</tr>
</thead>
<tbody>
{% for para, details in manualData.items %}
<tr>
<th style="text-align:center" scope="row">{{ details.1.name }}</th>
{% for key, entity in details.items %}
<td style="text-align:center">
<font color="white" size="4px">{{ entity.value }}</font>
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
I am using ajax script as follows:
<script type="text/javascript">
function refresh() {
var_ref = $.ajax({
success: function (data) {
$('#page-top').html(data);
}
});
}
$(function () {
setInterval('refresh()', 10000);
});
</script>
Conclusively, all I need is:
once the refreshing process is called, new process should not be
created, or else past process to be aborted if new process is to be
defined.
Kindly help me to attain the same.
Thanks in advance
Nakul
You need your ajax call to be synchronomous instead of async, this way you will block the thread until you get the data you require
Can be done by adding the corresponding attribute on the ajax call
When within the industry you would normally use the template system to load something like react, angular or vue which constantly update the DOM without having to make endless polling
Thanks to the answer at post: Refresh page periodically using jquery, ajax and django.
Also, Thank you #Mr-Programs for your suggestion regarding async attribute.
I have got a suitable answer for my query and updated the javascript as follows.
<script>
function worker(){
var url = 'yoururl';
$.ajax({
type:'get',
url: url,
async: false,
success: function(data) {
var dtr = $('.page-top',data);
# not necessarily body div, can use any section required to be updated
$('.page-top').html(dtr);
complete: function() {
setTimeout(worker, 10000);
}
});
}
$(document).ready(function(){
setTimeout(worker, 10000);
});
};
</script>

Django - Dynamically create element

I am making a complete admin and invoice app in Django.
For the invoice app, as the user clicks on "Create Sales Invoice" the invoice screen appears.
Now I want the system to dynamically generate new bill as soon as this screen appears, but not saved. As the user starts entering item, I want a new item detail (i.e. each bill has one item detail which has the list of items, its quantity and price).
However, none of them shall be saved unless the user clicks on create bill button.
I need help in how to do this thing, ie create a bill and item detail as the user goes to a create bill, link these two with foreign key, but also have the option to discard them if the user does not end up on clicking "save" button.
Edit 1
My invoicing HTML:
{% extends "base.html" %}
{% block title %}
{% load static from staticfiles %}
<script src="{% static 'bill/script.js' %}"></script>
<link rel="stylesheet" href="{% static 'bill/style.css' %}">
<title>Sales Invoice</title>
{% endblock %}
{% block content%}
<invoice>
<div id="invoice">
<invoiceheader>
<!--
<h1>Invoice</h1>
<address>
<p>Jonathan Neal</p>
<p>101 E. Chapman Ave<br>Orange, CA 92866</p>
<p>(800) 555-1234</p>
</address>
<span><img alt="" src="logo.png"><input type="file" accept="image/*"></span>
-->
</invoiceheader>
<invoicearticle>
<!--<h1>Recipient</h1>-->
<code>
<p>Customer code:
<input id="customer-code" ></input></p>
</code>
<address>
<p></p>
<p id="companyname">Some Company</p>
<p id = "companyaddress">c/o Some Guy</p>
</address>
<table class="meta">
<tr>
<th><span>Invoice #</span></th>
<td><span>101138</span></td>
</tr>
<tr>
<th><span>Date</span></th>
<td><span></span></td>
</tr>
<tr>
<th><span>Amount Due</span></th>
<td><span id="prefix">Rs. </span><span>600.00</span></td>
</tr>
</table>
<table class="inventory" id="inventory_table">
<thead>
<tr>
<th colspan="1"><span>Item Code</span></th>
<th colspan="2"><span>Item Name</span></th>
<th colspan="1"><span>Unit Rate</span></th>
<th colspan="1"><span>Discount 1</span></th>
<th colspan="1"><span>Quantity</span></th>
<th colspan="1"><span>Discount 2</span></th>
<th colspan="1"><span>Free Quantity</span></th>
<th colspan="1"><span>VAT Type</span></th>
<th colspan="1"><span>VAT</span></th>
<th colspan="1"><span>Net Rate</span></th>
</tr>
</thead>
<form>
<tbody>
<tr>
<td colspan="1"><a class="cut">-</a><span class="itemcode" contenteditable></span></td>
<td colspan="2"><span contenteditable></span></td>
<td colspan="1"><span contenteditable>150.00</span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable>4</span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable></span></td>
<td colspan="1"><span contenteditable></span></td>
</tr>
</tbody>
</form>
</table>
<a class="add">+</a>
<table class="balance">
<tr>
<th><span>Total</span></th>
<td><span data-prefix></span><span>600.00</span></td>
</tr>
<tr>
<th><span>Amount Paid</span></th>
<td><span data-prefix></span><span>0.00</span></td>
</tr>
<tr>
<th><span>Balance Due</span></th>
<td><span data-prefix></span><span>600.00</span></td>
</tr>
</table>
</article>
</div>
</invoice>
<script type="text/javascript">
/* url_sellbill = '{% url "billbrain:sellbill" %}' */
csrf_token='{{csrf_token}}'
</script>
{% endblock %}
My related jquery file (only the necessary part):
Generating Table:
function generateTableRow() {
var emptyColumn = document.createElement('tr');
emptyColumn.innerHTML = '<td><a class="cut">-</a><span class="itemcode" contenteditable></span></td>' +
'<td colspan="2"><span contenteditable></span></td>' +
'<td><span contenteditable>100.00</span></td>' +
'<td><span contenteditable></span></td>' +
'<td><span contenteditable></span></td>'+
'<td><span contenteditable></span></td>' +
'<td><span contenteditable></span></td>'+
'<td><span contenteditable></span></td>' +
'<td><span contenteditable></span></td>' +
'<td><span contenteditable></span></td>' ;
return emptyColumn;
}
Adding customer details on user entering customer code:
$( "#customer-code" ).change(function() {
/*alert( "Handler for .change() called." );*/
var input = $("#customer-code").val();
(function() {
$.ajax({
url : "",
type : "POST",
data : { customer_code: input,
datatype: 'customer',
'csrfmiddlewaretoken': csrf_token}, // data sent with the post request
dataType: 'json',
// handle a successful response
success : function(jsondata) {
$('#companyname').html(jsondata['name'])
$('#companyaddress').html(jsondata['address'])
console.log(jsondata); // log the returned json to the console
console.log("success"); // another sanity check
},
});
}());
});
Similarly, for products, on user entering product id, the other details are auto-generated:
$("#inventory_table").on("focus", ".itemcode", function(){
$(this).data("initialText", $(this).html());
/*alert( "On focus for table inventory called." );*/
});
$("#inventory_table").on("blur", ".itemcode", function(){
/*alert( "On blur for table inventory called." );*/
var input = $(this).html();
if ($(this).data("initialText") !== $(this).html()) {
var el = this;
/*valueis='Hi 5'
alert($(this).closest('tr').find('td:nth-child(4) span').html());*/
(function() {
$.ajax({
url : "",
type : "POST",
data : { item_code: input,
datatype: 'item',
'csrfmiddlewaretoken': csrf_token}, // data sent with the post request
dataType: 'json',
// handle a successful response
success : function(jsondata) {
$(el).closest('tr').find('td:nth-child(2) span').html(jsondata['name'])
$(el).closest('tr').find('td:nth-child(2) span').html(jsondata['name'])
$(el).closest('tr').find('td:nth-child(3) span').html(jsondata['sellingprice'])
console.log(jsondata); // log the returned json to the console
alert(jsondata['name']);
console.log("success"); // another sanity check
},
});
}());
}
});
Finally, this is my views.py file's relevant function:
def bill(request):
if request.method == 'POST':
datatype = request.POST.get('datatype')
if (datatype == 'customer'):
customerkey = request.POST.get('customer_code')
response_data = {}
response_data['name'] = Customer.object.get(customer_key__iexact=customerkey).name
response_data['address'] = Customer.object.get(customer_key__iexact=customerkey).address
jsondata = json.dumps(response_data)
return HttpResponse(jsondata)
if (datatype == 'item'):
productkey = request.POST.get('item_code')
response_data = {}
response_data['name'] = Product.object.get(prodkey__iexact=productkey).name
response_data['sellingprice'] = float(Product.object.get(prodkey__iexact=productkey).selling_price)
#response_data['address'] = Product.object.get(prodkey__iexact=productkey).address
jsondata = json.dumps(response_data)
return HttpResponse(jsondata)
return render(request, 'bill/invoicing.html')
You should use Model Forms to output to the user a form to fill and create an object after submit. You can also use some context data if you need to pre-fill some informations in the form.
Another way is to just create an object and flag it as "CANCELLED" if you want to remember some user's tries (what can be useful sometimes) or just remove it (what can cause performance issues if it is very common situation to not fill started bill).

Re-execute model hook and rerender in Ember js

I have in my Ember App, a route displaying a list of offers;
the model is loaded by jquery ajax (I don't use Ember-data):
Ember.$.ajax({
type: 'GET',
url: App.restAPIpath + '/offers/',
headers: {
"tokens": localStorage.tokens
},
async: false
}).then(function(res) {
data = res.offers;
});
return data;
The offers are shown in the template using a datatable and in each row there's a delete button that sends an ajax delete request to the server and correctly deletes the right offer:
{{#view App.dataTableView}}
<thead>
<tr>
<th>Created</th>
<th>Name</th>
<th>Deadline</th>
<th>Duration</th>
<th>Delete?</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Created</th>
<th>Name</th>
<th>Deadline</th>
<th>Duration</th>
<th>Delete?</th>
</tr>
</tfoot>
<tbody>
{{#each offer in model}}
<tr>
<td>
{{offer.createdAt}}
</td>
<td>
{{#link-to 'eng.offers.edit' offer}}{{offer.name}}{{/link-to}}
</td>
<td>
{{offer.deadline}}
</td>
<td>
{{offer.optionDuration}}
</td>
<td>
<button class="form-button-red" {{action "deleteOffer" offer}}>Delete</button>
</td>
</tr>
{{/each}}
</tbody>
{{/view}}
but then I need to update the model (and refresh the view?) because if not the deleted offer is still shown until you refresh the page...
I'd recommend switching your ajax to async, you'll block the router from doing other important things. You should be able to accomplish the same results doing this:
return Ember.$.ajax({
type: 'GET',
url: App.restAPIpath + '/offers/',
headers: {
"tokens": localStorage.tokens
},
}).then(function(res) {
return res.offers;
});
Then I'd do something like this for your delete (I'm going to guess a bit of your code) in your controller's delete action:
actions:{
delete: function(item){
var self = this;
Ember.$.ajax({
type: 'DELETE',
url: App.restAPIpath + '/delete/' + item.get('id'),
headers: {
"tokens": localStorage.tokens
},
}).then(function(){
//manually remove the item from your collection
self.removeObject(item);
});
}
}
BTW I think delete is a reserved key word and jslint and some minimizers are total haters, so you might do something like deleteItem