How to make ag-Grid table responsive such that headers and rows are transposed? - html-table

See the "Collapse Rows" animated example:
That's similar to what I want to achieve.
I'd like my table to be responsive using the approach of reorganizing itself such that it shows each original row transposed (but also transpose the headers and duplicate them so that they label each row).
ag-Grid seems like a phenomenal library that has countless features, so I was surprised that the docs seem not to specify how to accomplish my goal.

Unfortunately this feature is not available out of the box.
This is actually a feature request which can be found here:
https://www.ag-grid.com/ag-grid-pipeline/
AG-3142 Allow the grid to change columns for rows (transpose rows), so the grid show each row as one column, and each column as a row
To achieve this, you would have to write a function yourself to transpose the rows into one column.
You can then leverage Grid API methods to update the column and row data accordingly.
I've created a simple plunker which does this based on a button click:
function onBtnClick() {
let newColumnDefs = [{ field: 'transposed_rows' }];
let newRowData = [];
gridOptions.api.forEachNode((node) => {
let nodeDataValues = Object.values(node.data);
nodeDataValues.forEach((val) => newRowData.push({ transposed_rows: val }));
});
gridOptions.api.setColumnDefs(newColumnDefs);
gridOptions.api.setRowData(newRowData);
}

Related

Dgrid selection mix-in issue with order

I've been having issues with the dgrid selection mix-in with multi selects.
Using the selection property (for example)
var selected = Object.keys(datatable.selection)
it returns an array of row ids as expected. However the ORDER of those ids seems to be "arbitrary". It seems perhaps that the order of selecting has an affect.
In any event, in the datatable, I want the selected rows to be returned in order that they display in the list, and they do not.
I can get them in the proper order using dojo.query(".dgrid-selected", datatable.domNode), and use the HTML element to get the row data, but this seems like a hack.
I cannot find a proper method to do this on the SitePen docs. Anyone?
I don't think that there is a direct way to do that. The Object.keys(datatable.selection) returns the array of ids in the order in which the rows are selected. You can use some built-in functions of d-grid and JS to achieve this. Below are the steps:
Get the id by Object.keys.
var selected = Object.keys(datatable.selection)
Create a list of objects comprising of id and rowIndex of element
Code:
var dataList= [];
for(var i=0; i< selected.length; i++){
dataList.push({id: selected[i], index: datatable.row(selected[i]).element.rowIndex});
}
Sort the list using index as the attribute:
dataList.sort(function(a, b){ return a.index- b.index; })
The resulting dataList would have the list of objects in order in which they appear in the grid.

simplecart js setting column widths

I've used this site for assistance many times but never had to ask a question so finally joined...anyway, trying to set up simplecart checkout and having some trouble formatting cart output. I have my cart set to table and by default the simpleCart_items class displays the table and it's cells only as wide as they need be to fit the data. I can change this by specifying all cells(columns) as a percentage of the whole table. Unfortunately with 7 columns each only gets about 14% and this is way to much for a 1 or 2 digit quantity and not near big enough for all the characters in the item name without wrapping. What I want is a way to define a different width for each column. I have not found a way to do this even with colgroup but maybe just not doing it right. Any and all help would be appreciated!
Okay, so this may or may not help. This line is located in the simpleCart.js file. I changed it to something simple.
cartColumns : [
{ view: function(item, column){
return"<img src='"+item.get('image')+"' width='250px' height='250px'><br /><center><h3 ><span>"+item.get('name')+"</span></h3><p><a href='javascript:;' class='simpleCart_decrement'><button>-</button></a> "+item.get('quantity')+" <a href='javascript:;' class='simpleCart_increment'><button>+</button></a></p><p>$"+item.get('price')+"</p><p><a href='javascript:;' class='simpleCart_remove remove_icon'><img src='images/icon_x.png' /></a></p></center>";
},
}
],
You can change it to your own html
cartColumns : [
{ view: function(item, column){
return" YOUR HTML HERE ";
},
}
],
It MUST all be in ONE (1) LINE or else it may not work.
here are some values that are used
image = item.get('image')
name = item.get('name')
quantity = item.get('quantity')
price = item.get('price')
you can look at all the values here
http://simplecartjs.org/documentation/displaying_cart_data
but the point is that you can make a cart and display it how you want; with you own html and css. I hope this helped.

fnReloadAjax(url): two requests

I'd like to refresh my table when new item is added. I use such code:
$("#frm_create_user").submit(function() {
var formData = getFormData($("#frm_create_user"));
$.ajax({
type: "POST",
url: getApiUrl("/user"),
dataType: "json",
contentType: 'application/json',
data: JSON.stringify({user:{user_ref: formData.user_ref}}),
}).done(function(r) {
oTable.fnReloadAjax(getApiUrl("/users?sSearch=" + r.user.userid));
});
return false;
});
But for some reason, I can see two requests instead of one.
The first one is correct - http://symfony/app_dev.php/api/users?sSearch=kZoh1s23&_=1394204041433
And the second one is confusing - http://symfony/app_dev.php/api/users?sSearch=kZoh1s23&sEcho=3&iColumns=8&sColumns=&iDisplayStart=0&iDisplayLength=25&mDataProp_0=userid&mDataProp_1=user_ref&mDataProp_2=password&mDataProp_3=vpn_password&mDataProp_4=status_id&mDataProp_5=expire_account&mDataProp_6=created&mDataProp_7=&sSearch=&bRegex=false&sSearch_0=&bRegex_0=false&bSearchable_0=true&sSearch_1=&bRegex_1=false&bSearchable_1=true&sSearch_2=&bRegex_2=false&bSearchable_2=true&sSearch_3=&bRegex_3=false&bSearchable_3=true&sSearch_4=&bRegex_4=false&bSearchable_4=true&sSearch_5=&bRegex_5=false&bSearchable_5=true&sSearch_6=&bRegex_6=false&bSearchable_6=true&sSearch_7=&bRegex_7=false&bSearchable_7=true&iSortCol_0=0&sSortDir_0=asc&iSortingCols=1&bSortable_0=true&bSortable_1=false&bSortable_2=true&bSortable_3=true&bSortable_4=true&bSortable_5=true&bSortable_6=true&bSortable_7=true&_=1394204041505
If I remove fnReloadAjax() line, these two requests gone so that it looks like it is caused by fnReloadAjax()
How may I fix it to have only http://symfony/app_dev.php/api/users?sSearch=kZoh1s23&_=1394204041433 requests?
All these confusing parameters are Informations that your server sided script might need to clamp the data that has to be returned to dataTables.
Since I don't know your server sided code, I can only break up what they are good for:
&sEcho=3 //No need to react to this, it's just the result of the last ajax call
&iColumns=8 //Your table has 8 columns
&iDisplayStart=0 //You are on page 1
&iDisplayLength=25 //you want to display up to 25 entrys per page
&mDataProp_0=userid //Your first colum gets the value of [userid]
&mDataProp_1=user_ref //Your first colum gets the value of [user_ref]
&mDataProp_2=password //Your first colum gets the value of [password]
etc...
&sSearch=12345&bRegex=true//Your first column is filtered by userid 12345 and this value should be treated as a regex by your datasource
&sSearch_0=&bRegex_0=false//Your second column is not filtered and should not be treated as a regex by your datasource
etc...
&iSortCol_0=0&sSortDir_0=asc //your first column should be sorted ascending
&iSortingCols=1 //you have one column that is sortable
&bSortable_0=true //Column 0 is sortable
&bSortable_1=false //Column 1 is not sortable
etc..
Your server sided script should react to these values. In case of a mysql datasource it should set up its where clause to the filtering parameters, limit it by pagenumber and items per page, and sort according to the sortinfo.
All this is needed if you want to use the luxury features of datatables like pagination, sorting, individual column filtering, clamping ajax return values to minify serverload when working with thousands of entrys.
If you don't need that, just ignore the additional parameters in your server script and just react to the data you need. But leave them in, you might need them later:-)
Hope this helps

grid filter in dojo

can any one help with filtering multiple condition in dojo grid.
im using grid.DataGrid and json data.
data1 = {items: [ {"id":1,"media":"PRINT",pt:"Yellow Directory"},
{"id":2,"media":"DIGITAL",pt:"Social Media"},{id":3,"media":"DIGITAL",pt:"Yellow Online"}
],identifier: "id"};
a=1,b=2;
grid.filter({id:a,id:b})
the above line is just displaying the record with b value.
i need the record with both the values.
can any one help me with this.???
So you want the records that have any of the specified ids?
It comes down to the capabilities of the store you're using. If you're using a Memory store with SimpleQueryEngine, then you can specify a regex or an object with a test function instead:
grid.filter({id: {
test: function(x) {
return x === 'a' || x === 'b';
}
}});
If you're using JsonRest store, then you get to choose how your queries are processed server-side so you could potentially pass in an array of interesting values and handle that in your own way on the server. (i.e. filter({id:[a,b]}))

jqGrid/NHibernate/SQL: navigate to selected record

I use jqGrid to display data which is retrieved using NHibernate. jqGrid does paging for me, I just tell NHibernate to get "count" rows starting from "n".
Also, I would like to highlight specific record. For example, in list of employees I'd like a specific employee (id) to be shown and pre-selected in table.
The problem is that this employee may be on non-current page. E.g. I display 20 rows from 0, but "highlighted" employee is #25 and is on second page.
It is possible to pass initial page to jqGrid, so, if I somehow use NHibernate to find what page the "highlighted" employee is on, it will just navigate to that page and then I'll use .setSelection(id) method of jqGrid.
So, the problem is narrowed down to this one: given specific search query like the one below, how do I tell NHibernate to calculate the page where the "highlighted" employee is?
A sample query (simplified):
var query = Session.CreateCriteria<T>();
foreach (var sr in request.SearchFields)
query = query.Add(Expression.Like(sr.Key, "%" + sr.Value + "%"));
query.SetFirstResult((request.Page - 1) * request.Rows)
query.SetMaxResults(request.Rows)
Here, I need to alter (calculate) request.Page so that it points to the page where request.SelectedId is.
Also, one interesting thing is, if sort order is not defined, will I get the same results when I run the search query twice? I'd say that SQL Server may optimize query because order is not defined... in which case I'll only get predictable result if I pull ALL query data once, and then will programmatically in C# slice the specified portion of query results - so that no second query occur. But it will be much slower, of course.
Or, is there another way?
Pretty sure you'd have to figure out the page with another query. This would surely require you to define the column to order by. You'll need to get the order by and restriction working together to count the rows before that particular id. Once you have the number of rows before your id, you can figure what page you need to select and perform the usual paging query.
OK, so currently I do this:
var iquery = GetPagedCriteria<T>(request, true)
.SetProjection(Projections.Property("Id"));
var ids = iquery.List<Guid>();
var index = ids.IndexOf(new Guid(request.SelectedId));
if (index >= 0)
request.Page = index / request.Rows + 1;
and in jqGrid setup options
url: "${Url.Href<MyController>(c => c.JsonIndex(null))}?_SelectedId=${Id}",
// remove _SelectedId from url once loaded because we only need to find its page once
gridComplete: function() {
$("#grid").setGridParam({url: "${Url.Href<MyController>(c => c.JsonIndex(null))}"});
},
loadComplete: function() {
$("#grid").setSelection("${Id}");
}
That is, in request I lookup for index of id and set page if found (jqGrid even understands to display the appropriate page number in the pager because I return the page number to in in json data). In grid setup, I setup url to include the lookup id first, but after grid is loaded I remove it from url so that prev/next buttons work. However I always try to highlight the selected id in the grid.
And of course I always use sorting or the method won't work.
One problem still exists is that I pull all ids from db which is a bit of performance hit. If someone can tell how to find index of the id in the filtered/sorted query I'd accept the answer (since that's the real problem); if no then I'll accept my own answer ;-)
UPDATE: hm, if I sort by id initially I'll be able to use the technique like "SELECT COUNT(*) ... WHERE id < selectedid". This will eliminate the "pull ids" problem... but I'd like to sort by name initially, anyway.
UPDATE: after implemented, I've found a neat side-effect of this technique... when sorting, the active/selected item is preserved ;-) This works if _SelectedId is reset only when page is changed, not when grid is loaded.
UPDATE: here's sources that include the above technique: http://sprokhorenko.blogspot.com/2010/01/jqgrid-mvc-new-version-sources.html