Identifying filtered rows with DataTables - javascript

I have some issues with a project I inherited that is using DataTables and it's filter functionality.
The issue is that in the main function which populates the table, it has the following code:
var rowPos = mainTable.fnAddData(tableData, false)[0];
var rowData = mainTable.fnSettings().aoData[rowPos];
$(rowData.nTr).attr("id", "UID" + id); // Since the id doesn't always match the row
rowData.ID = id;
Now I know that the 3rd line is pretty much useless unless the 'false' argument of the fnAddData is set to 'true'. This is because the HTML elements don't actually exist in the DOM when set to 'false' so there is no way of setting the 'id' attribute.
I can't use 'true' because it will render the table in about 4 seconds when adding several hundred rows to the table. But when I use 'false' it renders the table almost instantaneously (less than a second). So using the 'true' flag in 'fnAddData()' is not even an option.
I see the last line seems to be doing something, but I've tried to find documentation for that on the DataTables web site but can't seem to find anything of value. I'm assuming it allows someone to bind a UID (unique record ID) to the actual row number, which is essential what is wanted.
The code I have also makes use of the 'fnRowCallback', which tries to set the 'id' attribute at this time, such as:
var id = mainTable.fnSettings().aoData[tablePos].ID;
$(row).attr("id", "UID" + id); // Since the id doesn't always match the row
The main problem is that it does not seem to work! If I apply a table filter and purposely filter out all records except the record which should be 'UID' 3, in the 'fnRowCallback', my 'id' variable is set to 0. So the attribute set is always 'UID0' and causes all sorts of bad references.
Is there a way to properly assign my database record ID to table row's? And then refer them later on, such as in the 'fnRowCallback' function? Or is there some other trick someone has managed to figure out?
Thanks in advance for your time and responses!
Update: 2012.11.01 12:33 - I've added an answer below based on various findings so far!

I've been doing a bit of digging and here are my conclusions so far...
Using a JavaScript object inspection that I found on this SO page (by 'goreSplatter') I was able to dump various DataTables objects.
I realized that my 'rowData' object was a tiny container, as expected. And realized that the 'rowData.ID' property did not originally exist in this data structure. I guess the application developer inserted it himself and it makes sense.
From the 'fnRowCallback()' function, I did the same object inspection to try and find the initial 'rowData' that I initialized my 'ID' on. I found it as follows:
var rowData = mainTable.fnSettings().aoData[tablePos];
And when I dump the value of 'rowData.ID' I realized that my 'ID' value was properly set as expected.
The problem occurs when I do my filter! The 'rowData.ID' seems to always be '0' for some reason. It seems like the DataTables takes a copy of the object but does not set any properties it does not know and thus results in '0'.
So it is definitely a bug (at least, in my opinion)! I will contact the DataTables people to see how they would expect users to bind custom application data to their rows and see if they can also set these properties during a filtering process.
I will report any further findings later on.

Related

Tabulator.js table elements retrieve the index of the row and serve as a control element to other plots

I am using tabulator package 4.3.0 to work on a webpage. The table generated by the package is going to be the control element of a few other plots. In order to achieve this, I have been adding a dataFiltered function when defining the table variable. But instead of getting the order of the rows in my data object, I want to figure a way to get the index of the rows in the filtered table.
Currently, I searched the manual a little bit and have written the code analogue to this:
dataFiltered: function(filters,rows){
console.log(rows[0]._row.data)
console.log(rows[0].getPosition(true));
}
But the getPosition always returned -1, which refers to that the row is not found in the filtered table. I also generated a demo to show the real situ when running the function. with this link: https://jsfiddle.net/Binny92/3kbn8zet/53/.
I would really appreciate it if someone could help me explain a little bit of how could I get the real index of the row in the filtered data so that I could update the plot accordingly and why I am always getting -1 when running the code written in this way.
In addition, I wonder whether there is a way to retrieve the data also when the user is sorting the table. It's a pity that code using the following strategy is not working in the way I am expecting since it is not reacting to the sort action and will not show the information when loading the page for the first time.
$('#trialTable').on('change',function(x){console.log("Yes")})
Thank you for your help in advance.
The reason this is happening is because the dataFiltered callback is triggered after the rows are filtered but before they have been laid out on the table, so they wont necessarily be ready by the time you call the getPosition function on them.
You might do better to use the renderComplete callback, which will also handle the scenario when the table is sorted, which would change the row positions.
You could then use the getRows function passing in the value "active" as the first augment return only rows that have passed the filter:
renderComplete: function(){
var rows = table.getRows("active");
console.log(rows[0].getPosition(true));
}
On a side note i notice you are trying to access the _row property to access the row data. By convention underscore properties are considered private in JavaScript and should not be accessed as it can result in unstable system behaviour.
Tabulator has an extensive set of functions on the Row Component to allow you to access anything you need. In the case of accessing a rows data, there is the getData function
var data = row.getData();

Relay: fetch for recursive data returns null

I have a recursive data structure to be fetched and displayed. I have a graph ql type as follow:
human {
name,
children: [human]
}
Now I wanted to incrementally fetch data and hence used to react classes HumanList and HumanItem, where I've used relay to fetch children only when a item is clicked. In my actual code relay gives children a null on very click i.e. on rendering very first set of children. I tried test code on relay playground and found similar issue. Here is the link to gist. Playground.js contains the code part and Playground.gql.js contains schema part. Clicking on each number open children under it. After 3 or 4 level it starts showing Found children as null. For me it happens on 1.1.2.2. If it doesn't happens so for you then try adding more levels in SCHEMA code and the bug would pop in.
I've already checked relay issues #246 and #536 but none of them helped.
Any help is very much welcome.
This was a bug. Given a plural field, when the time came to make a query for new data, we would diff what we have in the store with what the application wants. The bug was that we would assume that all records of a plural field have the same shape in the store, and only use the first store record in any plural field against which to diff. This was of course not true in your case, where some records in a plural field might be expanded and some might be collapsed.
This has been fixed as part of https://github.com/facebook/relay/issues/1243 and will be released in the version after Relay 0.9.1.

Sorting a DataTable using custom function does not work

I am working with DataTables plug-in in JavaScript.
Usually, if I need to update a cell value, I use the cell().data(set) method followed by .draw().
However, I do not want to use this way because my table contains heavy DOM object. So, when I need to update a cell, I just call some jQuery like $("#cell").attr("myattr", 50) for example, and then I managed to never have to use draw(). This prevents the object to be rebuilt each time, but unfortunately it also means that the DataTable is not aware of these changes (cell().data() returns the unchanged object).
This is a problem when I want my table to be sorted. In fact, the sorting is performed on the data that the datatable known, data which is not changed.
So I thought I could use the columns.render option, implementing a function like this:
function(data, type, row, meta) {
if (type === "sort") {
return $("#cell").attr("myattr");
}
return data;
}
This does not work and I think this is because of the fact that DataTable caches the data. So, as I never update cells data, cache never need to be updated, and sorting is done using this cache, which does not correspond the cell myattr attribute.
I am looking for a workaround which can allow me to sort a DataTable even if cells values are not changed internally but from outside.
Play with this JSFiddle, clicking the "CHANGE VALUES" button and trying to sort the column, you can see that the values are not correctly ordered.
There are couple solutions:
SOLUTION #1
Use cell().invalidate() API method to invalidate data in cache as shown below:
$('#example').DataTable().cell($("#a").closest('td')).invalidate('dom').draw(false);
DEMO
See this jsFiddle for code and demonstration.
SOLUTION #2
You can use columns.orderDataType to specify name of custom ordering plug-in, see Custom data source sorting. These plug-ins can access live DOM content.
Please note that there are no plug-ins built into DataTables, they must be added separately.
You can use dom-text plug-in as a base and write your own function to access the data for sorting.
DEMO
See this jsFiddle for code and demonstration.

jqGrid: How get all raw data, problems getting object inside object

I have a grid which data is like this:
As you can see, there are some rows (0,1,2 and 3 objets) and inside each there are more objects. Please pay attention that there is an object called 'datosPersonales' ('personalData') with has inside more objets; nombre (name), apellido1(firstname) etc.
The problem arise when I try to get the data from one row:
var empleado = $("#GRID_empleado").jqGrid("getRowData",numRow);
What I get is and object with object inside but the the previously mentioned 'datosPersonales' objetc is not a 'father' of more objects. With an image (from firebug) is easier to understand:
I don't know why but instead of get 'datosPersonales' with his 'sons' I get them like these:
datosPersonales.nombre
datosPersonales.apellido1
datosPersonales.calle
etc
What is the way to get all / whole / raw data from a certain row of a grid or even of the complete grid?
I have tried with some parameters but I've not been successful.
What I want is to get for example the data of [3] in the first image.
Thanks in advance!
You don't posted any code which shows how you use jqGrid. Even such important options of jqGrid like datatype and loadonce are unknown. So I can only guess. I suppose that you create grid with subgrids to display all the data which you posted. I suppose that you use approach close to the way which I described here and here. In the way you can use either getLocalRow or .jqGrid("getGridParam", "userData") instead of getRowData. If you don't know the answers which I referenced I recommend you to read there.

How can I call an element from an array created by "document.getElementBytag()"?

I am trying to make a page work for my website using the mootools framework. I have looked everywhere I can think of for answers as to why this isn't working, but have come up empty.
I want to populate several arrays with different data types from the html, and then, by calling elements from each array by index number, dynamically link and control those elements within functions. I was testing the simple snippet of code below in mootools jsfiddle utility. Trying to call an element from array "region" directly returns "undefined" and trying to return the index number of an element returns the null value of "-1".
I cannot get useful data out of this array. I can think of three possible reasons why, but cannot figure out how to identify what is really happening here:
1. Perhaps this array is not being populated with any data at all.
2. Perhaps it is being populated, but I am misunderstanding what sort of data is gotten by "document.getElementBytag()" and therefore, the data cannot be displayed with the "document.writeln()" statement. (Or am I forced to slavishly create all my arrays?)
3. Perhaps the problem is that an array created in this way is not indexed. (Or is there something I could do to index this array?)
html:
<div>Florida Virginia</div>
<div>California Nevada</div>
<div>Ohio Indiana</div>
<div>New York Massachussetts</div>
<div>Oregon Washington</div>
js:
var region = $$('div');
document.writeln(region[2]);
document.writeln(region.indexOf('Ohio Indiana'));
Thanks for helping a js newbie figure out what is going on in the guts of this array.
$$ will return a list of DOM elements. If you are only interested in the text of those DOM nodes, then extract that bit out first. As #Dimitar pointed out in the comments, calling get on an object of Elements will return an array possibly by iterating over each element in the collection and getting the property in question.
var region = $$('div').get('text');
console.log(region[2]); // Ohio Indiana
console.log(region.indexOf('Ohio Indiana')); // 2
Also use, console.log instead of document.writeln or document.write, reason being that calling this function will clear the entire document and replace it with whatever string was passed in.
See an example.

Categories