Grouping by month on extjs grid - date

I have a grid, which has a payments store. The Payment model, which it's store uses, has a field which is a date.
I've already implemented grouping by date, but that gives me a group of entries for each day, like this...
What I want to do is have a group for each month instead of each day.
Any ideas on how to do this?

Ok, nevermind. I just found a way to do this. I created a field using convert to find the month of the payment and used that field as the grouping field.
I'll leave this posted in case anyone ever needs it.
This is the Payment model...
Ext.define('Ext.model.Payment',{
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
fields: [
{
name: 'n_id_payment',
type:'integer'
},{
name: 'n_amount',
type:'integer'
}.....,
..... Several other fields .....
},{
name:'payment_month',
type:'date',
convert:function(model, record){
var today = new Date(record.data.dt_date);
var dd = today.getDate();
var mm = today.getMonth();
var month=new Array();
month[0]="Enero";
month[1]="Febrero";
month[2]="Marzo";
month[3]="Abril";
month[4]="Mayo";
month[5]="Junio";
month[6]="Julio";
month[7]="Agosto";
month[8]="Septiembre";
month[9]="Octubre";
month[10]="Noviembre";
month[11]="Diciembre";
return month[mm];
}
}
]
})
And this is the payment store...
Ext.define('Ext.store.PaymentsStore', {
extend: 'Ext.data.Store',
requires: [
'Ext.model.Payment',
'Ext.data.proxy.Memory'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
async:false,
groupField:'payment_month',
model: 'Ext.model.Payment',
method:'POST',
proxy: {
isSynchronous:true,
type: 'ajax',
url: 'http://localhost/index.php/TblPayment/fetch',
reader:{
type :'json',
method:'POST'
}
}
}, cfg)]);
}
});
This is the groupingFeature config...
var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
groupHeaderTpl:'{name}'
});
The grid should have this property set too features: [groupingFeature]
And in case you're stuck with an error with grouping, something about getRowStyleTableEl being null... There's a workaround for that issue...
Ext.override(Ext.view.Table, {
/*
Temporary fix for bug in ExtJS 4.2.1. See: sencha.com/forum/showthread.php?264657-Exception-When-Selecting-First-Grid-Row
*/
getRowStyleTableElOriginal: Ext.view.Table.prototype.getRowStyleTableEl,
getRowStyleTableEl: function() {
var el = this.getRowStyleTableElOriginal.apply(this, arguments);
if (!el) {
el = {
addCls: Ext.emptyFn,
removeCls: Ext.emptyFn,
tagName: {}
}
}
return el;
}
});

Related

How to give configurable URL in tableau WDC

I am trying to build a tabeau WDC.
this is my code
(function () {
var myConnector = tableau.makeConnector();
myConnector.getSchema = function (schemaCallback) {
var cols = [{
id: "month",
dataType: tableau.dataTypeEnum.string
}, {
id: "value1",
alias: "value1",
dataType: tableau.dataTypeEnum.float
}, {
id: "value2",
alias: "value2",
dataType: tableau.dataTypeEnum.float
}];
var tableSchema = {
id: "testfeed",
alias: "test Feed",
columns: cols
};
schemaCallback([tableSchema]);
};
myConnector.getData = function (table, doneCallback) {
$.getJSON('http://test.com/view?name=test&filters=[{"type":"number","id_equals":["123"]}]', function (resp) {
var feat = resp.DATA,
tableData = [];
// Iterate over the JSON object
for (var i = 0, len = feat.length; i < len; i++) {
tableData.push({
"MONTH": feat[I].month,
"ChargeEntryLag_NUMERATOR": feat[i]. value1,
"ChargeEntryLag_DENOMINATOR": feat[i]. value2
});
}
table.appendRows(tableData);
doneCallback();
});
};
tableau.registerConnector(myConnector);
$(document).ready(function () {
$("#submitButton").click(function () {
tableau.connectionName = "testFeed";
tableau.submit();
});
});
})();
my URL contains some filters as shown in the above code, so if U want to get data for a particular filter I have to hardcode it in URL and the use it.
In other word my URL is static , Is there a way to make it dynamic.
suppose I want the value of 'id' to be 10in my filter, for that I have to go the the WDC code and change it. can it be made configurable.
use tableau.connectionData to pass data. There is an example in this tutorial:
https://tableau.github.io/webdataconnector/docs/wdc_multi_table_tutorial
Typically you'd create a form. When you connect with the WDC in tableau desktop, you put in the URL of your form. The form will store the form vars in tableau.connectData. Your getData can then take those and create a custom Data Source inside tableau desktop for you.
- Mike

Why my filter is not working in v2.ODataModel "read"?

I am using the OData model to read data. But it doesn't work. Check the code below:
getGuid: function(pernr) {
var self = this;
var url = "/PersonalDetailSet?$filter=Pernr eq '00000001'";
self.setBusy(true);
this.oModel.read(url, {
success: function(res) {
// ...
},
error: function() {
// ...
}
});
}
I don't know why the filter in url is not working now?
Check if your OData service supports the $filter query in the first place.
Use the read method correctly:myV2ODataModel.read("/PersonalDetailSet"/* No $filter queries here! */, {
filters: [ // <-- Should be an array, not a Filter instance!
new Filter({ // required from "sap/ui/model/Filter"
path: "myField",
operator: FilterOperator.EQ, // required from "sap/ui/model/FilterOperator"
value1: "..."
})
],
// ...
});
API reference: sap.ui.model.odata.v2.ODataModel#read
API reference: sap.ui.model.Filter
First you check whether you are getting model in the scope or not. As i can see this.oModel which is not proper way of getting model. Better use this.getModel() or this.getView().getModel() and then check the call. Passing filter is not the right way but still it should work.
If you want to apply additional URL Parameters in the read function you have to do this via the "urlParameters" parameter:
getGuid: function(pernr){
var self = this;
var url = "/PersonalDetailSet";
self.setBusy(true);
this.oModel.read(url, {
urlParameters: {
"$filter" : "Pernr eq '00000001'"
},
success: function(res){
self.setBusy(false);
self.guid = res.results[0].Guid;
},
error: function() {
self.setBusy(false);
}
});
}

How to have an optional association using Waterline?

I'm using sails.js for a project and everything is going fine so far. Except that I don't know how to have an optional association between my two models. If I don't specify one, then if I use populate() it takes the first one available.
I have those two models:
// Book.js
module.exports = {
attributes: {
title: 'string',
serie: { model: 'serie' }
},
};
// Serie.js
module.exports = {
attributes: {
name: 'string',
books: { collection: 'book', via: 'serie' }
}
};
If I do this:
$ sails console
> Book.create({title: "Title"}).exec(function(err, book) {
Book.findOne({id: book.id }).populateAll().exec(function(err, book) {
console.log(book);
});
});
I get this:
{
serie: { name: 'Previously inserted serie' },
title: 'Title',
id: '55d6230122e3b1e70d877351'
}
Why isn't serie empty ? When inserting the book, I didn't specify any serie but it is still linked to a random one.
It was actually a bug from the sails-mongo adapter. I made a pull request that fixes it.

StrongLoop loopback - REST example using filters on related models?

I found this example to use the Node API to apply filters to related models, but I was wondering if it was possible to achieve the same result using REST?
Node Example:
Post.find({
include: {
relation: 'owner', // include the owner object
scope: { // further filter the owner object
fields: ['username', 'email'], // only show two fields
include: { // include orders for the owner
relation: 'orders',
scope: {
where: {orderId: 5} // only select order with id 5
}
}
}
}
}, function() { ... });
The closest version of a REST url I can get to work is:
...?filter[include][owners][orders]
Is it possible to create a REST url that behaves the same way as the above Node example, by limiting the results based on a related model filter... in this case orders?
I have this functions so when I call the Hdates/coming REST API it shows the events with date greater than today and also includes the venues... Hope it helps.
Hdate.coming = function(cb) {
Hdate.find({
where : {
event_date :{gt: Date.now()}
},
include : {
relation: 'event',
scope : {
include: {
relation: 'venue'
}
}
}
}, cb);
};
Hdate.setup = function() {
Hdate.base.setup.apply(this, arguments);
this.remoteMethod('coming', {
description: 'Find Coming Events by Date',
returns: {arg: 'events', root: true},
http: { verb: 'GET' }
});
};
Hdate.setup();

How can I validate a model attribute against another model attribute in Sails?

Let's say I have an Invoice model in SailsJS. It has 2 date attributes: issuedAt and dueAt. How can I create a custom validation rule that check that the due date is equal or greater than the issued date?
I tried creating a custom rule, but it seems I cannot access other properties inside a rule.
module.exports = {
schema: true,
types: {
duedate: function(dueAt) {
return dueAt >= this.issuedAt // Doesn't work, "this" refers to the function, not the model instance
}
},
attributes: {
issuedAt: {
type: 'date'
},
dueAt: {
type: 'date',
duedate: true
}
}
};
I hope you found a solution now, but for those interested to a good way to handle this i will explain my way to do it.
Unfortunatly as you said you can't access others record attributes in attribute customs validation function.
#Paweł Wszoła give you the right direction and here is a complete solution working for Sails#1.0.2 :
// Get buildUsageError to construct waterline usage error
const buildUsageError = require('waterline/lib/waterline/utils/query/private/build-usage-error');
module.exports = {
schema: true,
attributes: {
issuedAt: {
type: 'ref',
columnType: 'timestamp'
},
dueAt: {
type: 'ref',
columnType: 'timestamp'
}
},
beforeCreate: (record, next) => {
// This function is called before record creation so if callback method "next" is called with an attribute the creation will be canceled and the error will be returned
if(record.dueAt >= record.issuedAt){
return next(buildUsageError('E_INVALID_NEW_RECORD', 'issuedAt date must be equal or greater than dueAt date', 'invoice'))
}
next();
}
};
beforeCreate method in model as first param takes values. The best place for this kind of validation I see here.
beforeCreate: (values, next){
if (values.dueAt >= values.issuedAt) {
return next({error: ['...']})
}
next()
}