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

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.

Related

Why my table filter is removing the table headers?

I'm trying to implement this table filter which i found at this tutorial but for some reason my filter is removing my table headers and in the examples it doesn't remove the headers, I wonder what I'm doing wrong here?
This is my table:
<input type="text" id="inputFilter" placeholder="Procurar agendamentos..">
<table class="table table-hover table-dark" id="tableAgendamentos">
<thead>
<tr>
<th scope="col">Data</th>
<th scope="col">Animal</th>
<th scope="col">Procedimento</th>
<th scope="col">Status</th>
<th scope="col">Valor</th>
<th scope="col">Nota Fiscal</th>
</tr>
</thead>
<tbody>
#foreach (Agendamento agendamento in Model.ListaAgendamentos)
{
<tr>
<th scope="row">#agendamento.DataHoraInicio</th>
<td>#agendamento.nomeAnimal</td>
<td>#agendamento.NomeServico</td>
#if(agendamento.prioridadeAgendamento == 3)
{
<td class="text-success">Em até 7 dias</td>
}else if(agendamento.prioridadeAgendamento == 2)
{
<td class="text-primary">Em até 30 dias</td>
}else
{
<td class="text-danger">Atrasado/Vencido</td>
}
<td>R$100,00</td>
<td>Baixar</td>
</tr>
}
</tbody>
</table>
This is my script:
<script>
$(document).ready(function(){
$("#inputFilter").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#tableAgendamentos tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
</script>
This is how my table looks without searching anything
This is how my table looks after searching for some data
Thanks in advance.
Looks like the header is getting filtered out.
I think you could give it a try with an id for tbody instead of the whole table id in the script.
Looking at the tutorial, there seems to be a point at the end stating
Note that we start the search in tbody, to prevent filtering the table headers.
I think error is about this
$("#tableAgendamentos tr")
I think give a class name to tr instead of above code then try again

Bootstrap Table conditional show/hide columns

I need to show/hide columns in my bootstrap table. If a condition is true I want to show some colums and hidding some others.
I tried various methods, without success
I use thymeleaf for my views.
This is my html page code:
MY TABLE:
<table data-toggle="table"
th:data-url="#{/certificato/list/{idCommessa}(idCommessa=${commessa.id})}"
data-pagination="true"
data-search="true"
data-classes="table table-hover"
data-striped="true" id="tableCertificato"
data-side-pagination="client">
<thead>
<tr>
<th data-sortable="true" data-field="numeroCertificato" th:text="#{numeroCertificato}"></th>
<th data-sortable="true" data-field="dataCertificato" th:text="#{dataCertificato}" data-formatter="dateFormatter"></th>
<th data-field="nFabbrica" th:text="#{nFabbrica}" ></th>
<th data-field="modulo" th:text="#{modulo}" ></th>
<th data-field="categoriaRischio" th:text="#{categoriaRischio}"></th>
</thead>
My JS:
$(function(){
var tipoCertVar = [[${commessa.tipoAttivita}]];
if(tipoCertVar == 'TPED'){
$('#tableCertificato').bootstrapTable('hideColumn', 'nFabbrica');
$('#tableCertificato').bootstrapTable('hideColumn', 'modulo');
$('#tableCertificato').bootstrapTable('hideColumn', 'categoriaRischio');
}else{
$('#tableCertificato').bootstrapTable('showColumn', 'nFabbrica');
$('#tableCertificato').bootstrapTable('showColumn', 'modulo');
$('#tableCertificato').bootstrapTable('showColumn', 'categoriaRischio');
});
The condition is true, I debugged it with an alert message.
But the hide/show column not run. The columns are always shown.
I try to change my code without success so:
<th th:if="${commessa.tipoAttivita != 'TPED' }" data-field="nFabbrica" th:text="#{nFabbrica}"></th>
and using a conditional data-visible.
Same results.
Anyone can help me?
I had a similar problem and I had resolved with this step:
set data-visible="false" for all the conditional columns of your table;
change your javascript insert this var: $table = $('#tableCertificato').bootstrapTable({ }); and use this in your if-statement:
$table = $('#tableCertificato').bootstrapTable({ });
if(tipoCertVar != 'TPED') {
$table.bootstrapTable('showColumn', 'nFabbrica');
$table.bootstrapTable('showColumn', 'modulo');
$table.bootstrapTable('showColumn', 'categoriaRischio');
}
I hope this solution will help you.

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>

How to make href work in jquery-bootgrid basic plugin

Am using bootgrid-basic to show my data,
<table id="grid-basic"
class="table table-bordered table-striped table-condensed mb-none">
<thead>
<th data-column-id="aa">aa</th>
<th data-column-id="ss" data-order="desc">ss</th>
<th data-column-id="dd">dd</th>
<th data-column-id="ff">ff</th>
<th data-column-id="aaa">aaa</th>
<th data-column-id="aaaaa" >aaaAa</th>
</tr>
</thead>
<tbody>
#foreach($alldata as $data)
<tr>
<td>{{$data->aa}}</td>
<td>{{$data->ss}}</td>
<td>0</td>
<td>{{$data->dd}}</td>
<td>{{$data->ff}}</td>
<td>ASSSsdf</td>
</tr>
#endforeach
</tbody>
</table>
and initialized $("#grid-basic").bootgrid(); in script.
Everything is working fine like search,data ordering ,pagination but those links doesnt see to work.
If i use formatter links work and remaining doesnt work.
$("#grid-basic").bootgrid(
formatters: {
"action": function (column, row)
{
return '<a href=\"/model/' + row.actions + '"\>' +row.actions+ '</a>' ;
}});
A jsfiddle link here : http://jsfiddle.net/6xpyxbcg/
There is a parentheses missing in your JS, it should be bootgrid({ and you need to add data-formatter="link" to the th tag of the column you wish to use the formatter on (i.e. the link column).
HTML
<th data-column-id="link" data-formatter="link" >Received</th>
JQuery
$(function()
{
$("#grid-basic").bootgrid({
formatters: {
"link": function(column, row)
{
return "" + row.link + "";
}
}
}
)
});
Demo in jsFiddle
P.S. trying using the built in snippet next time, as there is a one click button that allows you to copy the code to the answer section and amend it accordingly.

Data Table hangs sporadically (No data available in table) when data sorted or loaded with Knockout binding

I am binding data to a table using Knockout JS and the JQuery/Bootstrap based; Data Table API. The table becomes unresponsive sporadically when sorted or loaded. There are no errors in the log.
It also shows 0 of 0 data as illustrated in the screenshot below:
I have seen similar errors/issues but could not get a solutions for them, E.g. This post:
Code:
function viewModel(){
var self = this;
self.Data = ko.observableArray([]);
$.getJSON('https://restcountries.eu/rest/v1/all', function(data){
self.Data(data);
});
}
ko.applyBindings(viewModel());
$(document).ready(function() {
$('#example').dataTable();
});
HTML:
<div class="table-responsive">
<table id="example" cellspacing="0"
class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th scope="col">Country</th>
<th scope="col">Capital</th>
<th scope="col">Population</th>
<th scope="col">Region</th>
</tr>
</thead>
<tfoot>
<tr>
<th scope="col">Country</th>
<th scope="col">Capital</th>
<th scope="col">Population</th>
<th scope="col">Region</th>
</tr>
</tfoot>
<tbody data-bind="foreach: Data">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: capital"></td>
<td data-bind="text: population"></td>
<td data-bind="text: region"></td>
</tr>
</tbody>
</table>
</div>
Here is a full working example (JSFiddle) utilizing a REST API so that the exact problem is accurately replicated:
I think the problem with your example may be with how you're dealing with your data when you get it back from the API call.
I've put together a quick example that achieves what I think you're trying to achieve and the sorting and searching work quickly for me.
When I get the JSON data back from the API, I use the Knockout arrayMap utility function to create an array of "Country" objects that have observable properties that I have mapped the JSON data to. I've bound the table to my observableArray of Country objects.
Initialising the data table in the same way you have works fine for me in this case.
The full working solution is here: http://plnkr.co/edit/eroIox6zqBFOVnf86Mdk?p=preview
script.js
var ViewModel = function(jsonData) {
var countries = ko.utils.arrayMap(jsonData, function(item) {
return new Country(item)
});
this.Countries = ko.observableArray(countries);
};
var Country = function(jsonItem) {
this.Name = ko.observable(jsonItem.name);
this.Capital = ko.observable(jsonItem.capital);
this.Population = ko.observable(jsonItem.population);
this.Region = ko.observable(jsonItem.region);
};
window.onload = function() {
$.getJSON('https://restcountries.eu/rest/v1/all', function(data) {
ko.applyBindings(new ViewModel(data));
$("#example").dataTable();
});
}
index.html
<table id="example" cellspacing="0" class="table table-striped table-bordered table-condensed">
<thead>
<tr>
<th scope="col">Country</th>
<th scope="col">Capital</th>
<th scope="col">Population</th>
<th scope="col">Region</th>
</tr>
</thead>
<tfoot>
<tr>
<th scope="col">Country</th>
<th scope="col">Capital</th>
<th scope="col">Population</th>
<th scope="col">Region</th>
</tr>
</tfoot>
<tbody data-bind="foreach: Countries">
<tr>
<td data-bind="text: Name"></td>
<td data-bind="text: Capital"></td>
<td data-bind="text: Population"></td>
<td data-bind="text: Region"></td>
</tr>
</tbody>
</table>
Tables are fairly slow to render within Knockout, and if your table is based on a computed, I could see how you could have some issues with redrawing time. But that's not happening here.
Apart from loading the data and binding it to the table rows, there's no data manipulation going on in your viewmodel. All the data manipulation is done by the dataTable plug-in, which you initialize with a single jQuery call. Properly, that should be done within a binding handler. You also need to know what is going on within the plug-in when it sorts, filters, or whatever it does, because you may need to mediate those changes back to your observableArray within your binding handler.
Bottom line: you need a binding handler for the dataTable. There may be one already written; I haven't Googled for it. Give that a try.

Categories