HTML override table element to show nothing - python

I am rendering a HTML table through Django. In this table, some of the cells or columns contain "0"'s as produced by my python code.
Is there any way in HTML to override that cell or column and for it to show instead a blank in the table cell rather than a 0?
I am using jQuery as well, if that helps.
<tr><td> Value</td>
{% for num in list %}
<td> <b>{{num}}</b>
{% endfor %}</td>
</tr>
Output is a list which contains 3 zero's...out of which I want two blanked out.
Lets say if I have something being returned that is
0
10
0
20
0
But want
""
10
""
20
0
$(".dem").each(function() {
for ( var i = 0; i<2; i++)
{
if ($(this).html() == "0") {
$(this).html(" ");
}
i = i+1
}
});
I did that ^....however it turned all 3 zeros blank...why?
Thanks!

See the last edit for my final answer. I'm leaving the rest in to show how important it is to ask a good question, and to show what was tried, what the input looked like and what the expected output should have been. That would have saved a lot of time.
Using jQuery, you can iterate over each table cell, check the value and change what it outputs. I prefer this over changing the actual data. It's better to leave your data intact and only change the way it is displayed here.
$("#test td").each(function() {
if ($(this).html() == "0") {
$(this).html("");
}
});
You can see it in action here.
Update:
If only some <td>s should be changed, I recommend using a class for those.
$(".noZeroAllowed").each(function() {
if ($(this).html() == "0") {
$(this).html("");
}
});
It works with HTML like this:
<table id="test">
<tr>
<td class="noZeroAllowed">10</td>
<td class="noZeroAllowed">5</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td class="noZeroAllowed">11</td>
<td class="noZeroAllowed">0</td>
<td>9</td>
<td>7</td>
</tr>
</table>
Also see the updated fiddle.
Update 2:
If the data is not atomic and the cells have multiple values in them, like this:
<table id="test">
<tr>
<td class="noZeroAllowed">10 0 foobar 0</td>
<td class="noZeroAllowed">5</td>
<td>0, 0, 0</td>
<td>1</td>
</tr>
</table>
Then you need to change the Javascript to use a regular expression instead. The \b means a word boundary. It will not work with decimals like 0.5 though.
$(".noZeroAllowed").each(function() {
var newStr = $(this).html().replace(/\b0\b/g, "");
$(this).html(newStr);
});
See the updated fiddle.
Update 3:
This will turn all the zeros inside of <b> tags in the relevant class <td>s into empty strings, but leave the last zero intact.
$(".noZeroAllowed").each(function() {
var zeros = new Array;
var b = $(this).find("b");
for (var i = 0; i < b.length; i++) {
$(b[i])
if ($(b[i]).html() == "0") {
zeros.push(b[i]);
}
}
for (var i = 0; i < zeros.length - 1; i++) {
$(zeros[i]).html("");
}
});
See it here.

If the zeros are the only thing that evaluates false, you can use the default template filter:
{{ value|default:" " }}
You may need to use the actual unicode character
{{ value|default:"\u00A0" }}
In response to your edit:
<tr><td> Value</td>
{% for num in list %}
<td> <b>{{ num|default:"\u00A0" }}</b>
{% endfor %}</td>
</tr>
For changing only the first row:
<tr><td> Value</td>
{% for num in list %}
<td> <b>{% if forloop.first %} {% else %}{{ num }}{% endfor %}</b>
{% endfor %}</td>
</tr>
For more on the forloop variables, check here.

You could use Django's templates (see documentation):
{% if val != 0 %}{{ val }}{% endif %}
Alternatively, if you want something neater, you could use a Django filter in a template:
{{ val | default: "" }}
... Colin beat me to that one. ;) See the documentation for the 'default' filter.
EDIT: In answer to your comment, you'd do it like this:
{% for num in list %}
<td><b>{{num | default: ""}}</b></td>
{% endfor %}
Note that you had your </td> outside the for loop, whereas it needs to be inside.

Related

Rendering Flask template show the HTM page twice

I have a flask route rendering a template (method1_result.html) containing a dataframe table. Clicking the table row will send the cell value to another flask route to render a new template (method2_result.html). This last operation is showing a new result relevant to the Cell Clicked but the new html page (method1_result.html) is displaying the result twice.
main.py
#app.route("/method1",methods=['POST', 'GET'])
def method1():
'
'
return render_template('method1_result.html')
#app.route("/method2",methods=['POST', 'GET'])
def method2():
if request.method == 'POST':
# get info here to render page!
.
.
return render_template('method2_result.html',var1=var1)
method1.html
{% block content %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<br/>
<h3 align="center" style="color:blue" style="font-family:verdana">Method1 Result</h3>
<br/>
<div class="container-fluid">
<table id="table" class="table table-striped table-bordered" style="width: 100%">
<thread>
<tr>
{% for header in table[0].keys() %}
<th>{{header}}</th>
{% endfor %}
</tr>
</thread>
<tbody>
{% for row in table %}
<tr class='clickable-row'>
<td>{{row['Field1']}}</td>
<td>{{row['Field2']}}</td>
<td>{{row['Field3']}}</td>
<td>{{row['Field4']}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script>
highlight_row();
function highlight_row(var1='') {
var table = document.getElementById('table');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
msg = 'The Failure Message : ' + rowSelected.cells[6].innerHTML;
var var1 = rowSelected.cells[3].innerHTML;
$.ajax({
url:"/method2",
method:"POST",
data:{var1:var1},
success:function(data)
{
$('tbody').html(data);
$('tbody').append(data.htmlresponse);
},
})
}
}
}
</script>
{% endblock %}
method2.html
{% block content %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<br/>
<h4 align="center" style="color:blue" style="font-family:verdana">Method2 result</h4><br/>
<br/>
<table id="table" class="table table-striped table-bordered table-hover" style="width: 100%">
<thread>
<tr>
{% for header in table1[0].keys() %}
<th>{{header}}</th>
{% endfor %}
</tr>
</thread>
<tbody>
{% for row in table1 %}
<tr>
<td>{{row['Start']}}</td>
<td>{{row['OperationID']}}</td>
<td style="color:red">{{row['Failure Message1']}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
Not sure what Am doing wrong ?
In your code, you are doing an asynchronous call (ajax). An asynchronous call does not reload a page. This means that user is still on method1_result.html when the result (i.e. method2_result.html) comes in.
Your code also says to simply append the entire method2_result.html to method1_result.html page. In fact, you do it twice because you have
// First you append the entire response i.e. the entire method2 result
$('tbody').html(data);
// Then you try to do it a second time but just the 'htmlresponse' (not sure where you are getting this fro
$('tbody').append(data.htmlresponse);
If you want to replace the entire page (method1_result) with the entire contents of method2_result, then you don't need an Ajax call. Replace that ajax call with code that creates a form, creates an input element with the values of the data that you want to pass to the server, and then submits the form. Since this is not an ajax call, it will load a new page which is method2.html
var form = document.createElement("form");
form.method = "POST";
form.action = "/method2";
var elem = document.createElement("input");
elem.name= var1;
elem.value= var1;
form.appendChild(elem1);
document.body.appendChild(form);
form.submit();
If you don't want to replace the entire page (maybe you want to replace the body of the existing page with the new page), then you can't just do append which means to add to the existing content, unless you have first cleared the existing content. You have 2 options
Option 1
$('tbody').empty() // Remove the current contents
$('tbody').append(data); // Add the new contents
Option 2
$('tbody').html(data)

Import list in flask in html table

I am facing an issue while accessing the contents in html file of the python list declared in Flask code. Here is the brief details.
FLASK code:
class TestSuiteForm(FlaskForm):
TestCases = ['Check Red LED Status', 'Check Red2 LED Status', 'Check Red3 LED Status']
NumOfTestCases = len(TestCases)
#app.route("/offlineTest")
def offlineTest():
form = TestSuiteForm()
return render_template("offlineTest.html", title='Offline Testing', form=form)
if __name__ == "__main__":
app.run(debug=True)
HTML code: Adding snippet which have the issue.
<p >
<h4>Test Cases2</h4>
<table id="testcaseTable2" style="width:50%"> </table>
</p>
<script language="javascript" type="text/javascript">
var text = "";
text = "<tr> <th>Sr num </th> <th>Test Case Name </th> <th>Select/Deselect</th> </tr>"
for (var i = 0; i < {{form.NumOfTestCases}}; i++)
{
text += '<tr>'
text += '<td>' + [i+1] + '</td>'
text += '<td>"' + {{form.TestCases[i]}} + '"</td>' //Not working; output NaN
text += '<td><input type="checkbox"/> </td> </tr>'
}
document.getElementById("testcaseTable2").innerHTML = text
</script>
I am not able to access the {{form.TestCases[i]}} data, but if I hardcode i with 0,1,2 it gives proper data.
Please let me know the problem. I beleive it is happening due to string concatenation but not sure how to solve it. I am really new to web page design so pardon me if its a stupid mistake.
Use a Jinja for loop to build the table.
<table id="testcaseTable2" style="width:50%">
{% for test_case in form.TestCases %}
<tr>
<td>{{ loop.index + 1 }}</td>
<td>{{ test_case }}</td>
<td><input type="checkbox"/> </td>
</tr>
{% endfor %}
</table>

How can I add a Bar Chart to my Django based Database?

Dear community members,
I really hope that you will help me to add a Bar Graph to my Django project.
1. I have a Database with around 1000 items.
2. I need to be able visualise a 3 month sales for each item when needed.
Not sure what is a correct approach.
here is my models.py:
from django.db import models
from math import *
from decimal import *
class Itemslist(models.Model):
item_n = models.CharField(max_length=200)
sales_this_month = models.DecimalField(blank=True, null=True, max_digits=19,
decimal_places=0)
saleslm = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
sales2m = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
sales3m = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
def __str__(self):
return self.item_n
here is my views.py file, that as an experiment I have created, using the last solution provided:
def charts(request):
charts = Itemslist.objects \
.values('saleslm') \
.annotate(lm=Count('saleslm')) \
.annotate(m2=Count('sales2m')) \
.annotate(3m3=Count('sales3m')) \
.order_by('saleslm')
return render(request, 'charts.html', {'charts': charts})
As you can see, this is not a solution I need, I was just trying to come up with at least something , and eaven that has shown me the graph with the same values.
here is my hmtl code:
{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}
<br>
<p>Logged in user: {{ user.username }}</p>
<br>
<html>
<head>
<meta charset="utf-8">
<title>Django Highcharts Example</title>
</head>
<body>
<div id="container"></div>
{
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script>
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Sales previous 3 months'
},
xAxis: {
categories: ['sales']
},
series: [{
name: '3mBack',
data: [ {% for entry in charts %}{{ entry.m3 }}{% endfor %} ]
}, {
name: '2mBack',
data: [ {% for entry in charts %}{{ entry.m2 }}{% endfor %} ]
}, {
name: 'Lmonth',
data: [ {% for entry in charts %}{{ entry.lm }}{% endfor %} ]
}, ]
});
</script>
</body>
</html>
{% endif %}
{% endblock %}
<!-- charting tutorial to follow : https://simpleisbetterthancomplex.com/tutorial/2018/04/03/how-to-integrate-highcharts-js-with-django.html -->
I have to create a request button for charts and then chart has to be generated with a right parameters.
Have looked at this question:
Displaying multiple bar graph in django
Also have searched through this solution
https://code.djangoproject.com/wiki/Charts
And looked at this article
https://simpleisbetterthancomplex.com/tutorial/2018/04/03/how-to-integrate-highcharts-js-with-django.html
The last article was the clearest one, and you can see, that I have just copy pasted the solution from there, with small changes.
here is a script that I have placed in my base.html file:
<script src="https://code.highcharts.com/highcharts.src.js"></script>
and that's the chart that I have finally got displayed:
But still can’t find how to deal with it in my situation.
All this solutions, as far as I can see, are showing how to implement charting to one array, or to sum or self generated array. But I want to be able to chose, when to show a graph and for which Item.
the button is placed on this html file:
{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}
<br>
<p>Logged in user: {{ user.username }}</p>
<br>
<body>
<table id="example" class="table table-striped table-bordered dt-responsive nowrap" style="width:100%">
<thead>
<tr>
<th>SUP:</th>
<th>Item N.:</th>
<th>SKU</th>
<th>Description</th>
<th>3mBack</th>
<th>2mBack</th>
<th>Lmonth</th>
<th>CMonth</th>
<th>Nmonth</th>
<th>N2Month</th>
<th>N3month</th>
<th></th>
</tr>
</thead>
<tbody>
{% for records in sorted %}
<tr>
<td>{{ records.sup }}</td>
<td>{{ records.item_n }}</td>
<td>{{ records.sku }}</td>
<td>{{ records.description }}</td>
<td>{{ records.sales3m }}</td>
<td>{{ records.sales2m }}</td>
<td>{{ records.saleslm }}</td>
<td>{{ records.sales_this_month }}</td>
<td>{{ records.m1predicted }}</td>
<td>{{ records.m2predicted }}</td>
<td>{{ records.m3predicted }}</td>
<td>
Edit
</td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
$(document).ready(function() {
var table = $('#example').DataTable( {
fixedColumns: true,
lengthChange: true,
buttons: [ 'copy', 'excel', 'csv', 'pdf', 'colvis' ]
} );
table.buttons().container()
.appendTo( '#example_wrapper .col-md-6:eq(0)' );
} );
</script>
</body>
</html>
{% endif %}
<div></div>
{% endblock js %}
This is my first question in this community, so if something is not clear, please help me to correct it in a right way.
waiting for any helpful answers!!!
Good News community.
I have been offered a very good solution, and now my question is completely sorted.
At least for my needs, this is a perfect solution.
instead of highcharts, I have been offered to use d3js.org, which is absolutely fine for me.
The logic behind a code is that you request data from the values displayed, hopefully it will be clear, when you will go through the code with comments.
as it's a django project, here's the heading of my html file:
{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}
<br>
<p>Logged in user: {{ user.username }}</p>
<br>
here is a part of my html code that displays table/value:
<table id="example" class="table table-striped table-bordered dt-responsive nowrap" style="width:100%">
<thead>
<tr>
<th>SUP:</th>
<th>Item N.:</th>
<th>SKU</th>
<th>Description</th>
<th>6mBack</th>
<th>5mBack</th>
<th>4mBack</th>
<th>3mBack</th>
<th>2mBack</th>
<th>Lmonth</th>
<th>CMonth</th>
<th>Nmonth</th>
<th>N2Month</th>
<th>N3month</th>
<th>AVGrowth</th>
<th></th>
<!-- This is header for new button to draw the Bar Charts -->
<th></th>
</tr>
</thead>
<tbody>
{% for records in sorted %}
<tr>
<td>{{ records.sup }}</td>
<td>{{ records.item_n }}</td>
<td>{{ records.sku }}</td>
<td>{{ records.description }}</td>
<td>{{ records.sales6m }}</td>
<td>{{ records.sales5m }}</td>
<td>{{ records.sales4m }}</td>
<td>{{ records.sales3m }}</td>
<td>{{ records.sales2m }}</td>
<td>{{ records.saleslm }}</td>
<td>{{ records.sales_this_month }}</td>
<td>{{ records.m1predicted }}</td>
<td>{{ records.m2predicted }}</td>
<td>{{ records.m3predicted }}</td>
<td>{{ records.avgrowths }}</td>
<td>
Edit
</td>
<!-- Add new button for drawing Bar Charts -->
<td>
<button class="btn btn-secondary" onclick="draw_chart(this)" data-toggle="modal" data-target="#myModal">Chart</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
please read comments to understand what is what.
and here is the rest of html, that is generating a chart on a topup window,by pressing a button in front of an array that has to be visualised:
<!-- Modal which Bar Chart will be placed -->
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog" style="max-width: 900px !important">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<!-- <svg> element which will contains the Bar Chart -->
<svg width="1000" height="500"></svg>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Insert D3.js Library -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
$(document).ready(function() {
var table = $('#example').DataTable( {
fixedColumns: true,
lengthChange: true,
buttons: [ 'copy', 'excel', 'csv', 'pdf', 'colvis' ]
} );
table.buttons().container()
.appendTo( '#example_wrapper .col-md-6:eq(0)' );
} );
// Main functions for Drawing Bar chart using D3.js
function draw_chart(item){
// `item` is the current clicked button element
// `row_ele` is the parent <tr> element of the current clicked button element
row_ele = item.closest('tr');
// Get the value from the <td> element using nth-child()
val_6mBack = row_ele.querySelector("td:nth-child(5)");
val_5mBack = row_ele.querySelector("td:nth-child(6)");
val_4mBack = row_ele.querySelector("td:nth-child(7)");
val_3mBack = row_ele.querySelector("td:nth-child(8)");
val_2mBack = row_ele.querySelector("td:nth-child(9)");
val_Lmonth = row_ele.querySelector("td:nth-child(10)");
val_CMonth = row_ele.querySelector("td:nth-child(11)");
val_Nmonth = row_ele.querySelector("td:nth-child(12)");
val_N2Month = row_ele.querySelector("td:nth-child(13)");
val_N3month = row_ele.querySelector("td:nth-child(14)");
// `data` is variable which store the data for Bar Charts
data = []
// Pushing data as key/value type objects into the `data` variable
data.push({'label':'6mBack', 'value': val_6mBack.innerHTML})
data.push({'label':'5mBack', 'value': val_5mBack.innerHTML})
data.push({'label':'4mBack', 'value': val_4mBack.innerHTML})
data.push({'label':'3mBack', 'value': val_3mBack.innerHTML})
data.push({'label':'2mBack', 'value': val_2mBack.innerHTML})
data.push({'label':'Lmonth', 'value': val_Lmonth.innerHTML})
data.push({'label':'CMonth', 'value': val_CMonth.innerHTML})
data.push({'label':'Nmonth', 'value': val_Nmonth.innerHTML})
data.push({'label':'N2Month', 'value': val_N2Month.innerHTML})
data.push({'label':'N3month', 'value': val_N3month.innerHTML})
// Set <svg> element's width and height
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin
// Remove the old contents of the <svg> element
svg.selectAll('*').remove()
// Initialize X-axis and Y-axis for Bar Chart
var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);
// Set all group which is placed in the <svg>element
// transform to (50,100) on <svg> area , margint in svg has been changed to 300 and instead 50/100, changed to 100/300, but then back.
var g = svg.append("g")
.attr("transform", "translate(" + 50 + "," + 100 + ")");
xScale.domain(data.map(function(d) { return d.label; }));
// If all values of data will be zero, we will fix the range of the Y-axis
if(d3.max(data, function(d) { return d.value; }) == 0){
yScale.domain([0, 10]);
}else{
// If all is not zero, we will set Y-axis from 0 to maximum value.
yScale.domain([0, d3.max(data, function(d) { return Number(d.value); })]);
}
// Set X- axis
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale));
// Set Y-axis using ticket
g.append("g")
.call(d3.axisLeft(yScale).tickFormat(function(d){
return d;
}).ticks(10));
console.log(data)
// Draw Bar Chart using <rect> element by data which is stored in the `data` variable
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xScale(d.label); })
.attr("y", function(d) { return yScale(d.value); })
.attr("width", xScale.bandwidth())
.attr("height", function(d) { return height - yScale(d.value); })
.style('fill','#899da6');
}
</script>
</body>
{% endif %}
{% endblock js %}
so finally here is how my html looks like live:
and here is a graph, that I get by pressing chart button:
in order to help community, please ask questions, and please add/correct if there is a better way.
Thank you very much for your help and attention!!!
views.py
You have an error on annotate(3m3 its cannot start with 3 here. You also have same function name and variable name def charts and charts inside. Python might be smart enough to figure it out but try to avoid doing this. I am also against naming variables saleslm and sales2m be explicit here.
def charts(request):
return render(request, 'charts.html')
def charts_ajax(request):
charts_data = Itemslist.objects \
.values('saleslm') \
.annotate(lm=Count('saleslm')) \
.annotate(m2=Count('sales2m')) \
.annotate(m3=Count('sales3m')) \
.order_by('saleslm')
return JsonResponse({'charts': list(charts_data)})
url.py
path('charts/', views.charts, name='charts_home'),
path('charts_ajax/', views.charts_ajax, name='render_charts_ajax')
html
You have multiple issues in your html file.
</html>
{% endif %}
<div></div>
{% endblock js %}
You have div after the html has ended. You should not have anything after html ends.
Few other organizational issues here. I usually would have a block content and then block js while you have everything inside block js. I would clean those. Now that you added datables also. You can add buttons as mentioned here. https://datatables.net/extensions/buttons/examples/initialisation/custom.html
but if i were you i would try to make it work with simple table and move on to datables.
<html>
<head>
<meta charset="utf-8">
<title>Django Highcharts Example</title>
</head>
<body>
<div id="container">
</div>
<button id="render_chart" type="button">Render Chart</button>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script>
$(document).ready(function(){
$('#render_chart').on('click', function(e){
$.ajax({
url: "{% url 'render_charts_ajax'%}",
type: "GET",
dataType: "json",
success: function (data) {
console.log(data.charts[0].saleslm)
Highcharts.chart('container',{
chart:{
type:'bar'
},
title:{
text:"Sales Last Month"
},
series:[{
name:"Sales LM",
data:[parseInt(data.charts[0].saleslm)]
}]
})
}
})
})
});
</script>
</body>
</html>
Your json might need some processing before the chart comes out right.

How to create multiple datetimepickers in django template (for loop) and jquery

I am having trouble getting django to display multiple datetimepickers in tabs on a html page. I can get them to work if I specify each element in the jquery outside of a loop, but when I put it in a loop, they don't show (only shows an empty input text box). As this has to be done on an array of varying sizes (min length of 1 and no max), I can't hard code each individual datetimepicker. The for loop on the django template html page works, and each tab and the sections where the datetimepickers go is made, but the jquery won't work.
I have tried to make the 4 datetimepickers via a loop (4 per tab, can have 1+ tabs), and they don't create the datetimepicker object. Just creates a input text box.
I have also tried putting them all into a class=datetimepicker, which does work, but then I can't add in default data from the array to fill in each datetimepicker, as the only function in jquery is a single one calling the class .datetimepicker. Tried $('#date1').datetimepicker({ defaultDate: array[counter][0] }) in an array to fill in each tab for the date1 datetimepicker, and that does not work either.
excluding usual django template code and just putting in the section not working:
------------------- template html ------------------------
{% if entryList %}
<ul id="tab_links" class="nav nav-tabs justify-content-center">
{% for entry in entryList %}
{% if forloop.first %} <!-- won't go through the first iteration otherwise -->
<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#tab_{{forloop.counter0}}">{{entry.0}}</a></li>
{% else %}
<li class="nav-item"><a class="nav-link" data-toggle="tab" href="#tab_{{forloop.counter0}}">{{entry.0}}</a></li>
{% endif %}
{% endfor %}
</ul>
<div id="tab_content" class="tab-content">
{% for entry in entryList %}
{% if forloop.first %}
<div id="tab_{{forloop.counter0}}" class="tab-pane fade in active">
<table cellspacing="10" cellpadding="10">
<tr>
<td> date1: </td>
<td style="position:relative">
<input class="datetimepicker" type="text" id="date_{{forloop.counter0}}" name="date_{{forloop.counter0}}" ">
</td>
<!-- other input like txt boxes or drop down menus -->
</tr>
<tr>
<td> date2: </td>
<td style="position:relative">
<input class="datetimepicker" type="text" id="date_{{forloop.counter0}}" name="date_{{forloop.counter0}}" ">
</td>
<!-- other input like txt boxes or drop down menus -->
</tr>
<tr>
<td> date3: </td>
<td style="position:relative">
<input class="datetimepicker" type="text" id="date_{{forloop.counter0}}" name="date_{{forloop.counter0}}" ">
</td>
<!-- other input like txt boxes or drop down menus -->
</tr>
<tr>
<td> date4: </td>
<td style="position:relative">
<input class="datetimepicker" type="text" id="date_{{forloop.counter0}}" name="date_{{forloop.counter0}}" ">
</td>
<!-- other input like txt boxes or drop down menus -->
</tr>
</table>
</div>
{% else %}
<div id="tab_{{forloop.counter0}}" class="tab-pane fade">
<table cellspacing="10" cellpadding="10">
<tr>
<td> date1: </td>
<td style="position:relative">
<input class="datetimepicker" type="text" id="date_{{forloop.counter0}}" name="date_{{forloop.counter0}}" ">
</td>
<!-- other input like txt boxes or drop down menus -->
</tr>
<tr>
<td> date2: </td>
<td style="position:relative">
<input class="datetimepicker" type="text" id="date_{{forloop.counter0}}" name="date_{{forloop.counter0}}" ">
</td>
<!-- other input like txt boxes or drop down menus -->
</tr>
<tr>
<td> date3: </td>
<td style="position:relative">
<input class="datetimepicker" type="text" id="date_{{forloop.counter0}}" name="date_{{forloop.counter0}}" ">
</td>
<!-- other input like txt boxes or drop down menus -->
</tr>
<tr>
<td> date4: </td>
<td style="position:relative">
<input class="datetimepicker" type="text" id="date_{{forloop.counter0}}" name="date_{{forloop.counter0}}" ">
</td>
<!-- other input like txt boxes or drop down menus -->
</tr>
</table>
</div>
{% endif %}
{% endfor %}
</div>
.
. other data on template html
.
<script> var numOfTabs = {{entryListLength}};
var jsondataList = {{json_dataList|safe}};
</script>
<script src="{% static 'js/dates.js' %}"> </script> <!-- right before /body tag -->
--------------------------------js/dates.js------------------------------
// gotta use a for loop to get all tabs
// 4 parts of the array are dates: 7 - date rec, 10 - date ret, 16 - key req date, 17 - key rec date
var count = 0;
for (count; count < numOfTabs; count++) {
// date1
if ((jsondataList != null) && (jsondataList.length != 0) && (jsondataList[count][7] != null) && (jsondataList[count][7].length != 0)) {
var datearr = jsondataList[count][7].split(/-|\s|:/);
var date1 = new Date(datearr[0], datearr[1] - 1, datearr[2], datearr[3], datearr[4], datearr[5]);
var inName = "#date1_" + count;
console.log('array slot : ', count, 7, date1, inName);
$(function() {
$(inName).datetimepicker({
useCurrent:false,
format: 'YYYY-MM-DD HH:mm:ss',
defaultDate: date1,
});
});
} else {
$(function() {
$("#date1_" + count).datetimepicker({
format: 'YYYY-MM-DD HH:mm:ss',
});
});
}
// date2
if ((jsondataList != null) && (jsondataList.length != 0) && (jsondataList[count][10] != null) && (jsondataList[count][10].length != 0)) {
var datearr = jsondataList[count][10].split(/-|\s|:/);
var date2 = new Date(datearr[0], datearr[1] - 1, datearr[2], datearr[3], datearr[4], datearr[5]);
var inName = "#date2_" + count;
console.log('array slot : ', count, 10, date2, inName);
$(function() {
$(inName).datetimepicker({
useCurrent:false,
format: 'YYYY-MM-DD HH:mm:ss',
defaultDate: date2,
});
});
} else {
$(function() {
$("#date2_" + count).datetimepicker({
format: 'YYYY-MM-DD HH:mm:ss',
});
});
}
// date3
if ((jsondataList != null) && (jsondataList.length != 0) && (jsondataList[count][16] != null) && (jsondataList[count][16].length != 0)) {
var datearr = jsondataList[count][16].split(/-|\s|:/);
var date3 = new Date(datearr[0], datearr[1] - 1, datearr[2], datearr[3], datearr[4], datearr[5]);
var inName = "#date3_" + count;
console.log('array slot : ', count, 16, date3, inName);
$(function() {
$(inName).datetimepicker({
useCurrent:false,
format: 'YYYY-MM-DD HH:mm:ss',
defaultDate: date3,
});
});
} else {
$(function() {
$("#date3_" + count).datetimepicker({
format: 'YYYY-MM-DD HH:mm:ss',
});
});
}
// date4
if ((jsondataList != null) && (jsondataList.length != 0) && (jsondataList[count][17] != null) && (jsondataList[count][17].length != 0)) {
var datearr = jsondataList[count][17].split(/-|\s|:/);
var date4 = new Date(datearr[0], datearr[1] - 1, datearr[2], datearr[3], datearr[4], datearr[5]);
var inName = "#date4_" + count;
console.log('array slot : ', count, 17, date4, inName);
$(function() {
$(inName).datetimepicker({
useCurrent:false,
format: 'YYYY-MM-DD HH:mm:ss',
defaultDate: date4,
});
});
} else {
$(function() {
$("#date4_" + count).datetimepicker({
format: 'YYYY-MM-DD HH:mm:ss',
});
});
}
}
The code for the class version is
$(function() {
$(".datetimepicker").datetimepicker();
});
*this works for making datetimepickers, but can't put default values in.
The expected result is that it has tabs on the page, with the number equal to the size of the list of arrays/lists i.e. list[x][y] there would be x tabs. On each tab is y input variables (text boxes, areas, etc.) as well as 4 datetimepickers. The datetimepickers should display the default value from the list for each tab, and have the option to choose a different value based on clicking the datetimepicker object and a calendar popping up.
The actual output shows everything but the datetimepickers. The datetimepickers are shown as textboxes, don't populate the default values, and don't load the calendar when clicked on (just act like textboxes instead). If I make the js as a function acting on just the class itself, it will make the datetimepicker objects, but doesn't allow me to put in default values.
Everything else in the template works, just the datetimepickers when in a loop that don't. Been trying for a couple of weeks now to figure it out.
EDIT:
Also, a thing to note: if I create each of the 4 datetimepickers outside a loop, then for the tab I create them for it will work, but since I don't know how many tabs I'll have I have to do it dynamically, hence why their in a javascript loop.
figured out a solution for anyone else who has the same or similar problem. Instead of directly making the datetimepickers in the loop, I separated the datetimepicker function from the loop and just call it.
i.e:
for loop
....
....
call mydatetimepicker(variable, variable)
mydatetimepicker(variable, variable) {
code to create a datetimepicker
}
for the life of me couldn't get it to work inside the loop, but as soon as i separate them it works fine even with the default dates.

How do I auto increment my results in a page?

I made this table but I can't figure out how to do the numbering. I want a top 10 list and I get all the data from a database. I essentially want to make it show '1' and the next '2' and the next '3' and so forth. How would I able to do this?
https://imgur.com/a/9Isf941
def home(request):
straatData = data.objects.all()[:10]
count = data.objects.count()
numbers = []
for dataCount in range(1, count + 1):
numbers.append(dataCount)
context = {
'data': straatData,
'count': numbers,
}
return render(request, 'home.html', context)
I need to get the top numbers to show 1,2,3,4... as many as the results. But I don't know how to do it
You don't need to set a context variable for that. You can use forloop.counter in your template code.
{% for item in data %}
<tr>
<td> {{ foorlop.counter }} </td>
<td> {{ item }} </td>
</tr>
{% endfor %}
If you want to start counting at 0, use forloop.counter0
Perhaps you should be using jinja to render the table in a loop?
In your html:
{% for num in count %}
<tr>
<td> {{ num }} </td>
<td> {{ data[num][0] }} </td>
<td> {{ data[num][1] }} </td>
<!-- Im not sure how your data is formatted! -->
</tr>
{% endfor %}
Without seeing your html it's hard to know how you're currently rendering the table.

Categories

Resources