Jquery DOMNodeInserted not working in Chrome but works in IE - javascript

I have a module to develop in which I have a parent table and for each row there is a child table both dynamically generated using JSON array via Ajax call using jQuery.
Now I need to fire an alert every time a child table with class "childtable" is inserted into the parent table row showing the id of the child table.
I tried to achieve this using jQuery DOMNodeInserted event and it works perfectly for me in IE but it doesn't work in Chrome.
I'm using Google Chrome Version 56.0.2924.87. The piece of code is as shown below.
$('body').on('DOMNodeInserted', 'table.childtable', function(e) {
if ( ! $.fn.DataTable.isDataTable('#'+$(this).attr('id'))) {
var tab='#'+$(this).attr('id');
alert(tab); //fire id as alert
$('#'+$(this).attr('id')).DataTable({
"bSort" : false,
"scrollCollapse": true,
"searching": false,
"bInfo" : false,
"paging": false,
"columnDefs": [{
"targets": [ 0 ],
"visible": false
}]
});
$( tab).find( "thead tr th" ).each( function( index1 ) {
index1 += 1;
$(tab).find("tbody tr td:nth-child(" + index1 + ")").attr("data-title", $(this).text());
});
}
});

After a long search i finally found an answer to my question. Thanks to Uzair Farooq.
The above thing can be achieved using the arrive.js which works on Mutation observers.
Click here to download the file.
arrive.js
Code:
$('body').arrive('table.childtable', function(){
alert('#'+$(this).attr('id'));
});
Now my concern is i cannot use this code in old browsers.Bcoz mutations observers is not supported in old browsers.
So how can we find out whether deprecated mutation events is supported in browser or not using jquery?

Related

How to fix alignment in jquery datatable between thead and tbody [duplicate]

I am using jQuery datatables. When running the application, the header width is not aligned with the body width. But when I click on the header, it is getting aligned with the body width but even then there is some light misalignment. This problem occurs only in IE.
JSFiddle
This is how it looks when the page gets loaded:
After clicking on the header:
My datatable code:
$("#rates").dataTable({
"bPaginate": false,
"sScrollY": "250px",
"bAutoWidth": false,
"bScrollCollapse": true,
"bLengthChange": false,
"bFilter": false,
"sDom": '<"top">rt<"bottom"flp><"clear">',
"aoColumns": [{
"bSortable": false
},
null,
null,
null,
null
]
});
rates is my table id.
Could anyone help me with this?
CAUSE
Most likely your table is hidden initially which prevents jQuery DataTables from calculating column widths.
SOLUTION
If table is in the collapsible element, you need to adjust headers when collapsible element becomes visible.
For example, for Bootstrap Collapse plugin:
$('#myCollapsible').on('shown.bs.collapse', function () {
$($.fn.dataTable.tables(true)).DataTable()
.columns.adjust();
});
If table is in the tab, you need to adjust headers when tab becomes visible.
For example, for Bootstrap Tab plugin:
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e){
$($.fn.dataTable.tables(true)).DataTable()
.columns.adjust();
});
Code above adjusts column widths for all tables on the page. See columns().adjust() API methods for more information.
RESPONSIVE, SCROLLER OR FIXEDCOLUMNS EXTENSIONS
If you're using Responsive, Scroller or FixedColumns extensions, you need to use additional API methods to solve this problem.
If you're using Responsive extension, you need to call responsive.recalc() API method in addition to columns().adjust() API method. See Responsive extension – Incorrect breakpoints example.
If you're using Scroller extension, you need to call scroller.measure() API method instead of columns().adjust() API method. See Scroller extension – Incorrect column widths or missing data example.
If you're using FixedColumns extension, you need to call fixedColumns().relayout() API method in addition to columns().adjust() API method. See FixedColumns extension – Incorrect column widths example.
LINKS
See jQuery DataTables – Column width issues with Bootstrap tabs for solutions to the most common problems with columns in jQuery DataTables when table is initially hidden.
I solved this problem by wrapping the "dataTable" Table with a div with overflow:auto:
.dataTables_scroll
{
overflow:auto;
}
and adding this JS after your dataTable initialization:
jQuery('.dataTable').wrap('<div class="dataTables_scroll" />');
Don't use sScrollX or sScrollY, remove them and add a div wrapper yourself which does the same thing.
Found the solution :
Added table-layout:fixed to the table. And opened the application in IE mode.
I fixed, Work for me.
var table = $('#example').DataTable();
$('#container').css( 'display', 'block' );
table.columns.adjust().draw();
Or
var table = $('#example').DataTable();
table.columns.adjust().draw();
Reference: https://datatables.net/reference/api/columns.adjust()
Use these commands
$('#rates').DataTable({
"scrollX": true,
"sScrollXInner": "100%",
});
As Gyrocode.com said "Most likely your table is hidden initially which prevents jQuery DataTables from calculating column widths."
I had this problem too and solved it by just init the dataTable after showing the div
For example
$('#my_div').show();
$('#my_table').DataTable();
issue is data table is called before the data table is drawn on DOM,use set time out before calling data table.
setTimeout(function(){
var table = $('#exampleSummary').removeAttr('width').DataTable( {
scrollY: "300px",
scrollX: true,
scrollCollapse: true,
paging: true,
columnDefs: [
{ width: 200, targets: 0 }
],
fixedColumns: false
} );
}, 100);
do not need to come up with various crutches, table header width not aligned with body, because due to the fact that the table did not have enough time to fill in the data for this, do setTimeout
setTimeout(function() {
//your datatable code
}, 1000);
This code will align the header with the body.
data-table-basic is the id of the data table I gave.
<style>
#data-table-basic_wrapper .dataTable, #data-table-basic_wrapper .dataTables_scrollHeadInner {
width: 100% !important;
}
</style>
When scrolling is enabled in DataTables using scrollX or scrollY parameters, it will split the entire table into two or three individual HTML table elements; the header, the body and, optionally, the footer. This is done in order to provide the ability to scroll the different sections of the DataTable in a cross-browser manner.
In my case I wanted to have horizontal scroll bar because content are scrolling to right. So adding "scrollX" parameter created this issue in some of the pages which are having more columns.
Below code wrap a div around the DataTable with style "overflow as auto". We need to add div when dataTable completed the execution. We can do this as below:
$('#DataTableID').DataTable({
//"scrollX": true,
"initComplete": function (settings, json) {
$("#DataTableID").wrap("<div style='overflow:auto; width:100%;position:relative;'></div>");
},
});
If you are using the scrollX,scrollY, scrollXInner or sScrollXInner options - remove them. They may cause problems.
Source: http://sforsuresh.in/datatables-header-body-not-aligned
None of the above solutions worked for me but I eventually found a solution that did.
My version of this issue was caused by a third-party CSS file that set the 'box-sizing' to a different value. I was able to fix the issue without effecting other elements with the code below:
$table.closest(".dataTables_wrapper").find("*").css("box-sizing","content-box").css("-moz-box-sizing","content-box");
Hope this helps someone!
make sure table width is 100%
Then "autoWidth":true
$("#rates").dataTable({
"bPaginate": false,
"sScrollY": "250px",
"bAutoWidth": false,
"bScrollCollapse": true,
"bLengthChange": false,
"bFilter": false,
"sDom": '<"top">rt<"bottom"flp><"clear">',
"aoColumns": [{
"bSortable": false
},
null,
null,
null,
null
]}).fnAdjustColumnSizing( false );
Try calling the fnAdjustColumSizing(false) to the end of your datatables call. modified code above.
Discussion on Column sizing issue
After a ton of hours, I just removed scrollY from options and it's working fine
None of the above solutions worked for me, so I'll post my solution: I was loading the table into a hidden div and then showing the div after the table was built. When I showed/unhid the div first and then built the table while the table was visible, it worked.
So DataTables can't size columns in a hidden div, likely because it is getting a column width of 0px on the backend when the table is hidden.
Simply wrap table tag element in a div with overflow auto and position relative. It will work in chrome and IE8.
I've added height 400px in order to keep table size fixed even after reloading data.
table = $('<table cellpadding="0" cellspacing="0" border="0" class="display" id="datat"></table>').appendTo('#candidati').dataTable({
//"sScrollY": "400px",//NO MORE REQUIRED - SEE wrap BELOW
//"sScrollX": "100%",//NO MORE REQUIRED - SEE wrap BELOW
//"bScrollCollapse": true,//NO MORE REQUIRED - SEE wrap BELOW
//"bScrollAutoCss": true,//NO MORE REQUIRED - SEE wrap BELOW
"sAjaxSource": "datass.php",
"aoColumns": colf,
"bJQueryUI": true,
"sPaginationType": "two_button",
"bProcessing": true,
"bJQueryUI":true,
"bPaginate": true,
"table-layout": "fixed",
"fnServerData": function(sSource, aoData, fnCallback, oSettings) {
aoData.push({"name": "filters", "value": $.toJSON(getSearchFilters())});//inserisce i filtri
oSettings.jqXHR = $.ajax({
"dataType": 'JSON',
"type": "POST",
"url": sSource,
"data": aoData,
"success": fnCallback
});
},
"fnRowCallback": function(nRow, aData, iDisplayIndex) {
$(nRow).click(function() {
$(".row_selected").removeClass("row_selected");
$(this).addClass("row_selected");
//mostra il detaglio
showDetail(aData.CandidateID);
});
},
"fnDrawCallback": function(oSettings) {
},
"aaSorting": [[1, 'asc']]
}).wrap("<div style='position:relative;overflow:auto;height:400px;'/>"); //correzione per il disallineamento dello header
Use this: Replace your modal name, clear your datatable and load
$('#modalCandidateAssessmentDetail').on('shown.bs.modal', function (e) {
});
from this answer
var table = $('#example').DataTable();
table.columns.adjust().draw();
to
setTimeout(function () {
var table = $('#example').DataTable();
table.columns.adjust().draw();
}, 3000);
to work!!!!
From linking the answer from Mike Ramsey I eventually found that the table was being initialized before the DOM had loaded.
To fix this I put the initialization function in the following location:
document.addEventListener('DOMContentLoaded', function() {
InitTables();
}, false);
See this solution. It can be solved with a window scroll event firing one time only.
I was facing the same issue.
I added the scrollX: true property for the dataTable and it worked.
There is no need to change the CSS for datatable
jQuery('#myTable').DataTable({
"fixedHeader":true,
"scrollY":"450px",
"scrollX":true,
"paging": false,
"ordering": false,
"info": false,
"searching": false,
"scrollCollapse": true
});
I know this is old, but I just ran into the problem and didn't find a great solution. So, I decided on using some js to get the scrollBody's height, as compared to the tables height. If the scrollBody is smaller than the table, then I increase the tables width by 15px to account for the scrollbar. I set this up on resize event too, so that it works when my container changes sizes:
const tableHeight = $('#' + this.options.id).height();
const scrollBodyHeight = $('#' + this.options.id).closest('.dataTables_scrollBody').height();
if (tableHeight > scrollBodyHeight) {
$('#' + this.options.id).closest('.dataTables_scrollBody').css({
width: "calc(100% + 15px)",
})
} else {
$('#' + this.options.id).closest('.dataTables_scrollBody').css({
width: "100%",
})
}
$('.DataTables_sort_wrapper').trigger("click");
Unfortunately, none of those solutions worked for me. Perhaps, due to the difference in the initialization of our tables, we have different results. It might be possible, that one of those solutions would work for someone. Anyways, wanted to share my solution, just in case someone is still troubled with this issue. It is a bit hackish, though, but it works for me, since I don't change the width of the table later.
After I load the page and click on the header, so that it expands and shows normally, I inspect the table header and record the width of the .dataTables_scrollHeadInner div. In my case it is 715px, for example. Then add that width to css:
.dataTables_scrollHeadInner
{
width: 715px !important;
}
My solution was add this:
...
initComplete () {
      this.api (). columns (). header (). each ((el, i) => {
          $ (el) .attr ('style', 'min-width: 160px;')
      });
},
...
and it look fine.
Gyrocode.com answer to problem was totally correct but his solution will not work in all cases. A more general approach is to add the following outside your document.ready function:
$(document).on( 'init.dt', function ( e, settings ) {
var api = new $.fn.dataTable.Api( settings );
window.setTimeout(function () {
api.table().columns.adjust().draw();
},1);
} );
Add fixed width for container table
JS:
otableCorreo = $("#indexTablaEnvios").DataTable({
"fnInitComplete": function (oSettings, json) {
$(otableCorreo.table().container()).addClass("tablaChildren");
},
});
CSS:
.tablaChildren {
width: 97%;
}
I had a similar issue. I would create tables in expandable/collapsible panels. As long as the tables were visible, no problem. But if you collapsed a panel, resized the browser, and then expanded, the problem was there. I fixed it by placing the following in the click function for the panel header, whenever this function expanded the panel:
// recalculate column widths, because they aren't recalculated when the table is hidden'
$('.homeTable').DataTable()
.columns.adjust()
.responsive.recalc();
add to your script in page :
$( window ).resize(function() {
var table = $('#tableId').DataTable();
$('#container').css( 'display', 'block' );
table.columns.adjust().draw();
});
I was using Bootstrap 4, and had added the class table-sm to my table. That messed up the formatting. Removing that class fixed the problem.
If you can't remove that class, I would suspect that adding it via javascript to the headers table would work. Datatables uses two tables to display a table when scrollX is enabled -- one for the header, and one for the body.

Can I dynamically generate & remove content from jQuery Accordion before tab is opened and closed?

I'm using the Accordion control from jQuery UI. The contents of the accordion are generated dynamically from a user's data with JavaScript and then inserted into accordion via the innerHTML property before it is created. This approach works, but has one drawback. Since I'm generating HTML for all tabs the resulting accordion may be somewhat sluggish. For instance, in my example with 256 accordion tabs and some extensive HTML for each tab, it was performing somewhat slow on my older laptop.
So I was curious, for the sake of optimizing performance, is it possible to attach HTML content to the accordion's tab right before it's open? And a second question, can I also remove it right after the tab is closed?
Just to provide more details, my accordion is created as such:
$("#accordion").accordion({
collapsible: true,
heightStyle: "content",
active: nActiveTab
});
Use the beforeActivate and activate methods, as described in the API.
beforeActivate: function (event, ui) {
var el = ui.newPanel[0];
if (el) el.innerHTML = returnContent(el.id); // Opening
},
activate: function (event, ui) {
var el = ui.oldPanel[0];
if (el) el.innerHTML = "" // Closing
}
Working demo: http://jsfiddle.net/ag0gw7cu/

Selecting row in kendo grid when virtualization is enabled

I'm using kendoUI grid widget to display dataset. Because size of dataset is quite large (200-400k) I'm using virtualization feature to improve performance and usability. When setting grid up I have faced with the following problem: because virtualization is enabled, grid DOM objects (i mean table rows here) are refreshed every time when page is changed. That implementation of grid results in the following behavior: I can select row but after scrolling down to next page and scrolling back selection disappears. Here is example where this problem can be reproduced: http://trykendoui.telerik.com/OkOg
Maybe someone has similar problem and can offer some workaround.
You can restore the selection in the grid's dataBound event, e.g. like this (note that this only works for single row selection, so you might need to adapt for other modes):
$("#grid").kendoGrid({
dataSource: dataSource,
change: function () {
this._lastSelectedItem = this.dataItem(this.select());
},
dataBound: function () {
var row;
if (this._lastSelectedItem) {
row = $(this.tbody).find("tr[data-uid='" + this._lastSelectedItem.uid + "']")
if ($(row).length > 0) {
// or this.select(row); if you don't mind the
// change event getting triggered again
$(row).addClass("k-state-selected");
}
}
},
height: 430,
scrollable: {
virtual: true
},
selectable: true,
columns: columns
});

Inconsistent results when loading HTML snippet into select tag

I'm using Ajax to load the contents of a select:
<select id = "idResultEntryMeet" class="form-control input-md" size = 1>
</select>
...
$('#idResultEntryMeet').mousedown(function() {
$.post("/cgi-bin/listOptions", function(data) {
$('#idResultEntryMeet').html(data);
});
});
This isn't consistent across browsers, which makes me think that there's a problem with the code:
IE9 never shows anything in the select
FF 27 works as expected
Chrome and IE11 don't show anything in the pull-down on the first
mouse click, but will show the expected contents on the second mouse
click. I can fix this on both browsers by pre-loading the select
during the initial page load
Opera and Safari require a second mouse click, even with an initial preload
Any suggestions on what's wrong with this?
EDIT
Sorry, guess this wasn't obvious: the select must be dynamic. The options are constantly changing, depending on the contents of a database. The idea is that the user sees the current options when they click the pull-down on the select. Using a click (instead of mousedown) handler doesn't work, since the user can't then actually select anything they see in the pull-down.
And the CGI code returns an HTML snippet, containing the options. Firebug shows a correctly-formed select containing options on completion of the POST.
EDIT
The problem is that the Ajax request has to be synchronous (Sjax?) (as more-or-less suggested in the comments), to prevent interfering with whatever happens when the select pull-down is activated. This code works with proper browsers (and almost works in IE9), but changing async to true causes consistent problems with various browsers:
$('#idResultEntryMeet').mousedown(function() {
$.ajax({
type : "POST",
url : "/cgi-bin/listOptions",
async : false
}).done(function(data, textStatus, jqXHR) {
$('#idResultEntryMeet').html(data);
});
});
Try that (just tested on chrome):
$('#idResultEntryMeet').on('mousedown', function(e){
if(!e.view) return;
e.preventDefault();
var _self = this;
$.post("/cgi-bin/listOptions", function (data) {
$(_self).html(data);
var mdwn = document.createEvent("MouseEvents");
mdwn.initMouseEvent("mousedown", false, false, null, 0, 0, 0, 0, 0, true, false, false, true, 0, null);
_self.dispatchEvent(mdwn);
});
});
Simplified DEMO
EDIT: doesn't work on FF nor IE...
Try change your code for:
html
<select id="idResultEntryMeet" class="form-control input-md" size="1">
</select>
js
$(document).ready(function() {
$.post("/cgi-bin/listOptions", function(data) {
$('#idResultEntryMeet').html(data);
});
});
$('#idResultEntryMeet').change(function() {
var valueSelected = $(this).val();
alert(valueSelected);
//Do something
});
Edit:
you need include the delegate bind with jquery for do this dinamic.
$('#idResultEntryMeet').bind("click", function() {
var data = '<option value="volvo">Volvo</option><option value="saab">Saab</option>';
$('#idResultEntryMeet').html(data);
});
And need format the return of the method some like this

DataTables & X-Editable making out of focus items editable

I have a working setup for data-tables and x-editable that allows a user to edit data inline in a table that gets loaded from the database. Once the page loads my code below fires and makes all the editable options editable, except it only seems to work for the first page of results. When you click next, change the number of results or do a search, any items that were not on the first page don't get made editable. I am assuming this is because data-tables hides the data that is not on the current page removing it from the document flow. How can I make sure all my data in the table is editable?
$(document).ready(function () {
$.fn.editable.defaults.mode = 'inline';
$('.LocatorID').editable();
$('.Title').editable();
$('.Latitude').editable();
$('.Longitude').editable();
$('.Website').editable();
$('.Address').editable();
$('.City').editable();
$('.State').editable();
$('.Zip').editable();
$('.Country').editable();
$('.Phone').editable();
});
First, move your x-editable setup into its own function:
function setupXedit() {
$.fn.editable.defaults.mode = 'inline';
$('.LocatorID').editable();
$('.Title').editable();
...
}
Then set so that you call the function on every draw:
$('#example').dataTable({
"fnDrawCallback": function( oSettings ) {
setupXedit();
}
});
Do like this: one $('.edit').editable(); inside Datatable fnDrawCallback and one outside .Datatable function
var table = $('#tbldivdsthietlap').DataTable({
"fnDrawCallback": function( oSettings ) {
$('.edit').editable();
}
});
$('.edit').editable();

Categories