How to build a column from nested data in SlimGrid (SlickGrid for Vue)? - slickgrid

I have a data structure like this:
{
year: 1999,
make: "ford",
model: {
name: "escort",
type: {
name: "wagon",
id: 2
}
}
And I want to show all the first-level attributes (year, make) as well as nested attributes (model.name, model.type.name).
In SlimGrid you have column definitions that look like this:
columnOptions: {
'year': {
name: 'Car Year',
order: 0,
formatter (row,cell,value){
return new Date(year);
}
}
}
model.name works fine with these options:
'model': {
name: 'Model Name',
order: 2,
formatter (row,cell,value){
return value.name;
}
}
Because model is a top-level attribute.
But when I try to build a new column, that has no direct top-level equivalent, the column does not appear:
'': {
name: 'Type of Car',
order: 3,
formatter (row,cell,value){
return this.tableData[row].model.type.name;
}
}
What I have:
Car Year | Make | Car Model
---------+-------+----------
1999 | ford | escort
What I want:
Car Year | Make | Car Model | Type of Car
---------+-------+-----------+------------
1999 | ford | escort | wagon
How can I create an extra column in SlimGrid/SlickGrid that has no connection to a top-level attribute?

Don't know about SlimGrid, but I can answer for SlickGrid, at least for the current repo at https://github.com/6pac/SlickGrid.
You're only using the first few parameters of the formatter call. The whole signature is:
formatter(rowIndex, cellIndex, value, columnObject, rowObject, grid)
The columnObject is your columnOptions from above. rowObject is the current row object - the one you are referencing with this.tableData[row].
It's using this.tableData[row] that would not work with SlickGrid (use rowObject instead), but again it depends on the repo you are using. You can see what the formatter call signature is by searching for result = getFormatter(row, m)(row, cell, value in the slick.grid.js file.

Related

check if record exists using prisma graphql apollo

trying to check if a record exists in a table in Postgres using Prisma, but seems like I can only query the id field, but not any other fields like name and location, which gives a compiler error
model schema.prisma
model place {
id Int #id #default(dbgenerated("nextval('place_id_seq'::regclass)"))
name String
location String #unique
}
generated type
export type Place = {
__typename?: 'Place';
name?: Maybe<Scalars['String']>;
location?: Maybe<Scalars['String']>;
};
Query resolver
let findPlace = await prisma.place.findUnique(
{
where: {
name: "abc"
}
}
)
error
Type '{ name: string; }' is not assignable to type 'placeWhereUniqueInput'.
Object literal may only specify known properties, and 'name' does not exist in type 'placeWhereUniqueInput'.ts(2322)
index.d.ts(1361, 5): The expected type comes from property 'where' which is declared here on type '{ select?: placeSelect | null | undefined; include?: placeInclude | null | undefined; rejectOnNotFound?: RejectOnNotFound | undefined; where: placeWhereUniqueInput; }'
what's missing here to make this work?
Prisma won't accept findUnique queries where the condition only contains non unique fields (in this case, name). If you just need to find whether a place record with appropriate condition exists or not, you can use the count API.
let placeCount = await prisma.place.count(
{
where: {
name: "abc"
}
}
)
// placeCount == 0 implies does not exist
findUnique only works for unique fields. You shouldn't use count either as it unnecessarily goes through the whole table.
The better approach is to use findFirst, which is basically a LIMIT 1 on the database, so the database can stop searching for more results after the first hit.
const exists = !!await prisma.place.findFirst(
{
where: {
name: "abc"
}
}
);
I'm using the !! to cast the object to a boolean.

Validate nested domain class instance in command object

I try to validate a nested domain class instance on a command object.
Having the following command object
package demo
import grails.databinding.BindingFormat
class SaveEventCommand {
#BindingFormat('yyyy-MM-dd')
Date date
Refreshment refreshment
static constraints = {
date validator: { date -> date > new Date() + 3}
refreshment nullable: true
}
}
And having the following domain class with its own constraints
package demo
class Refreshment {
String food
String drink
Integer quantity
static constraints = {
food inList: ['food1', 'food2', 'food3']
drink nullable: true, inList: ['drink1', 'drink2', 'drink3']
quantity: min: 1
}
}
I need when refreshment is not nullable the command object validates the date property and check the corresponding restrictions in refreshment instance
For now try with this code in the controller:
def save(SaveEventCommand command) {
if (command.hasErrors() || !command.refreshment.validate()) {
respond ([errors: command.errors], view: 'create')
return
}
// Store logic goes here
}
Here through !command.refreshment.validate() I try to validate the refresh instance but I get the result that there are no errors, even when passing data that is not correct.
Thank you any guide and thank you for your time
I typically just include some code that will use a custom validator to kick off validation for any property that is composed of another command object. For example:
thePropertyInQuestion(nullable: true, validator: {val, obj, err ->
if (val == null) return
if (!val.validate()) {
val.errors.allErrors.each { e ->
err.rejectValue(
"thePropertyInQuestion.${e.arguments[0]}",
"${e.objectName}.${e.arguments[0]}.${e.code}",
e.arguments,
"${e.objectName}.${e.arguments[0]}.${e.code}"
)
}
}
})
This way it's pretty clear that I want validation to occur. Plus it moves all the errors up into the root errors collection which makes things super easy for me.
Two things I could think of:
Implement grails.validation.Validateable on your command object
What happens when you provide an invalid date? Can you see errors while validating?

Kendo Input with big dataSource

I have create a Kendo Grid, and a custom Form for selected row of grid.
Using AngularJS, i stored to 'formData' variable the selected row data.
For example
$scope.fromData = { uid: guid, id: guid, name: string, otherEntityId: guid }
Now in my form i have a KendoDropDown input for the 'otherEntityId'.
Using dataTextField and dataValueField, i want to look in other datasource and based to foreign key display other property.
dataTextField: "Name",
dataValueField: "otherEntityId",
For example i have one entity person with
{ id: guid, name: string, cityId: guid}
And another entity cities with
{ name: string, id: guid }
Where the first cityId is the same of second entity id.
In my form this works, i have the id from the first datasource and in my input i display the name based to id, its like 'look up' field.
The problem is that the datasource of my second entity is too large, and i cannot load at once.
I want an mechanism that, for every selection of row in grid, the input will send a request with filter in datasource like
dataSource.filter = { field: dataValueField, operator: "eq", value: $scope.formDataItem[dataValueField] };
And when the user click to see more options of dropdownlist input i want to have other filter with 'startswith' like
dataSource.filter = { field: dataTextField, operator: "startswith", value: getInput().text() };
How can do it? How can change the filters of datasource on open event?
I use the filtering event. So.. when i initiliaze value i have in datasource filter with guid so can load only one item and when the filtering event called i change filters and works fine.
$scope.options.filtering = function (e) {
e.preventDefault();
if (prevText.length >= minLength) {
delete dataSource.filter;
dataSource.filter = { field: dataTextField, operator: "startswith", value: getInput()._prev};
getInput().setDataSource(dataSource);
}
else
getInput().setDataSource({ data: [] });
}

ExtJs 6 doSort method

I didn't find doSort function available in EXT 6 with respect to the grid columns and also didnt find it in any upgrade notes. may be because it is a private function, can anyone please tell me what is the alternative to do the same thing what doSort was doing in Ext 4 ?
I tried to use sorters instead,
{
text: 'columnText',
dataIndex: 'columnIndex',
sorter: me.sort
}
sort: function(v1,v2) {
...
}
but i didn't found smth like dataIndex or columnName in v1, v2 parameters to do sort. (it's just a model)
I need empty cell be from below after Sort Ascending, empty cell be from above after Sort Descending
Thanks.
What is the problem here? You can use the model object to retrieve your column data to sort. From the docs:
sorter: function(record1, record2) {
var name1 = record1.data.columnIndex;
var name2 = record2.data.columnIndex;
return name1 > name2 ? 1 : (name1 === name2) ? 0 : -1;
}
EDIT: If you dont want to rewrite this for every column, then you can do a trick like this:
sorter: (function(columnIndex){ return function(v1, v2){ me.sort(v1, v2, columnIndex);} })("column1")
Now, you can get the column name as 3rd argument in your sort function.
You want to sort the store, not a column. Have a look at the doSort function in ExtJS 4 for a moment:
doSort: function(state) {
var tablePanel = this.up('tablepanel'),
store = tablePanel.store;
// If the owning Panel's store is a NodeStore, this means that we are the unlocked side
// of a locked TreeGrid. We must use the TreeStore's sort method because we cannot
// reorder the NodeStore - that would break the tree.
if (tablePanel.ownerLockable && store.isNodeStore) {
store = tablePanel.ownerLockable.lockedGrid.store;
}
store.sort({
property: this.getSortParam(),
direction: state
});
},
/**
* Returns the parameter to sort upon when sorting this header. By default this returns the dataIndex and will not
* need to be overriden in most cases.
* #return {String}
*/
getSortParam: function() {
return this.dataIndex;
},
Now, this code is still working in ExtJS 6, just that it is no longer part of the framework. You can "put it back into the framework" (e.g. as an override) and it should work again. Or you can use the relevant parts directly from the column event, e.g.
columns:[{
dataIndex:'ABC',
listeners:{
headercontextmenu:function(ct, column) {
column.mySortState = column.mySortState=='ASC'?'DESC':'ASC';
ct.up('grid').getStore().sort({
property:column.dataIndex;
direction:column.mySortState
});
}
}
}]
Maybe you need to define it in the model like this:
fields: [{
name: "textField",
type: 'string',
//sortType: 'asInt'
}]

How to implement custom row sorting for a ExtJS GridPanel

I have implemented a Web - Application which features a GridPanel which can be grouped or ungrouped and where the rows should be sorted alphanumerically (like the standard grid sorting function does) but with the exception that some rows which represent summary rows should not be sorted at all and should stay at the same row position.
To archieve this i wanted to write a custom row sorting function for the gridpanel. Can someone give me a hint how to archive this ? (overwrite which functions, how to implement). Or does anybody know literature, tutorials, examples etc. or could share source code on how this can be done ?
I am using ExtJs Version 3.4.
Many thanks in advance.
Cheers,
Seha
To sort the store data that underlies a gridpanel, the Ext.data.Store.sort() method is used. You can override that method in your particular store instance.
The other possibility is to set remoteSort to true and sort the data on the server.
Here is some sample code that worked for me in ExtJS 3.4.
You can use this in a GridPanel or EditorGridPanel, I placed it in the constructor using an inherited class, but you should be able to add it if you are instantiating a vanilla grid as well, just make sure you are not using the global variable scope.
Make sure the grid variable contains a reference to your grid (after it has been defined).
// Apply column 'sortBy' overrides
var column, columns = grid.getColumnModel() && grid.getColumnModel().config;
var sortColumns = {}, sortByInfo = {};
if (columns && columns.length) {
for (var i = 0; i < columns.length; i++) {
column = columns[i];
// Do we have a 'sortBy' definition on a column?
if (column && column.dataIndex && column.sortBy) {
// Create two hashmap objects to make it easier
// to find this data when sorting
// (using 'if (prop in object)' notation)
sortColumns[column.dataIndex] = column.sortBy;
sortByInfo[column.sortBy] = column.dataIndex;
}
}
if (!$.isEmptyObject(sortColumns)) {
// Override the 'getSortState()' helper on the store, this is needed to
// tell the grid how its currently being sorted, otherwise it
// will get confused and think its sorted on a different column.
grid.store.getSortState = function() {
if (this.sortInfo && this.sortInfo.field in sortByInfo)
return { field: sortByInfo[this.sortInfo.field], direction: this.sortInfo.direction || 'ASC' };
return this.sortInfo;
}
// Override the default sort() method on the grid store
// this one uses our own sorting information instead.
grid.store.sort = function(field, dir) {
var sort = this.constructor.prototype.sort;
if (field in sortColumns) {
return sort.call(this, sortColumns[field], dir);
} else {
return sort.call(this, field, dir);
}
}
}
}
Then just add a sortBy entry to your column definition:
colModel: new Ext.grid.ColumnModel({
defaults: {
sortable: true
},
columns: [
{
header: 'Name',
dataIndex: 'name',
width: 350
}, {
header: 'Code',
dataIndex: 'code_summary',
sortBy: 'code_sort_order',
width: 100
}, {
header: 'Start Date',
dataIndex: 'start_date',
width: 85
}]
}),
PS: dont forget to add the field you are sorting on (code_sort_order) to your data store.

Resources