How to redraw a Datatable before injecting values via JavaScript - datatables

I would like to have a table to keep a history of the uploaded files
Here is a dummy example of what I did so far
Whenever I update the table injecting some values via JS, the row with the text No data available in table still appears.
I've tried the solutions provided in other questions but none of them worked for me
Any help would be appreciated

This happens because your datatable object is unaware of the changes that were made in DOM. You need to use the datatables rows.add() api instead of appending <tr><td> to your table.
Please modify your javascript as below. Notice the use of DT1.row.add inside your $.each instead of $('#nameBody').append :
$(document).ready(function() {
$('#fileholder').change(function(e){
var files = $('#fileholder').prop("files")
var names = $.map(files, function(val) { return val.name; });
var modDates = $.map(files, function(val) { return val.lastModifiedDate; });
$.each(names, function(index){
DT1.row.add([names[index], modDates[index]]).draw();
});
});
var DT1 = $('#names').DataTable({
columnDefs: [
{ className: 'text-center', targets: [1] },
],
order: [
[1, 'asc']
],
dom: 'rt'
});
});

Related

Datatable export generic data outside table

I'm trying to add aditional rows during exportation(plz, see attached image), i don't find the right way to do it, please someone tell me whether or not its possible, since many reports carry parent data that not necesarily appears inside the table. I need the Pdf output with the same format. I'm using yajra datatables for laravel.
buttons :[
{
extend: 'pdfHtml5',
pageSize: 'letter',
title: "Informe Asistencia",
exportOptions: {
columns: [0,1,2,3,4,5,6,7,8,9,10 ]
}
},
['excel','csv','colvis']
],
calling the function and drawing table
$.get('{{ url("informes/get_informe_asistencia") }}',
{
'fecha_inicio': fecha_inicio,
'fecha_fin' : fecha_fin,
'numero' : numero
},function(resp){
console.log(resp);
$('.desde').append(fecha_inicio);
$('.hasta').append(fecha_fin);
$('.nombre').append(resp.informe[1].nombre);
$('.ficha').append(resp.informe[1].numero);
dtinforme.clear().draw();
dtinforme.rows.add(resp.informe).draw();
}
missing data
you can export manually.
text: 'PDF',//title
titleAttr: 'Exportar PDF',
exportOptions: {
...
},
action: function (e, dt, node, config) {
var table = this;
dt.clear().draw();
dt.rows.add("YOUR DATA").draw();
$.fn.dataTable.ext.buttons.pdfHtml5.action.call(table, e, dt, node, config);
}
So you need modify your data from with dt.rows().data().toArray(),dt.settings().init().columns.

grid.startup() not working for different data in the Dojo data grid

Below I have pasted a function to show the data in the datagrid based on the function call shownames('a'). DataGrid is not refreshing for different characters like shownames('b')...and so on . Or, How do I change the data in the datagrid without destroying the grid completely ?
function shownames(chr) {
require([
"dojox/grid/EnhancedGrid",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/_base/xhr",
"dojo/domReady!"
], function(DataGrid, Memory, ObjectStore, xhr){
var grid, dataStore;
xhr.get({
url: "http://localhost/xampp/namedb.php?name_idx="+chr,
handleAs: "json"
}).then(function(data){
dataStore = new ObjectStore({ objectStore:new Memory({ data: data.items }) });
if(dijit.byId("namegrid")) {
grid.destroy();
} else {
grid = new dojox.grid.EnhancedGrid({
id: "namegrid",
store: dataStore,
query: { name_id: "*" },
queryOptions: {},
structure: [
{ name: "Name", field: "name", width: "25%" },
{ name: "Actual Meaning", field: "meaning", width: "50%" },
{ name: "name_id", field : "name_id", hidden: true }
]
}, "alphanames");
grid.startup();
}
/*
dojo.connect(grid, "onRowClick", grid, function(evt){
var idx = evt.rowIndex,
item = this.getItem(idx);
// get the ID attr of the selected row
var value = this.store.getValue(item, "country_name");
});
*/
});
});
}
Thanks,
Raja
you should not refresh the grid the way you posted it !
First you need to initialize a grid at startup. So the grid shows you some data. Dont create a grid each time !!!! AFTER that your function has to communicate with the grid by using it's methods !
I constantly use this bulk to refresh the grid:
var grid= // CREATE GRID IN HERE
function yourFunction(id) {
var prepareQuery={};
prepareQuery["name_id"]=id; // Create a query based on id
grid._pending_requests={}; // Stop everything thats loading
grid._setQuery(prepareQuery); // Pass query to the grid
grid._refresh(true); // Refresh grid
}
It may also work with your code, but you may have to do some adaptions.

Nested grid in ExtJS 4.1 using Row Expander

On the front-end I have a Calls grid. Each Call may have one or more Notes associated with it, so I want to add the ability to drill down into each Calls grid row and display related Notes.
On the back-end I am using Ruby on Rails, and the Calls controller returns a Calls json recordset, with nested Notes in each row. This is done using to_json(:include => blah), in case you're wondering.
So the question is: how do I add a sub-grid (or just a div) that gets displayed when a user double-clicks or expands a row in the parent grid? How do I bind nested Notes data to it?
I found some answers out there that got me part of the way where I needed to go. Thanks to those who helped me take it from there.
I'll jump straight into posting code, without much explanation. Just keep in mind that my json recordset has nested Notes records. On the client it means that each Calls record has a nested notesStore, which contains the related Notes. Also, I'm only displaying one Notes column - content - for simplicity.
Ext.define('MyApp.view.calls.Grid', {
alias: 'widget.callsgrid',
extend: 'Ext.grid.Panel',
...
initComponent: function(){
var me = this;
...
var config = {
...
listeners: {
afterrender: function (grid) {
me.getView().on('expandbody',
function (rowNode, record, expandbody) {
var targetId = 'CallsGridRow-' + record.get('id');
if (Ext.getCmp(targetId + "_grid") == null) {
var notesGrid = Ext.create('Ext.grid.Panel', {
forceFit: true,
renderTo: targetId,
id: targetId + "_grid",
store: record.notesStore,
columns: [
{ text: 'Note', dataIndex: 'content', flex: 0 }
]
});
rowNode.grid = notesGrid;
notesGrid.getEl().swallowEvent(['mouseover', 'mousedown', 'click', 'dblclick', 'onRowFocus']);
notesGrid.fireEvent("bind", notesGrid, { id: record.get('id') });
}
});
}
},
...
};
Ext.apply(me, Ext.apply(me.initialConfig, config));
me.callParent(arguments);
},
plugins: [{
ptype: 'rowexpander',
pluginId: 'abc',
rowBodyTpl: [
'<div id="CallsGridRow-{id}" ></div>'
]
}]
});

EnhancedGrid scrolling (with large amount of data)

I'm using dojox.grid.EnhancedGrid which is created by the class MyGrid, explained below.
var MyGrid = declare(null, {
constructor: function (app, id, opts) {
this.id = id;
this.app = app;
this.core_id = app.getCoreId();
var myStore;
var jquery = {
scope: 'core',
command: 'rest',
args: {
resource: this.id,
serve: 'cooked'
},
core_id: this.core_id
};
this.jsonStore = new custom.store.JsonRest({
target: app.get_dispatcher_url(),
jquery: jquery,
// setstruct is an object to provide a method that sets a new
// grid structure as soon as data arrives.
set_structure: dojo.hitch(this, this.set_structure),
app: this.app
});
// avoid closures from holding a reference
// to jquery and preventing its GCing
jquery = null;
this.memoryStore = new Memory();
myStore = new Cache(this.jsonStore, this.memoryStore);
this.dataStore = new ObjectStore({
objectStore: myStore,
onSet: onEdited,
onNew: onEdited,
onDelete: onEdited
});
myStore = null;
// create grid
this.grid = new EnhancedGrid({
store: this.dataStore,
height: '100%',
structure: [
{ name: 'Waiting for data...', field: 'no-field', width: '10em' }
],
plugins: {
menus: { rowMenu: this._create_menu() },
nestedSorting: true,
selector: { row: 'disabled', col: 'disabled', cell: 'multi' }
}
});
// start grid
this.grid.startup();
}
});
Note that I omitted code to focus just on the creation of the "grid/store". MyGrid displays the grid on a ContentPane.
So I create an object to display the grid (with a large amount of data) and scroll to the bottom, and it will request only the visible rows properly. However, it just so happens that when I create a second grid it will request the content for the second grid and all data for the first grid!!
How can this happen? Any idea of what can be causing this?
EDITED (22/02/13):
I created a jsfiddle to demonstrate the problem I'm getting: see jsfiddle
How to reproduce the problem:
Click on New Tab button, open the console and check how many rows were fetched.
Go to the bottom of the grid (quickly) and check the console again.
Click on New Tab again, go to the console and you can see that all rows, not loaded yet, from previous grid were fetched.
Note: I found out that this only happens on Google Chrome. I tested with Firefox and everything worked well.

dijit.form.FilteringSelect how to add separator programmatically

I am new to Dojo. I am writing up a page which loads the FilteringSelect with a memory store programmatically. Memory store gets the data from a Json service. I want to add separator to FilteringSelect dropdown values but I am not able to find out how to do that. How can I do it it programmatically?
I know it´s kind of old, but i was searching for this and came across this question, so this is what i got:
The dojo documentation ( http://bill.dojotoolkit.org/api/1.9#addOption), shows that:
If value of the option is empty or missing, a separator is created instead.
So, if you use a store to populate the select, the code below should work on dojo 1.10.4:
require(["dijit/form/Select",
"dojo/data/ObjectStore",
"dojo/store/Memory",
"dojo/domReady!"
], function(Select, ObjectStore, Memory){
var store = new Memory({
data: [
{ id: "foo", label: "Foo" },
{ id: "bar", label: "Bar" }
]
});
var os = new ObjectStore({ objectStore: store });
var s = new Select({
store: os
}, "target");
s.startup();
s.on("change", function(){
console.log("my value: ", this.get("value"))
})
})