I would say I am fairly decent with javascript and jQuery, well, enough to get the job done and done pretty well. I do however lack a deep understanding of js.
I have created some functions for highlighting table elements. ctrl+click toggles selections shift+click+drag highlights selection
My question does not pertain to whether or not my implementation is the best way or not but ...
How do I abstract this functionality so I can add this functionality to any table. Like if I add more highlighting features and such and put this in its own .js file. How would I attach it to any html table?
Sorry if this has already been answered, but I could not think of what to search for.
Thank you.
****Newest Code**** This code is in its own .js file and is attached to my table. All the current functionality is there. The only thing I am weary of is the .off() functions. In my case, I am reloading new tables.... as I type this, I realize I should just empty the tr's from the table instead of recreating a new table all the time, then I could get rid of the .off() calls.
$.fn.addEvents = function(obj)
{
console.log("Adding events to table");
var properties = $.extend(true,
{
shifting: false,
ctrling: false,
mousing: false,
mouseenter: 0,
mouseleave: 0,
mousestartindex: 0,
mouseenterindex: 0,
mouseleaveindex: 0,
trajectory: null,
tmptrajectory: null
}, obj || {});
$(document)
.off('mouseup')
.on('mouseup', function(e)
{
properties.mousing = false;
properties.trajectory = null;
})
.off("keyup")
.on("keyup", function(e)
{
if(e.which == 16)
{
properties.shifting = false;
}
if(e.which == 17)
{
properties.ctrling = false;
}
})
.off("keydown")
.on("keydown", function(e)
{
if(e.which == 16)
{
properties.shifting = true;
}
if(e.which == 17)
{
properties.ctrling = true;
}
if($(this).find('tr.selected').length > 0)
{
switch(e.which)
{
//case 37: // left
//break;
case 38: // up
var index = $(this).find('tr.selected').index();
if(index > 0)
{
$(this).find('tr').removeClass('selected');
$(this).find('tr td').removeClass('selected');
$(this).find('tr:eq(' + index + ')').addClass('selected');
$(this).find('tr:eq(' + index + ') td').addClass('selected');
}
break;
//case 39: // right
//break;
case 40: // down
var index = $(this).find('tr.selected').index();
if(index < $(this).find('tr').length - 2)
{
$(this).find('tr').removeClass('selected');
$(this).find('tr td').removeClass('selected');
$(this).find('tr:eq(' + (index+2) + ')').addClass('selected');
$(this).find('tr:eq(' + (index+2) + ') td').addClass('selected');
}
break;
case 117: // f6
var index = $(this).find('tr.selected').index();
if(index > 0)
{
....
}
break;
case 118: // f7
var index = $(this).find('tr.selected').index();
if(index < $(this).find('tr').length - 1)
{
....
}
break;
default: return; // exit this handler for other keys
}
e.preventDefault(); // prevent the default action (scroll / move caret)
}
return;
});
return $(this)
.off('click')
.off('contextmenu')
.on('click', function()
{
if(!properties.ctrling && !properties.shifting)
{
$('#datatablebody tr, #datatablebody tr td').removeClass('selected');
$(this).addClass('selected');
$(this).find('td').addClass('selected');
}
else if(properties.ctrling && $(this).hasClass('selected'))
{
$(this).removeClass('selected');
$(this).find('td').removeClass('selected');
}
else if(properties.ctrling && !$(this).hasClass('selected'))
{
$(this).addClass('selected');
$(this).find('td').addClass('selected');
}
})
.on('contextmenu', function(ev)
{
ev.preventDefault();
$('#datatablebody tr, #datatablebody tr td').removeClass('selected');
$(this).addClass('selected');
$(this).find('td').addClass('selected');
showContextMenuTR($(this).closest('tr').attr('id'), ev.clientX, ev.clientY);
return false;
})
.off('mousedown')
.on('mousedown', function(e)
{
properties.mousing = true;
properties.mousestartindex = $(this).index();
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
})
.off('mouseenter')
.on('mouseenter', function(e)
{
properties.mouseenter = e.clientY;
properties.mouseenterindex = $(this).index();
if(properties.tmptrajectory === properties.trajectory)
{
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
}
})
.off('mouseleave')
.on('mouseleave', function(e)
{
properties.mouseleave = e.clientY;
if(properties.shifting && properties.mousing)
{
properties.tmptrajectory = properties.mouseenter - properties.mouseleave < 0?1:-1;
}
if(properties.trajectory != null && properties.tmptrajectory !== properties.trajectory && $(this).index() !== properties.mousestartindex)
{
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
}
if(properties.shifting && properties.mousing)
{
if(properties.trajectory == null)
{
properties.trajectory = properties.tmptrajectory;
}
else if(properties.tmptrajectory !== properties.trajectory && $(this).index() === properties.mousestartindex)
{
properties.trajectory = properties.tmptrajectory;
}
}
})
.off('mouseup')
.on('mouseup', function(e)
{
properties.mousing = false;
properties.trajectory = null;
if(properties.shifting && properties.mousing)
{
multiselectrow($(this));
}
});
}
function multiselectrow(obj)
{
if($(obj).hasClass('selected'))
{
$(obj).removeClass('selected');
$(obj).find('td').removeClass('selected');
}
else
{
$(obj).addClass('selected');
$(obj).find('td').addClass('selected');
}
}
#datatablebodyfor some element(s) that the user provides. Then just change your selectors to$(userSelectedTable).find('tr')etc.$tableand then using that throughout your code, instead of the table ID. Alternatively look at creating a jQuery plugin and then call it like (for example)$("#datatablebody").addTableFunctionality(). You can read about that approach here.