Answered: How does one drag an ExtJS Panel only by panelheader? - extjs

I have a panel which contains items in its body, and I would like the panel itself to be draggable, but only when the user drags the panelheader. (I don't want the user to be able to drag the panel by clicking and dragging in the body). Is there a simple way to do this?
Here is my code for creating the panel:
const newGridPanel = Ext.create({
xtype: 'panel',
id: newpanelid,
floated: true,
closable: true,
draggable: true,
scrollable: true,
width: 400,
height: 300,
resizable: {
constrainToParent: true,
dynamic: true,
edges: 'all',
minSize: 250,
maxSize: [window.innerWidth,window.innerHeight]
},
layout: 'fit',
title: 'Title',
tools: [
{
iconCls: 'x-fa fa-plus',
reference: 'addempbtn',
handler: function() {
newGridPanel.down(xt).getController().onAdd()
},
tooltip: 'Add a New Employee'
}
],
defaults: {
flex: 1
},
items: [
{
xtype: xt,
id: newgridid,
}
]
});
newGridPanel.setX(20);
newGridPanel.setY(20);
newGridPanel.show();
EDIT: I was able to figure out the problem and correct it. The solution has to do with the handle property of the Ext.drag.Source object. You have to specify the CSS handle of the element you want to be able to initiate the drag. In My case, the corrected code is as follows.
const newGridPanel = Ext.create({
xtype: 'panel',
id: newpanelid,
floated: true,
closable: true,
draggable: {handle: 'x-panelheader'}, // <- This is the part that needed to be changed
scrollable: true,
width: 400,
height: 300,
resizable: {
constrainToParent: true,
dynamic: true,
edges: 'all',
minSize: 250,
maxSize: [window.innerWidth,window.innerHeight]
},
layout: 'fit',
title: 'Title',
tools: [
{
iconCls: 'x-fa fa-plus',
reference: 'addempbtn',
handler: function() {
newGridPanel.down(xt).getController().onAdd()
},
tooltip: 'Add a New Employee'
}
],
defaults: {
flex: 1
},
items: [
{
xtype: xt,
id: newgridid,
}
]
});
newGridPanel.setX(20);
newGridPanel.setY(20);
newGridPanel.show();

Related

How to switch between cards in card layout

I have a card layout having two cards one with tab panel.Inside tab panel grid panel is there and another card is my content panel. I have to switch to next card i.e my content panel on cell click on my grid panel.
Have used the setActiveitem() function but something is wrong.
extend: Ext.panel.Panel,
id: 'cardpanel',
width: 300,
height: 1000,
reference: 'resultcardPanel',
itemid: 'cardPanel',
layout: {
type: 'card',
anchor: '100%'
},
activeItem: 0,
xtype: 'searchresults',
bodyStyle: 'padding:15px',
defaults: {
border: false
},
controller: 'email',
viewModel: {
type: 'email'
},
items: [{
xtype: 'tabpanel',
//id:'searchresults',
requires: [
'Ext.grid.Panel',
'Ext.toolbar.Paging',
'Ext.grid.column.Date'
],
cls: 'shadow',
activeTab: 0,
margin: 20,
///////////////////////////////////////////////////////
items: [{
xtype: 'grid',
cls: 'allRecordsCls',
scrollable: false,
border: false,
title: 'Primary',
routeId: 'inbox',
bind: '{inbox}',
itemclick: function() {
centerpanel = new Ext.Panel({
layout: 'card',
items: [homepanel, browser.grid]
});
centerpanel.getLayout().setActiveItem(1);
},
selModel: {
selType: 'checkboxmodel',
checkOnly: true,
showHeaderCheckbox: true
},
headerBorders: false,
rowLines: false,
scrollable: false,
listeners: {
itemclick: 'onGridCellItemClick2'
},
columns: [
{
dataIndex: 'from',
text: 'From',
width: 140,
},
{
dataIndex: 'title',
text: 'Subject',
flex: 1,
},
{
xtype: 'datecolumn',
dataIndex: 'received_on',
width: 90,
text: 'Received On'
}
],
},
//////////////////////////////////////////////////////////
{
xtype: 'grid',
cls: 'allRecordsCls',
scrollable: false,
border: false,
title: 'Social',
routeId: 'inbox',
bind: '{inbox}',
listeners: {
itemclick: 'clickme'
},
selModel: {
selType: 'checkboxmodel',
checkOnly: true,
showHeaderCheckbox: true
},
headerBorders: false,
rowLines: false,
scrollable: false,
columns: [
{
dataIndex: 'from',
text: 'From',
width: 140,
},
{
dataIndex: 'title',
text: 'Subject',
flex: 1,
},
{
xtype: 'datecolumn',
dataIndex: 'received_on',
width: 90,
text: 'Received On'
}
],
},
///////////////////////////////////////////////////////
{
xtype: 'grid',
cls: 'allRecordsCls',
scrollable: false,
border: false,
title: 'Promotion',
routeId: 'inbox',
bind: '{inbox}',
selModel: {
selType: 'checkboxmodel',
checkOnly: true,
showHeaderCheckbox: true
},
listeners: {
itemclick: 'onGridCellItemClick2'
},
headerBorders: false,
rowLines: false,
scrollable: false,
columns: [
{
dataIndex: 'from',
text: 'From',
width: 140,
},
{
dataIndex: 'title',
text: 'Subject',
flex: 1,
},
{
xtype: 'datecolumn',
dataIndex: 'received_on',
width: 90,
text: 'Received On'
}
],
},
],
},
///////////////////////////////////////////
{
id: 'cardPanel',
xtype: 'emaildetails'
},
]
what to write in function in "onGridCellItemClick2" which is declared in controller

Panel VBOX does not render items

As what the title suggest, is that I have a panel that will execute a command onRender to add items, like the code below, a treepanel. I wrapped treepanel in a layout - border and then on a vbox panel to be put on region west. Unfortunately the whole tree panel does not render. I inspected the HTML, and the elements are there but they are sort of disabled because the elements have that blurry font in the firebug. Why is it doing that? Please help.
Ext.define('anr.panels.report', {
extend : 'Ext.panel.Panel',
pageLimit : 15,
title : 'Report Generator',
layout : 'border',
border : false,
frame : true,
initComponent: function() {
this.callParent(arguments);
},
onRender:function() {
var me = this;
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{ text: "detention", leaf: true },
{ text: "homework", expanded: true, children: [
{ text: "book report", leaf: true },
{ text: "algebra", leaf: true}
] },
{ text: "buy lottery tickets", leaf: true }
]
}
});
var reportItem = {
xtype: 'panel',
layout: 'vbox',
id:'westpanel',
region:'west',
width: 350,
height: 300,
minSize: 350,
maxSize: 350,
border: false,
split: true,
margin: '1 0 5 1',
items: [
{
border: false,
layout: 'border',
items:[
{
xtype: 'treepanel',
height: 250,
width: 200,
store: store,
id: 'menu-panel',
frame: false,
rootVisible: false
}
]
}
]
};
this.add(reportItem);
this.callParent(arguments);
}
});
Im not really sure why you are using the onRender method instead of placing the panels in the items but there are too many errors there anyway.
Every border panel needs height, width or flex and it is required to have one panel with the center region.
If you change your code to this, it will work but be careful with all these nested panels, it seems like you are getting lost.
CODE
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "detention", leaf: true
},{
text: "homework", expanded: true,
children: [{
text: "book report", leaf: true
},{
text: "algebra", leaf: true
}]
}, {
text: "buy lottery tickets",
leaf: true
}]
}
});
Ext.define('anr.panels.report', {
extend : 'Ext.panel.Panel',
width: 800,
height: 400,
border: true,
title : 'Report Generator',
layout : 'border',
items: [{
xtype: 'panel',
layout: 'vbox',
region:'west',
width: 350,
height: 300,
minSize: 350,
maxSize: 350,
border: false,
split: true,
margin: '1 0 5 1',
items: [{
xtype: 'panel',
border: false,
layout: 'border',
flex: 1,
width: 350,
items:[{
xtype: 'treepanel',
height: 250,
width: 200,
store: store,
id: 'menu-panel',
region: 'center',
frame: false,
rootVisible: false
}]
}]
},{
xtype : 'panel',
region: 'center'
}]
});
Ext.create('anr.panels.report',{
renderTo: Ext.getBody()
});

Getting the Editable form on click of a Edit Button using ExtJs 3.4

I'm pasting my updated code here. Please have a look and let me know what mistake I'm doing here. In the form itself I'm displaying the grid too.
So when I click on the record to edit, I need to populate the form where I can edit the corresponding record details and update into DB.
var grid = new Ext.grid.GridPanel({
frame: true,
store: store,
selModel: sm,
enableHdMenu: false,
stripeRows: true,
autoScroll: true,
trackMouseOver: true,
disableSelection: false,
loadMask: true,
enableColumnMove: false,
height: 350,
width: 960,
title: 'Edit Contractor Details',
columns: [{
header: "Requestor Name",
width: 75,
sortable: true,
dataIndex: 'requestorname'
}, {
header: "Start Date",
width: 85,
sortable: true,
xtype: 'datecolumn',
dataIndex: 'startdate',
dateFormat: 'n/j/Y'
}, {
header: "Supervisor",
width: 75,
sortable: true,
dataIndex: 'supervisor'
}, {
header: "Company",
width: 100,
sortable: true,
dataIndex: 'company'
}, {
header: "Last Name",
width: 75,
sortable: true,
dataIndex: 'lastname'
}, {
header: "First Name",
width: 75,
sortable: true,
dataIndex: 'firstname'
},
sm
],
tbar: [{
iconCls: 'contractor-add',
text: 'Edit Employee',
handler: function(grid, rowIndex, colIndex) {
alert("test");
var editWindow = new Ext.Window({
id: 'id_editWindow',
title: 'Edit',
closable: true,
width: 750,
height: 380,
plain: true,
layout: 'fit',
items: simple,
listeners: {
show: function EditUser(rec) {
var formpanel = Ext.getCmp('formPanel');
formpanel.getForm().loadRecord(rec);
}
}
});
editWindow.show();
}
}],
// customize view config
viewConfig: {
forceFit: true,
enableRowBody: true,
showPreview: true,
getRowClass: function(record, Index) {}
},
// paging bar on the bottom
bbar: new Ext.PagingToolbar({
store: store,
displayInfo: true,
displayMsg: 'Displaying Records {0} - {1} of {2}',
emptyMsg: "No cases to display"
})
});
//Form Creation
var simple = new Ext.form.FormPanel({
standardSubmit: true,
frame: true,
xtype: 'form',
// id: 'tabForm',
id: 'formPanel',
bodyPadding: 5,
width: 1000,
border: false,
bodyBorder: false,
fieldDefaults: {
labelWidth: 75,
msgTarget: 'side'
},
items: {
xtype: 'tabpanel',
id: 'tabpanel',
activeTab: 0,
defaults: {
bodyPadding: 10,
layout: 'anchor'
},
items: [{
title: 'New Contractor Details',
defaultType: 'textfield',
defaults: {
anchor: '100%'
},
items: [{
//Requestor Info
xtype: 'fieldset',
title: 'Requestor Details',
defaults: {
width: 150
},
fieldDefaults: {
msgTarget: 'side',
labelWidth: 300
},
defaultType: 'textfield',
layout: 'column',
labelWidth: 150,
defaults: {
anchor: '100%'
},
items: [{ // column #1
xtype: 'container',
columnWidth: .5,
layout: 'form',
items: [{
xtype: 'textfield',
fieldLabel: 'Requestor Name',
afterLabelTextTpl: required,
labelStyle: 'color:#000000',
name: 'requestorname',
id: 'requestorname',
//hasfocus:true,
anchor: '80%',
allowBlank: false,
listeners: {
afterrender: function(field) {
field.focus(false, 1000);
}
}
}, {
title: 'Manage Contractor Details',
// renderTo: bd,
// activeTab: 0, // first tab initially active
defaults: {
bodyPadding: 10
},
items: [grid]
}]
}],
buttons: [{
text: 'Submit',
formBind: true,
handler: function() {
var requestorname = Ext.getCmp('requestorname').getValue();
var form = Ext.getCmp('formPanel').getForm();
if (form.isValid()) {
//alert('Tests');
Ext.Ajax.request({
url: 'NewHireDetailsInsertion?firstname=' + firstname + '&' + 'middlename=' + middlename + '&' + 'lastname=' + lastname +
'&' + 'suffix=' + suffix + '&' + 'company=' + company + '&' + 'requestorname=' + requestorname + '&'...so on...
method: 'POST',
submitEmptyText: false
});
simple.getForm().getEl().dom.action = 'NewHireDetailsInsertion';
//Ext.Msg.maxWidth =2000;
Ext.Msg.alert('Message', "New Hire information Submitted");
simple.getForm().reset();
} else {
Ext.Msg.alert('Message', "Please enter all required fields");
}
}
}, {
text: 'Reset',
handler: function() {
simple.getForm().reset();
}
}]
}]
}]
});
});
simple.render('mydiv');
You could have provided a bit more sample code, as well as ensured that the code you provided was formatted correctly... As so, the example I'm providing should guide you in the right direction if I understand what you are trying to achieve.
It is very messy to put logic into your views, which is what I see you are doing in the code you have provided. The role of the controller in ExtJS MVC is to observe the events fired by views (or other controllers!) and react accordingly.
You can save yourself a lot of time and headache by establishing reference's (refs) on the Controller for commonly accessed components. In your scenario, both your Grid and Window would make great candidates for references.
Have a look at the Controller documentation for a more thorough explanation of ref capabilities, as well as the Controller's control function: http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.app.Controller
Ext.define('My.controller.Grid', {
extend: 'Ext.app.Controller',
/** List required views, models, stores here */
refs: [
{
name: 'grid',
selector: '',
xtype: 'my-grid' // Defined in the Grid's config i.e., alias: 'widget.my-grid'
},{
name: 'editWindow',
selector: '',
xtype: 'my-edit-window',
autoCreate: true // Automatically create this if it isn't already created
}
],
init:function(app){
/** Observe your Views by their itemId or any valid ComponentQuery selector */
'#my-grid-panel': {
itemdblclick: { fn: this.onGridRecordDoubleClick, scope: this }
},
'#my-edit-window': {
afterrender: { fn: this.editWindowDidRender, scope: this },
close: { fn: this.onWindowClose, scope: this }
}
},
onGridRecordDoubleClick: function(grid, record, element, index, event){
/** save a reference to the selected record on the controller instance */
this.selectedRecord = record;
/** Show the 'Edit' Window if possible */
if(!this.activeWindow)
this.getEditWindow(); // Magic method created by Controller Reference
},
editWindowDidRender: function(view){
/** Get the Form by its itemId */
var myForm = view.down('#my-form');
/** Load the selected record into the form */
myForm.loadRecord(this.selectedRecord);
/** Save a reference to the window, why not? */
this.activeWindow = view;
},
onWindowClose: function(){
/** remove the reference to the window and selected record */
this.activeWindow = undefined;
this.selectedRecord = undefined;
/** Clear selection on the grid */
this.getGrid().getSelectionModel().clearSelections();
this.getGrid().reconfigure();
}
});

ExtJS HTMLEditor toolbar gets disappeared after reaching specified height

I am using ExtJS HTMLEditor and set the properties as follows-
{ xtype: "htmleditor", width: 500, height: 250}
While entering the text, after reaching the specified height, the toolbar gets disappeared.
I tried removing the height and setting autoHeight: true but in both cases the HTML editor does not fit to the window (HTMLEditor is inside Ext.form.FormPanel).
Anyone having idea to solve it.
This is my code
Ext.onReady(function() {
Ext.create('Ext.window.Window', {
title: 'This is Title',
resizable: false,
modal: true,
height: 300,
width: 500,
layout: 'fit',
closeAction: 'hide',
items: [
new Ext.form.FormPanel({
border: false,
autoHeight: true,
items: [
{ allowBlank: false, xtype:
"htmleditor", height: 250, width: 600, anchor:'100%'}
]
})
],
buttons: [
{text: 'Ok' },
{text: 'Cancel'}
]
}).show();
});
I have solved the problem- Added layout: 'fit' to Formpanel
Ext.onReady(function() {
Ext.create('Ext.window.Window', {
title: 'This is Title',
resizable: false,
modal: true,
height: 300,
width: 500,
layout: 'fit',
closeAction: 'hide',
items: [
new Ext.form.FormPanel({
border: false,
layout: 'fit', // This fixed the issue
items: [
{ allowBlank: false,
xtype: "htmleditor",
height: 250,
width: 600
}
]
})
],
buttons: [
{text: 'Ok' },
{text: 'Cancel'}
]
}).show();
});

extjs xml tree example that I put into the layout-browser example provided by extjs

Below is a javascript variable that I'm using to load into the layout-browser...you will notice the listener section is commented out...when I uncomment this section the layout-browser and the tree do not show up. When I comment out the listener section, the layout-browser and the tree work fine with the exception of the listener populating the pool-details-panel.
Any ideas why the listener is blowing the render of the layout-browser and tree up?
var PoolStackTree = {
id: 'PoolStackTree-panel',
title: 'Pool List',
layout: 'border',
width: 500,
height: 500,
items: [{
xtype: 'treepanel',
id: 'pooltree-panel',
region: 'center',
margins: '2 2 0 2',
singleExpand: true,
animate: true,
useArrows: true,
autoScroll: true,
rootVisible: false,
root: new Ext.tree.AsyncTreeNode(),
loader: new Ext.app.PoolLoader({ dataUrl: 'calmonpool_views_xml.cgi' })
/*
listeners { 'render': function(tp) {
tp.getSelectionModel().on('selectionchange', function(tree-pool, node-pool) {
var el = Ext.getCmp('pool-details-panel').body;
if(node-pool && node-pool.leaf) {
tpl.overwrite(el, node-pool.attributes);
} else {
el.update(detailsText);
}
})
}}
*/
},{
id: 'pool-details-panel',
title: 'Pool Details',
region: 'south',
autoScroll: true,
collapsible: true,
split: true,
margins: '0 2 2 2',
cmargins: '2 2 2 2',
height: 220,
html: detailsText
}]
};
You're missing a comma before the "listeners" property name and a colon after the property name:
...,
listeners: { ...
Well just for starters you're missing a ":" after "listeners". That would certainly cause the Tree not to render.

Resources