I am trying to create a live crypto currency price chart with jQuery, Javascript, Ajax and Websocket. Datatable is using for sorting purpose. Live crypto currency price is always appearing in <input>. It will always work outside of the datatable <table>. But if I put <input> in the datatable <table>, live price is not appearing. I searched in google and found the solution. DOM function needed to getting live number value in datatable <input>. I am using this https://datatables.net/examples/advanced_init/stocks.html datatable for my project. I got DOM javascript code from https://datatables.net/examples/plug-ins/dom_sort.html for live DOM number sorting.
<script type="">
$.fn.dataTable.ext.order['dom-text-numeric'] = function (settings, col) {
return this.api()
.column(col, { order: 'index' })
.nodes()
.map(function (td, i) {
return $('input', td).val() * 1;
});
};
$(document).ready(function () {
$('#example').DataTable({
columns: [
{ orderDataType: 'dom-text-numeric' },
],
});
});
</script>
These are the javascript code for live DOM soring. I don't know how/where put this codes in my Ajax javascript file.
In the ajax javascript fie, I added,
return type === 'display' ?
'<input type="text" id="btc-price" value="">' :
val;
So <input> is appearing in web page without live crypto price. I think DOM is missed in this datatable.
I tried many times. But all my efforts was failure.. Codepen preview: https://codepen.io/themecode/pen/VwxPOpJ Please help me..
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"></script>
</head>
<body>
<!-- **************************************** -->
<table id="example" class="display nowrap" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Symbol</th>
<th>Price</th>
<th>Chnge</th>
<th>Last</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Symbol</th>
<th>Price</th>
<th>Chnge</th>
<th>Last</th>
</tr>
</tfoot>
</table>
<!-- **************************************** -->
<input type="text" id="btc-price" value="">
<input type="text" id="ltc-price" value="">
<!-- **************************************** -->
<script type="text/javascript">
const streams = {
'btcusdt@trade': { name: 'btc', input: document.getElementById('btc-price') },
'ltcusdt@trade': { name: 'ltc', input: document.getElementById('ltc-price') },
};
const streamParams = Object.entries(streams).map(([streamId]) => streamId).join(`/`);
const streamUrl = `wss://stream.binance.com:9443/stream?streams=${streamParams}`;
const wss = new WebSocket(streamUrl);
wss.onmessage = (event) => {
const eventData = JSON.parse(event.data);
const streamId = eventData.stream;
const latestPrice = Number.parseFloat(eventData.data.p);
const lastPrice = streams[streamId].lastPrice || latestPrice;
// compare latest and last prices
const inputClass = latestPrice > lastPrice
? 'inc'
: latestPrice < lastPrice ?
'dec' : '';
// update relevant input with value
const input = streams[streamId].input;
// remove any existing classes
input.classList.remove('inc','dec');
// add inc/dec class only
if (inputClass)
input.classList.add(inputClass);
// set input value
input.value = latestPrice.toFixed(2);
// save the latest price for this coin.
streams[streamId].lastPrice = latestPrice;
// Call calculators.change() here - I can't actually add it because it will break the snippet.
// calculators.change;
};
</script>
<script type="text/javascript">
$(document).ready(function() {
var stock_data = [
{
"name": "ACME Gadgetsrrrrrrr",
"symbol": "AGDTS",
"last": [2, 9, 14, 18, 23, 27, 39]
},
{
"name": "Spry Media Productions",
"symbol": "SPMP",
"last": [1.12, 1.11, 1.08, 1.08, 1.09, 1.11, 1.08]
},
{
"name": "Widget Emporium",
"symbol": "WDEMP",
"last": [3.40, 3.39, 3.46, 3.51, 3.50, 3.48, 3.49]
},
{
"name": "Sole Goodman",
"symbol": "SGMAN",
"last": [16.20, 16.40, 16.36, 16.35, 16.61, 16.46, 16.19]
},
{
"name": "Stanler Bits and Bobs",
"symbol": "SBIBO",
"last": [82.51, 83.47, 83.40, 83.68, 83.81, 83.29, 83.72]
}
];
let table = $('#example').DataTable({
ajax: function(dataSent, callback, settings) {
let data = this.api().ajax.json();
if(data == undefined) {
data = stock_data; // ======================= data = stock_data;
} else {
data = data.data;
for(i = 0; i < data.length; i++) {
data[i].last.push(data[i].last.shift())
}
}
callback({data: data});
},
paging: false,
initComplete: function() {
let api = this.api();
setInterval(function() {
api.ajax.reload();
}, 3000);
},
drawCallback: function() {
$('.sparkline')
.map(function() {
return $('canvas', this).length ? null : this;
})
.sparkline('html', {
type: 'line',
width: '250px'
})
},
columns: [
// ## 01 // Price
{
data: null, // Price
render: function(data, type, row, meta) {
return row.last[row.last.length - 1].toFixed(2);
}
},
// ## 02 // Difference
{
data: null, // Difference
render: function(data, type, row, meta) {
var val = (row.last[row.last.length - 1] - row.last[row.last.length - 2]).toFixed(2);
var colour = val < 0 ? 'red' : 'green'
return type === 'display' ?
'<input type="text" id="btc-price" value="">' :
val;
}
},
// ## 03 // Price
{
data: null, // Price
render: function(data, type, row, meta) {
return row.last[row.last.length - 1].toFixed(2);
}
},
// ## 04 // Difference
{
data: null, // Difference
render: function(data, type, row, meta) {
var val = (row.last[row.last.length - 1] - row.last[row.last.length - 2]).toFixed(2);
var colour = val < 0 ? 'red' : 'green'
return type === 'display' ?
'<span style="color:' + colour + '">' + val + '</span>' :
val;
}
},
// ## 05 // Price
{
data: null, // Price
render: function(data, type, row, meta) {
return row.last[row.last.length - 1].toFixed(2);
}
}
]
});
});
</script>