Can I retrieve column/search specific data from a jQuery DataTable? - datatables

I am currently working on a page for a web app that displays member data in a jQuery DataTable. I am building a custom plugin for the DataTable that allows for a wide range of filtering per table column.
My current task is to be able to retrieve filtered data from the DataTable, although not updating that data on the table. I know already it is possible to retrieve all filtered data by doing:
var data = $table.dataTable().$('tr', { filter: 'applied' });
This gets data for any text in the search box and any filters applied to columns. I am also aware this call gets the jQuery selectors of cells. That's what I need. But I need more...
My questions are:
Can I get data by only applying what's in the search box, without any other current filters applied to columns? I tried:
var data = $table.dataTable().$('tr', { search: 'applied' });
But that returns the same as { filter : 'applied' }.
Can I target specific columns for getting data, such as:
var data = $table.dataTable().$('tr', { filter: 'applied', columns: [1, 2, 5] });
Can I target specific columns AND what's in the search box?
My plugin needs to able to keep track of data with various combinations of column/search filters applied.

For DataTables 1.9
There is a fnFilter() API method but it applies filtering to the table which is not what you want.
Alternatively you may want to use fnGetData() to get the data for the whole table and filter it yourself.
For DataTables 1.10
There is a search() API method but it applies filtering to the table when used with draw() which is not what you want.
Also there is filter() API method. It is not exactly what you're looking for but very close, however you would need to perform the searching yourself.
You can retrieve the content of the search box as follows:
var searchVal = $('.dataTables_filter input', $table).val();
Then you would need to do the searching yourself, shown below is a simplistic approach which may not match how DataTables perform the search internally.
To search first and second column only, specify [0,1] to columns() method. If no parameters are specified, all columns will be searched instead.
var filteredData = $table.DataTable()
.columns([0, 1])
.data()
.eq( 0 )
.filter( function ( value, index ) {
returrn (value.search(new RegExp(searchVal, "i")) !== -1)
? true : false;
} );
According to the manual, variable filteredData would contain a new API instance with the values from the result set which passed the test in the callback.
To retrieve data for all or selected columns, use columns().data().

Related

Filtering Content in Sanity Studio

I am wondering if it is possible to filter content in Sanity Studio according to set criteria. For example, return all published posts or all posts within a particular category, etc.
Here is a short video showing what I mean: https://www.loom.com/share/5af3a9dd79f045458de00e8f5365cf00
Is this possible? If so, is there any documentation on how to do it?
Thanks.
The easiest way I've found to make all kinds of filters is using the Structure Builder. With it you add as many sections you like, name them, and give it your own filter in the form of groq and params.
Se documentation: https://www.sanity.io/docs/structure-builder-introduction
As an example I've added a S.listItem to the deskStructure.js file that gets all articles that are missing the module field.
export default async () =>
S.list()
.title('Content')
.items([
// ...
S.listItem() // <-- New root item for my filters
.title('My article filters')
.icon(FaRegCopyright)
.child(
S.list() // <-- List of filters
.title('My article filters')
.items([
S.listItem() // <-- Item with filter description
.title('Articles without module')
.icon(FaCogs)
.child(
S.documentList() // <-- Filtered list of articles
.title('Articles without module')
.menuItems(S.documentTypeList(menuType).getMenuItems())
.filter('_type == $type && !defined(module)')
.params({ type: 'article' })
),
S.listItem(), // more filters
S.listItem(), // more filters
])
),
// ...
It doesn't make different filters on one list of elements. It's more making different lists that are all ready filtered as you need. And you can give it what ever icon and text you want. Potato/potàto ,'-)
In the sorting list I don't think you can do much other than adding more sorting. And It doesn't work when the list of elements get larger anyways so I wouldn't bother. But it's in the Sort Order section: https://www.sanity.io/docs/sort-orders

Vuetify - strict datatable custom filter

So I have a data table whereby the names of the objects are similar and case sensitive like "A", "Aa", or "a" and I'm having issues trying to filter the data by those exact values. I'm filtering my data using a v-select bound to the search property of the data table. When creating the custom filter, the only two options I've found are by filtering the specific column by the search input:
customFilter(items, search, filter) {
search = search.toString().toLowerCase();
return items.filter(row => filter(row["name"], search));
}
or filtering the Object.keys:
customFilter(items, search, filter) {
search = search.toString().toLowerCase();
return items.filter(i => (
Object.keys(i).some(j => filter(i[j], search))
))
}
With how the custom filter works, I can't seem to use the search parameter without it being put to lower case as removing .toLowerCase() breaks it completely and using a different method on the Objects.key like .find() rather than .some() results still filters the "Aa" items when selecting "A" or "a".
Is there any way I can use the custom filter in order to filter my items both case sensitive and by the string exactly?
Thanks!
Turns out using the search and custom filter of the data table was the wrong way about it as they're too restricted. I just linked the datatable to a separate array which I filter myself when selecting an option in the v-select.

How can I get all the rows of ag-grid?

ag-grid provides a way to get selected rows using api.getSelectedRows() function. And provides a way to set all rows using api.setRowData([]) function.
I'm looking for something getAllRows() to return all the rows in the grid. I know there is a way to loop through all the rows using api.forEachNode() etc.
Is there any way I can get the entire array of rows?
I don't think there is such a method but you can make your own:
getAllRows() {
let rowData = [];
this.gridApi.forEachNode(node => rowData.push(node.data));
return rowData;
}
you are looking for getRenderedNodes
gridOptions.api.getRenderedNodes()
Note: this will only retrieve the rendered rows. If you use row virtualization, meaning only the rows in the viewport will be in the DOM, only those will be returned. As per the functions docs:
Retrieve rendered nodes. Due to virtualisation this will contain only the current visible rows and those in the buffer.
I think this is the simplest answer.
let {rowsToDisplay} = params.api.getModel();
Ag-grid doesn't provide any method to do that. You can check it here Accessing Data Ag-grid and here Grid Api.
I guest the reason is because you can do it through a loop, as you mentioned before.
let items: Array<rows> = [];
this.gridApi.forEachNode(function(node) {
items.push(node.data);
});
Or if the source of your ag-grid is linked through angular there is no need to loop over the grid (assuming that the data grid has not pending changes)
This is how I get the rowData from the grid API:
api.getModel().gridOptionsWrapper.gridOptions.rowData
Lots of methods include gridOptionsWrapper in their return object, so you don't necessarily have to use getModel().
It gives a list of all rows, even if you filter by any columns.
getAllRows() {
let allRows = [];
this.gridApi.forEachNodeAfterFilter((rowNode) => allRows.push(rowNode));
return allRows;
}
I was wondering the same thing and found it annoying that you cannot simply get all rows. In my case I needed to flip a flag on all rows, where the indicator is set outside the component containing the grid, so I did the following. This is in TypeScript for a React app.
gridApi!.selectAll();
const rows = gridApi!.getSelectedRows();
rows.forEach(row => {
row.coverageAction = this.props.isIndicatorChecked;
});
gridApi!.setRowData(rows);

Transaction BODY Field from COLUMN Field (Netsuite)

I have an issue where some of our orders are being imported directly into Netsuite, and there is information from the first line item, that I need to copy into the transaction record (i.e. custom field on sales order)
I want to set this up so that it is automatic, I don't have access to the system that is used to bring the orders into Netsuite, and I only JUST got suitescript access and everything I read about that is way above my head..
I know basic HTML and some of the scripting formulas from Netsuite and that's all.
I was hoping there would be a CUSTOM FIELD FORMULA or some other similar way that I can just easily source the information directly from the first item in the item sublist?
This would be quite trivial to implement using SuiteScript. The example below assumes you want to copy the Memo field (description) from the first line item to the body Memo field. The basic idea would be something like the below (untested code):
function userEventBeforeSubmit(type){
if (type === 'create') {
var record = nlapiGetNewRecord();
var memo = record.getLineItemValue('item', 'memo', 1);
record.setFieldValue('memo', memo);
}
}
If want to accomplish this via custom fields etc. it is possible using "Custom Fields with Values Derived from Summary Search Results".
To do this create a Saved Search as follows:
Type: Transaction
Criteria: [none]
Results: Formula (Text), Summary
Type = Maximum, Formula: DECODE({line}, 1, {memo}, NULL)
Available Filters: Internal ID
Then create a Custom Transaction Body Field as follows:
Type: Free Form Text
Store Value: F
Validation & Filtering > Search: [Saved Search from previous step]
As this is a dynamically calculated field (Store Value = F), it would be available when viewing the record, but not in Saved Searches and lists. To remove this limitation, you can create a Workflow that would copy this field to another one that is stored.

less than greater than filtered queries, aerospike

Its been hard for me to find finite documentation on aerospike. Using aerospike filters with or without lua, is it possible for me to :
Order my results server side
Use a filter to do a greater than/less than query
Essentially I want to encode a value(client side) and retrieve the first row from aerospike whos value is greater than the encoded one.
Another way to put it, is opposite of price is right... what is the lowest value i can find in aerospike, whos value is not lower than the one i give.
Id like a simple way, but I am also open to work arounds(or flat out no if its not reasonable/practical)
Aerospike does not natively support ordering of data on server-side.
Aerospike supports filters on the query. You can specify a range filter for your need. See the example at this link.
Basic Sorting is natively supported in large lists (LDT).
In a Large List your key (index) is always ordered in a lexical manner by default.
Please notice that ldt-enabled true directive must be present in the namespace's config area in aerospike.conf
an example with the javascript client
var key = {ns: 'test', set: 'mySet', key: 'myKey'};
var callback = function (status, result) {console.log(status, result)}
var list = client.LargeList(key, 'targetBinName', null, callback));
// add first item (also determinate the list values type)
list.add(1, callback);
// add multiple items
list.add([0, 2, 4, 5], callback);
list.add(3, callback);
// get all items
list.scan(function (status, list) {
// list = [0, 1, 2, 3, 4, 5]
})
// select by values range
list.findRange(0, 3, callback)
// filter using udf to do custom gt/lt filtering
list.filter('udfName', callback)
if you need to store objects then you must add a key property that will be the index for sorting, range, duplicates etc (no duplicates are allowed by default)
list.add({key: 1})
list.add([{key: 0},{key: 2}])
I'm sure the other languages drivers have the same methods more or less.
more on Large list in Aerospike docs
Large list docs section in NodeJS client on Github
In the past you would have expressed this as a stream UDF, but since release 3.12 a predicate filter would be the correct solution.
Take a look at the PredExp class of the Java client and its examples for building complex filters. Predicate filtering also currently exists for the C, C# and Go clients.