Kendo ui tooltip content return "e.uniqueSort is not a function" error - kendo-ui-grid

I'm showing tooltip on kendo grid column. When i return string in content in kendo tooltip i get an error: "e.uniqueSort is not a function".
I can't find any solution for this problem.
this is my code:
gridMain.table.kendoTooltip({
filter: ".meghdarVahedFari",
position: "right",
showOn: "click",
autoHide: false,
width: 200,
content: function (e) {
var grid=$("#grid").data("kendoGrid");
var row = $(e.target).closest("tr");
var dataItem = grid.dataItem(row);
return dataItem.AmountFarei;
}
}).data("kendoTooltip");
and this is my grid:
function fillGrid(dataSource) {
var gridMain=$("#grid").kendoGrid({
scrollable: true,
filterable: {mode:"row"},
height: 450,
dataSource: {
data: dataSource,
schema: {
model: {
id:"ID",
fields: {
ID: {type: "number"},
Product:{type:"string"},
AmountFarei:{type:"number"}
}
}
},
pageSize: 15
},
columns: [
{field: "Product",title: "Product Code",width: "11%",attributes: {
"class": "meghdarVahedFari"
}
}
]
}).data("kendoGrid");

My problem was jquery version. according to:
https://www.telerik.com/forums/-58994e55a90b
This problem will be fixed in our upcoming service pack release R2 2019 SP1.
You can solve this problem with change jquery version to 3.4.1. or if you can't change your version of jquery, you can add following code:
kendo.jQuery.uniqueSort = kendo.jQuery.uniqueSort ? kendo.jQuery.uniqueSort : kendo.jQuery.unique;
That used in:
https://dojo.telerik.com/AGAsAKAG/3

Related

VueJS - How to have a custom headerName of columnDefs in ag-grid-vue

I am trying to display my header name in a new line, but i am unable to do it.
Version of ag-grid-vue: 6.12.0
Here is what i tried but it did not work out:
defaultColDef: {
sortable: true,
editable: true,
resizable: true,
suppressMenu: true
},
columnDefs: [
{
headerName: 'Average low ', // This value is displayed in a single line
field: 'average_low',
width: 200,
},
{
headerName: 'Average high ', // Even this value is displayed in a single line
field: 'average_high',
width: 200,
},
...
}
I tried something like this to display the headerName in new line:
{
headerName: 'Avg. \n low ', // This value is displayed in a single line
field: 'average_low',
width: 200,
},
{
headerName: 'Avg. </br> high ', // Even this value is displayed in a single line
field: 'average_high',
width: 200,
},
I want to display something like this:
Please tell me how i can do this. Here is the officially documentation:
https://www.ag-grid.com/documentation/vue/component-header/
and here is the plunker which shows the example and can be used to workout:
https://plnkr.co/edit/QGopxrvIoTPu2vkZ
EDIT: here is a working solution >> https://plnkr.co/edit/Lr6cneCFiT91lCOD
Adapt it to your liking with the according theme (alpine, balham and so on) and the height that you wish or any other CSS structure that you have.
As told below, this inspired by this guy's work.
A working solution can be done with the script below
const MIN_HEIGHT = 80; // this line is the one you're looking for !
function autosizeHeaders(event) {
if (event.finished !== false) {
event.api.setHeaderHeight(MIN_HEIGHT);
const headerCells = document.querySelectorAll('#myGrid .ag-header-cell-label');
let minHeight = MIN_HEIGHT;
headerCells.forEach(cell => {
minHeight = Math.max(minHeight, cell.scrollHeight);
});
event.api.setHeaderHeight(minHeight);
}
}
(function() {
document.addEventListener('DOMContentLoaded', function() {
var gridDiv = document.querySelector('#myGrid');
var gridOptions = {
enableColResize: true,
enableSorting: true,
onColumnResized: autosizeHeaders,
onGridReady: autosizeHeaders,
columnDefs: [
{
headerName: 'Header with a very long description',
field: 'name',
headerClass: 'multiline'
},
{
headerName: 'Another long header title',
field: 'role',
headerClass: 'multiline'
}
],
rowData: [
{name: 'Niall', role: 'Developer'},
{name: 'Eamon', role: 'Manager'},
{name: 'Brian', role: 'Musician'},
{name: 'Kevin', role: 'Manager'}
]
};
new agGrid.Grid(gridDiv, gridOptions);
});
})();
There is a github issue here with a Stackoverflow thread with a lot of hacky (but working) solutions. It looks like there is no official support for this, so your best bet would be to check there and try out the various CSS solutions.
If you have a hosted example that we can play with, I may help more but right now, I can only recommend reading the various comments and try to tinker the CSS with your dev tools ! :)

Using Rally WsapiDataStore at a certain date

I want to create a chart of how many tasks are in a given Schedule State during the length of the sprint. Is it possible to call WsapiDataStore on each day?
What you are looking for is a lookback Snapshot Store , using the Lookback API - this allows you to specify a date or a point in time that you want to query by.
A typical use looks like this:
Ext.create('Rally.data.lookback.SnapshotStore', {
pageSize : 10000,
fetch : ['fetch'],
filters : [{
property : '__At',
value : 'current'
},{
property : '_ItemHierarchy',
value : 'HierarchicalRequirement'
}]
}).load({
callback : function(records) {
Ext.Array.each(records, function(record) {
// do something with each record
});
}
});
WsapiDataStore is not intended for historic data. You need to use Rally.data.lookback.SnapshotStore which retrieves data from the Lookback API.
Lookback API allows to see what any work item or collection of work items looked like in the past. This is different from using WS API directly (or via WsapiDataStore) which can provide you with the current state of objects, but does not have historical data.
LBAPI documentation is available here
As far as Rally release object's attributes see WS API object model here. But it is not clear from your comment what you mean by data for the entire release. If you are interested in getting back user stories assigned to a specific release then your query object should be hierarchical requirement and not release, and you may filter by release.
Here is an app that builds a chart using a Release dropdown. Based on the selection in the dropdown the chart is refreshed (it is destroyed and added):
Ext.define('CustomApp', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'release',
comboboxConfig: {
fieldLabel: 'Select a Release:',
labelWidth: 100,
width: 300
},
addContent: function() {
this._makeStore();
},
onScopeChange: function() {
this._makeStore();
},
_makeStore: function() {
Ext.create('Rally.data.WsapiDataStore', {
model: 'UserStory',
autoLoad: true,
filters: [this.getContext().getTimeboxScope().getQueryFilter()],
listeners: {
load: this._onDataLoaded,
scope: this
}
});
},
_onDataLoaded: function(store, data) {
var records = [];
var scheduleStateGroups = ["Defined","In-Progress","Completed","Accepted"]
// State count variables
var definedCount = 0;
var inProgressCount = 0;
var completedCount = 0;
var acceptedCount = 0;
// Loop through returned data and group/count by ScheduleState
Ext.Array.each(data, function(record) {
//Perform custom actions with the data here
//Calculations, etc.
scheduleState = record.get('ScheduleState');
switch(scheduleState)
{
case "Defined":
definedCount++;
break;
case "In-Progress":
inProgressCount++;
break;
case "Completed":
completedCount++;
break;
case "Accepted":
acceptedCount++;
}
});
if (this.down('#myChart')) {
this.remove('myChart');
}
this.add(
{
xtype: 'rallychart',
height: 400,
itemId: 'myChart',
chartConfig: {
chart: {
},
title: {
text: 'User Story Schedule State Counts',
align: 'center'
},
xField : 'ScheduleState',
xAxis: [
{
//categories: scheduleStateGroups,
title: {
text: 'ScheduleState'
}
}
],
yAxis: {
title: {
text: 'Count'
}
},
plotOptions : {
column: {
color: '#F00'
},
series : {
animation : {
duration : 2000,
easing : 'swing'
}
}
}
},
chartData: {
categories: scheduleStateGroups,
series: [
{
type: 'column',
data: [definedCount, inProgressCount, completedCount, acceptedCount]
}
]
}
}
);
this.down('#myChart')._unmask();
}
});

sencha touch dynamic chart

in Sencha Touch 2.1 how can I load the chart dynamically from json, also with dynamic fields store, chart axes, and chart series,
I know maybe this is too much, but I need to display many kind of data, If I create 1 chart component for each display means I have to create more than 15 chart component, I'm afraid it get bloated
I did not complete this dynamically, but I made it seem dynamic.
I first request a user to fill out a form.
I also have multiple panels that holds charts with empty stores, in the form of several different layouts.
Based on the user's form, I show and hide panels, or chart when they need to be displayed only after loading the store with the required data.
yes it is bulky, and they are static, but I found it slightly easier to handle than dynamically loading.
EDIT
After thinking,
have you tried a function like
function dynamiccharts(var1, var2, var3){
return Ext.chart.Chart({
....
})
}
variables would include things like data, url, store or etc.
This is my example creating a chart on controller inside a panel: axis, series, store fields, url are became parameters, PAR_FORM is global variable showing the difference between views, I'm using this code for another chart (Column, Pie)
Ext.define("Geis.controller.app", {
extend: "Ext.app.Controller",
config: {
refs: {
mainview: 'mainview',
barchartview: 'barchartview',
btnShowChartAnggaran: '#btnShowChartAnggaran'
},
control: {
'btnShowChartAnggaran': {
tap: 'onShowChartAnggaran'
}
}
}
createBarChart: function(fields, series_xfield, series_yfield, url) {
this.getBarchartview().add(new Ext.chart.CartesianChart({
id: 'barchartgenerateview',
store: {
fields: fields,
proxy: {
type: 'jsonp',
url: url
}
},
background: 'white',
flipXY: true,
colors: Geis.view.ColorPatterns.getBaseColors(),
interactions: [
{
type: 'panzoom',
axes: {
"left": {
allowPan: true,
allowZoom: true
},
"bottom": {
allowPan: true,
allowZoom: true
}
}
},
'itemhighlight'
],
series: [{
type: 'bar',
xField: series_xfield,
yField: series_yfield,
highlightCfg: {
strokeStyle: 'red',
lineWidth: 3
},
style: {
stroke: 'rgb(40,40,40)',
maxBarWidth: 30
}
}],
axes: [{
type: 'numeric',
position: 'bottom',
fields: series_yfield,
grid: {
odd: {
fill: '#e8e8e8'
}
},
label: {
rotate: {
degrees: -30
}
},
maxZoom: 1
},
{
type: 'category',
position: 'left',
fields: series_xfield,
maxZoom: 4
}]
}));
Ext.getCmp('barchartgenerateview').getStore().load();
},
onShowChartAnggaran: function() {
this.getBarchartview().remove(Ext.getCmp('barchartgenerateview'), true);
if (PAR_FORM == 'Dana Anggaran') {
this.createBarChart(['kode', 'keterangan', 'nilai'], 'keterangan', 'nilai',
Geis.util.Config.getBaseUrl() + 'anggaran/laporan/json/get_dana_anggaran_json/');
} else if (PAR_FORM == 'Alokasi Anggaran') {
this.createBarChart(['kode', 'keterangan', 'belanja_pegawai', 'belanja_barang', 'belanja_modal'],
'keterangan', ['belanja_pegawai', 'belanja_barang', 'belanja_modal'],
Geis.util.Config.getBaseUrl() + 'anggaran/laporan/json/get_alokasi_json/');
}
this.getMainview().animateActiveItem(1, {type:'slide', direction:'left'});
}
});
base on my experiment if you want to activate the interactions features you need to set the chart id dynamically too, for example by creating Global Counter Variable

ExtJS RowExpander - nextBd is null

I have problem configuring RowExpander for my grid. When the grid renders the expander is already opened for each row and with nothing inside. When i click on its icon the following error is generated: nextBd is null. I found very similar problem here http://www.sencha.com/forum/showthread.php?185837-Grid-Panel-PlugIn-Rowexpander-nextBd-is-null but the solution does not work for me and still dont get it why plugin config cannot be passed in initComponent method:
Here is my grid code:
Ext.define('GSIP.view.plans.PlanReqList' ,{
extend: 'Ext.grid.Panel',
alias : 'widget.gsip_devplan_list',
id: 'gsip_plan_list',
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'Nazwa:{name}'
]
}],
//title:i18n.getMsg('gsip.view.PlanReqList.title'),
layout: 'fit',
initComponent: function() {
this.store = 'DevPlan';
// this.plugins = [{
// ptype: 'rowexpander',
// rowBodyTpl : [
// {name}
// ]
// }];
this.features = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
this.tbar = [{
xtype:'commandbutton',
id: 'newReq',
iconCls:'icon-application_add',
text: i18n.getMsg('gsip.view.plans.PlanReqList.addReq'),
command: 'newReq',
}];
this.viewConfig = {
forceFit:true,
getRowClass: function(record, index) {
var c = record.get('elapsedPercent');
if (c >= 0) {
return 'elapsed-normal';
}
}
}
this.columns = [
{header: "Id", dataIndex: "id", width:50, sortable: true, filter:{type:'numeric'}},
{header: i18n.getMsg('gsip.view.plans.PlanReqList.column.name'), dataIndex: "name", flex:1, sortable: true, filter:{type:'string'} },
}
];
this.callParent(arguments);
},
The rowexpander plugin makes use of a feature called rowbody.
In your initComponent() you override this.features (which already includes rowbody) with this line:
this.features = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
Thus the rowbody feature is not included; thus the .x-grid-rowbody-tr class is not injected; thus rowexpander can't find such class for nextBd and returns null.
You should try:
var iNewFeatures = [{ftype:'filters', encode:false, local:true},{ftype:'grouping'}];
this.features = iNewFeatures.concat( this.features );
Lastly, plugins cannot be initiated in InitComponent(), you can either declare them as configs, or within the constructor. See this thread for more info.

Extjs 4 treepanel bug

I use a simple treepanel for my application, and sometimes it stops expanding and unexpanding nodes with the next error:
records[i] is undefined
http://localhost:8080/extjs/ext-all-debug.js
Line 58763
My code is quite simple:
var tree_store = Ext.create('Ext.data.TreeStore', {
id: 'tree_store_id',
proxy: {
type: 'ajax',
url: 'tree_data.json?object_id=' + Ext.getCmp('object_id').value
},
root: {
text: 'Парки',
id: 'objectId',
expanded: true,
iconCls: 'tree-cls-root'
}
});
var tree = Ext.create('Ext.tree.Panel', {
id: 'stock_tree_id',
store: tree_store,
autoWidth: true,
height: 600,
autoScroll: true,
renderTo: document.getElementById('stock_tree_div'),
useArrows: true,
border: false,
rootVisible: true,
listeners: {
itemclick: function (view, rec, item, index, eventObj) {
document.getElementById("stock_div").innerHTML = rec.data.text;
}
}
});
Has anyone faced this problem?
May be it's problem at your JSON. Is it include something like:
"leaf" : "true",
"expanded" : "true"
?
In my case this was caused by the fact that server response json contained parent node as a first element.
So when I was expanding node 123, server was returning node 123 itself and then all of it's children.