I have a grid with records from a store using the modern material theme on ExtJS 7.2. I want to create multiple floating, draggable formpanels from this view, but when I drag the formpanel around, closing it leaves a blank white space where the formpanel was, obscuring the background. Here is the source for the formpanel.
onItemClick: function (grid,rowIndex,e) {
var record = grid.getStore().getAt(rowIndex);
var form = Ext.create({
xtype: 'formpanel',
id: `${record.id}_form_${record.get('blah')}`,
title: `Invoice ${record.get('blah')}`,
floating: true,
closable: true,
centered: true,
draggable: true,
shadow: true,
width:300,
height:window.innerHeight*0.8,
scrollable: true,
modal: null,
items: [
{
xtype: 'textfield',
name: 'Blah',
label: 'Blah',
value: record.get('blah'),
},
{
xtype: 'toolbar',
docked: 'bottom',
items: [{
xtype: 'button',
text: 'Save',
ui: 'raised round',
iconCls: 'x-fa fa-save',
handler: function() {
var theform = this.up('formpanel').getFields();
record.set(
{
'blah': theform['Blah'].getValue(),
}
);
this.up('formpanel').destroy();
}
},'->', {
xtype: 'button',
text: 'Cancel',
ui: 'raised round',
iconCls: 'x-fa fa-close',
handler: function() {
this.up('formpanel').destroy();
},
}]
}
]
});
Ext.Viewport.add(form);
}
Does anyone have experience with this problem? I have tried messing around with a custom Ext.drag.Source object, but with no success so far. When I try to close a formpanel that has been dragged, I get an error:
TypeError: Argument 1 of Node.replaceChild is not an object.
Any help would be appreciated.
there is not property called "floating" in the modern toolkit. Did you mean "floated"?
Instead of adding to Viewport better use show() method.
Something like this:
onItemClick: function (grid,rowIndex,e) {
var record = grid.getStore().getAt(rowIndex);
var form = Ext.create({
xtype: 'formpanel',
id: `${record.id}_form_${record.get('blah')}`,
title: `Invoice ${record.get('blah')}`,
floated: true, // It is not called "floating"
closable: true,
centered: true,
draggable: true,
shadow: true,
width:300,
height:window.innerHeight*0.8,
scrollable: true,
modal: null,
items: [
{
xtype: 'textfield',
name: 'Blah',
label: 'Blah',
value: record.get('blah'),
},
{
xtype: 'toolbar',
docked: 'bottom',
items: [{
xtype: 'button',
text: 'Save',
ui: 'raised round',
iconCls: 'x-fa fa-save',
handler: function() {
var theform = this.up('formpanel').getFields();
record.set(
{
'blah': theform['Blah'].getValue(),
}
);
this.up('formpanel').destroy();
}
},'->', {
xtype: 'button',
text: 'Cancel',
ui: 'raised round',
iconCls: 'x-fa fa-close',
handler: function() {
this.up('formpanel').destroy();
},
}]
}
]
});
form.show(); // Show instead of add to Viewport.
//Ext.Viewport.add(form);
}
Related
I am creating a menu using Ext.tab.Panel and would like to have Search feature. Something like Bootstrap navbar - https://getbootstrap.com/docs/4.0/components/navbar/
I tried to simply add the textfield element but didn't work obviously.
Ext.create('Ext.TabPanel', {
fullscreen: true,
items: [{
title: 'Home',
iconCls: 'home',
html: 'Home Screen'
},
{
title: 'Contact',
iconCls: 'user',
html: 'Contact Screen'
},
{
xtype: 'textfield',
name: 'name',
fieldLabel: 'Name',
allowBlank: false // requires a non-empty value
}
]
});
Is it possible to achieve this at all?
You can archive it with the tabbar config of the Ext.tab.Panel.
The Ext.tab.Bar is a specialized Ext.container.Container where you can add items like a to Textfield.
So add te search textfield to the tabbar config and you can archive what you want to, see the example code below and the Sencha Fiddle.
Ext.create('Ext.TabPanel', {
fullscreen: true,
items: [{
title: 'Home',
iconCls: 'home',
html: 'Home Screen'
},
{
title: 'Contact',
iconCls: 'user',
html: 'Contact Screen'
},
],
tabBar: {
items: [
{
xtype: 'textfield',
name: 'name',
fieldLabel: 'Name',
allowBlank: false // requires a non-empty value
}
]
},
renderTo: Ext.getBody()
});
At first this functionality does not exist in the tabpanel, which I recommend you do and replace the idea of tabpanel to apply a cardlayout which is the same tabpanel layout system.
And then you can use a toolbar, with the buttons being configured with the toogleGroup, in short, you'd better see the code example below working.
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create('Ext.Panel', {
fullscreen: true,
renderTo: Ext.getBody(),
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'toolbar',
height: 42,
defaults: {
xtype: 'button',
},
items: [{
text: 'Tab1',
handler: function(button){
var me = this,
fakeContainer = button.up('panel').down('#fakeTab');
fakeContainer.setActiveItem(button.tabIndex);
},
tabIndex: 0,
toggleGroup: 'tabHandler',
enableToggle: true,
pressed: true,
margin: '0'
}, {
text: 'Tab2',
handler: function(button){
var me = this,
fakeContainer = button.up('panel').down('#fakeTab');
fakeContainer.setActiveItem(button.tabIndex);
},
tabIndex: 1,
enableToggle: true,
margin: '0'
}, {
text: 'Tab3',
handler: function(button){
var me = this,
fakeContainer = button.up('panel').down('#fakeTab');
fakeContainer.setActiveItem(button.tabIndex);
},
tabIndex: 2,
toggleGroup: 'tabHandler',
enableToggle: true,
margin: '0'
}, '->', {
xtype: 'textfield',
fieldLabel: 'Search:',
labelWidth: 70,
width: 250,
margin: 0
}, {
iconCls: 'x-fa fa-search',
handler: function(){
alert('Your Search here!');
}
}]
}, {
xtype: 'container',
itemId: 'fakeTab',
margin: '16 0 0 0',
flex: 1,
layout: 'card',
defaults: {
xtype: 'container',
height: 800
},
items: [{
html: '<STRONG>TAB 1 your content here</STRONG>'
}, {
html: '<STRONG>TAB 2 your content here</STRONG>'
}, {
html: '<STRONG>TAB 3 your content here</STRONG>'
}]
}]
});
}
});
Working sample here
I am working on Ext JS 6.5 modern. I have some condition to disable the grid component, user has only rights to view the grid no one else.
I have tried disabled config and disable method but not working. Here is my Fiddle.
Code snippet
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create('Ext.data.Store', {
storeId: 'gridStore',
fields: ['name'],
data: [{
name: 'Test 1'
}, {
name: 'Test 2'
}, {
name: 'Test 3'
}, {
name: 'Test 4'
}]
});
Ext.create({
xtype: 'grid',
layout: 'fit',
fullscreen: true,
title: 'Baisc grid example',
store: 'gridStore',
//Here I have put {disabled: true} but not working
disabled: true,
columns: [{
text: 'Name',
flex: 1,
dataIndex: 'name'
}],
listeners: {
childtap: function (grid, location, eOpts) {
alert('childtap');
}
},
items: [{
xtype: 'toolbar',
items: {
xtype: 'button',
ui: 'action',
text: 'Disabled grid',
iconCls: 'x-fa fa-ban',
handler: function () {
//IT is also not working
this.up('grid').setDisabled(true);
this.up('grid').disable();
}
}
}]
//renderTo:Ext.getBody()
});
}
});
Somebody please help me with a solution for disabling the grid component.
As a workaround we can use grid.setMasked(true);
Here is the example Fiddle.
Another approach is to set grid's hideMode to opacity and then set it to hidden (this.up('grid').setHidden(true);).
For Example (editing your fiddle)
Ext.create('Ext.data.Store', {
storeId: 'gridStore',
fields: ['name'],
data: [{
name: 'Test 1'
}, {
name: 'Test 2'
}, {
name: 'Test 3'
}, {
name: 'Test 4'
}]
});
Ext.create({
xtype: 'grid',
layout: 'fit',
fullscreen: true,
title: 'Baisc grid example',
store: 'gridStore',
//Here I have put {disabled: true} but not working
//disabled: true,
hideMode: 'opacity',
columns: [{
text: 'Name',
flex: 1,
dataIndex: 'name'
}],
listeners: {
childtap: function (grid, location, eOpts) {
alert('childtap');
}
},
items: [{
xtype: 'toolbar',
items: {
xtype: 'button',
ui: 'action',
text: 'Disabled grid',
iconCls: 'x-fa fa-ban',
handler: function () {
this.up('grid').setHidden(true);
}
}
}]
//renderTo:Ext.getBody()
});
Also you need this css override:
<style>
.x-hidden-opacity {
opacity: 0.2 !important; //default is 0
pointer-events: none;
}
</style>
Here my code in sencha for my applicaiton,I have included table and two buttons in resetpanel and addded into tab view
var tab= Ext.create('Ext.List', {
fullscreen: true,
dock: 'left',
width: 320,
height: 200,
ui: 'round',
store: {
fields: ['ext_xtype'],
data: [{
ext_xtype: 'fieldset',
}, {
ext_xtype: 'formpanel',
}]
},
itemTpl: '<span style="width:300px; display:inline-block;">{ext_xtype}</span> '
});
var resetPanel1 = new Ext.form.FormPanel({
id: 'resetPanel1',
style:{background:'#D8D8D8'},
dockedItems:[]
,
items: [tab,{
xtype: 'button',
text: 'Add',
ui: 'confirm',
handler: function() {
view.setActiveItem('welcomepanel', {type:'fade', direction:'left'});
}
},{
xtype: 'button',
text: 'Add',
ui: 'Search',
handler: function() {
view.setActiveItem('welcomepanel', {type:'fade', direction:'left'});
}}]});
var view = Ext.create('Ext.TabPanel', {
fullscreen: true,
tabBarPosition: 'bottom',
scroll:'vertical',
items: [{
title: 'ITEMS',
iconCls: 'star',
layout:'card',
items: [{
docked: 'top',
xtype: 'titlebar',
title: 'Add Items',
},resetPanel1
]
}]
});
Ext.Viewport.add(view);
}
});
The resetPanel1 is not viewing in tab view.Whats wrong with my code.Please help me to sort it out.
Remove the fullscreen and dock properties from the list, you should have fullscreen : true only in the main view, In your case TabPanel.
var tab= Ext.create('Ext.List', {
width: 320,
height: 200,
ui: 'round',
store: {
fields: ['ext_xtype'],
data: [{
ext_xtype: 'fieldset',
},{
ext_xtype: 'formpanel',
}]
},
itemTpl: '<span style="width:300px; display:inline-block;">{ext_xtype}</span>'
});
How can we add maximize and minimize in the panel of EXTJS 4 portal example:
http://docs.sencha.com/extjs/4.2.1/extjs-build/examples/portal/portal.html
Fully working code:
Ext.define('Ext.app.Portal', {
extend: 'Ext.container.Viewport',
requires: ['Ext.app.PortalPanel', 'Ext.app.PortalColumn', 'Ext.app.GridPortlet', 'Ext.app.ChartPortlet'],
initComponent: function(){
var content = '<div class="portlet-content">'+Ext.example.shortBogusMarkup+'</div>';
var mainColumnPanelId;
//var mainPanelId;
var itemNo=0;
this.tools= [
{
type:'minimize',
hidden:true,
scope:this,
handler: function(e, target, panel)
{
var cardPanel=Ext.getCmp("app-portal");
var c = panel.up("viewport");
var maximizePortletPanel = Ext.getCmp("maximizePortletPanel");
cardPanel.layout.setActiveItem(0);
var originalPanel=Ext.getCmp(mainColumnPanelId);
originalPanel.insert(itemNo,maximizePortletPanel.items.items[0]);
panel.tools['close'].setVisible(true);
panel.tools['collapse-top'].setVisible(true);
panel.tools['minimize'].setVisible(false);
panel.tools['maximize'].setVisible(true);
}
},
{
type:'maximize',
scope:this,
handler: function(e, target, panel)
{
var cardPanel=Ext.getCmp("app-portal");
var columnPanel = panel.ownerCt.ownerCt;
var maximizePortletPanel = Ext.getCmp("maximizePortletPanel");
mainColumnPanelId=columnPanel.getId();
var columnPanelItems=columnPanel.items.items;
for(var j=0;j<columnPanelItems.length;j++){
if(columnPanelItems[j].getId()==panel.ownerCt.getId()){
itemNo=j;
break ;
}
}
maximizePortletPanel.insert(0,panel.ownerCt);
cardPanel.layout.setActiveItem(1);
panel.tools['minimize'].setVisible(true);
panel.tools['close'].setVisible(false);
panel.tools['collapse-top'].setVisible(false);
panel.tools['maximize'].setVisible(false);
}
}];
Ext.apply(this, {
id: 'app-viewport',
layout: {
type: 'border',
padding: '0 5 5 5' // pad the layout from the window edges
},
items: [{
id: 'app-header',
xtype: 'box',
region: 'north',
height: 40,
html: 'Ext Portal'
},{
xtype: 'container',
region: 'center',
layout: 'border',
items: [{
id: 'app-options',
title: 'Options',
region: 'west',
animCollapse: true,
width: 200,
minWidth: 150,
maxWidth: 400,
split: true,
collapsible: true,
layout:{
type: 'accordion',
animate: true
},
items: [{
html: content,
title:'Navigation',
autoScroll: true,
border: false,
iconCls: 'nav'
},{
title:'Settings',
html: content,
border: false,
autoScroll: true,
iconCls: 'settings'
}]
},{
id: 'app-portal',
region: 'center',
layout:'card',
items:[{
xtype: 'portalpanel',
items: [{
id: 'col-1',
items: [{
id: 'portlet-1',
title: 'Grid Portlet',
tools: this.tools,
items: Ext.create('Ext.app.GridPortlet'),
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
},{
id: 'portlet-2',
title: 'Portlet 2',
tools: this.tools,
html: content,
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
},{
id: 'col-2',
items: [{
id: 'portlet-3',
title: 'Portlet 3',
tools: this.tools,
html: '<div class="portlet-content">'+Ext.example.bogusMarkup+'</div>',
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
},{
id: 'col-3',
items: [{
id: 'portlet-4',
title: 'Stock Portlet',
tools: this.tools,
items: Ext.create('Ext.app.ChartPortlet'),
listeners: {
'close': Ext.bind(this.onPortletClose, this)
}
}]
}]
},{ //title: 'Portlet',
xtype:'panel',
id:'maximizePortletPanel',
layout:'fit',
autoScroll:true
//border:true,
//frame:true
}]////
}]//
}]
});
this.callParent(arguments);
},
onPortletClose: function(portlet) {
this.showMsg('"' + portlet.title + '" was removed');
},
showMsg: function(msg) {
var el = Ext.get('app-msg'),
msgId = Ext.id();
this.msgId = msgId;
el.update(msg).show();
Ext.defer(this.clearMsg, 3000, this, [msgId]);
},
clearMsg: function(msgId) {
if (msgId === this.msgId) {
Ext.get('app-msg').hide();
}
}
});
You cannot 'maximize' or 'minimize' the 'Viewport' because it automatic render to body, If you want to use maximize/minimize feature you must work with Window that is the better way to do.
The Viewport renders itself to the document body, and automatically
sizes itself to the size of the browser viewport and manages window
resizing. There may only be one Viewport created in a page.
See: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.container.Viewport
But if you want to maximize some panel inside the viewport you should use showBy method of each panel to show it by the specified size with target component.
See: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.window.Window-method-showBy
You can push panel as item inside Window. Then provide maximize and minimize functionality by using tool[tbar in extjs].
IMPORTANT: THIS IS WORKING IN VERSION 2.0 AND NOT IN 2.1.1
My app has 2 different tabs at the bottom (near by, search)
Both this tab use the same list as given below.
Also both NearBy and Search use card layout, the only difference is in Near By the list is in the first card and for Search the list is in the Second card
i am trying this for last 2 day and no progress in this. Please help me
Ext.define('ChurchLookup.view.ChurchList', {
extend: 'Ext.List',
xtype: 'churchlist',
config:
{
title: 'Zip Code',
cls: 'x-contacts',
grouped: true,
store: 'Churches',
itemTpl:
[
'<div class="headshot" style="background-image:url(resources/images/church-type-logo/{icon}.png);"></div>',
'{name}, {city}',
'<span>{phone} / {email}</span>'
].join('')
}});
For Near by when the tab is clicked the list will displayed inside the tab panel.
This is working perfectly and I can see the list.
NEAR BY CARD CODE
Ext.define('ChurchLookup.view.NearBy',
{
extend: 'Ext.Panel',
xtype: 'nearbycard',
config:
{
iconCls: 'locate',
title: 'Near By',
scrollable: 'vertical',
layout:
{
type: 'card',
animation:
{
type: 'pop',
duration: 500,
}
},
items:
[
{
docked: 'top',
xtype: 'titlebar',
title: 'Near by Churches',
items:
[
{
itemId: 'btnBackNearBy',
text: "Back",
ui: "back",
hidden: true,
action: 'onBackNearBy'
}/*,
{
itemId: 'btnHomeSettings',
iconMask:true,
iconCls: 'settings',
ui: 'border',
align: 'right',
action: 'pingHomeBadge'
}*/
]
},
{
xtype: 'churchlist'
},
{
xtype: 'churchdetailsnearby'
}
],
listeners:
[
{
delegate: "#btnHomeSettings",
event: "tap",
fn: "onHomeScreenSettings"
},
{
delegate: "#btnBackNearBy",
event: "tap",
fn: "onBackNearBy"
}
]
},
onHomeScreenSettings: function ()
{
this.fireEvent("homeScreenSettings", this);
},
onBackNearBy: function ()
{
this.fireEvent("onBackNearBy", this);
}
});
But for the search when we click the "Search" tab it will show a card layout with 2 card.
The frist card is the search form and the second card is the list.
When the user fill the form and click the search button I just load the store and change the card layout to show the list.
But the card layout is showing the second page but not the list.
SEARCH TAB CODE
Ext.define('ChurchLookup.view.Search',
{
extend: 'Ext.Panel',
xtype: 'searchcard',
config:
{
iconCls: 'search',
title: 'Search',
scrollable: 'vertical',
layout:
{
type: 'card',
animation:
{
type: 'pop',
duration: 500,
}
},
items:
[
{
docked: 'top',
xtype: 'titlebar',
title: 'Search Church',
items:
[
{
itemId: 'btnBackSearch',
text: "Back",
ui: "back",
hidden: true,
action: 'onBackSearch'
}/*,
{
itemId: 'btnHomeSettings',
iconMask:true,
iconCls: 'settings',
ui: 'border',
align: 'right',
action: 'pingHomeBadge'
}*/
]
},
{
xtype: 'searchform'
},
{
xtype: 'favouritecard'
},
{
xtype: 'churchdetailssearch'
}
],
listeners:
[
{
delegate: "#btnHomeSettings",
event: "tap",
fn: "onHomeScreenSettings"
},
{
delegate: "#btnBackSearch",
event: "tap",
fn: "onBackSearch"
}
]
},
onHomeScreenSettings: function ()
{
this.fireEvent("homeScreenSettings", this);
},
onBackSearch: function ()
{
this.fireEvent("onBackSearch", this);
}
});
Maybe height problem.
Is 'churchdetailssearch' the same as 'churchlist' ?
If churchdetailssearch' has toolbar or something set layout :'vbox' to 'churchdetailssearch', and add the list of 'churchdetailssearch' flex : 1.
Maybe useful the page.
Explain how to a scrollable List use dynamic height without fixed height