yii2 sort gridview on function column - sorting

I have a grid view i am populating with a data provider that gets its data from an active query. One of my columns is displayed via a function in the view that evaluates data from 2 different tables and displays one or the other value (based on date) i would like to be able to sort this column, but because its not part of the original SQL statement the ORDER BY clause created by the sort widget is not aware of the column to sort on. My question is, is there a way to sort the data after it has been passed and loaded into the grid view, or is there a better way to gather the data retrieved from the function so that it can be sorted.
[
'label'=>'Last Backup Date',
'value'=>function($data)
{
if(!is_null($data->backupEvent) && !is_null($data->backups))
{
return MAX($data->backupEvent->eventTime,$data->backups->fieldValue);
}elseif(!is_null($data->backupEvent))
{
return $data->backupEvent->eventTime;
}elseif(!is_null($data->backups)) {
return $data->backups->fieldValue;
}
}
],

Related

Text-Widget Applied to an aggregated data table

Utilizing the solution provided by Gordon, I've successfully created a selectable table that contains aggregated data. Now I would like to filter the data with the text-filter-widget.
I understand that the filter needs an array to work properly. What I am trying to understand is how might one be able to update the table rows when the table filters are looking at a group?
A text filter widget is different from a chart in that it takes a dimension to filter on.
We also need to declare a second market dimension so that it will filter the table.
Thus
var marketDim, marketDim2;
// ...
marketDim = facts.dimension(function(d) {
return d.Location;
});
marketDim2 = facts.dimension(function(d) {
return d.Location;
});
// ...
search
.dimension(marketDim2);
Fork of your fiddle.

SOLVED: Looking for a smarter way to sync and order entries in Laravel/Eloquent pivot table

In my Laravel 5.1 app, I have classes Page (models a webpage) and Media (models an image). A Page contains a collection of Media objects and this relationship is maintained in a "media_page" pivot table. The pivot table has columns for page_id, media_id and sort_order.
A utility form on the site allows an Admin to manually associate one or more Media items to a Page and specify the order in which the Media items render in the view. When the form submits, the Controller receives a sorted list of media ids. The association is saved in the Controller store() and update() methods as follows:
[STORE] $page->media()->attach($mediaIds);
[UPDATE] $page->media()->sync($mediaIds);
This works fine but doesn't allow me to save the sort_order specified in the mediaIds request param. As such, Media items are always returned to the view in the order in which they appear in the database, regardless of how the Admin manually ordered them. I know how to attach extra data for the pivot table when saving a single record, but don't know how to do this (or if it's even possible) when passing an array to attach() or sync(), as shown above.
The only ways I can see to do it are:
loop over the array, calling attach() once for each entry and passing along the current counter index as sort_order.
first detach() all associations and then pass mediaIds array to attach() or sync(). A side benefit would be that it eliminates the need for a sort_order column at all.
I'm hoping there is an easier solution that requires fewer trips to the database. Or am I just overthinking it and, in reality, doing the loop myself is really no different than letting Laravel do it further down the line when it receives the array?
[SOLUTION] I got it working by reshaping the array as follows. It explodes the comma-delimited 'mediaIds' request param and loops over the resulting array, assigning each media id as the key in the $mediaIds array, setting the sort_order value equal to the key's position within the array.
$rawMediaIds = explode(',', request('mediaIds'));
foreach($rawMediaIds as $mediaId) {
$mediaIds[$mediaId] = ['sort_order' => array_search($mediaId, $rawMediaIds)];
}
And then sorted by sort_order when retrieving the Page's associated media:
public function media() {
return $this->belongsToMany(Media::class)->orderBy('sort_order', 'asc');
}
You can add data to the pivot table while attaching or syncing, like so:
$mediaIds = [
1 => ['sort_order' => 'order_for_1'],
3 => ['sort_order' => 'order_for_3']
];
//[STORE]
$page->media()->attach($mediaIds;
//[UPDATE]
$page->media()->sync($mediaIds);

Add row name to cde table component

I have a table component in my Pentaho CDE dashboard and data source is sql. I want to make a table like this
enter image description here
I need to add a column as row names for this table and a row on the top of column header.
I found a method here:
Table Component SubColumns
to add header, but how can i add a column before other columns?
I think a clever way to do the extra column part would be by modifying the query result object after it's retrieved from the query, so that you add the columns and rows as needed. You can do this in the PostFetch callback function, which takes the query result object as first argument:
function yourTableComponentPostFetch(queryResult) {
// Let's say you have an array of row names
var rowNames = ['Title1', 'Title2', ... ];
// Add a "title" column for every row
queryResult.resultset.forEach(function (row, idx) {
// Push it at the beginning of the row array
row.unshift(rowNames[idx]);
});
// Change metadata description of columns to reflect this new structure
queryResult.metadata.unshift({
colName: 'Title',
colIndex: -1, // this makes sense when reindexing columns below ;)
colType: 'String'
});
// One last re-indexing of metadata column descriptions
queryResult.metadata.forEach(function (column, idx) {
// The title added column will be 0, and the rest will rearrange
column.colIndex++;
});
}
The only tricky part is the part about modifying the metadata since you are effectively changing the structure of the dataset, and making sure the queryResult object is updated in-place instead of just changing its reference (queryResult = myNewQueryResult would not work), but the code I proposed should do the trick.

Remove blank column in jqGrid - Pivot

I have created a jqGrid - Pivot table JSFiddle example: here.
In this It should not print the line if Component Type value is blank, I Used this empty column, to show all periods(months) in the year, which is mandatory.
Need help in removing that blank line. and also is it possible to remove the last sum column 2015 from grid, if so how?
You includes dummy data with ComponentType:"" group which you don't want to display. So the best solution which I see would be to include the data in the input pivot data only, but don't use the dummy data in the grid data. jqPivot uses datatype: "jsonstring" to prevent additional sorting of previously sorted data. The input data will be placed as the value of datastr option. So one can use the following onInitGrid to remove the dummy data before the data will be processed by jqGrid:
onInitGrid: function () {
var p = $(this).jqGrid("getGridParam"),
userdata = p.datastr.userdata;
p.datastr = $.grep(p.datastr, function (item) {
return item.ComponentType !== "";
});
p.datastr.userdata = userdata;
}
see the modified demo http://jsfiddle.net/OlegKi/b47ocLd7/11/.

jqgrid randId() produces duplicates after page reload

On my grid, after a user enters text on the bottom row, I am adding another row so they can fill out another row if needed. The grid will grow as needed by the user. This is working fine, however after a page reload and populating from db, the addrowdata() function does not honor existing row ids and creates duplicates, starting from 1 again, e.g. jqg1. It should look at existing row ids and create new unique ids. So if I have 5 rows already, it might start at jqg6. Here is the relevant code inside onCellSelect:
var records = jQuery("#table-1").jqGrid('getGridParam', 'records');
var lastRowId = jQuery("#table-1").jqGrid('getDataIDs')[records - 1];
if (lastRowId == id)
{
jQuery('#table-1').addRowData(undefined, {}, 'last');
}
I have also tried $.jgrid.randId() instead of undefined, same results as expected.
Thanks
Ryan
I think that the error is in the part where you fill grid with the data from the database. The data saved in the database has unique ids. The ids are not in the form jqg1, jqg2, ... So if should be no conflicts. You should just fill the id fields of the JSON with the ids from the database.
One more possibility is that you just specify the rowid parameter (the first parameter) of addRowData yourself. In the case you will have full control on the new ids of the rows added in the grid.
The code of $.jgrid.randId function is very easy. There are $.jgrid.uidPref initialized as 'jqg' and $.jgrid.guid initialized to 1. The $.jgrid.randId function do the following
$.jgrid.randId = function (prefix) {
return (prefix? prefix: $.jgrid.uidPref) + ($.jgrid.guid++);
}
If it is really required you can increase (but not decrease) the $.jgrid.guid value without any negative side effects.

Resources