I am trying render the plotly.js graph,
For some reason though, the traces.push(this.getTrace(val, calAdjustData)) part seems to be overwriting previous data in the traces array, For every iteration it is returns single value, but finally last value is overwriting all previous values.
destArray.forEach(val=> {
traces.push(this.getTrace(val, calAdjustData));
});
getTrace() function is
getTrace(trace:any, data:any) {
let appConfig: any = [];
appConfig['TABLES'] = {
'R_FORMAT': ',d',
'MONTH_BEGIN_DATE_KEY': 'MONTH_BEGIN_DT',
'CAST_KEYS': [
'DOLLARS_ACTUAL', 'DOLLARS_FORECAST', 'DOLLARS_CALC_FORECAST',
'PY_DOLLARS_ACTUAL', 'PY_DOLLARS_FORECAST', 'PY_DOLLARS_CALC_FORECAST',
'DOLLARS_SUBMITTED', 'PY_DOLLARS_SUBMITTED',
'DOLLARS_ADJ', 'PY_DOLLARS_ADJ',
'DOLLARS_BUDGET', 'NEWNESS_FLAG'
]
};
var traceTmpl:any = Object.assign(this.graphConfig.graphSettings.traceTmpl);
if ("color" in trace) traceTmpl.line.color = trace.color;
if ("dash" in trace) traceTmpl.line.dash = trace.dash;
//traceTmpl.visible = "legendonly";
if ( trace[ "legendgroup" ] ) traceTmpl.legendgroup = trace.legendgroup;
// Compile the trace name for legened and display
traceTmpl.name = trace.label.replace("{type}", this.graphConfig.display.typeLabelMap[this.displaySettings.type]);
traceTmpl.label = trace.label;
if (!(localStorage['legendItems'] =='')) {
let tempArray = JSON.parse(localStorage['legendItems']).filter((x:any)=>x.name.replace("{type}",this.graphConfig.display.typeLabelMap[this.displaySettings.type]) == traceTmpl.name);
if(tempArray && tempArray.length){
traceTmpl.visible = "legendonly"
}
}
// Compile the field name to pluck out of the data array
var field = trace.field.replace("{cal}", this.displaySettings.cal).replace("{type}", this.displaySettings.type);
// Prepare the trace data
traceTmpl.x = _.map(data, appConfig.TABLES.MONTH_BEGIN_DATE_KEY );
traceTmpl.y = _.map(data, field);
// todo: refactor into a function
var tempDate = new Date();
var currentDate = this.getDate( this.displaySettings.currentMonth || [ tempDate.getUTCFullYear(), ( tempDate.getUTCMonth() > 8 ? '':'0' ) + ( tempDate.getUTCMonth() + 1 ), '01' ].join('-') );
if( trace.name.endsWith('actuals') || trace.name.endsWith('actuals_LY') ){
var lastIdx = -1;
traceTmpl.y.forEach( function( val:any, idx:any ) {
if ( val !== 0 ) lastIdx = idx;
} );
for ( let idx = lastIdx + 1; idx < traceTmpl.y.length; ++idx ) traceTmpl.y[ idx ] = void 0;
} else if ( trace.name.endsWith('work_plan')){
var firstIdx = -1;
traceTmpl.y.forEach((val : any, idx :any) => {
var monthCheck = this.getDate( data[idx][ appConfig.TABLES.MONTH_BEGIN_DATE_KEY ] ).getMonth() > currentDate.getMonth();
var yearCheck = this.getDate( data[idx][ appConfig.TABLES.MONTH_BEGIN_DATE_KEY ] ).getUTCFullYear() >= currentDate.getUTCFullYear();
if ( val !== 0 && firstIdx === -1 && ( ( yearCheck && monthCheck ) || this.getDate( data[idx][ appConfig.TABLES.MONTH_BEGIN_DATE_KEY ] ).getUTCFullYear() > currentDate.getUTCFullYear() ) ) {
firstIdx = idx;
}
})
if ( firstIdx !== -1 ){
for ( let idx = 0; idx < firstIdx; ++idx ) traceTmpl.y[idx] = void 0;
}
if ( firstIdx > 0 && trace.altField ){
var altField = trace.altField.replace("{cal}", this.displaySettings.cal).replace("{type}", this.displaySettings.type);
traceTmpl.y[ firstIdx - 1 ] = data[ firstIdx - 1 ][ altField ];
}
} else if ( trace.name == "inventory.forecast" ){
traceTmpl.y.forEach( function ( val:any, idx:any, array:any ) {
if ( val ){
array[ idx ] = val > 0 ? val:0;
}
} );
}
//convert to K dollars as plotly doesn't support that format
//Convert from string to numbers (temporary as DB2 returning strings for some reason) and then convert to K dollars or Units
var denominator = 1000; // K Dollars
if (this.displaySettings.type === "UNITS") denominator = 1;
for (let i in traceTmpl.y) traceTmpl.y[i] = ((+traceTmpl.y[i]) / denominator);
var formatter = d3.format( ( this.displaySettings.type === "DOLLARS" ? '$':'' ) + appConfig.TABLES.R_FORMAT );
traceTmpl.text = traceTmpl.y.map( function ( d:any ){
} );
traceTmpl.text = traceTmpl.y.map((d : any) => {
if ( d || d === 0 ){
return formatter( Math.ceil( d ) );
}else{
return undefined;
}
});
return traceTmpl;
};
Please suggest any solution for this issue, already few similar questions here, but nothing worked for me.
I'm using a Vue Js cryptocurrency chart which displays the latest prices of a list of cryptocurrencies, the problem is that there are a lot of icons links that are broken, but it's not like I can fix them individually, they're all retrieved from a github iconbase. Is there any way I can fix that or at least set a default "No image" icon to show up where there's no icon?
Part responsible for retrieving the icons:
// vue instance
new Vue({
// mount point
el: '#app',
// app data
data: {
endpoint : 'wss://stream.binance.com:9443/ws/!ticker#arr',
iconbase : 'https://raw.githubusercontent.com/rainner/binance-watch/master/public/images/icons/',
cache : {}, // coins data cache
coins : [], // live coin list from api
asset : 'USDT', // filter by base asset pair
search : '', // filter by search string
sort : 'assetVolume', // sort by param
order : 'desc', // sort order ( asc, desc )
limit : 50, // limit list
status : 0, // socket status ( 0: closed, 1: open, 2: active, -1: error )
sock : null, // socket inst
cx : 0,
cy : 0,
},
My full Js:
// common number filters
Vue.filter( 'toFixed', ( num, asset ) => {
if ( typeof asset === 'number' ) return Number( num ).toFixed( asset );
return Number( num ).toFixed( ( asset === 'USDT' ) ? 3 : 8 );
});
Vue.filter( 'toMoney', num => {
return Number( num ).toFixed( 0 ).replace( /./g, ( c, i, a ) => {
return i && c !== "." && ( ( a.length - i ) % 3 === 0 ) ? ',' + c : c;
});
});
// component for creating line chart
Vue.component( 'linechart', {
props: {
width: { type: Number, default: 400, required: true },
height: { type: Number, default: 40, required: true },
values: { type: Array, default: [], required: true },
},
data() {
return { cx: 0, cy: 0 };
},
computed: {
viewBox() {
return '0 0 '+ this.width +' '+ this.height;
},
chartPoints() {
let data = this.getPoints();
let last = data.length ? data[ data.length - 1 ] : { x: 0, y: 0 };
let list = data.map( d => ( d.x - 10 ) +','+ d.y );
this.cx = last.x - 5;
this.cy = last.y;
return list.join( ' ' );
},
},
methods: {
getPoints() {
this.width = parseFloat( this.width ) || 0;
this.height = parseFloat( this.height ) || 0;
let min = this.values.reduce( ( min, val ) => val < min ? val : min, this.values[ 0 ] );
let max = this.values.reduce( ( max, val ) => val > max ? val : max, this.values[ 0 ] );
let len = this.values.length;
let half = this.height / 2;
let range = ( max > min ) ? ( max - min ) : this.height;
let gap = ( len > 1 ) ? ( this.width / ( len - 1 ) ) : 1;
let points = [];
for ( let i = 0; i < len; ++i ) {
let d = this.values[ i ];
let val = 2 * ( ( d - min ) / range - 0.5 );
let x = i * gap;
let y = -val * half * 0.8 + half;
points.push( { x, y } );
}
return points;
}
},
template: `
<svg :viewBox="viewBox" xmlns="http://www.w3.org/2000/svg">
<polyline class="cryptocolor" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" :points="chartPoints" />
<circle class="cryptocolor" :cx="cx" :cy="cy" r="4" fill="#fff" stroke="none" />
</svg>`,
});
// vue instance
new Vue({
// mount point
el: '#app',
// app data
data: {
endpoint : 'wss://stream.binance.com:9443/ws/!ticker#arr',
iconbase : 'https://raw.githubusercontent.com/rainner/binance-watch/master/public/images/icons/',
cache : {}, // coins data cache
coins : [], // live coin list from api
asset : 'USDT', // filter by base asset pair
search : '', // filter by search string
sort : 'assetVolume', // sort by param
order : 'desc', // sort order ( asc, desc )
limit : 50, // limit list
status : 0, // socket status ( 0: closed, 1: open, 2: active, -1: error )
sock : null, // socket inst
cx : 0,
cy : 0,
},
// computed methods
computed: {
// process coins list
coinsList() {
let list = this.coins.slice();
let search = this.search.replace( /[^\s\w\-\.]+/g, '' ).replace( /[\r\s\t\n]+/g, ' ' ).trim();
if ( this.asset ) {
list = list.filter( i => i.asset === this.asset );
}
if ( search && search.length > 1 ) {
let reg = new RegExp( '^('+ search +')', 'i' );
list = list.filter( i => reg.test( i.token ) );
}
if ( this.sort ) {
list = this.sortList( list, this.sort, this.order );
}
if ( this.limit ) {
list = list.slice( 0, this.limit );
}
return list;
},
// show socket connection loader
loaderVisible() {
return ( this.status === 2 ) ? false : true;
},
// sort-by label for buttons, etc
sortLabel() {
switch ( this.sort ) {
case 'token' : return 'Token';
case 'percent' : return 'Percent';
case 'close' : return 'Price';
case 'change' : return 'Change';
case 'assetVolume' : return 'Volume';
case 'tokenVolume' : return 'Volume';
case 'trades' : return 'Trades';
default : return 'Default';
}
},
},
// custom methods
methods: {
// apply sorting and toggle order
sortBy( key, order ) {
if ( this.sort !== key ) { this.order = order || 'asc'; }
else { this.order = ( this.order === 'asc' ) ? 'desc' : 'asc'; }
this.sort = key;
},
// filter by asset
filterAsset( asset ) {
this.asset = String( asset || 'BTC' );
},
// set list limit
setLimit( limit ) {
this.limit = parseInt( limit ) || 0;
},
// on socket connected
onSockOpen( e ) {
this.status = 1; // open
console.info( 'WebSocketInfo:', 'Connection open ('+ this.endpoint +').' );
},
// on socket closed
onSockClose( e ) {
this.status = 0; // closed
console.info( 'WebSocketInfo:', 'Connection closed ('+ this.endpoint +').' );
setTimeout( this.sockInit, 10000 ); // try again
},
// on socket error
onSockError( err ) {
this.status = -1; // error
console.error( 'WebSocketError:', err.message || err );
setTimeout( this.sockInit, 10000 ); // try again
},
// process data from socket
onSockData( e ) {
let list = JSON.parse( e.data ) || [];
for ( let item of list ) {
// cleanup data for each coin
let c = this.getCoinData( item );
// keep to up 100 previous close prices in hostiry for each coin
c.history = this.cache.hasOwnProperty( c.symbol ) ? this.cache[ c.symbol ].history : this.fakeHistory( c.close );
if ( c.history.length > 100 ) c.history = c.history.slice( c.history.length - 100 );
c.history.push( c.close );
// add coin data to cache
this.cache[ c.symbol ] = c;
}
// convert cache object to final prices list for each symbol
this.coins = Object.keys( this.cache ).map( s => this.cache[ s ] );
this.status = 2; // active
},
// start socket connection
sockInit() {
if ( this.status > 0 ) return;
try {
this.status = 0; // closed
this.sock = new WebSocket( this.endpoint );
this.sock.addEventListener( 'open', this.onSockOpen );
this.sock.addEventListener( 'close', this.onSockClose );
this.sock.addEventListener( 'error', this.onSockError );
this.sock.addEventListener( 'message', this.onSockData );
}
catch( err ) {
console.error( 'WebSocketError:', err.message || err );
this.status = -1; // error
this.sock = null;
}
},
// start socket connection
sockClose() {
if ( this.sock ) {
this.sock.close();
}
},
// come up with some fake history prices to fill in the initial line chart
fakeHistory( close ) {
let num = close * 0.0001; // faction of current price
let min = -Math.abs( num );
let max = Math.abs( num );
let out = [];
for ( let i = 0; i < 50; ++i ) {
let rand = Math.random() * ( max - min ) + min;
out.push( close + rand );
}
return out;
},
// finalize data for each coin from socket
getCoinData( item ) {
let reg = /^([A-Z]+)(BTC|ETH|BNB|USDT|TUSD)$/;
let symbol = String( item.s ).replace( /[^\w\-]+/g, '' ).toUpperCase();
let token = symbol.replace( reg, '$1' );
let asset = symbol.replace( reg, '$2' );
let name = token;
let pair = token +'/'+ asset;
let icon = this.iconbase + token.toLowerCase() + '_.png';
let open = parseFloat( item.o );
let high = parseFloat( item.h );
let low = parseFloat( item.l );
let close = parseFloat( item.c );
let change = parseFloat( item.p );
let percent = parseFloat( item.P );
let trades = parseInt( item.n );
let tokenVolume = Math.round( item.v );
let assetVolume = Math.round( item.q );
let sign = ( percent >= 0 ) ? '+' : '';
let arrow = ( percent >= 0 ) ? '▲' : '▼';
let info = [ pair, close.toFixed( 8 ), '(', arrow, sign + percent.toFixed( 2 ) +'%', '|', sign + change.toFixed( 8 ), ')' ].join( ' ' );
let style = '';
if ( percent > 0 ) style = 'gain';
if ( percent < 0 ) style = 'loss';
return { symbol, token, asset, name, pair, icon, open, high, low, close, change, percent, trades, tokenVolume, assetVolume, sign, arrow, style, info };
},
// sort an array by key and order
sortList( list, key, order ) {
return list.sort( ( a, b ) => {
let _a = a[ key ];
let _b = b[ key ];
if ( _a && _b ) {
_a = ( typeof _a === 'string' ) ? _a.toUpperCase() : _a;
_b = ( typeof _b === 'string' ) ? _b.toUpperCase() : _b;
if ( order === 'asc' ) {
if ( _a < _b ) return -1;
if ( _a > _b ) return 1;
}
if ( order === 'desc' ) {
if ( _a > _b ) return -1;
if ( _a < _b ) return 1;
}
}
return 0;
});
},
},
// app mounted
mounted() {
this.sockInit();
},
// app destroyed
destroyed() {
this.sockClose();
}
});
Js Fiddle:
https://jsfiddle.net/g5mhe923/1/
My version is from this modification:
https://codepen.io/rainner/pen/bjJYjp
Original source code:
https://github.com/rainner/binance-watch
Js files from the updated version:
https://rainner.github.io/binance-watch/public/bundles/app.min.js
https://rainner.github.io/binance-watch/public/js/crypto-js.min.js
Original demo:
https://rainner.github.io/binance-watch/
Can anyone tell me where I can find a reference to this part?
I couldn't find any reference to this part too:
// app data
data: {
endpoint : 'wss://stream.binance.com:9443/ws/!ticker#arr',
iconbase : 'https://raw.githubusercontent.com/rainner/binance-watch/master/public/images/icons/',
I know 2 tricks for broken link images:
The first is to hide the images with broken link:
<img :src="c.icon" :alt="c.pair" onerror="this.style.display='none'"/>
The second is to use a default image from your choice and display it in case the image link is broken. Like the following where I took one of your images as a default image
<img :src="c.icon" :alt="c.pair" onerror="this.src='https://raw.githubusercontent.com/rainner/binance-watch/master/public/images/icons/xtz_.png'" />
Here is a Demo
Alright... My HTML looks like this:
<div id="_content"></div>
And then, there is a method like this:
Main.LoadContent(source, target)
{
var reader = new FileReader();
var s = '';
reader.onload = function()
{
s = reader.result;
var t = $(target).html;
alert(t);
t.html = s;
}
var f = new File([""], source);
reader.readAsText(f);
}
Mind the 'alert(t)' line, it returns:
function ( value ) {
return access( this, function( value ) {
var elem = this[ 0 ] || {},
i = 0,
l = this.length;
if ( value === undefined ) {
return elem.nodeType === 1 ?
elem.innerHTML.replace( rinlinejQuery, "" ) :
undefined;
}
// See if we can take a shortcut and just use innerHTML
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
!wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
value = value.replace( rxhtmlTag, "<$1></$2>" );
try {
for (; i < l; i++ ) {
// Remove element nodes and prevent memory leaks
elem = this[i] || {};
if ( elem.nodeType === 1 ) {
jQuery.cleanData( getAll( elem, false ) );
elem.innerHTML = value;
}
}
elem = 0;
// If using innerHTML throws an exception, use the fallback method
} catch(e) {}
}
if ( elem ) {
this.empty().append( value );
}
}, null, value, arguments.length );
}
The call to Main.LoadContent looks like this:
Main.LoadContent('start.htf', '#_content');
What's my sublime stupidity come to here...???
HTML is a function... put the s variable inside of the function to set the HTML... see what that gets you. Example:
Main.LoadContent(source, target)
{
var reader = new FileReader();
var s = '';
reader.onload = function()
{
s = reader.result;
var t = $(target).html();
alert(t);
//t.html(s);
$(target).html(s);
}
var f = new File([""], source);
reader.readAsText(f);
}
I am trying to perform two distinct formatting operations on a datatable object using the DT and magrittr packages. One uses the helper function formatRound() and the other is passed in as JavaScript to a rowCallback option in the datatable function.
When I run either of the formatting operations individually the datatable renders with the expected formatting. However, when I run both together the datatable renders blank but I do not get an error.
This code shows the behavior I am describing.
library(magrittr)
library(DT)
df = data.frame(matrix(rnorm(20), nrow=10))
datatable(
data = df
) %>%
formatRound(c("X1", "X2"), 1)
#table renders as expected
datatable(
data = df,
options = list(
rowCallback = JS("
function( row, data, index ) {
if ( index > 2 ) {
$(row).css('background-color', '#EDEDED');
}
else if ( index > 0 ) {
$(row).css('background-color', '#DEDEDE');
}
else {
$(row).css('background-color', '#D3D3D3');
}
}"
)
)
)
#table renders as expected
datatable(
data = df,
options = list(
rowCallback = JS("
function( row, data, index ) {
if ( index > 2 ) {
$(row).css('background-color', '#EDEDED');
}
else if ( index > 0 ) {
$(row).css('background-color', '#DEDEDE');
}
else {
$(row).css('background-color', '#D3D3D3');
}
}"
)
)
) %>%
formatRound(c("X1", "X2"), 1)
#table renders as blank but with no error returned
If you have a look at the JS function of your third attempt in the browser's JS console(click on "Inspect Element option in browser"), it shows up an error saying that 'var' is unidentified because it is outside the scope of the JS function:
(
var d = parseFloat(data[1]); $(this.api().cell(row, 1).node()).html(isNaN(d) ? '' : d.toFixed(1));
var d = parseFloat(data[2]); $(this.api().cell(row, 2).node()).html(isNaN(d) ? '' : d.toFixed(1));
function( row, data, index ) {
if ( index > 2 ) {
$(row).css('background-color', '#EDEDED');
}
else if ( index > 0 ) {
$(row).css('background-color', '#DEDEDE');
}
else {
$(row).css('background-color', '#D3D3D3');
}
})
If you put those two lines inside the JS function, it works perfectly.
You can find the updated code below.
datatable(
data = df,
options = list(
rowCallback = JS("
function( row, data, index ) {
var d = parseFloat(data[1]);
$(this.api().cell(row, 1).node()).html(isNaN(d) ? '' : d.toFixed(1));
var d = parseFloat(data[2]);
$(this.api().cell(row, 2).node()).html(isNaN(d) ? '' : d.toFixed(1));
if ( index > 2 ) {
$(row).css('background-color', '#EDEDED');
}
else if ( index > 0 ) {
$(row).css('background-color', '#DEDEDE');
}
else {
$(row).css('background-color', '#D3D3D3');
}
}"
)
)
)
I am trying to Place the ColumnFilterWidget plugin in the Header of the Datatables Table.
Here are the changes i made in it :
/**
* Menu-based filter widgets based on distinct column values for a table.
*
* #class ColumnFilterWidgets
* #constructor
* #param {object} oDataTableSettings Settings for the target table.
*/
var ColumnFilterWidgets = function( oDataTableSettings ) {
var me = this;
var sExcludeList = '';
// me.$WidgetContainer = $( '<div class="column-filter-widgets"></div>' );
me.$WidgetContainer = $( '<tr class="head"></tr>' );
me.$MenuContainer = me.$WidgetContainer;
me.$TermContainer = null;
me.aoWidgets = [];
me.sSeparator = '';
if ( 'oColumnFilterWidgets' in oDataTableSettings.oInit ) {
if ( 'aiExclude' in oDataTableSettings.oInit.oColumnFilterWidgets ) {
sExcludeList = '|' + oDataTableSettings.oInit.oColumnFilterWidgets.aiExclude.join( '|' ) + '|';
}
if ( 'bGroupTerms' in oDataTableSettings.oInit.oColumnFilterWidgets && oDataTableSettings.oInit.oColumnFilterWidgets.bGroupTerms ) {
me.$MenuContainer = $( '<div class="column-filter-widget-menus"></div>' );
me.$TermContainer = $( '<div class="column-filter-widget-selected-terms"></div>' ).hide();
}
}
// Add a widget for each visible and filtered column
$.each( oDataTableSettings.aoColumns, function ( i, oColumn ) {
var $columnTh = $( oColumn.nTh );
var $WidgetElem = $( '<th><div class="column-filter-widget"></div></th>' );
if ( oColumn.bVisible && sExcludeList.indexOf( '|' + i + '|' ) < 0 ) {
me.aoWidgets.push( new ColumnFilterWidget( $WidgetElem, oDataTableSettings, i, me ) );
}
me.$MenuContainer.append( $WidgetElem );
} );
if ( me.$TermContainer ) {
me.$WidgetContainer.append( me.$MenuContainer );
me.$WidgetContainer.append( me.$TermContainer );
}
oDataTableSettings.aoDrawCallback.push( {
name: 'ColumnFilterWidgets',
fn: function() {
$.each( me.aoWidgets, function( i, oWidget ) {
oWidget.fnDraw();
} );
}
} );
return me;
};
I added a extra <tr class='head'> inside the Datatable, and later on i am trying to append the Filters to that with attached to them,But instead of that it is creating new TR tag and then appending the filters in it.
I even changed my dom of data tables to : dom: '<"clear">Cf<"clear">ltWrip',
So the table elements should be there so that it can insert filters inside the head.
FOUND THE ANSWER
Here is it if anyone else needs it .
Add a <TR id='Filter.$i'> element in the html
Use a for loop and append the counter value to the ID.
then modified the column.filterwidget plugn js
var ColumnFilterWidgets = function( oDataTableSettings ) {
var me = this;
var sExcludeList = '';
me.$WidgetContainer = $( '<div class="column-filter-widgets"></div>' );
me.$MenuContainer = me.$WidgetContainer;
me.$TermContainer = null;
me.aoWidgets = [];
me.sSeparator = '';
if ( 'oColumnFilterWidgets' in oDataTableSettings.oInit ) {
if ( 'aiExclude' in oDataTableSettings.oInit.oColumnFilterWidgets ) {
sExcludeList = '|' + oDataTableSettings.oInit.oColumnFilterWidgets.aiExclude.join( '|' ) + '|';
}
if ( 'bGroupTerms' in oDataTableSettings.oInit.oColumnFilterWidgets && oDataTableSettings.oInit.oColumnFilterWidgets.bGroupTerms ) {
me.$MenuContainer = $( '<div class="column-filter-widget-menus"></div>' );
me.$MenuContainer = $( '<div class="column-filter-widget-menus"></div>' );
me.$TermContainer = $( '<div class="column-filter-widget-selected-terms"></div>' ).hide();
}
}
var cnt= 0;
// Add a widget for each visible and filtered column
$.each( oDataTableSettings.aoColumns, function ( i, oColumn ) {
var $columnTh = $( oColumn.nTh );
cnt ++;
var $WidgetElem = $( '<div class="column-filter-widget" id=col'+cnt+'></div>' );
if ( oColumn.bVisible && sExcludeList.indexOf( '|' + i + '|' ) < 0 ) {
me.aoWidgets.push( new ColumnFilterWidget( $WidgetElem, oDataTableSettings, i, me ) );
}
var Tcol = document.getElementById('A');
console.log('---------'+i);
//me.$MenuContainer.append( $WidgetElem );
$('#Filter'+i).append( $WidgetElem );
} );
if ( me.$TermContainer ) {
me.$WidgetContainer.append( me.$MenuContainer );
me.$WidgetContainer.append( me.$TermContainer );
}
oDataTableSettings.aoDrawCallback.push( {
name: 'ColumnFilterWidgets',
fn: function() {
$.each( me.aoWidgets, function( i, oWidget ) {
oWidget.fnDraw();
} );
}
} );
return me;
};
Hope this helps.