I want to update value of 'log_data_full' from django template, i have extracted updated value in json from AJAX, i dont' want to refresh the page . i just want to update table view with updated value. Is that possible?
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>=Id</th>
<th>Category</th>
<th>Fee</th>
<th>Search</th>
</tr>
</thead>
<tbody>
{% for log in log_data_full %}
<tr>
<td>{{ log.Id }}</td>
<td>13</td>
<td>100</td>
<td>{{ log.search }}</td>
</tr>
{% endfor %}
</tbody>
</table>
AJAX query
$.ajax({
url: "/filter",
type: "POST",
data: {
from_date:from_date,
to_date:to_date,
csrfmiddlewaretoken: '{{ csrf_token }}',
},
success : function(json) {
debugger
if(json != 'error'){
var res = JSON.parse(json);
}
else{
alert('Server Error! Could not get data');
}
},
error : function(xhr,errmsg,err) {
alert("Could not send URL to Django. Error: " + xhr.status + ": " + xhr.responseText);
}
});
How to update value by of template variable 'log_data_full'?
Assuming you want to show the updated data in the table received from the server.
in your success function
success : function(json) {
if(json != 'error'){
$("#dataTable").empty(); //remove existing data
var res = JSON.parse(json);
rowHtml = '';
$.each(res, function (i, item) {
rowHtml = '<tr><td>' + res.id + '</td><td>' + res.category + '</td><td>' + res.fee + '</td><td>'+ res.search +'</td></tr>';
});
$('#dataTable').append(rowHtml);
}
Related
I have this:
#views.route('/')
def home():
while True:
try:
token=getToken()
if(token!='null' or token!=''):
plazas=getInfo(token,id)
except:
print('Conection failed')
time.sleep(secs)
return render_template("home.html", plazas=plazas)
Need update "plazas" variable value which is constantly refreshing with "while True" loop in my html template on td tag:
{% for parking in parkings %}
<tr>
<td class="par"><img src={{parking.image}} alt="img"></td>
<td class="nombre">{{parking.nombre}}</td>
{% if plazas|int >= (totalplazas*30)/100 %}
<td class="num" style="color:#39FF00">
{{plazas}}</td>
{% elif plazas|int < 1%}
<td class="num" style="color:red"><p class="an">COMPLETO</p></td>
{% elif plazas|int <= (totalplazas*10)/100%}
<td class="num" style="color:red">
{{plazas}}</td>
{% else %}
<td class="num" style="color:yellow">
{{plazas}}</td>
{% endif %}
<td class="dir"><img src={{parking.direccion}} alt="img"></td>
</tr>
{% endfor %}
I have tried to use javascript, but when the 10 seconds pass it tells me that the result of {{plazas}} is undefined.
Any help?
<script type="text/javascript">
window.onload = setInterval(refresh, 10000);
function refresh(places) {
var elements = document.getElementsByClassName("num");
for(let i = 0; i < elements.length; i++) {
elements[i].innerHTML = places;
}
return elements[i].innerHTML = places;
}
</script>
To refresh it with new text, you can fetch to your own flask route and update the information using setInterval
HTML
<td id="num" style="color:#39FF00">{{plazas}}</td>
<script>
var element = document.findElementById("num")
async function reload() {
const promise = await fetch('/myroute')
const data = await promise.text()
element.innerHTML = data
}
window.onload = setInterval(reload, 1000)
</script>
Flask
#app.route('/myroute')
def myroute():
# time is just an example
return time.time()
I Have this form in a table with two button.
Code:
index.html
<form action="{% url 'Prediction' %}" method="post">
{% csrf_token %}
<table class="table table-striped table-dark" cellspacing="0">
<thead class="bg-info">
<tr>
<th>Company's Symbol</th>
<th>Current Price</th>
<th>View Current chart</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for a,b in stocks %}
<tr>
<th scope="row" class="comp_name">{{ a }}</th>
<td>{{ b }}</td>
<td>
<input type="submit" class="btn graph-btn" formaction="{% url 'Graph' %}" name="_graph" value="View Graph">
</td>
<td>
<input type="submit" class="btn predict-btn" name="_predict" value="Predict Closing Price">
</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
By clicking .graph-btn I need to pass the data of row that button is clicked on. Here is code that's working.
<script>
$(".graph-btn").click(function() {
var $row = $(this).closest("tr");
var $text = $row.find(".comp_name").text();
console.log($text);
$.ajax({
type:'POST',
url:'{% url 'Graph' %}',
data:{
text: $text,
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(),
},
success:function(json){
console.log($text);
},
error : function(xhr,errmsg,err) {
}
});
});
</script>
But Problem is that In views.py returning none:
views.py
def graph(request):
if request.method == 'POST' and '_graph' in request.POST:
print(request.POST.get('text'))
# context = {'name': name}
# # print(name)
return render(request, 'StockPrediction/chart.html')
else:
return render(request, 'StockPrediction/greet.html')
urls.py
urlpatterns = [
path("", views.greet, name='greet'),
path("index/", views.index, name='Stock Prediction'),
path("prediction/", views.prediction, name='Prediction'),
path("view/", views.graph, name='Graph'),
]
try adding dataType: 'json' to the request. For example:
$.ajax({
type: 'post',
url: '{% url 'Graph' %}',
headers: {
'X-CSRFToken': $('input[name=csrfmiddlewaretoken]').val()
}
data: {
text: $text,
},
dataType: 'json',
success: function (data) {
console.log(data)
},
error: function(error) {
console.log(error)
}
});
In your views function graph(request) you are not returning a value but instead rendering an HTML page with the request.
A view function in Django should either return a JSON or a dictionary or can return a Webpage You can either do one of following
1) return a dictionary or JSON
return {"key":"value","key":"value"}
2) return a HttpResponse
return HttpResponse(status_code, response_data)
3) Redirect to another page
return redirect('/some/redirect/url/')
Try the above and comment if it helps
I have the data that get from database, the data is about more that 30,000 record, when i render the template with these data, the template is very slow, so what is the best way to pass the massive data and display on template.
This is my code.
route.py
#app.route('/index', methods=['GET', 'POST'])
def index():
asset_table = asset.query.all()
return render_template('index.html', asset_table=asset_table)
index.html
<table class="table table-hover table-sm table-striped" id="asset_table">
<thead class="thead-dark">
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody>
{% for asset in asset_table %}
<tr>
<td>{{ asset.asset_id }}</td>
<td>{{ asset.asset_name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<script>
$(document).ready(function () {
$('#asset_table').DataTable({
"scrollX": true,
});
$('.dataTables_length').addClass('bs-select');
});
</script>
models.py
from application import db
class asset(db.Model):
__tablename__ = 'asset'
asset_id = db.Column(db.String(30), primary_key=True)
asset_name = db.Column(db.String(30))
I would use a library called sqlalchemy-datatables which is a bit old now but does it work.
The code should look like this:
Flask Code
from datatables import ColumnDT, DataTables
#app.route('/index', methods=['GET'])
def index():
"""
Code which renders the index page
"""
return render_template('index.html')
#app.route('/data', methods=['GET'])
def data():
"""
Returns data for the index page.
GET:
params:
Please learn about the other parameters here:
https://datatables.net/manual/server-side#Sent-parameters
responses:
Please learn about the response parameters here:
https://datatables.net/manual/server-side#Returned-data
"""
columns = [
ColumnDT(
asset.asset_id,
mData="ID"
),
ColumnDT(
asset.asset_name,
mData="Name"
)
]
query = db.session.query().select_from(asset)
params = request.args.to_dict()
rowTable = DataTables(params, query, columns)
return jsonify(rowTable.output_result())
HTML/Jquery Code
<table class="table table-hover table-sm table-striped" id="asset_table">
<thead class="thead-dark">
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script>
$(document).ready(function () {
$('#asset_table').DataTable({
processing: true,
serverSide: true,
ajax: "{{ url_for('data')}}",
dom: 'Bflrtip',
columns: [
{ "data": "ID" },
{ "data": "Name" },]
});
});
</script>
Cheers!
I am using jquery UI .sortable to sort my table rows by drag and drop. I have declare a field map_order in the model as an order update. so the thing is when I am making ajax call to update the model order field. it didn't update it. but when I console log the sort variable it will show the assigning of index to the pk of model.
I have tried to update the filed but it did,nt work
HTML
<tbody id="#layerTable">
{% for layer in layers %}
<tr data-pk="{{ layer.id }}" class="ui-state-default"> <td><input type="checkbox" name="ids" value="{{ layer.id }}" /></td>
<td> {{ layer.name }} </td>
<td>{{ layer.heading }}</td>
<td>{{ layer.class_group }}</td>
<td> <span class="glyphicon glyphicon-resize-vertical"></span> {{ layer.map_order }}</td>
<td>{{ layer.map_server }} </td>
<td> {% if layer.sql_schema %}{{ layer.sql_schema }}.{{ layer.sql_table }}{% endif %} </td>
</tr>
JS
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$("tbody").sortable({
update: function(event, ui) {
sort = {};
window.CSRF_TOKEN = "{{ csrf_token }}";
$("tbody").children().each(function(){
sort[$(this).data('pk')] = $(this).index();
});
{#var csrftoken = $('input[name="csrfmiddlewaretoken"]').val();#}
$.ajax({
url: "{% url "mapport.maps.layers.all" map.id %}sort/",
type: "post",
data:{sort,
csrfmiddlewaretoken: window.CSRF_TOKEN,
},
});
console.log(sort)
},
}).disableSelection();
});
</script>
views
#csrf_exempt
def sort(self):
for index, pk in enumerate(self.request.POST.getlist('layer[]')):
layer = get_object_or_404(Layer, pk=pk)
layer.map_order = index
layer.save()
return HttpResponse('')
I I have expected to update the field map_order.. but it didn't update. the index is assigning in browser to the id when I drag and drop rows
I created a HTML table, it contains some information. However I want to add the possibility to edit table row text and by clicking "save", the database would be updated.
Can someone help me?
Do I need to use Ajax? If so please can I get some guidance?
<table style="width:100%">
<tr>
<th>Questions</th>
<th>Answers</th>
<th>Action</th>
</tr>
{% for q in questions%}
<tr>
<td contenteditable='true'>{{q.question}}</td>
<td contenteditable='true'>{{q.answer}}</td>
<td>
<center>Save Edit --- Delete</center>
</td>
</tr>
{%endfor%}
</table>
Here is my view, I know it shouldn't look like this because there is no parameter passed between the view and the HTML table, this needs to be fixed:
def edit_question(request,id):
question = Question.objects.get(id=id)
if(question):
question.update(question = quest, answer = ans)
return redirect('list_questions')
return render(request, 'generator/questions.html', {'question': question})
UPDATE
I used the solution that #xxbinxx provided, However in the view function, the condition request.method == "POST" doesn't seem to be verified even if it's in ajax function ?
heres the updated code :
<script type="text/javascript">
function saveQuestionAnswer(e, id) {
e.preventDefault();
console.log(id)
editableQuestion = $('[data-id=question-' + id + ']')
editableAnswer = $('[data-id=answer-' + id + ']')
console.log(editableQuestion.text(), editableAnswer.text())
$.ajax({
url: "list/update/"+id,
type: "POST",
dataType: "json",
data: { "question": editableQuestion.html(), "answer": editableAnswer.html() },
success: function(response) {
// set updated value as old value
alert("Updated successfully")
},
error: function() {
console.log("errr");
alert("An error occurred")
}
});
return false;
}
</script>
HTML :
<table style="width:90%">
<tr>
<th ><font color="#db0011">Questions</th>
<th><font color="#db0011">Answers</th>
<th><font color="#db0011">Action</th>
</tr>
{% for q in questions%}
<tr>
<td width="40%" height="50px" contenteditable='true' data-id="question-{{q.id}}" data-old_value='{{q.question}}' onClick="highlightEdit(this);">{{q.question}}</td>
<td width="45%" height="50px" contenteditable='true' data-id="answer-{{q.id}}" data-old_value='{{q.answer}}'>{{q.answer}}</td>
<td width="15%" height="50px"><center>
<a class="button" href="{% url 'edit_question' q.id %}" onclick="saveQuestionAnswer('{{q.id}}')">Edit</a>
<a class="button" href="{% url 'delete_question' q.id %}">Delete</a>
</center></td>
</tr>
{%endfor%}
</table>
views.py
def edit_question(request,id):
quest = Question.objects.get(id=id)
print(quest)
if request.method=='POST': # It doesn't access this condition so the updates won't occur
print("*"*100)
quest.question = request.POST.get('question')
quest.answer = request.POST.get('answer')
print(quest)
quest.save()
return redirect('list_questions')
return render(request, 'browse/questions.html', {'quest': quest})
Can someone help me solve this final issue ?
Yes you'll have to use AJAX to achieve in-place editing. I'm posting quick code so you get the idea.
NOTE: the below code has errors ;) I don't want to write in detail as it would be of no good to you. You must brainstorm and try it yourself.
contenteditable=”true” is to make column editable.
an attribute data-old_value to keep old value to check before making Ajax request to update changed value in your database table.
Code is making use of function saveQuestionAnswer()
on blur event to update changed value and function highlightEdit() to highlight column in edit mode.
<table style="width:100%">
<tr>
<th>Questions</th>
<th>Answers</th>
<th>Action</th>
</tr>
{% for q in questions%}
<tr>
<td contenteditable='true' data-id="question-{{q.id}}" data-old_value='{{q.question}}' onClick="highlightEdit(this);">{{q.question}}</td>
<td contenteditable='true' data-id="answer-{{q.id}}" data-old_value='{{q.answer}}' onClick="highlightEdit(this);">{{q.answer}}</td>
<td>
<center><a onclick="saveQuestionAnswer('{{q.id}}')">Save your edit --- </a>Delete</center>
</td>
</tr>
{%endfor%}
</table>
<script>
function saveQuestionAnswer(id) {
editableQuestion = $('a[data-id=question-'+id+']') //this will get data-id=question-1 where 1 is the question ID
editableAnswer = $('a[data-id=answer-'+id+']') //this will get data-id=answer-1 where 1 is the question ID
// no change change made then return false
if ($(editableQuestion).attr('data-old_value') === editableQuestion.innerHTML && $(editableAnswer).attr('data-old_value') === editableAnswer.innerHTML)
return false;
// send ajax to update value
$(editableObj).css("background", "#FFF url(loader.gif) no-repeat right");
$.ajax({
url: "/my-save-url/",
type: "POST",
dataType: "json",
data: {"question": editableQuestion.innerHTML, "answer": editableAnswer.innerHTML}
success: function(response) {
// set updated value as old value
$(editableQuestion).attr('data-old_value', response.question);
$(editableQuestion).css("background", "#FDFDFD");
$(editableAnswer).attr('data-old_value', response.answer);
$(editableAnswer).css("background", "#FDFDFD");
},
error: function() {
console.log("errr");
alert("An error occurred")
}
});
}
function highlightEdit(elem){
$(elem).css("background", "#e3e3e3") //just add any css or anything, it's only to depict that this area is being edited...
}
</script>
Your view will now get data in json format as {'question': <value>, 'answer': <value>}
you can add another key 'id' in this json if you want, or you can keep your url like this /saveQuestionAnswer/<id>. Here you have your id in url itself.
I hope you understand now.
Thanks