Auto refresh a webpage on content update only - javascript

I have created a webpage on my website which gets content updates every 1-60 mins (random/varies) and at first I made the webpage auto refresh using:
<meta http-equiv="refresh" content="30" >
However, this is very annoying when scrolling and just generally using the webpage.
I thought about using an iframe on a separate webpage like so:
<iframe src="output.html" width="2500" height="10000" frameborder="0" allowfullscreen></iframe>
However, again this throws up more problems with it not refreshing (if I remove the meta tags) and my original webpage height varies depending on how much data is on the page.
I'm looking for some advice / code help to get a way to only refresh the main webpage if the content is updated. (It doesn't matter if a suggested solution is in HTML, PHP or any other language)
Any suggestions or constructive comments would be greatly appreciated.
Thanks in advance
- Hyflex
EDIT:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="refresh" content="5" >
<title>data data data data data</title>
<style type="text/css">
<!--
#import url("style.css");
-->
</style>
</head>
<body>
<table id="gradle" summary="main">
<thead>
<tr>
<th scope="col">data</th>
<th scope="col">data</th>
<th scope="col">data</th>
<th scope="col">data Rank</th>
<th scope="col">data Odds</th>
<th scope="col">data</th>
<th scope="col">data</th>
<th scope="col">AV10</th>
<th scope="col">data Rank</th>
<th scope="col">data</th>
<th scope="col">data Rank</th>
<th scope="col">data</th>
<th scope="col">data</th>
<th scope="col">Age</th>
<th scope="col">data</th>
<th scope="col">data</th>
<th scope="col">data 14 Day</th>
<th scope="col">data CSR</th>
<th scope="col">data TSR</th>
<th scope="col">data</th>
<th scope="col">data 14 Day</th>
<th scope="col">data CSR</th>
<th scope="col">data TSR</th>
<th scope="col">data</th>
<th scope="col">data data</th>
<th scope="col">data data</th>
<th scope="col">data data</th>
<th scope="col">data data</th>
<th scope="col">data data</th>
<th scope="col">data</th>
<th scope="col">data</th>
<th scope="col">data</th>
<th scope="col">data</th>
<th scope="col">data</th>
</tr>
</thead>
<tbody>
<tr><td>data</td><td>data</td><td>data data</td><td>data</td><td>data</td><td>5f 212y</td><td><div align="left">2</div></td><td>117.88</td><td>1</td><td>117.88</td><td>1</td><td>-1</td><td> </td><td>2</td><td>22</td><td>data</td><td>14</td><td>data</td><td>data</td><td>Tdata</td><td>6</td><td>data</td><td>135.0%</td><td>data</td><td>555.0%</td><td>0.0%</td><td>10.0%</td><td>2</td><td>data</td><td>data</td><td>£45552.43</td><td></td><td>data</td><td>data</td><tr>
</tbody>
</table>
</body>
</html>
Closest I've got thanks to a post below is:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
update_content()
$(document).ready(function (e)
{
var refresher = setInterval("update_content();", 250);
})
function update_content()
{
$.ajax(
{
type: "GET",
url: "output.html",
timeout: 10000,
cache: false,
})
.done(function (page_html)
{
var newDoc = document.documentElement.innerHTML;
if (page_html != newDoc)
{
alert("LOADED");
var newDoc = document.open("text/html", "replace");
newDoc.write(page_html);
newDoc.close();
}
});
}
</script>

http://jsfiddle.net/Ask3C/
You will have to replace the path to the one of your page. Should rewrite the document every 30 seconds. It is a bit of a hack approach but if you are still using Meta Refresh - it is light years better. Give it a go. The script for jQuery library is just pulling from Google repository.
$(document).ready(function(e) {
var refresher = setInterval("update_content();",30000); // 30 seconds
})
function update_content(){
$.ajax({
type: "GET",
url: "index.php", // post it back to itself - use relative path or consistent www. or non-www. to avoid cross domain security issues
cache: false, // be sure not to cache results
})
.done(function( page_html ) {
alert("LOADED");
var newDoc = document.open("text/html", "replace");
newDoc.write(page_html);
newDoc.close();
});
}

Your problem is very common. Have you explored how twitter like feed update is working?. You have to do as follows
var interval = function() {
setTimeout(function() {
$.ajax({
// Ajax options goes here
success : function(data) {
// Process Data
// Generate HTML
// Insert Generated HTML whereever you want in document
interval() //Initiate next fetch
}
})
}, 1000 // Interval time
);
};
Note: Here I am using jQuery ajax.
Hopefully this will give an idea.

A good solution would be to use javascript and make ajax calls at set intervals. Then update whatever element with new content from your response. This way you won't have to deal with refreshes which would be very annoying.

Related

make some column not editable in editable data-table

I have a web app, frontend using HTML5, backend using Django.
I have an editable table in HTML5.
But the use need to make some columns not editable.
I could only set the editable flag on the table basis, not sure how to set it on the column basis, as my table do not have a table body(call restful API to render the table body).
How could I make some column of the table not editable?
<table contenteditable='true' class="table table-bordered table-sm" width="100%" cellspacing="0" style="font-size: 1.0rem;"
id="bk-table"
data-toggle="table"
data-toolbar="#toolbar"
data-cookie="true"
data-cookie-id-table="materialId"
data-show-columns="true"
data-show-refresh="true"
data-show-fullscreen="true"
data-show-export="true"
data-height="650"
data-click-to-select="true"
data-id-field="id"
data-show-footer="true"
data-url="/api/materials/"
data-query-params="queryParams"
data-remember-order="true"
data-pagination="true"
data-side-pagination="client"
{# data-side-pagination="server" #}
data-total-field="count"
data-data-field="results">
<colgroup>
<col span="3" style="background-color:white">
<col span="5" style="background-color:#e8ecfd">
<col span="1" style="background-color:white">
<col span="7" style="background-color:#e8ecfd">
</colgroup>
<thead class="thead-dark" >
<tr >
<!--th data-sortable="true" >ID</th-->
<th data-field="state" data-checkbox="true"></th>
<th data-field="courseCode" data-formatter="renderCourse">Course Code</th>
<th data-field="type">Course Type</th>
<th class ='title' data-field="book.title">Course Material Title</th>
<th class ='author' name="Author" data-field="book.author">Author/Editor</th>
<th class ='pub_date' name="pub_date" data-field="book.pub_date">Publication Year</th>
<th class ='edition' data-field="book.edition">Edition + Special Edition</th>
<th class ='publisher' data-field="book.publisher">Publisher</th>
<th class ='isbn' data-field="book.isbn">iSBN or e-iSBN/VBID</th>
<th class ='Format_issued' data-field="book.Format_issued">Material Format</th>
<th class ='Purchase_Price' data-field="book.e_price_cur">eText SUSS Price Currency</th>
<th class ='Total_StockAndWrap' data-field="book.e_price">eText SUSS Price</th>
<th class ='Distribution_platform' data-field="book.Distribution_platform">Distribution Mode</th>
<th class ='Discard_Status' data-field="status">Book Status</th>
<th class ='discard_reason' data-field="discard_reason">Discard Reason</th>
<th data-field="remark">Remarks</th>
</tr>
</thead>
</table>
restapi:
class MaterialSerializer(serializers.ModelSerializer):
book = BookSerializer(many=False)
course = CourseSerializer(many=False)
courseId = serializers.ReadOnlyField(source='course.courseInfo.id')
year = serializers.ReadOnlyField(source='course.semester.year')
month = serializers.ReadOnlyField(source='course.semester.month')
term = serializers.ReadOnlyField(source='course.semester.term')
quota = serializers.ReadOnlyField(source='course.quota')
course_title = serializers.ReadOnlyField(source='course.courseInfo.title')
type = serializers.ReadOnlyField(source='course.courseInfo.type')
available = serializers.ReadOnlyField(source='course.courseInfo.available')
postgraduate = serializers.ReadOnlyField(source='course.courseInfo.postgraduate')
Presentation_Pattern = serializers.ReadOnlyField(source='course.courseInfo.pattern')
discipline = DisciplineSerializer(source='course.courseInfo.discipline')
retail_price_display = serializers.ReadOnlyField(source='book.retail_price_display')
cover = serializers.ReadOnlyField(source='book.cover')
courseCode = serializers.SerializerMethodField()
def get_courseCode(self, obj):
return f'{obj.course.courseInfo.discipline_code}{obj.course.courseInfo.code}'
class Meta:
model = Material
fields = ['id', 'book', 'course', 'course_title', 'type','school', 'available', 'postgraduate', 'courseCode', 'courseId', 'year', 'month', 'term', 'quota',
'modified', 'discipline', 'remark', 'status', 'is_discard', 'discard_reason', 'retail_price_display', 'Presentation_Pattern','cover']
You can use the same contenteditable attribute and set it to false. Although setting it on the <th> elements will not also set it on all the <td> elements in that column in tbody. You have to set contenteditable to false on every <td> in that column like:
<td contenteditable="false">Content</td>
Can you modify the restful API's render function to set the attribute?
We can achieve this by adding flags in Django models.
Add is_editable flag with default value as True. Based on this flag you can hide the edit button and also restrict users by editing this data through URL ID.
In MaterialSerializer model add is_editable = models.BooleanField(default=True)
Based on this flag you can hide/un-hide the edit functionality for the users.

How to add a button in data table flask

i got problem with add botton in boostrap datatable. Im now in flask (python), js please give me some tips or solution i will be very gratefull.
i want do something like this.
I try return botton with jsonify data. I try change js for it. But cant found right solution.
For fill date in table js code.
Html code
<div class="row-90">
<table class="table display" id="calEvents">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">GROUP</th>
<th scope="col">WEEKDAY</th>
<th scope="col">DATE</th>
<th scope="col">TICKER</th>
<th scope="col">EVENT</th>
<th scope="col">READX</th>
<th scope="col">ACTION</th>
</tr>
</thead>
<tfoot>
<tr>
<th scope="col">ID</th>
<th scope="col">GROUP</th>
<th scope="col">WEEKDAY</th>
<th scope="col">DATE</th>
<th scope="col">TICKER</th>
<th scope="col">EVENT</th>
<th scope="col">READX</th>
<th scope="col">ACTION</th>
</tr>
</tfoot>
</table>
</div>
js code
$('#calEvents').DataTable( {
'columnDefs': [
{
targets: 2, render: function(data1){ return moment(data1).format('dddd')},
}, //data-toggle="modal" data-target="#exampleModal"
{ targets: 3, render: function(data2){ return moment(data2).format('YYYY-MM-DD')}},
]
} );
Please help me. (this code without bootton code, because for now idk there place it(no one solution not working so...). Please not to judge me.
You can use the defaultContent attribute in DataTable to add additional buttons at in your table. (Reference)
$('#calEvents').DataTable( {
"processing": true,
"serverSide": false,
"order": [[ 3, "asc" ]],
"ajax": "/api/v1/calendar/get",
'columnDefs': [
{
targets: 2, render: function(data1){ return moment(data1).format('dddd')},
defaultContent: '<button class="btn-view" type="button">Edit</button>'
+ '<button class="btn-delete" type="button">Delete</button>'
},
{ targets: 3, render: function(data2){ return moment(data2).format('YYYY-MM-DD')}},
]
} );

JQuery doesn't recognize 'tbody' and 'tr' of datatable using hover() method

So I am working with a datatable and trying to create a hover window which will display data from the datatable and a picture, not important, thing is I am trying to append a div with premade css classes for this project into either a cell or row using hover(), but jquery doesn't recognize the body and row of the datatable. Here is a fiddle I tested it on https://jsfiddle.net/r6tbv9uz/6/ and it works just fine,
and here is a code I am using in the project:
$('.datatable-sort').find('tbody').hover(
function () {
console.log('hovered in');
var iDiv = CreateHoverElement();//the div is a bit complex so I have separate function for it
var element = $(this).closest('tr');
element.append(iDiv);
},
function () {
var element = document.getElementById('tablehover');
element.parentNode.removeChild(element);
console.log('hovered out');
}
);
The thing is when I use the hover as such:
$('.datatable-sort').hover(function(){...},function(){...})
The hover function works perfectly but that wont help me as I need the hover out part to work within a row and only in tbody.
I have tried lot of googling around and lot of trial and error but can't figure it out, if anyone has ideas i would appriciate it, Thanks.
EDIT: html snippet of the datatable:
<table class="table table-striped datatable-sort compact fixedHeader-locked">
<thead>
<tr>
<th scope="col">Time</th> <!--Created-->
<th scope="col">Lane</th> <!--LaneNumber-->
<th scope="col">Credence(%)</th> <!--Credence-->
<th scope="col">LPN</th> <!--Plate-->
<th scope="col">LPN(%)</th> <!--PlateConfidence-->
<th scope="col">Country</th> <!--CountryCode-->
<th scope="col">Country(%)</th> <!--CountryConfidence-->
<th scope="col">Speed(km/h)</th> <!--Speed-->
<th scope="col">Speed change(km/h)</th> <!--SpeedDifference-->
<th scope="col">Width(cm)</th> <!--Width-->
<th scope="col">Height(cm)</th> <!--Height-->
<th scope="col">Length(cm)</th> <!--Length-->
<th scope="col">Weight(kg)</th> <!--Weight-->
<th scope="col">Axles</th> <!--Axles-->
<th scope="col">VehicleID</th> <!--ID-->
<th scope="col">ClassEUR13</th> <!--Classification-->
<th scope="col">Version</th> <!--null-->
<th scope="col">Title</th> <!--null-->
<th scope="col">Direction</th> <!--Direction-->
<th scope="col">Certainty</th> <!--null-->
<th scope="col">Axles Count</th> <!--AxleCount-->
<th scope="col">Gross Weight</th> <!--null-->
<th scope="col">Axles 1 weight(kg)</th> <!--Axles[0].Weight-->
<th scope="col">Axles 2 weight(kg)</th> <!--Axles[1].Weight-->
<th scope="col">Heading (sec)</th> <!--Height-->
<th scope="col">Gap (sec)</th> <!--Gap-->
<th scope="col">Digital Signature</th> <!--null-->
<th scope="col">Checksum</th> <!--Checksum-->
</tr>
</thead>
</table>
Rows are added to the table via JS script.
It sounds like you are adding these elements dynamically. If that is correct, then the event handlers when they are defined are not able to attach to the elements themselves because they are not present in the DOM at the time of binding. To solve this, try using dynamic event handlers:
$('.datatable-sort').on('mouseenter', 'tbody', function () {
console.log('hovered in');
var iDiv = CreateHoverElement();//the div is a bit complex so i have separate function for it
var element = $(this).closest('tr');
element.append(iDiv);
}).on('mouseleave', 'tbody', function () {
var element = document.getElementById('tablehover');
element.parentNode.removeChild(element);
console.log('hovered out');
});
I'm not aware of a way to delegate the .hover() event but according to the docs for .hover(), it is a shorthand syntax for two events: mouseenter and mouseleave, so delegating each of these should provide the same effect.

Change background color for a group of columns not first two columns using jquery

I need to change background color for a group of columns using column id.The first two columns background would not need to change.How to achieve in Jquery?
This is I have tried so far.I have added my Complete script in this you can get more info about it.
var fromtime = obj[i].FromTime; // Here fromtime gives id of a column not index
var totime = obj[i].totime; // Here totime gives id of a column not index
$(row1).children('td').slice(fromtime,totime).not('td:eq(0)').not('td:eq(0)').css({ "background-color": workcolor });
Edit:
I have added my HTML Code
<table class="table table-striped" id="table1">
<thead>
<tr>
<th class="" id="profilepic">Image</th>
<th id="empName">Employee</th>
<th id="00">00:00</th>
<th id="01">01:00</th>
<th id="02">02:00</th>
<th id="03">03:00</th>
<th id="04">04:00</th>
<th id="05">05:00</th>
<th id="06">06:00</th>
<th id="07">07:00</th>
<th id="08">08:00</th>
<th id="09">09:00</th>
<th id="10">10:00</th>
<th id="11">11:00</th>
<th id="12">12:00</th>
<th id="13">13:00</th>
<th id="14">14:00</th>
<th id="15">15:00</th>
<th id="16">16:00</th>
<th id="17">17:00</th>
<th id="18">18:00</th>
<th id="19">19:00</th>
<th id="20">20:00</th>
<th id="21">21:00</th>
<th id="22">22:00</th>
<th id="23">23:00</th>
</tr>
</thead>
<tbody id="body1">
</tbody>
Complete script:
$(row1).children('td').not('td:eq(0)').not('td:eq(0)').css({ "background-color": workcolor });
I am appending a new row each time called "row1" that's cells background color needs to modified based on a "fromtime" to "ToTime" values.There is Children('td') td used means the whole row got colored.But I need the certain cells only.
your code have many other things that don't apply or doesn't seem relevant to the question, then, I making here a code that can help you with your exactly question (apply background to columns but not first and second ones).
I'm using a very basic logic, looping through all columns, starting at index 2 (cause you don't want the first 2 columns to have BG)
Maybe you won't use it exactly like I did below, but I'm sure that this can help and you may find a way to use it inside your code.
please, take a look at the snippet and tell me if you need more help here.
EDIT
If you need just some listed IDs to receive the background, maybe you can have or receive an array and then check to see if they are what you need. This will also change the foor loop, because now you don't need to start at 2, you can loop through all columns and will apply background just to the ones listed in the array, look below:
OPTION 1
loop through all columns (to ensure that you will find only columns, not any other element), then check the IDs.
$(document).ready(function(){
var arrayOfIDs = ["02", "03", "04", "07", "10", "15", "21"];
var myTable = $(".table-striped");
var myColumns = $(myTable.find("th"));
//loop through all columns
myColumns.each(function(){
var column = this;
//loop through all IDs you want to change
for (var i = 0; i < arrayOfIDs.length; i++){
if (column.id == arrayOfIDs[i]){
column.style.background = "rgba(50,50,200,0.85)";
}
}
});
});
th{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-striped" id="table1">
<thead>
<tr>
<th class="" id="profilepic">Image</th>
<th id="empName">Employee</th>
<th id="00">00:00</th>
<th id="01">01:00</th>
<th id="02">02:00</th>
<th id="03">03:00</th>
<th id="04">04:00</th>
<th id="05">05:00</th>
<th id="06">06:00</th>
<th id="07">07:00</th>
<th id="08">08:00</th>
<th id="09">09:00</th>
<th id="10">10:00</th>
<th id="11">11:00</th>
<th id="12">12:00</th>
<th id="13">13:00</th>
<th id="14">14:00</th>
<th id="15">15:00</th>
<th id="16">16:00</th>
<th id="17">17:00</th>
<th id="18">18:00</th>
<th id="19">19:00</th>
<th id="20">20:00</th>
<th id="21">21:00</th>
<th id="22">22:00</th>
<th id="23">23:00</th>
</tr>
</thead>
<tbody id="body1">
</tbody>
OPTION 2
Just loop through IDs to find the columns directly and then apply the BG.
--EDIT 2--> Also, if you need to modify the code on the run, create a function that changes background, this way, every time you need to change the background, call this function, passing the IDs you want and the color you want... as below:
$(document).ready(function(){
//function that loop through all IDs you want to change
var paintBackground = function(arrayOfIds, colorIWant){
for (var i = 0; i < arrayOfIds.length; i++){
var myId = arrayOfIds[i];
var column = $("#"+myId);
column.css('background', colorIWant);
}
}
var firstArrayToPaint = ["00", "01", "02", "06", "07", "08"];
paintBackground(firstArrayToPaint, "orange");
//Added a timeout just to better examplify, don't use the timeout if you don't need it
setTimeout(function(){
//add new row
var myTable = $('.table thead');
var row1 = document.createElement("tr");
myTable[0].append(row1);
//specifying new columns to this row
var qtdOfNewColumns = 6;
var secondArrayToPaint = ["17", "18", "19", "20", "21", "22"];
for (var i = 0; i < qtdOfNewColumns; i++){
var column = document.createElement("th");
column.id = secondArrayToPaint[i];
column.textContent = secondArrayToPaint[i]+":00";
row1.append(column); //adding the columns to the row
}
paintBackground(secondArrayToPaint, "yellow");
},1500);
});
th{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-striped" id="table1">
<thead>
<tr>
<th class="" id="profilepic">Image</th>
<th id="empName">Employee</th>
<th id="00">00:00</th>
<th id="01">01:00</th>
<th id="02">02:00</th>
<th id="03">03:00</th>
<th id="04">04:00</th>
<th id="05">05:00</th>
<th id="06">06:00</th>
<th id="07">07:00</th>
<th id="08">08:00</th>
<th id="09">09:00</th>
<th id="10">10:00</th>
</tr>
</thead>
<tbody id="body1">
</tbody>

CSS an javascript gone after I click on a button

Currently I have a problem on all the pages.The page contains a form with a submit button and a table that contains buttons.The problem is whenever I click on edit button from the table the cssandjavascript are gone.
Here is jascript code
<script type="text/javascript">
$(document).ready(function() {
var table = $('#datatable').dataTable();
var tableTools = new $.fn.dataTable.TableTools(table, {
'aButtons' : [ ],
'sSwfPath' : 'js/copy_csv_xls_pdf.swf'
});
$(tableTools.fnContainer()).insertBefore('#datatable_wrapper');
});
</script>
The table
<table id="datatable" class="hover" >
<thead>
<tr>
<th width="80">Poll ID</th>
<th width="120">Poll Name</th>
<th width="120">Poll Description</th>
<th width="120">poll publisher</th>
<th width="60">Edit</th>
<th width="60">Delete</th>
<th width="60">Voter</th>
<th width="60">Afficher courbe</th>
</tr>
</thead>
<tfoot>
<tr>
<th width="80">Poll ID</th>
<th width="120">Poll Name</th>
<th width="120">Poll Description</th>
<th width="120">poll publisher</th>
<th width="60">Edit</th>
<th width="60">Delete</th>
<th width="60">Voter</th>
<th width="60">Afficher Courbe</th>
</tr>
</tfoot>
<c:forEach items="${listpolls}" var="poll">
<tbody>
<tr>
<td>${poll.id_poll}</td>
<td>${poll.titre}</td>
<td>${poll.description}</td>
<td>${poll.emp_login}</td>
<td>Edit</td>
<td>Delete</td>
<td>Vote</td>
<td>Afficher courbe</td>
</tr>
</c:forEach>
</tbody>
</table>
Here is an picture of the table before i click on edit.
And now
As you can see css and javascipt code are both gone.
What am I doing wrong here? Any help is much appreciated.
Problem is the /poll/edit/... etc. in link's href. Even if redirected, browser still thinks you're in different directory from where relative paths to your styles & scripts won't work.
Specify base directory for all links on page:
<base href="http://www.domain.com/somebasedir/" />
Then regardless of the redirection, for example this stylesheet:
<link rel="stylesheet" type="text/css" href="path/style.css" />
should always be looked for in:
/somebasedir/path/style.css

Categories