Reputation: 495
I have a working piece of JQuery which finds a certain row in a table and then does something to it, my problem is that, sometimes, i have over 2000 pieces of data to match to a td and over 2000 rows in the table, so it can take a very long time.
(P.S Each td can only be matched once)
JQuery
$("#tableAName").on("click", "tr", function () {
//Get Some Data
$.ajax({
url: '@Url.Action("GetGroupRights", "Home")',
data: { 'groupName': insertText },
type: "post",
cache: false,
datatype: 'json',
success: function (data) { <=== data RETURNS LIST OF STRING WHICH MATCH TD'S
if (!jQuery.isEmptyObject(data)) {
$td = $('#tableBName td');
$.each(data.groupIDs, function (index, val) {
$td.each(function () {
if ($(this).text() === val) {
$(this).closest(".classY").addClass(".classX")
$(".classX").find(".classA").removeClass('classB').addClass('classC');
}
});
});
}
});
});
As I mentioned before this works perfectly fine but can be very slow, is there a way of maybe not looking at a certain row once it has been found?
Thanks and please ask if you have any questions and/or need any more info
Upvotes: 1
Views: 395
Reputation: 24638
You can use .filter(fn)
on $td
to eliminate the inner loop. The method will only return td
elements that meet the condition and you can operate on them directly. Please note that .filter(fn)
does use .each()
internally. Therefore, there may not be much performance improvement but your code does look more concise.
$td = $('#tableBName td');
$.each(data.groupIDs, function (index, val) {
$td.filter(function() {
return $(this).text() === val;
})
.closest(".classY").addClass(".classX")
.find(".classA").removeClass('classB').addClass('classC');
});
Upvotes: 1
Reputation: 13949
You can shorten some of the time by adding the :contains filter to your td selector
if (!jQuery.isEmptyObject(data)) {
$.each(data.groupIDs, function (index, val) {
$td = $('#tableBName td:contains(val)');
$td.each(function () {
if ($(this).text() === val) {
$(".classX").find(".classA").removeClass('classB').addClass('classC');
return false;
}
});
});
}
Upvotes: 1
Reputation: 413866
You can make a pass over the table to create a map of cell values and element references:
var map = {};
$("tableName td").each(function() {
map[$(this).text()] = this;
});
Then your ajax callback can do this:
$.each(data.groupIDs, function (index, val) {
$(map[val]).find(".classA").removeClass("classB").addClass("classC");
});
(If you always do a .find()
like that in your real code, you could pre-compute that when you're making the map too.)
Upvotes: 2