Retrieving original row data from jqGrid - javascript

It is possible to use the getRowData method to retrieve the current of a cell but this retrieves the current cell content rather than the original data before it went through the formatter.
How do I retrieve the original content before the formatting transformations are applied? FYI I am populating the table using JSON.

I had to dig through the documentation a bit to come up with the solution, to see it in its original context go here: jqGrid Data Manipulation, specifially the section near the end titled "User Data".
First, modify your jsonReader implementation as follows:
jsonReader: {
root: 'Data',
page: 'Page',
total: 'Total',
records: 'Records',
userdata : 'Data',
repeatitems: false,
id: 'Id'
}
Note the userdata option set to the same as root 'Data'
In my case I needed to retrieve the original row data when the user selected a row. I implemented this as follows:
onSelectRow: function(rowid) {
processRow(rowid);
}
To retrieve the data within the process row method I have the following:
var rowData = $("#resultGrid").getGridParam('userData')[rowId - 1];
Where #resultGrid is a reference to my jqGrid.
This will then return the original data bound to that row before any formatting was applied.
A couple of points to note:
In my case the grid is paged so the result set is never greater than 10 items therefore the 'userdata' wont grow too large
Sorting is performed server side so that index rowId will always return the correct value from 'userData'
While 'userdata' as referenced as an option on jsonReader is all lower case, to retrieve it using getGridParam you need to reference it as 'userData'

This is how to retrieve cell data from a row.
var rowData = jQuery(this).getRowData(rowId);
var colData = rowData['columnName']);
columnName is table's column name.

Related

keep filter after ag-grid update

I'm trying to keep a grid's filter after updating a row.
When I click on a row in the grid, I open a dialog where I update the informations for this row, and then I look for the clicked row in the grid's rowData after that I update the corresponding record in the rowData with the values from the dialog, as following :
row[0].x = dg.x;
row[0].y = dg.y;
dg.gridOptions.rowData[index] = row[0];
dg.gridOptions.api.setRowData(newRows);
But after this I loose the filter on the grid, I did some search and I tried all the following solutions :
Setting the gridOptions property deltaRowDataMode to true.
filterParams: {apply: true, newRowsAction: 'keep'}
But none of these has worked.
How can I solve this ?
You can set the filterParams newRowsAction to keep, like that
dg.defaultColDef = { filterParams: { newRowsAction: 'keep'}} ;
refer to https://www.ag-grid.com/javascript-grid-filtering/index.php
Use this method (gridOptions.api.refreshCells()) instead of setRowData. Or if you need to use setRowData, save the filter model before the call and apply the filter again afterwards using these methods:
const model = this.gridOptions.api.getFilterModel();
//some code
this.gridOptions.api.setFilterModel(model);
I had same issue and this what I did to resolve it (kinda hacky).
Subscribe to rowDataChanged event of the ag grid.
(rowDataChanged)="onRowDataChanged($event)"
Inside the onRowDataChanged put your filtration logic
// Get a reference to the name filter instance
const filterInstance = this.gridApi.getFilterInstance('fieldNameHere');
// Call some methods on Set Filter API that don't apply the filter
filterInstance.setModel({
type: 'contains', // type of filter
filter: 'yourData' // set filter on data
});
// Get grid to run filter operation again
this.gridApi.onFilterChanged();
onRowDataChanged will be triggered twice, first when the grid clears everything and second when the data reloaded. So, you should put some conditions to avoid any errors.
For example, I needed to set the filter from the data that was loaded after the refresh this is what I did:
const filtered = this.rowData.filter(x => x.Id === this.Id);
if (filtered.length > 0) {
// Get a reference to the name filter instance
const filterInstance = this.gridApi.getFilterInstance('fieldNameHere');
// Call some methods on Set Filter API that don't apply the filter
filterInstance.setModel({
type: 'contains', // type of filter
filter: filtered[0].name // set filter on data
});
// Get grid to run filter operation again
this.gridApi.onFilterChanged();
}

How to dynamically build a table from a JSON array?

I've placed an AJAX GET call in an Enyo view. The GET calls a web service which returns an array of records including the column headers.
My aim is to dynamically build a table with this returned array, where a row is created for each index and columns for each header within the index.
What I do know in terms of Enyo is to create one record by mapping the AJAX response headers to component fields:
this.$.actionsTaken.setContent( inResponse.ActionsTaken);
But I'm not sure how to do that dynamically and create the table on the fly.
So for example when I inspect the web service response my index 0 contains the following: (Where ActionsTaken, Application and EM are the col headers.)
{
ActionsTaken: "Tested uptime"
Application: "2011 Hanko"
EM: "EM102 "
}
Question:
How can you dynamically build a table from a JSON array?
The AJAX GET:
fetch: function() {
var ajax = new enyo.Ajax({
url: "http://testservice.net/WebService/GetHistory",
async: false,
handleAs:"json",
xhrFields: {withCredentials: true}
});
ajax.go(this.data);
ajax.response(this, "gotResponse");
ajax.error(this, function(inSender, inError) {
Misc.hideMask();
ViewLibrary.back();
Misc.showToast("Error retrieving data");
});
},
gotResponse: function(inSender, inResponse)
{
var debugVar = inResponse;
this.$.actionsTaken.setContent( inResponse.ActionsTaken);
this.$.configurationItemLogicalName_value.setContent( inResponse.Application);
this.$.eM.setContent( inResponse.EM);
},
The components that hold the data values:
{name:"outage_table", kind: "FittableRows",components:[
{content: "Actions Taken", name: "actionsTaken", },
{content: "Application", name: "application", },
{content: "EM", name: "eM", },
]}
Depending on the complexity of all your data, you might be able to do this fairly simply. Iterate through your array and on each object, you can then iterate through its keys and create each column with its data.
Something like:
for (var k in theObject) {
// make column k
// add theObject[k] to it
}
I think the problem is that you have created named components that match this example data, but it is unknown if those will always be the same keys?
There is a kind (enyo.DataTable, which, surprisingly, I have never used) that you might use instead. It lets you add rows (no headers) so you would make your first row from all the object keys, then the next row would be those keys' data. It is derived from DataRepeater so there may be some implementation to work out, such as using an enyo.Collection to store your data and then set the collection to the DataTable.
The other alternative that matches closer to what you have would be to just dynamically create the components as you need them:
this.$.outage_table.createComponents([{...}]);
this.$.outage_table.render(); // need to re-render when dynamically adding components

dijit form select disregards sorting of dojo store memory datasource

I'm using a dojo store memory as a datasource for dijit form select. The problem I'm having is that the select control ignores the sort I've set on the data store and instead sorts data on the label field. I'm trying this:
mhusStore = new Memory({ data: data, idProperty: "MHID", sort: [{ attribute: "SegIDOrder", descending: false }] }); //verified the sort is on SegIDOrder in debug mode (it also comes out of the db this way
this.selectUSMAS.set("labelAttr", "MHID");
//this.selectUSMAS.set("sort", "SegIDOrder");//tried this no result
this.selectUSMAS.set("store", mhusStore);
any ideas how I can get the select to use the order of the memory store?
Thanks
already answered here:
How to change order of elements in a dijit.form.Select
this.selectUSMAS.set("sortByLabel", false);

Getting original data from kendo UI DataSource

In the Kendo UI documentation for the DataSource component, it states that the data function is used to get data items for the data source.
However it also states that if the data source is bound to a JavaScript array (via the data option) the data method will return the items of that array. Every item from the array is wrapped in a kendo.data.ObservableObject or kendo.data.Model.
How can I retrieve the original unwrapped data items (i.e. having same reference) that were passed into the data source?
I ask because I'm using a Kendo UI treeview control and in its event handlers (e.g. check event) I want to update the original data item for a tree node based on some custom logic.
Update
For example here is a simple treeview having a single node (of course in a realistic scenario the tree would contain many nodes) . When checking the node I want to get a reference to the original data item for the checked node. this.dataItem(e.node) does not return the original data item as the log statement outputs false.
<div id="treeview"></div>
<script>
var mydata = [
{ text: "foo", checked: false}
];
$("#treeview").kendoTreeView({
checkboxes: true,
dataSource: mydata,
check: function(e) {
console.log(this.dataItem(e.node) == mydata[0]); //I want this to output true
}
});
</script>
If I understand your question correctly, you can get to the records independently by referencing your data source and using the .at(x) function, where x equals whatever record of your data source you are attempting to access. So to get the first.
var theData = yourDataSource.at(0);
To update it, you then use .set and .sync.
theData.set('userFirstName', 'Joe');
theData.set('userAverageTime', 10);
yourDataSource.sync();
Using .set() is handy because if you store all your updates into an iterable collection, then you can just run through them.
$.each(updatedVars, function(key, element) {
theData.set(key, element);
});
yourDataSource.sync();

Retrieving the updated datasource from YUI datatable after editing it

I am using the datatables from YUI 2.8.2 and its widgets to edit a datasource (YAHOO.example.Data.response) as follows:
this.bpDataSource = new YAHOO.util.DataSource(YAHOO.example.Data.response);
response_datasource = this.bpDataSource;
this.bpDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
this.bpDataSource.responseSchema = {
resultsList: "item_evaluacion",
fields: [ ... ]
};
this.standardSelectDataTable = new YAHOO.widget.ScrollingDataTable("div_item",
bpColumnas, this.bpDataSource, {height:"9em"} );
I want to retrieve the edited data from this datatable and proccess it. I tried a variable pointing to this.bpDataSource first but this variable contains only the original datasource without the changes the user made.
How can I retrieve the updated version of my datasource?
The DataSource only retrieves the data but does not keep a reference to the data retrieved. Once it has passed the retrieved data to whatever requested it, in this case DataTable, it forgets about it. DataTable then keeps the data in the RecordSet collection, which is composed of individual Record instances where you can fetch the values by field name. For some funny reason, the API docs for both Record and RecordSet are not under DataTable. I know the docs for those two are somewhere in there, but they somehow got filed under some other component.
Anyway, in DataTable, you have method getRecord() which takes an index. You can loop through it until it returns null or undefined. Otherwise, I believe you could do getRecordset().getLength() and use that to iterate with a for loop. Then, on each record instance, method getData() takes the column key and returns the value.
For more information read the two 'Working with the DataTable widget' articles referenced in the heading of DataTable.

Categories