I have a model form that I am displaying in a table. The form has about 40 fields broken down into 6 different tables. I have setup an if statements to not display the table elements if the field is empty in the db. This works as expected the only issue is that if all the elements are hidden the table header is still displayed. How could I hide the table header if all if the elements in that particular table are hidden.
<table class="post-table">
<tr>
<th class="table-header" colspan="2">
<h3>Pool Details</h3>
</th>
</tr>
<tbody>
{% if post.pool_size != '' %}
<tr>
<td>pool size:</td>
<td>{{ post.pool_size }}</td>
</tr>
{% endif %}
{% if post.pool_style != '' %}
<tr>
<td>Pool Style:</td>
<td>{{ post.pool_style }}</td>
</tr>
{% endif %}
</tbody>
</table>
Update:
<table class="post-table">
<tr>
<th class="table-header" COLSPAN="1" id="tab_header">
<H3>ADDITIONAL INFO</H3>
</th>
</tr>
<tbody id="tab_body">
{% if post.additional_info != '' %}
<tr>
<td>{{ post.additional_info }}</td>
</tr>
{% endif %}
</tbody>
</table>
<br>
<script>
let tbody = document.getElementById("tab_body").innerHTML;
if (tbody === '') {
tab_header = document.getElementById("tab_header").innerHTML = " ";
} else {
// Nothing to do i guess
}
</script>
You can use JavaScript to hide the header if the <tbody> is empty :
Suppose that we have <th id="tab_header">Tab header</th> <tbody id="tab_body">Some content here</tbody>
Then
let tbody = document.getElementById("tab_body").innerHTML;
# Check if it contains something
if (tbody === '') {
tab_header = document.getElementById("tab_header").innerHTML = "";
} else {
// Nothing to do i guess
}
NB Be aware about checking the content of may be it is not empty string but sme other thing else.
<table class="post-table" id="table-example">
<tr>
<th class="table-header" COLSPAN="1" id="tab_header">
<H3>ADDITIONAL INFO</H3>
</th>
</tr>
<tbody id="tab_body">
{% if post.additional_info != '' %}
<tr>
<td id="test">{{ post.additional_info }}</td>
</tr>
{% endif %}
</tbody>
</table>
<script>
var tbl = document.getElementById('table-example');
if (tbl.rows.length == 1) {
console.log('IT WORKED')
tab_header = document.getElementById("tab_header").innerHTML = "";
}
console.log(tbl.rows.length)
</script>
Related
Currently, I am developing a site that guides coin market arbitrage information.
I wonder if the way below is possible in JavaScript.(not React)
backend - django
def index(request):
data = [{"name": "BTC", "binance": "price1", "gecko": "price2", "ftx": "price3"},
{"name": "ETH", "binance": "price1", "gecko": "price2", "ftx": "price3"}]
return render(request, 'index.html', context={'data': data})
html -
<table class="table table-striped mb-0 fixed">
<thead>
<tr>
<th>name</th>
<th>binance</th>
<th>gecko</th>
<th>ftx</th>
</tr>
</thead>
<tbody>
{% for d in data %}
<tr>
<td>{{ d.name }}</td>
<td>{{ d.binance }}</td>
<td>{{ d.ftx }}</td>
<td>{{ d.okx }}</td>
</tr>
{% endfor %}
</tbody>
</table>
JS -
var socket = new WebSocket(
'ws://' + window.location.host +
'/ws?session_key=${sessionKey}')
socket.onmessage = function (e) {
let positions_data = JSON.parse(e.data)
//if positions_data {"site": "binance", "price": "27000", "name": "BTC"}
//update data ->
data = [{"name": "BTC", "binance": "27000", "gecko": "price2", "ftx": "price3"},
{"name": "ETH", "binance": "price1", "gecko": "price2", "ftx": "price3"}]
//do something?
//then change html value
}
Is it possible to change the html value just by changing the variable in JS
Or is it possible to take additional code? Or is there another way?
Change your HTML so that the rows have a unique ID based on the coin name, and the columns have classes that indicate their roles.
<table class="table table-striped mb-0 fixed">
<thead>
<tr>
<th>name</th>
<th>binance</th>
<th>gecko</th>
<th>ftx</th>
</tr>
</thead>
<tbody>
{% for d in data %}
<tr id="row-{{d.name}}">
<td class="name">{{ d.name }}</td>
<td class="binance">{{ d.binance }}</td>
<td class="ftx">{{ d.ftx }}</td>
<td class="okx">{{ d.okx }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Then you can find the row that corresponds to positions_data and update it:
let row = document.querySelector(`#row-${positions_data.name}`);
let site = positions_data.site;
row.querySelector(`.${site}`).innerText = positions_data.price;
I have a list of entries. Insider the list of entries I have a link to individual entries. I have an update form that updates one field.
I want to open the update form inside a new window. The user then submits the form is directed to a success page which currently has a timed close.
The issue I am encountering is with the inline JavaScript which opens the form in a new window. When I attempt to assign the kwarg on the URL it the JavaScript does not change with each entry in the list.
I have limited JavaScript, and jQuery knowledge.
I just want the JavaScript to open a new window for each update form.
I have included the template below.
<thead>
<tr>
<th>Script No.</th>
<th>Entered on</th>
<th>Patient</th>
<th>Email</th>
<th>Product</th>
<th>Form</th>
<th>Units</th>
<th>Dispensing Price</th>
<th>Status</th>
<th>Dispatch Date</th>
<th>Entered by</th>
<th></th>
</tr>
</thead>
<tbody>
{% for script in scripts %}
<tr>
<td>{{script.pk}}</td>
<td>{{script.entered_on}}</td>
<td>{{script.patient}}</td>
<td>{{script.patient.email}}</td>
<td>{{script.product}}</td>
<td>{{script.product.form.description}}</td>
<td>{{script.quantity}}</td>
<td>$ {{ script.dispensing_price }}</td>
{% if script.dispatch_date is not none %}
<td>{{script.get_script_status_display}}</td>
{% else %}
<td>{{script.get_script_status_display}}</td>
{% endif %}
<td><a href ="#" onclick="updateStatus()" style="float:right;">
<script>var url = "{% url "script:script_update_status" script.pk %}";
function updateStatus() {var myWindow = window.open(url, "_blank", "toolbar=yes,scrollbars=yes,resizable=yes,top=500,left=500,width=400,height=250");}
</script></td>
{% if script.dispatch_date is none %}
<td>Not Sent</td>
{% else %}
<td>{{script.dispatch_date}}</td>
{% endif %}
<td>{{script.created_by.first_name}} {{script.created_by.last_name}}</td>
<td><small>View | Edit | Lab Label | <a href="{% url 'label:dispense_label' script.pk %}">Dispense Label
</a> | Shipping Label | Repeat</small></td>
</tr>
{% endfor %}
</tbody>
</table> ```
Kind Regards
AC
My script successfully shows and hides a column in the table, I would like by default for it to be hidden and the script to reveal it.
Thanks for your help.
<a onclick="myFunction()" style="float:right;">Hide/Show</a>
<table>
<tr>
<th>TO Date</th>
<th id="myDIV">LDG Date</th>
<th>TO Time</th>
<th>LDG Time</th>
<th>Dep. air.</th>
<th>Arr. air.</th>
<th></th>
</tr>
{% for l in logbook %}
<tr>
<td>{{ l.TO_Date }}</td>
<td id="myDIV">{{ l.LDG_Date }}</td>
<td>{{ l.TO_time }}</td>
<td>{{ l.LDG_time }}</td>
<td>{{ l.dep_airport }}</td>
<td>{{ l.arr_airport }}</td>
<td ><a style="color:red;" href="{{ url_for('logbookdelete',id_del=l.id ) }}">Delete</a></td>
</tr>
{% endfor %}
</table>
<script>
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "block") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
Just add style="display: none;" to your cells:
<th class="myDIV" style="display: none;">
Notice I've changed id to class as you are not supposed to have two equal id's on the same page.
But I'd do that this way:
<style>
.ldg-date-hidden .myDIV { display: none; }
</style>
<a onclick="myFunction()" style="float:right;">Hide/Show</a>
<table id="myTable" class="ldg-date-hidden">
<tr>
<th>TO Date</th>
<th class="myDIV">LDG Date</th>
<th>TO Time</th>
<th>LDG Time</th>
<th>Dep. air.</th>
<th>Arr. air.</th>
<th></th>
</tr>
{% for l in logbook %}
<tr>
<td>{{ l.TO_Date }}</td>
<td class="myDIV">{{ l.LDG_Date }}</td>
<td>{{ l.TO_time }}</td>
<td>{{ l.LDG_time }}</td>
<td>{{ l.dep_airport }}</td>
<td>{{ l.arr_airport }}</td>
<td ><a style="color:red;" href="{{ url_for('logbookdelete',id_del=l.id ) }}">Delete</a></td>
</tr>
{% endfor %}
</table>
<script>
function myFunction() {
document.getElementById("myTable").classList.toggle("ldg-date-hidden");
}
</script>
You can hide the column by setting display:none by default and then you can do the below:
function myFunction() {
var x = document.getElementsByClassName("myDIV");
for(var i=0;i<x.length;i++)
{
if (x[i].style.display === "block") {
x[i].style.display = "block";
} else {
x[i].style.display = "none";
}
}
}
You can force the initial state by putting the inline style (display:none) on the tag, its not the best way but that should work.
I recommend you to make the styles on a css file separated of the html file to avoid hierarchy issues.
const x = document.getElementById('myDIV');
function toggleVisibility() {
if (x.classList.contains('hidden')) {
x.classList.remove('hidden');
} else {
x.classList.add('hidden');
}
}
CSS file
.hidden: {
display: none;
}
I am working on a web app which is built on flask,postgreSQL. It is used to collect lab data and manage the data collected. There are two pages in this app, which I have attached are used to show lab data of some labs chosen by the user by querying from a database.
One page(admin_select_lab_for_data.html) enables the user to select some existing labs and redirects the user to the other page(admin_edit_data.html), which shows all the data in the selected labs. When I select the labs and click the button go to lab, the browser fails to redirect to (admin_edit_data).
The outputs printed by python are all correct(which proves that in flask, the redirection happens,lab_ids are passed correctly and all the related data are queried correctly). The http request returns 200 ok. However, the browser just stay on the same page and ajax POST request alerts the error(which is inconsistent with the fact that the data have already been received by admin_select_lab_for_data).
main.py
# review/edit Data
#app.route('/admin_select_lab_for_data',methods=['GET','POST'])
def admin_select_lab_for_data():
if request.method=='POST':
lab_ids = []
jsonData = request.get_json()
lab_ids = jsonData['lab_ids']
return redirect(url_for('admin_edit_data',lab_ids={'lab_ids':lab_ids}))
lab_list = []
db_session = db.get_session()
for lab in db_session.query(schema.Lab_info).all():
data_num = 0
query_rows = db_session.query(schema.Lab_rows).filter(schema.Lab_rows.lab_id==lab.lab_id)
for r in query_rows:
data_num += db_session.query(schema.Lab_data).filter(schema.Lab_data.row_id==r.row_id).count()
lab_list.append({'lab_id':lab.lab_id,'lab_name':lab.lab_name,'class_name':lab.class_name,'prof_name':lab.prof_name,'data_num':data_num})
return render_template('admin_select_lab_for_data.html',lab_list=lab_list)
# review/edit Data
#app.route('/admin_edit_data')
def admin_edit_data():
# Get a list of lab_ids that are needed to be retrieved
lab_ids = ast.literal_eval(request.args['lab_ids'])['lab_ids']
# lab_ids = ['test1_101_C','test2_101_N']
lab_data = []
lab_data_by_student = []
row_names_list = []
err_msg = ''
db_session = db.get_session()
#Group row data according to row_name
query_rows = db_session.query(schema.Lab_rows).filter(schema.Lab_rows.lab_id==lab_ids[0]).order_by(schema.Lab_rows.row_order)
for r in query_rows:
lab_data.append({'row_name':r.row_name,'row_data_list':[]})
row_names_list.append(r.row_name)
for lab_id in lab_ids:
query_rows = db_session.query(schema.Lab_rows).filter(schema.Lab_rows.lab_id==lab_id).order_by(schema.Lab_rows.row_order)
index = 0
#Check whether these labs are compatitble with each other(the number of rows and the names of rows must be the same)
if query_rows.count()!=len(row_names_list):
err_msg = lab_ids[0]+' and '+lab_id+' are incompatible: the number of rows is different-'+str(query_rows.count())+' and '+str(len(row_names_list))
else:
for r in query_rows:
if (row_names_list[index]!=r.row_name):
err_msg = lab_ids[0]+' and '+lab_id+' are incompatible:'+row_names_list[index]+' and '+r.row_name+' are different row names'
break
else:
query_datas = db_session.query(schema.Lab_data).filter(schema.Lab_data.row_id==r.row_id).order_by(schema.Lab_data.data_id)
for data in query_datas:
lab_data[index]['row_data_list'].append({'lab_id':lab_id,'student_name':data.student_name,'data_id':data.data_id,'row_data':data.row_data})
index+=1
if err_msg!='':
return render_template('admin_edit_data.html',lab_data=lab_data,student_data=lab_data_by_student,lab_ids=lab_ids,err_msg=err_msg)
#Group row data according to student_name
for row in lab_data:
#sort row_data_list to make all the data across different lists
sorted(row['row_data_list'],key=lambda element:element['data_id'])
# if list is empty, add student names into it
if not lab_data_by_student:
for data in row['row_data_list']:
lab_data_by_student.append({'student_name':data['student_name'],'lab_id':data['lab_id'],'row_data_list':[]})
for i in range(len(row['row_data_list'])):
data = row['row_data_list'][i]
lab_data_by_student[i]['row_data_list'].append({'row_name':row['row_name'],'row_data':data['row_data']})
print('\n\n\n')
print(lab_ids)
print('\n\n\n')
print(lab_data)
print(lab_data_by_student)
print(lab_ids)
print(err_msg)
print('\n\n\n')
return render_template('admin_edit_data.html',lab_data=lab_data,student_data=lab_data_by_student,lab_id=lab_id,err_msg=err_msg)
admin_select_lab_for_data.html
{% extends "admin_home.html" %}
{% block head %}
<meta charset="UTF-8">
<title>Select lab for data</title>
<script>
$(document).ready(function(){
$('button[name=go_to_lab]').click(function(){
var lab_ids = [];
var checkboxes = document.getElementsByTagName('input')
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].type == 'checkbox' && checkboxes[i].checked) {
lab_ids.push($(checkboxes[i]).data('labid'));
}
}
if (lab_ids.length==0){
$('#error_message_no_lab_choose').show().delay(1000).fadeOut();
}
else{
$.ajax({
type: 'POST',
contentType: 'application/json',
dataType: 'json',
url: 'http://127.0.0.1:5000/admin_select_lab_for_data',
data: JSON.stringify({'lab_ids':lab_ids}),
success: function(result){
alert('Submit successfully');
},
error : function(result){
alert('Fail to submit');
console.log(result)
}
});
}
});
});
</script>
{% endblock %}
{% block content %}
{% if (lab_list|length)==0 %}
No lab exists<br>
{% else %}
<table class="table">
<thead>
<tr>
<th class="tg-yw4l">Lab Index</th>
<th class="tg-yw4l">Lab Name</th>
<th class="tg-yw4l">Class Name</th>
<th class="tg-yw4l">Professor Name</th>
<th class="tg-yw4l">Number of data available</th>
<th class="tg-yw4l">Choose</th>
</tr>
</thead>
<tbody>
{% for lab in lab_list %}
<tr>
<th class="tg-yw4l">{{loop.index}}</th>
<td class="tg-yw4l">{{lab.lab_name}}</td>
<td class="tg-yw4l">{{lab.class_name}}</td>
<td class="tg-yw4l">{{lab.prof_name}}</td>
<td class="tg-yw4l">{{lab.data_num}}</td>
<td class="tg-yw4l"><input type="checkbox" data-labid="{{lab.lab_id}}"></td>
</tr>
{% endfor %}
</tbody>
</table>
<br>
<button name="go_to_lab">Go to lab</button>
<div class="temporary_message" id="error_message_no_lab_choose">You need to select one lab</div>
{% endif %}
{% endblock %}
admin_edit_data.html
{% extends "admin_home.html" %}
{% block head %}
<meta charset="UTF-8">
<title>Edit Data</title>
{% endblock %}
{% block content %}
{% if lab_data|length==0 %}
<h1> No data available for this lab </h1>
{% elif err_msg!="" %}
<h1> {{err_msg}} <h1>
{% else %}
<table class="table" id={{lab_id}} name={{lab_data|length}}>
<thead>
<tr>
<th>Index</th>
<th>Student Name</th>
<th>Lab ID</th>
{% for r in lab_data %}
<th>{{r["row_name"]}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for s in student_data %}
<tr>
<th>{{loop.index}}</th>
<td><input value={{s["student_name"]}}></td>
<td>{{s["lab_id"]}}</td>
{% for i in range(lab_data|length) %}
<td><input value={{s["row_data_list"][i]["row_data"]}}></td>
{% endfor %}
<td><button name=save_all>Save All</button></td>
<td><button name=delete>Delete</button></td>
</tr>
{% endfor %}
</tbody>
</table>
<button>Return</button>
{% endif%}
{% endblock %}
You can never achieve a page redirect as a result of an Ajax post request.
You either have to submit a regular form post and do the redirect or you need to return a result from the Ajax call and change the page using window.location in the browser.
I'm trying to send an array of row id's to a controller in order to do a batch update, I think I already did the array part (i'm not good at jQuery, still learning) but I have no idea how to send to the controller the array that contains the ids of the rows to update.
Here's my twig:
{% block javascripts %}
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
$(document).ready(function () {
$('#selectall').click(function () {
$('.selectedId').prop('checked', isChecked('selectall'));
});
});
function isChecked(checkboxId) {
var id = '#' + checkboxId;
return $(id).is(":checked");
}
function resetSelectAll(id) {
// if all checkbox are selected, check the selectall checkbox
// and viceversa
if ($(".selectedId").length == $(".selectedId:checked").length) {
$("#selectall").attr("checked", "checked");
var ids = [];
ids.concat(id);
} else {
$("#selectall").removeAttr("checked");
removeItem = id;
ids = jQuery.grep(arr, function(value) {
return value != removeItem;
});
}
if ($(".selectedId:checked").length > 0) {
$('#edit').attr("disabled", false);
} else {
$('#edit').attr("disabled", true);
}
}
</script>
{% endblock %}
{% block body %}
<table>
<thead>
<tr>
<th><input type="checkbox" id="selectall"></th>
<th>{{ 'general.date'|trans }}</th>
<th>{{ 'general.order_number'|trans }}</th>
<th>{{ 'general.description'|trans }}</th>
<th>{{ 'general.company_name'|trans }}</th>
<th>{{ 'general.name'|trans }}</th>
<th>{{ 'form.status'|trans }}</th>
<th>WinPoints</th>
</tr>
</thead>
{% for details in details %}
<tbody>
<tr>
<td><div align="center"><input type="checkbox" class="selectedId" name="selectedId" onclick="resetSelectAll({{details.id}});" /></div></td>
<td>{{ details.date | date("m/d/Y") }}</td>
<td>{{ details.order_number }}</td>
<td>{{ details.description }}</td>
<td>{{ details.company }}</td>
<td>{{ details.name }}</td>
<td>{{ details.status }}</td>
<td>{{ details.winpoints }}</td>
</tr>
</tbody>
{% endfor %}
</table>
<form action="{{ path('advd_group_batch_p_r_status') }}" method="post" {{ form_enctype(formBase) }}>
{{ form_widget(form) }}
<input class="input_button" type="submit" value="Procesar" />
</form>
{% endblock %}
Any ideas? Plus, if you see any mistakes on the jquery code, please let me know what i'm doing wrong, i haven't been able to test it because I don't know how to send the array to the controller.
Thank you for any help you may offer me.
{% block javascripts %}
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script>
$(document).ready(function () {
$('#selectall').click(function () {
$('.selectedId').prop('checked', isChecked('selectall'));
});
});
function isChecked(checkboxId) {
var id = '#' + checkboxId;
return $(id).is(":checked");
}
function resetSelectAll(id) {
// if all checkbox are selected, check the selectall checkbox
// and viceversa
if ($(".selectedId").length == $(".selectedId:checked").length) {
$("#selectall").attr("checked", "checked");
var ids = [];
ids.concat(id);
} else {
$("#selectall").removeAttr("checked");
removeItem = id;
ids = jQuery.grep(arr, function(value) {
return value != removeItem;
});
}
if ($(".selectedId:checked").length > 0) {
$('#edit').attr("disabled", false);
} else {
$('#edit').attr("disabled", true);
}
}
$(function(){
$('.input_button').click(function(){
$.ajax({
url:"advd_group_batch_p_r_status",
dataType:'json',
type:'post',
data:$("#formC").serialize()
});
});
});
</script>
{% endblock %}
{% block body %}
<form action="{{ path('advd_group_batch_p_r_status') }}" method="post" {{ form_enctype(formBase) }} id="formC">
<table>
<thead>
<tr>
<th><input type="checkbox" id="selectall"></th>
<th>{{ 'general.date'|trans }}</th>
<th>{{ 'general.order_number'|trans }}</th>
<th>{{ 'general.description'|trans }}</th>
<th>{{ 'general.company_name'|trans }}</th>
<th>{{ 'general.name'|trans }}</th>
<th>{{ 'form.status'|trans }}</th>
<th>WinPoints</th>
</tr>
</thead>
{% for details in details %}
<tbody>
<tr>
<td><div align="center"><input type="checkbox" class="selectedId" name="selectedId" onclick="resetSelectAll({{details.id}});" /></div></td>
<td>{{ details.date | date("m/d/Y") }}</td>
<td>{{ details.order_number }}</td>
<td>{{ details.description }}</td>
<td>{{ details.company }}</td>
<td>{{ details.name }}</td>
<td>{{ details.status }}</td>
<td>{{ details.winpoints }}</td>
</tr>
</tbody>
{% endfor %}
</table>
{{ form_widget(form) }}
<input class="input_button" type="submit" value="Procesar" />
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
I have a Newsletter form in my application that is posted with the following javascript:
<script type="text/javascript">
function subscribeButtonPressed() {
$.post('{{path('mailchimp_subscribe')}}',
{
EMAIL: $("#mce-EMAIL").val(),
listid: $("#listid").val()
},
function (response) {
ga('send', 'pageview', '{{ path('mailchimp_subscribe') }}');
console.log(response);
if (response.code == 100 && response.success) {//dummy check
var alert = '<div class="span12 padding20" id="formContainer">\n\
<h1>Great!</h1>\n\
</div>';
$('#formContainer').fadeOut('slow', function () {
$('#thanksContainer').append(alert).hide().fadeIn('slow');
});
}
}, 'JSON');
}
$(document).ready(function () {
$('#mc-embedded-subscribe')
.click(function (event) {
var btn = $(this);
if ($("#mce-EMAIL").val() != "") {
event.preventDefault();
btn.button('loading');
subscribeButtonPressed();
}
});
});
</script>
I also log the event via google analytics and show some response html. But I guess you get the idea, just use $.post with the path where you want to send it to. And I pick the single values of my form, but you could also just send the whole form.