Error on calling showAt method of Ext.menu.Menu - extjs

Hi I am trying to display context menu on right click of a dataview item. I handled itemcontextmenu event in which I instantiated Ext.menu.Menu and called its showAt method, but
it is giving me error as TypeError: me.el.translatePoints is not a function in Component.js
I observed the el is undefined, what value should be assigned to it so that the translatePoints function works? or there can be other work around?
Please find my code below:
{
xtype: 'dataview',
store: 'SearchedGraphics',
tpl: [
'<tpl for=".">',
'<div class="thumb-wrap" id="{name:stripTags}">',
'<div class="thumb"><table><tr><td><img class="img" src="{url}" title="{name:htmlEncode}"></td></tr></table></div>',
'<span class="x-editable">{shortName:htmlEncode}</span>',
'</div>',
'</tpl>',
'<div class="x-clear"></div>'
],
multiSelect: true,
height: 310,
trackOver: true,
overItemCls: 'x-item-over',
itemSelector: 'div.thumb-wrap',
emptyText: ORT.Utility.GridEmptyText,
prepareData: function(data) {
Ext.apply(data, {
shortName: Ext.util.Format.ellipsis(data.name, 15),
sizeString: Ext.util.Format.fileSize(data.size),
dateString: Ext.util.Format.date(data.lastmod, "m/d/Y g:i a")
});
return data;
},
listeners: {
selectionchange: function(dv, nodes ){
if(false) {
var l = nodes.length,
s = l !== 1 ? 's' : '';
this.up('panel').setTitle('Simple DataView (' + l + ' item' + s + ' selected)');
}
},
itemcontextmenu: function(dataview, record, item, index, event, eOpts){
var menu = Ext.create('Ext.menu.Menu', {
width: 100,
el:'p',
margin: '0 0 10 0',
floating: false,
items: [{
text: 'regular item 1'
},{
text: 'regular item 2'
},{
text: 'regular item 3'
}]
}).showAt(event.getXY());
}
}
}

1) Not sure why you set floating to false. It's a menu, so it should float.
2) You shouldn't be setting the el config at all.

Related

ExtJS :Pass groupname in grouped combobox tpl dynamically

I am working on a group combobox where I need to pass group-name dynamically(from its config).
var data = [{
group: 'Fubar',
key: '1',
name: '2015 Product Development'
}, {
group: 'Fubar',
key: '2',
name: 'Message Filter'
}, {
group: 'Fubar',
key: '3',
name: '2014 Product Development (Little)'
}, {
group: 'Other',
key: '4',
name: 'Global Structure'
}, {
group: 'Other',
key: '5',
name: 'My SW'
}];
Ext.apply(combo, {
listConfig: {
tpl = new Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<tpl for="group" if="this.shouldShowHeader(group)"><div class="group-header">{[this.showHeader(values.group)]}</div></tpl>',
'<div class="x-boundlist-item"><input type="checkbox" />{name}</div>',
'</tpl>', {
shouldShowHeader: function(group) {
return this.currentGroup !== group;
},
showHeader: function(group) {
this.currentGroup = group;
return group;
}
});
}
});
var combo = Ext.create('Ext.data.Store', {
fields: ['group', 'key', 'name'],
data: data
});
items: [{
xtype: 'combobox',
id: 'searchInput',
store: combo,
multiSelect: true,
labelWidth: 50,
queryMode: 'local',
displayField: 'name',
fieldLabel: 'Choose',
listConfig: {
cls: 'grouped-list'
},
tpl: tpl,
groupName: 'group'
}]
I have tried with code but not working. It giving group, property itself instead of its value.
<tpl for="combo.groupName" if="this.shouldShowHeader(combo.groupName)">
Here combo is combobox instance being used.
Tpl should be used in this way to get desired output.
'<tpl for=".">',
'<tpl for="' + combo.groupName + '" if="this.shouldShowHeader(' + combo.groupName + ')"><div class="group-header">{[this.showHeader(values.' + combo.groupName + ')]}</div></tpl>',
'<div class="x-boundlist-item"><input type="checkbox" />{name}</div>',
'</tpl>'

EXTJS5 - how to add the legend color of pie chart dynamically?

I have an issue while using custom legend color in EXTJS 5 chart. I can apply custom color to the chart legend but i cannot apply that to the legend item. i can hard-code the colors using "colors" property within series to handle this issue statically .like
series: {
type: 'bar',
colors: ['orange', 'yellow'],
...
}
But,i need to pass the color dynamically. i need to fetch the legend colors from store.So i cannot hard-code it
My code.
Ext.define('GMIS.view.charts.pie.BasicPieLegend', {
extend: 'Ext.Panel',
config:{
storeValue: null, //'BankerDataStoreChr'
widthValue: null,
heightValue: null,
identifier: null,
titleValue : null,
styleValue : null,
styleValue1 : null,
chartValue : null,
selBanker : null
},
storeValue: null,
constructor: function(cfg){
this.initConfig(cfg);
this.callParent();
this.addCls(this.getStyleValue());
this.addCls(this.getStyleValue1());
},
xtype: 'basic-pie1',
border: 0,
initComponent: function() {
var me = this;
me.items = [{
xtype: 'polar',//'chart',
id: this.identifier,
itemId: this.identifier,
border:0,
legend: {
docked: 'top',
},
interactions: 'rotate',
width: this.widthValue,
height: this.heightValue,
animate: false,
shadow: false,
store: this.storeValue,
insertPadding: 0,
series: [{
type: 'pie',
label: {
field: 'name',
display: 'rotate',
},
xField: 'data1',//angleField:
donut: 30,
//colors: ['orange', 'yellow'],
/*colors : ['#55aaff',
'#ffbb00',
'#DA4545',
'#8866ff',
'#ff6600',
'#B8005C',
'#947171'],*/
renderer: function (sprite, config, rendererData, index/*sprite, record, attr, index*/) {
var record = rendererData.store.getData().items[index];
console.log(record.data.color);
return Ext.apply(rendererData, {
fillStyle: record.data.color
});
},
showInLegend: true
}]
}];
this.callParent();
},
});
Please let me know if i need to change something.
Thanks in advance
I've created fiddle for you: Dynamic colors fiddle.
Just use setColors() method and update layout with doLayout() method. Your chart colors (with legend colors too) will be updated.
You can use legend tpl for this implementation.
legend: {
docked: 'bottom',
tpl: ['<div class="', Ext.baseCSSPrefix, 'legend-container">', '<tpl for=".">', '<div class="', Ext.baseCSSPrefix, 'legend-item">', '<span ', 'class="', Ext.baseCSSPrefix, 'legend-item-marker {[ values.disabled ? Ext.baseCSSPrefix + \'legend-inactive\' : \'\' ]}" ', 'style="background:{[this.getLegendColor(values)]};">', '</span>{name}', '</div>', '</tpl>', '</div>',
{
getLegendColor: function(recordValues) {
var color = null;
// Set color using data from corresponding record
return color;
}
}]
}

hide combo box value when already selected extjs

I have 2 combo box inside grid. The second combo box value will be change base on first combo box.
For example the combo has 3 item : America, Europe, Asia. If in the first combo box Europe is selected, then in the second combo box, Europe is not appear again.
I don't know which version of extjs I used, but here's the code :
MY COMBO STORE
var cb_group = Ext.create('Ext.data.Store', {
model: 'cb_group',
autoLoad: false,
proxy: {
type: 'ajax',
url: 'srv/master/group/combo',
reader: {
type: 'json',
root: 'rows'
}
}
});
MY COMBO INSIDE GRID
var set_approval_dtl = Ext.create('Ext.Window', {
title: title_approval2, width: 850, height: 395, rowdblclick: true, forceFit: true,
closeAction: "hide", store: ms_set_approval_dtl_store,
defaults: {
sortable: true, resizable: false
},
items: [
{xtype: "form", items: [
{layout: 'column', columnWidth: .5, itemId: 'set_approve', defaults: {border: false},
items: [{xtype: "panel", itemId: "set_approve_panel", height: 330, defaultType: 'textfield', margin: '0 10px 0 10px',
defaults: {labelWidth: 120, width: 850, maxLength: 200},
items: [
{xtype: "grid", itemId: "grid_items", width: 782, height: 280, margin: '0 10px 10px 10px', autoScroll: true,
plugins: Ext.create('Ext.grid.plugin.CellEditing', {clicksToEdit: 1, pluginId: 'rowEditing'}),
store: ms_set_approval_dtl_store, stripeRows: true, defaultType: "gridcolumn",
viewConfig: {forceFit: true},
columns: [
{header: grid18j, width: 150, dataIndex: 'nm_act', align: 'center'},
{header: subtitle_approval3, width: 126, dataIndex: 'level1', align: 'center',
editor: {xtype: "combobox", name: "cdgr", itemId: "cdgr1", typeAhead: true, editable: false, triggerAction: "all", forceSelection: true,
emptyText: grid8k, store: cb_group, valueField: "id", displayField: "nm",
listeners: {
expand: function(field, options, val) {
if (Ext.typeOf(field.getPicker().loadMask) !== "boolean") {
field.getPicker().loadMask.hide();
}
},
select: function(value) {
var obj = this.lastSelection[0].data;
return obj.nm;
this.lastSelection[0].hide;
cb_group.removeAt(0);
}
}},
renderer: function(val) {
var index = cb_group.findExact('id', val);
if (index !== -1) {
var rs = cb_group.getAt(index).data;
return rs.nm;
}
}
},
{header: subtitle_approval4, width: 126, dataIndex: 'level2', align: 'center', itemId: "level2",
editor: {xtype: "combobox", name: "cdgr", itemId: "cdgr2", typeAhead: true, editable: false, triggerAction: "all", forceSelection: true,
emptyText: grid8k, store: cb_group, valueField: "id", displayField: "nm",
listeners: {
expand: function(field, options) {
if (Ext.typeOf(field.getPicker().loadMask) !== "boolean") {
field.getPicker().loadMask.hide();
}
}
}
},
select: function(value) {
var obj = this.lastSelection[0].data;
return obj.nm;
},
renderer: function(val) {
var index = cb_group.findExact('id', val);
if (index !== -1) {
var rs = cb_group.getAt(index).data;
return rs.nm;
}
}
}]
}]}
]}]}
]});
I've tried this.lastSelection[0].hide; and cb_group.removeAt(0); in the first combo. But it didn't work at all. And I dont know why my select listener is not working.
please share some solution. Thanks
You can use XTemplates to manage this kind of behavior with one store and two comboboxes.
At first you have to create an XTemplate for your list of items in the combobox:
// displayfield = displayfield configured in your combobox
var template = Ext.create('Ext.XTemplate',
'<tpl for=".">',
' <tpl if="[Ext.getCmp(\'combobox1\').getValue()] != id && [Ext.getCmp(\'combobox2\').getValue()] != id">',
' <div class="x-boundlist-item">{label}</div>',
' <tpl else>',
' <tpl if="id == null || id == \'\'">',
' <div class="x-boundlist-item">{label}</div>',
' <tpl else>',
' <div class="x-boundlist-item" style="font-size:0px; height:0px;"></div>',
' </tpl>',
' </tpl>',
'</tpl>'
);
The XTemplate contains some statements to check if the specific value is already selected in one of the comboboxes. If not, then the entry will appear in the dropdown list, otherwise it will be hidden. To make it work, you have to set the template in your combobox and add some listeners to them:
// Combobox 1
{
xtype: 'combo',
id: 'combobox1',
store: 'your_store',
tpl: template,
displayField: 'label',
valueField: 'id',
listeners: {
beforeSelect: function (combo, record, index, eOpts)
{
// Check if the selected value is already selected in combobox2
var cbx2value = !!Ext.getCmp('combobox2').getValue() ? Ext.getCmp('combobox2').getValue() : '';
if (cbx2value != record.get('id') && cbx2value != record.get('id')) {
return true; // selected entry will be selected successfully
} else {
return false; // selected entry will not be selected
}
},
change: function ()
{
// Get the picker (list of items) of the other combobox and refresh it's template state
var cbx2picker = Ext.getCmp('combobox2').getPicker();
cbx2picker.refresh();
}
}
// Combobox 2
{
xtype: 'combo',
id: 'combobox2',
store: 'your_store',
tpl: template,
displayField: 'label',
valueField: 'id',
listeners: {
beforeSelect: function (combo, record, index, eOpts)
{
// Check if the selected value is already selected in combobox2
var cbx1value = !!Ext.getCmp('combobox1').getValue() ? Ext.getCmp('combobox1').getValue() : '';
if (cbx1value != record.get('id') && cbx1value != record.get('id')) {
return true; // selected entry will be selected successfully
} else {
return false; // selected entry will not be selected
}
},
change: function ()
{
// Get the picker (list of items) of the other combobox and refresh it's template state
var cbx1picker = Ext.getCmp('combobox1').getPicker();
cbx1picker.refresh();
}
}
It's not the ultimate solution, but for one of my projects it worked like a charm. I have simplified the example as good as possible to make the solution clearer.
You will need two stores, one for each combo box, both filled with the same data.
And then you will do:
combo1.on('select',function(combo, newVal) {
combo2.getStore().filterBy(function(rec){
return rec.get("value")!=newVal;
})
});

Extjs DataView store.reload re-adds items

I have an extjs dataview:
var dv = Ext.create('Ext.view.View', {
store: this.eventInstanceImagesStore,
tpl: [
'<tpl for=".">',
'<div class="thumb-wrap" id="{name:stripTags}">',
'<div class="thumb"><img src="http://stimages.blob.core.windows.net/medium/{value}" title="{name:htmlEncode}"></div>',
'<span class="x-editable">{shortName:htmlEncode}</span>',
'</div>',
'</tpl>',
'<div class="x-clear"></div>'
],
multiSelect: true,
trackOver: true,
overItemCls: 'x-item-over',
itemSelector: 'div.thumb-wrap',
emptyText: 'No images to display',
plugins: [
// Ext.create('Ext.ux.DataView.DragSelector', {}),
Ext.create('Ext.ux.DataView.LabelEditor', { dataIndex: 'name' })
],
prepareData: function (data) {
Ext.apply(data, {
shortName: Ext.util.Format.ellipsis(data.name, 15),
sizeString: Ext.util.Format.fileSize(data.size),
dateString: Ext.util.Format.date(data.lastmod, "m/d/Y g:i a")
});
return data;
}
});
I also have a file upload form which, when the image has been successfully uploaded I am reloading the dataview:
dv.store.reload({
params: {
id: eid
}
});
However, when the reload happens it seems to re-add the images twice. So I end up with 2 dataviews... Has anyone seen this before?
Try doing dv.store.removeAll(); first before doing a
dv.store.reload({
params: {
id: eid
}
});

How do I enable custom drag and drop (ext js 4.1.3)

Edit: I deleted the code that didn't matter for the question being asked
I am trying to mimic the example given in the documentation here: http://docs.sencha.com/ext-js/4-1/#!/example/dd/dragdropzones.html.
When I click and drag inside any of the divs created by the dataview, I start selecting text instead of dragging the dataview item.
I have put console.log() statements here and there to verify that the code is firing. All of the elements that are returned by the getDragData function hold information.
I have tried adding both "draggable: true" and "enableDrag: true". Neither one allowed me to drag the div. However, "draggable: true" did make it such that when I clicked and dragged I was no longer selecting text.
I believe this is the only code that pertains to the issue:
SearchDataView.js
Ext.require('Client.store.SearchStore');
Ext.define('Client.view.SearchDataView',
{
extend: 'Ext.view.View',
alias: 'widget.SearchDataView',
config:
{
store: Ext.create('Client.store.SearchStore'),
tpl: '<tpl for=".">' +
'<div class="search-wrapper">' +
'<div class="search-icon">' +
'<img src="../../Images/icons/Person50x50.jpg" />' +
'</div>' +
'<div class="search-text">' +
'<span class="title">{FirstName} {LastName}</span>' +
'<span class="address">address, city, state zip</span>' +
'<span class="info">DOB: 7/3/1970</span>' +
'</div>' +
'</div>' +
'</tpl>',
itemSelector: 'div.search-wrapper',
emptyText: 'Nobody in database',
deferEmptyText: false,
singleSelect: true,
listeners:
{
render: initializeSearchDragZone
}
}
}
);
function initializeSearchDragZone(v) {
v.dragZone = Ext.create('Ext.dd.DragZone', v.getEl(), {
getDragData: function (e) {
var sourceEl = e.getTarget(v.itemSelector, 10), d;
if (sourceEl) {
d = sourceEl.cloneNode(true);
d.id = Ext.id();
return v.dragData = {
sourceEl: sourceEl,
repairXY: Ext.fly(sourceEl).getXY(),
ddel: d,
searchData: v.getRecord(sourceEl).data,
sourceStore: v.store
}
}
},
getRepairXY: function () {
return this.dragData.repairXY;
}
});
}
Viewport.js
Ext.require('Client.view.SearchPanel');
Ext.require('Client.view.DesktopPanel');
Ext.define('Client.view.Viewport',
{
extend: 'Ext.container.Viewport',
initComponent: function () {
Ext.apply(this,
{
layout: 'border',
items:
[
{
region: 'north',
margins: 5,
height: 30,
xtype: 'container'
},
{
region: 'west',
margins: '0 5 0 5',
flex: .25,
collapsible: true,
titleCollapse: true,
xtype: 'SearchPanel'
},
{
region: 'center',
xtype: 'DesktopPanel'
},
{
region: 'east',
margins: '0 5 0 5',
width: 200,
collapsible: true,
titleCollapse: true,
collapsed: true
},
{
region: 'south',
margins: '0 5 5 5',
flex: .3,
split: true
}
]
}
);
this.callParent(arguments);
}
}
);
SearchPanel
Ext.require('Client.view.SearchForm');
Ext.require('Client.view.SearchDataView');
Ext.require('Client.view.AddTrashForm');
Ext.define('Client.view.SearchPanel',
{
extend: 'Ext.panel.Panel',
alias: 'widget.SearchPanel',
config:
{
items:
[
{
xtype: 'SearchForm'
},
{
xtype: 'SearchDataView'
},
{
xtype: 'AddTrashForm'
}
]
},
cls: 'searchpanel'
}
);
I added layout config to SearchPanel, and drag started working:
layout:
{
type: 'vbox',
align: 'stretch'
}
It changes some of my layout, so I will have to adjust css now, but drag is working.

Resources