I am trying to populate a table in django template, but I want to compare cell values, one of them is javascript variable and another is django template variable. Is it possible to compare them without converting django variables to javascript variables? or is there a quick work around?
{% for x in price_data %}
<script>
counter++
var VALUE =document.getElementById("price_table").rows[0].cells.item(counter).innerHTML;
</script>
{% if x.room_scan == i and x.checkin == VALUE %}
I want to check if x.checkin is equals to VALUE.
Thanks.
You can do something like this. Code I used to create the table (as I don't have original table)
<table id="price_table">
<tr>
{% for x in range %}
<td>{{ x }}</td>
{% endfor %}
</tr>
</table>
I passed these variables to view
{
'range': range(1,5),
'x_room_scan': 2
}
and inside the template (I reduced the code a bit to simplify it)
<script>
var counter = 0;
{% for x in range %}
counter++;
var value =document.getElementById("price_table").rows[0].cells.item(counter).innerHTML;
if({{ x_room_scan }} == value) {
console.log(value);
}
{% endfor %}
</script>
Related
I am using flask.
I pass 4 different lists into the HTML file, loop through them and put their value in the table
{% for (s_pid, s_name, s_cpu_percent, s_memory_percent) in zip(pid, name, cpu_percent, memory_percent)%}
<tr>
<td id="task-pid">{{s_pid}}</td>
<td id="task-name">{{s_name}}</td>
<td id="task-cpu-percent">{{s_cpu_percent}}</td>
<td id="task-memory-percent">{{s_memory_percent}}</td>
</tr>
{% endfor %}
It looks great and I can see every value in the table clearly
I need to update these values every 5 seconds and for that, I am using jquery (using ajax just to get the updated value and put in the values below e.g var task_status_cpu_percent = data["task status cpu percent"];(list))
for(var i = 0; i< task_status_pid.length; i++){
$("#task-pid").text(task_status_pid[i]);
$("#task-memory-percent").text(task_status_memory_percent[i]);
$("#task-name").text(task_status_name[i]);
$("#task-cpu-percent").text(task_status_cpu_percent[i]);
}
task_status_pid is a list, in fact, all of the task_status are lists in the same length but when the jquery code accrues it doesn't do anything! I tried using replaceWith and that didn't go well
what happened is that all the values were on the first tab.
what do I need to do in order to go through all of the values in task-pd task-name etc' like it is on the loop ({% for (s_pid, s_name, s_cpu_percent, s_memory_percent) in zip(pid, name, cpu_percent, memory_percent)%})
You need to use class or add a counter to the ID. IDs MUST be unique
So EITHER
{% set count = namespace(value=0) %}
{% for (s_pid, s_name, s_cpu_percent, s_memory_percent) in zip(pid, name, cpu_percent, memory_percent)%}
<tr>
<td id="task-pid{{count.value}}">{{s_pid}}</td>
<td id="task-name{{count.value}}">{{s_name}}</td>
<td id="task-cpu-percent{{count.value}}">{{s_cpu_percent}}</td>
<td id="task-memory-percent{{count.value}}">{{s_memory_percent}}</td>
</tr>
{% set count.value = count.value + 1 %}
{% endfor %}
and then
$("#task-pid"+i).text(task_status_pid[i]);
OR (recommended)
const $tasks = $(".task-pid");
for(var i = 0; i< task_status_pid.length; i++){
$tasks.eq(i).text(task_status_pid[i]);
....
}
using <td class="task-pid" etc
I'm new at python, but no at programing. I'm using Django to create a webapp and in some part, I have to create products. A product has a name, brand and type, but this product can have many "inventories". For example: The product Iphone has a brand Apple, type Phone and since I have 3 in my stock, there is another table that saves 3 individual codes for them (and the price and state as well).
For this solution I have used formsets, and it was working fine without the JS. What I mean is that the process is ok, but when I want to dinamically add a new row to add a new Inventory, is added visually but then when I tried to save it, it just saves the last row. I have looked into the debug console of chrome and it seems that the problem is that the name and ID, of the new row, remains the same as the original one (the prefix I believe), but I don't know how to change it. Here is my code: Note in this image that the prefix of the second row is 0
views.py:
class ProductoInline(InlineFormSetFactory):
model= Inventario
fields = ['codigo', 'Producto', 'Precio', 'Estado']
factory_kwargs = {'extra':1 , 'max_num': 10,
'can_order': False, 'can_delete': False}
class InventarioCreateView(LoginRequiredMixin, CreateWithInlinesView):
model = Producto
inlines = [ProductoInline]
fields = '__all__'
factory_kwargs = {'extra': 3, 'max_num': 10,'can_order': False,
'can_delete': False}
template_name = 'ventas/inventario_form.html'
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
inventario_form.html:
{%extends "ventas/base.html" %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{%block content %}
<section class="card">
<header class="card-header">Crea/actualiza producto</header>
<div class="card-body">
<form method="POST">
{% csrf_token %}
{{ form|crispy }}
{% for formset in inlines %}
<table class="table table-bordered table-responsive-md table-striped text-center">
<tr>
<th class="text-center">Código</th>
<th class="text-center">Precio</th>
<th class="text-center">Estado</th>
<th class="text-center">Eliminar</th>
</tr>
{{formset.management_form}}
<tbody>
{% for form2 in formset %}
<tr id="{{ form2.prefix }}-row" class="dynamic-form">
<td>{{ form2.codigo }}</td>
<td>{{ form2.Precio }}</td>
<td>{{ form2.Estado }}</td>
<td><a id="remove-{{ form2.prefix }}-row" href="javascript:void(0)" class="delete-row">Eliminar</a></td>
</tr>
{% endfor %}
<tr>
<td colspan="4">Añadir producto</td>
</tr>
</tbody>
</table>
{% endfor %}
<button type="submit">Crear producto</button>
</form>
</div>
{%endblock content %}
formset.js:
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for",
$(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function addForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
var row = $('.dynamic-form:first').clone(true).get(0);
$(row).removeAttr('id').insertAfter($('.dynamic-form:last')).children('.hidden').removeClass('hidden');
$(row).children().not(':last').children().each(function() {
updateElementIndex(this, prefix, formCount);
$(this).val('');
});
$(row).find('.delete-row').click(function() {
deleteForm(this, prefix);
});
$('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1);
return false;
}
function deleteForm(btn, prefix) {
$(btn).parents('.dynamic-form').remove();
var forms = $('.dynamic-form');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).children().not(':last').children().each(function() {
updateElementIndex(this, prefix, i);
});
}
return false;
}
I'm currently learning d3.js for visualization, using Flask as the python backend, and following this example of showing two simple charts with different datasets on the same page.
I'm attempting the following modification: instead of using CSVs, I'd like to pass a json file from a python backend (the example just reads in data from two csv files). How might I pass 2 json datasets over? I can pass one as follows:
Python backend
import flask...
app = flask.Flask(__name__)
#app.route("/")
def index():
return flask.render_template("index.html")
#app.route("/data")
def data():
x = [1, 2, 3, 4, 5]
y = [1, 2, 3, 4, 5]
js = [{"x":x[i], "y":y[i]} for i in range(len(x))]
return json.dumps(js)
index.html
<script>
d3.json("/data", function(data) ...)
</script>
I've tried writing another python function, like def data_bar to return a separate json dataset, but that couldn't be read. In theory, I could pass both data sets in one json dataset, like:
x = [1,2,3,4,5]
y = [1,2,3,4,5]
x1 = [10,20,30]
y1 = [40,50,60]
But this encounters problems if the domains of the first set (x and y) and the second set (x1 and y1) aren't the same. e.g. the first set could be "student_name" and "grade", the second set could be "class_name" and "average_grade".
render with one data set passed in:
return render_template("result.html",resultVarInHtml = myData)
render with multiple data set passed in:
return render_template("result.html",resultVarInHtml = myData, resultVarInHtml2 = myData2)
Now when I load result.html
I can use this code to show my data (assuming a key value dictionary object, but you get the point)
results.html
<!doctype html>
<html>
<body>
<p>First Data Set</p>
<table border = 1>
{% for key, value in resultVarInHtml.iteritems() %}
<tr>
<th> {{ key }} </th>
<td> {{ value }} </td>
</tr>
{% endfor %}
</table>
<p>2nd Data Set</p>
<table border = 1>
{% for key, value in resultVarInHtml2.iteritems() %}
<tr>
<th> {{ key }} </th>
<td> {{ value }} </td>
</tr>
{% endfor %}
</table>
</body>
</html>
And you will get a proper table, mate.
I'd like to filter dynamically a flask generated table thanks to a variable set in JavaScript from another similar table.
Unfortunately, it seems that Javascript variables cannot be reused in Jinja2 contexts (because jinja2 contexts are run prior to Javascript).
In the example below, I'd like to filter the tasks with the project_id. This project_id was set thanks to the value selected in another table.
Note: I'd like to avoid to reload the page thanks to this solution.
{% for Task in mytasks %}
{% if Task.project_id == var_project_id %} <- Not working, the javascript variable is not recognized
<tr class="clickable-row">
<td style="display:none;"> {{ Task.task_id }} </td>
<td style="display:none;"> {{ Task.project_id }} </td>
<td>{{ Task.title }}</td>
<td class="task_description" > {{ Task.description }} </td>
<td class="task_creation_date"> {{ Task.creation_date }} </td>
</tr>
{% endfor %}
I've found a solution thanks to a simple javascript function.
Here is it, just in case some one else has the same issue:
<script>
//The project id is defined when the project is selected in a hover table
$('#myTableProject tbody tr').click(function (event) {
$('tr').not(this).removeClass('highlight');
$(this).addClass('highlight');
project_id = $(this).find('td.project_id').text();
//...
var tableTasks;
tableTasks = document.getElementById("myTableTasks");
tr = tableTasks.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[1];// [1] is the column number you want to filter
if (td) {
//each cell of the column [1] is compared to the project id
if (td.innerHTML.toUpperCase().indexOf(project_id) > -1) {
tr[i].style.display = "";//the data is displayed
} else {
tr[i].style.display = "none";//the data is hidden
}
} }
</script>
More info:
https://www.w3schools.com/howto/howto_js_filter_table.asp
For some reason, I cannot obtain the text/html from the 2nd TD as specified below
The template tags are Django.
{% block content %}
{% if host.host_scripts %}
<table class="table">
<button class="btn btn-info add" id="{{forloop.counter}}">Add to session</button>
{% for script in host.host_scripts %}
<tr>
<td id="script-name-{{forloop.counter}}">{{script.scriptName}}</td>
<td id="script-output-{{forloop.counter}}">{{script.scriptOutput|linebreaks}}</td>
</tr>
{% endfor %}
</table>
{% endif %}
<script>
$(".add").click(function(e) {
var id = $(this).attr('id');
scriptList = []
e.preventDefault();
$("#myTable-"+id+" tr ").each(function() {
var name = $(this).find('#script-name-'+id).html();
var output = $(this).find('#script-output-'+id).html();
var myList = [name, output];
console.log('Name -> ' + name);
console.log('Output -> ' + output);
scriptList.push(myList);
});
});
</script>
{% endblock %}
I can get the name variable just fine. For some reason I cannot get the scriptOutput variable.
I assumed this was due to |linebreaks but removing it has no influence on the behavior.
Desired behavior:
Per tr in the table, get the contents of the td's and add to the list.
Current behavior:
It only get's the name variable, skips the scriptOutput variable for some reason.
I managed to get 'some' output, now I get the same value returned for output for every scriptName. I'm baffled as I can't see what's wrong with the ID's.
{% block content %}
{% if host.host_scripts %}
<table class="table myTable">
<button class="btn btn-info add" id="{{forloop.counter}}">Add to session</button>
{% for script in host.host_scripts %}
<tr>
<td id="script-name-{{forloop.counter}}">{{script.scriptName}}</td>
<td id="script-output-{{forloop.counter}}">{{script.scriptOutput|linebreaks}}</td>
</tr>
{% endfor %}
</table>
{% endif %}
<script>
var scriptList = []
$("#myTable-"+id+" tr").each(function() {
var name = $(this).find('td:first').html();
var output = $('#script_output-'+id).html();
var script = [name, output];
scriptList.push(script);
console.log('Text: ' + output);
});
console.log(scriptList);
</script>
I am aware I should probably expand my ID to something of sorts:
<td id="script-output-{{forloop.parentloop.counter}}-{{forloop.counter}}">{{script.scriptOutput|linebreaks}}</td>
Yet I can't seem to figure it out, what am I doing wrong??
Try this instead:
<script>
$(".add").click(function(e) {
var id = $(this).attr('id');
scriptList = []
e.preventDefault();
$("#myTable-"+id+" tr ").each(function(index, el) {
var name = $(el).find('#script-name-'+id).html();
var output = $(el).find('#script-output-'+id).html();
var myList = [name, output];
console.log('Name -> ' + name);
console.log('Output -> ' + output);
scriptList.push(myList);
});
});
</script>