i am trying to display multiple Running Times in a table.
The table has 3 columns (nr, name, time). The time is displayed in that format 'hh:mm:ss.f', that means that i update the time every 100ms.
function updateTimes() {
setTimeout(updateTimes, 100);
// requestAnimationFrame(updateTimes);
$("#livedata tbody tr").each(function (index, value) {
var live = $(value).data("base");
$("#" + live.Entry.Id + "_time").text(formatTimeF(moment().subtract(live.Data)));
});
}
//Create Table Row
function UpdateLive(live) {
var e = $("#" + live.Entry.Id);
if (e.length == 0) {
e = $("<tr id='" + live.Entry.Id + "' class='live'/>");
$("<td id='" + live.Entry.Id + "_name" + "'></td>").appendTo(e);
$("<td id='" + live.Entry.Id + "_nr" + "'></td>").appendTo(e);
$("<td id='" + live.Entry.Id + "_time" + "'></td>").appendTo(e);
e.appendTo($("#livedata"));
}
e.data("base", live);
}
The code works and the time is displayed as expected on "normal" PCs, my problem are mobile Devices (Cell Phones). It seems that the update Intervall (100ms) is too fast for most of these devices, so the time starts to "jump". If I only update the times of existing table elements the "jumping" is not that hard, but if I add table rows its getting worst until the row is added.
I use JQuery for manipulating the table.
Does anyone have an idea how i can improve my Performance?
Kind Regards
Manu
Some ideas:
It would certainly help to use direct references to your elements instead of accessing them by $ selectors all the time. E.g. use $(live.childNodes[2]) instead of $("#" + live.Entry.Id + "_time"), or store references to the individual cells. Then you can drop all the id attributes of your cells.
Assuming that the bottleneck is element creation, you could create hidden table rows in advance and show them once you use them, hiding them again after use. That would require a major rewrite of these functions, though.
I'm not sure how much overhead $('<td>') adds. Maybe document.createElement('td') is significantly faster.
(and this should actually come in the beginning of every performance-related change) Profile your code, e.g. using the Profile tab in Chrome's developer tools. It will show where exactly how much time is spent so that you know what the most expensive function calls are. I would assume that even if it's faster on the desktop, what's slowest on mobile will still be slowest on desktop.
Related
Disclaimer: I am not a front-end engineer, and never was. So, I apologise if I'm missing something very obvious, but I can't wrap my head around whatever I have just experimented in the JavaScript and jQuery.
In my HTML document, I have some div elements, a button element, and a <script> containing:
$("button").click(function(){
$("div").fadeOut();
var colour = "rgb(" + Math.floor(Math.random()*255) + ", " + Math.floor(Math.random()*255) + ", " + Math.floor(Math.random()*255) + ")"
$("div").css("background-color", colour);
$("div").fadeIn(100);
});
and this works as expected. Each and every new click on the <button> changes background colour of all the div elements, in the enclosing HTML document, setting them to randomly generated RGB values.
If I, however, want to play a little bit and make some "colourful show", by putting all this snippet in a loop, as:
$("button").click(function(){
for (var i = 0; i < 10; i++) {
$("div").fadeOut();
var colour = "rgb(" + Math.floor(Math.random()*255) + ", " + Math.floor(Math.random()*255) + ", " + Math.floor(Math.random()*255) + ")"
console.log(colour);
$("div").css("background-color", colour);
$("div").fadeIn(100);
}
});
all the iterations fade out and fade in with the same colour, although, I expect them to be random, and even console.log(colour) prints different (random) values.
Note, that I understand, that random can be a pseudo-random, relying on the default seed, but this doesn't matter here.. my problem is having discrete values, in colour variable, but not having them worked, as expected, in the .css method.
So, why does this (probably - .css?) work differently inside and outside of loop?
I am using Google's Chrome, if that matters.
I have a function that creates an HTML table based on an array. Once the HTML table is finished being created, I then want to call jQuery DataTables to render the table.
However, this doesn't work. I get the "No data Available in Table" line whenever I do this, and my table data appears. But, as soon as I click a filter for it, all the <td> HTML data disappears. I've checked my table's HTML, it's correctly defined, has all the necessary tags, and matches with what my function creates.
From what I've read, the issue lies with the DataTables function firing too early. I confirmed this by using the setTimeout function- it creates the table perfectly and with no errors. However, this solution isn't scalable and would cause the same problem once the data expands.
I've tried fixing this by using a callback (DataTables still fires too early, I used renderTable(function(){$('#divtable').DataTable();}), and a promise (it still fires too early, I tried to use function.done()...). How can I call the render function as only when the HTML table div is finished updating?
Here is my (shortened) code:
HTML Table render:
function renderTable() {
for (var i = 0; i < array.length; i++) {
var tableRow = '';
tableRow += '<tr><td class="ID">' + array[i].id + '</td><td>' + array[i].date + '</td><td>' + array[i].total + '</td><td><input type=button class="editValues" value="Edit Values" /></td></tr>';
$("#divtable > tbody").append(tableRow);
}
jQuery:
$(document).ready(function() {
renderTable();
$('#divtable').DataTable();
}
I have a div with a fixed width which contains 'tags' like the stackoverflow-tags.
Now, what's disturbing me, is that the Hallo Tag is in the last line, but it would fit in the first line. Like this:
The order of the elements is irrelevant. So, reordering would be an option.
Question: How can i achieve this? I'm currently using a <ul><li></li></ul> construct.
The nicest way would be a CSS-Way, but i guess it's up to JS to solve this problem.
Any ideas would be appreciated :)
UPDATE
JSFiddle: http://jsfiddle.net/CLj2q/
Got it: The jsFiddle is here
$(function() {
$('.as-close').click(function(e) { $(this).parent().remove(); });
DoTagSort();
});
function DoTagSort() {
var TheItems = [], TheHTML = '';
var TheLinks = $('.as-selections').find('li').each(function () {
TheItems.push($(this).text().slice(1));
});
TheItems.sort(function(a, b) { return b.length - a.length; });
var TheTag = '<li class="as-selection-item"><a class="as-close">×</a>';
while(TheItems.length > 1) {
TheHTML = TheHTML + TheTag + TheItems[0] + '</li>';
TheHTML = TheHTML + TheTag + TheItems[TheItems.length - 1] + '</li>';
TheItems.splice(0, 1);
TheItems.splice(TheItems.length - 1, 1);
}
if (TheItems.length) {
TheHTML = TheHTML + TheTag + TheItems[0] + '</li>';
}
$('.as-selections').html(TheHTML);
}
Assuming that the container for the tags is a set-width, and the tags themselves aren't (ie: they inherit their width from their contents, rather than us being able to give them a set-width) there's not a huge amount that you can do from the CSS perspective without breaking and re-ordering the flow of the markup.
If the markup is being generated server-side I'm sure you could calculate widths and re-order prior to pushing the markup into the view. If not, you're a bit stuck without using JavaScript.
Given that the order requirement appears to be purely appearance-based (ie: not functional), there's no harm in enhancing the standard float view that you've displayed in your screenshot with JavaScript. This means that JS-enabled visitors will get an 'enhanced' view (with the elements ordered nicely), whilst non-JS users would still have a fully-functional tag cloud, albeit in a slightly less-organised fashion.
jQuery Masonry or Isotope would probably do would do exactly what you need.
This is off the shelve solution. And a bit of a cheat with Masonry (notice the columnWidth: 1).
$('.as-selections').masonry({
itemSelector: '.as-selection-item'
, columnWidth: 1 });
http://jsfiddle.net/D5ud7/1/
I guess you could find more appropriate library for this or better html form for masonry to crunch.
I hope to get some advise about how to write the javascript and jQuery code more beautiful and gain more readability.
In this case, I hope to insert table inside a list element. Both list and table are added dynamic by using script.
I have some code like this:
$('#Items').append("<ul></ul>");
var car_index;
var photo_index;
var lot_index;
for (car_index = 0; car_index < cars.length; car_index++)
{
lot_index = car_index + 1;
//From here, I thought the code is really ugly...though it works.
//I can't image that I will need to adde 3 rows with 6 cols into the table by using this way
//Also each col may has their own style need to be assigned....
//Any advise??
$('#Items ul').append("<li id='r_" + car_index +"'></li>");
$('#r_' + car_index).append("<table cellspacing='2' cellpadding='0'><tr><td width='50' align='left' style='font-size:10pt; font-weight:bold'>Lot " + lot_index +"</td></tr></table>");
}
As I write in the comments of above code. I could use append method and put a lot of HTML code in there. However it really looks ugly... and in the above example, I just added one row in the list. In the final goal, I have to add three rows, with about 6 cells. Each cell will have their own style set for the content. It will really be a mess.
Any advice will be appreciate! Thank you!
Perhaps use templating via either Mustache or jQuery.
See more: What Javascript Template Engines you recommend?
try this, coz
$('#Items ul').append("<li id='r_" + car_index +"'></li>); is not enclosed between " "
$('#Items ul').append("<li id='r_"+car_index+"'></li>");
$('#r_' + car_index).append("<table cellspacing='2' cellpadding='0'><tr><td width='50' align='left' style='font-size:10pt; font-weight:bold'>Lot " + lot_index +"</td></tr></table>");
}
Alright...After some thought, I find a way which will be more clear to write this kind of code. I'm not sure if this is the goog choice since it will require more work...but I feel it is better to write this way.
The idea is really simple, create object to store the HTML tags which will fixed for every block. As my example, it is a table will repeated every time a list will be added. So why not store all fixed table tags and their style attribute into one array like object?
var unit =
{
table_header : "<table border = '1'>",
row_1_col_1 : "<tr><td>Lot ",
row_1_col_2 : "</td><td><a class='addto' href='#'>Add to like</a>",
row_2_col_1 : "</td></tr><tr><td>",
row_2_col_2 : "</td><td><img src='",
row_3 : "'></td></tr><tr><td>",
table_end : "</td></tr></table><hr />"
};
Make this variable global, than when you need to add table, the original code:
$('#r_' + car_index).append("<table cellspacing='2' cellpadding='0'><tr><td width='50' align='left' style='font-size:10pt; font-weight:bold'>Lot " + lot_index +"</td></tr></table>");
Will become like this:
$('#r_' + car_index).append(unit['table_header'] +
unit['row_1_col_1'] + "Content in cell 1" +
unit['row_1_col_2'] + "Content in cell 2" +
unit['row_2_col_1'] + "Content in cell 3" +
unit['row_2_col_2'] + "Content in cell 4" +
unit['row_3'] + unit['table_end']);
Just be careful about double quote sign and single quote sign, and also, the array's index need to be quoted(see javascript array's use for detail if you got problem).
I think the advantage of this method is much more easy to modify the table. Add row, change content, or change style make much more easy since it use the single object.
I also not sure if this is a good way or not, hope to hear more about your thought! Thank you!
I have a report that has some headers on the top of the table(columns) but also some headers on the left of the table (rows). Those headers are variable, never fixed. The whole entire table is built through DOM Scripting based on an Ajax response that returns me the top headers, the left headers, and the qty at a particular intersection.
I already have an algorithm that knows how populate the cells in that table based on the column header and the row header.
In Firefox, Chrome, and Safari the following works:
document.getElementById("myTable").rows[row].cells[column].firstChild.nodeValue = item.qty.toString();
The problem is in IE7 (what the client uses). IE 7 does not let me access a particular cell by using the [index] notation.Basically, its blowing up at ".cells[column]" . Do you guys know the equivalent of the statement above in IE7?
Also do you know of a jQuery way to fill a known cell once I have the row and the column coordinates?
Thanks,
-Dario
jQuery("#myTable tbody tr:eq(" + row + ") td:eq(" + column + ")").html("foo");
jQuery selector #id
jQuery selector element
jQuery selector eq()
jQuery html()
row and column will start from 0. Use the above codes.
Non-jquery way:
document.getElementById("myTable").getElementsByTagName('tbody')[0].getElementsByTagName('tr')[row].getElementsByTagName('td')[column].innerHTML = item.qty.toString();
$("#myTable tr:eq(" + row + ") td:eq(" + column + ")").html(item.qty.toString());
However you should be aware of nested tables. Especially if you have another table inside the table with the myTable id. If so let me know, i might rewrite the line for you.
Also you should be aware that I was using jQuery here. To add jQuery to your page you should add the following to the page, preferably in the <head> element:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
This if you want to make use of the jQuery file hosted by google, but of course you can download it and host it yourself if you wish so.
Try this:
$("#myTable tr:eq(" + row + ") td:eq(" + columnh + ")").html(item.qty.toString());