Container fixed position but only on horizontal scroll - javascript

I am trying to achieve a specific kind of layout. My effort so far can be previewed from this fiddle example.
Basically I need to make my left container (fixedContainer) with red border containers, to have fixed position and be fully visible when I scroll horizontally. But when I scroll vertically it needs to scroll normally with rest of the containers.
Current code:
Ext.create('Ext.window.Window', {
title: 'Hello',
height: 500,
width: 700,
layout:'vbox',
scrollable:true,
items:[{
xtype:'container',
reference:'mainContainer',
layout:{
type:'hbox'
},
margin:10,
items:[{
xtype:'container',
reference:'fixedContainer',
style:'position:relative;',
defaults:{
style:'border: 1px solid red;',
left:100,
width:200,
height:120,
bodyPadding:10
},
items:[{
html:'panel1'
},{
html:'panel2'
},{
html:'panel3'
},{
html:'panel4'
}]
},{
xtype:'container',
reference:'scrollContainer',
defaults:{
border:true,
width:700,
height:120,
bodyPadding:10
},
items:[{
html:'panel1'
},{
html:'panel2'
},{
html:'panel3'
},{
html:'panel4'
}]
}]
}]
}).show();

If I understood what you are looking for, you need to change a few layouts in your code. First you need to make your window a layout: 'fit', so that it's child's fit into the window container.
Then set your mainContainer to a layout: border and set both the child panels to region: 'west' and region: 'center' respectively. This anchors your fixedContainer to the left and your scrollableContainer to the center.
Finnally, add the scrollable: "horizontal" property to your scrollableContainer to scroll horizontally.
Ext.create('Ext.window.Window', {
title: 'Hello',
height: 500,
width: 700,
layout: 'fit', // Changed this
scrollable:true,
items:[
{
xtype:'container',
reference:'mainContainer',
layout: 'border', // Changed this
margin:10,
items:[
{
xtype:'container',
region:'west', // Added this
reference:'fixedContainer',
defaults:{
style:'border: 1px solid red',
width:200,
height:120,
bodyPadding:10
},
items:[{
html:'panel1'
},{
html:'panel2'
},{
html:'panel3'
},{
html:'panel4'
}]
},
{
xtype:'container',
region: 'center', // Added this
scrollable: "horizontal", // Added this
reference:'scrollContainer',
defaults:{
border:true,
width:700,
height:120,
bodyPadding:10
},
items:[{
html:'panel1'
},{
html:'panel2'
},{
html:'panel3'
},{
html:'panel4'
}]
}
]
}]
}).show();
EDIT1:
As #Evan Trimboli stated, the first code sample did not respect the vertical scrolling on panels overflow, this second sample sets the border layout to scroll vertically. The scrollContainer is wrapped into an additional container that will satisfy the vertical scroll. The remaining code stays the same from the initial answer.
Ext.create('Ext.window.Window', {
title: 'Hello',
height: 500,
width: 700,
layout: 'fit', // Changed this
items: [{
xtype: 'container',
reference: 'mainContainer',
scrollable: 'vertical', // #edit1: Added this
layout: 'border', // Changed this
margin: 10,
items: [{
xtype: 'container',
region: 'west', // Added this
reference: 'fixedContainer',
defaults: {
style: 'border: 1px solid red',
width: 200,
height: 120,
bodyPadding: 10
},
items: [{
html: 'panel1'
}, {
html: 'panel2'
}, {
html: 'panel3'
}, {
html: 'panel4'
}, {
html: 'panel5'
}]
}, {
xtype: 'container', //#edit1: New container here to satisfy the vertical scroll
region: 'center',
items: [{
xtype: 'container',
scrollable: "horizontal", // Added this
reference: 'scrollContainer',
defaults: {
border: true,
width: 700,
height: 120,
bodyPadding: 10
},
items: [{
html: 'panel1'
}, {
html: 'panel2'
}, {
html: 'panel3'
}, {
html: 'panel4'
}, {
html: 'panel5'
}]
}]
}]
}]
}).show();

Ok this is my working solution for this issue
Ext.application({
name: 'Fiddle',
launch: function () {
var horizontalScroll = 0
var gridwindow = Ext.create('Ext.window.Window', {
referenceHolder: true,
title: 'Hello',
height: 500,
width: 700,
layout: 'vbox',
scrollable: true,
items: [{
xtype: 'container',
reference: 'mainContainer',
layout: {
type: 'hbox'
},
margin: 10,
items: [{
xtype: 'container',
reference: 'fixedContainer',
style: 'position:relative; z-index:10; box-shadow: -20px 0px 0px 1px #fff;',
defaults: {
style: 'border: 1px solid red; outline',
width: 200,
height: 120,
bodyPadding: 10
},
items: [{
html: 'panel1'
}, {
html: 'panel2'
}, {
html: 'panel3'
}, {
html: 'panel4'
}]
}, {
xtype: 'container',
reference: 'scrollContainer',
defaults: {
border: true,
width: 700,
height: 120,
bodyPadding: 10
},
items: [{
html: 'panel1'
}, {
html: 'panel2'
}, {
html: 'panel3'
}, {
html: 'panel4'
}]
}]
}]
}).show();
gridwindow.body.on('scroll', function (event) {
var scrollLeft = event.target.scrollLeft;
if (horizontalScroll !== scrollLeft) {
var fixedContainer = this.lookup('fixedContainer');
fixedContainer.el.translate((scrollLeft), 0)
}
horizontalScroll = scrollLeft;
}, gridwindow);
}
});
https://fiddle.sencha.com/#view/editor&fiddle/28ug
Thanks all for the effort. Hopefully this is good enough to help someone else with a similar problem.

Related

Extjs 5.1.3 in tbar add button who mask/unmask grid

In Extjs, i want to add button in tbar chart, which hide/unhide my grid, i have some difficult with layout, so in certains case, my button take 100% place, also my grid disapear, my code is bellow:
var barchart = {
xtype: 'cartesian',
legend: {
docked: 'bottom'
},
tbar: [{
xtype: 'container',
layout: {
type: 'vbox',
columns: 1,
align: 'stretch'
},
items: [{
xtype: 'button',
text: 'Afficher DSO',
listeners: {
click: function(btn){
var dsoGrid = btn.nextSibling();
if( dsoGrid.hidden ){
helperCache.multiToolbox(dsoGrid, ["NOT_HIDE"]);
btn.setText("Masquer DSO");
} else {
helperCache.multiToolbox(dsoGrid, ["HIDE"]);
btn.setText("Afficher DSO");
}
}
}
},{
xtype: 'grid',
itemId: 'grid_history_dso',
// hidden: true,
scrollable: 'x',
margin: 5,
flex: 1,
store: dsoStore,
columns: dsoColumns,
}]
}],
.......
I like to my button take normal size, and my grid take fit all place of his container with x scroll
For helping anyone in same case, i solved my problem with :
var barchart = {
xtype: 'cartesian',
legend: {
docked: 'bottom'
},
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
layout: {
type: 'anchor',
},
items: [{
xtype: 'button',
text: 'Afficher DSO',
listeners: {
click: function(btn){
var dsoGrid = btn.nextSibling();
if( dsoGrid.hidden ){
helperCache.multiToolbox(dsoGrid, ["NOT_HIDE"]);
btn.setText("Masquer DSO");
} else {
helperCache.multiToolbox(dsoGrid, ["HIDE"]);
btn.setText("Afficher DSO");
}
}
}
},{
xtype: 'grid',
itemId: 'grid_history_dso',
hidden: true,
scrollable: 'x',
margin: 5,
anchor: '100%',
store: dsoStore,
columns: dsoColumns,
}]
}],
dockedItem was key

How do I create Layout 2X2 layout in ext js with border?

I have a requirement to create 2X2 layout, for that I am using the layout as the border and I have tried the below code,I am getting the below exception on the browser console:
Uncaught TypeError: Cannot set property 'component' of null and below is my code that I have tried.
Can anyone help me on how do I create 2X2 layout in ext js ? ( I am using Ext JS Library 3.3.1 version)
<!DOCTYPE html>
<html>
<head>
<link href = "https://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/classic/theme-classic/resources/theme-classic-all.css"
rel = "stylesheet" />
<script type = "text/javascript"
src = "https://cdnjs.cloudflare.com/ajax/libs/extjs/6.0.0/ext-all.js"></script>
<script type = "text/javascript">
Ext.onReady(function() {
var panelHeightLandingPage = (screen.height / 2) - 150;
var viewPort = new Ext.Viewport({
layout: 'border',
autoScroll: true,
items: [{
// The header bar.
region: 'north',
layout: 'fit',
margins: '0 0 0 0',
border: false,
contentEl: 'header',
autoHeight: true
},{
region: 'center',
layout: 'fit',
border: false,
margins: '5 5 5 5',
items: [tabPanelLayout],
contentEl: 'content'
}],
renderTo: Ext.getBody()
});
var tabPanelLayout = new Ext.TabPanel({
id:'tabPanel',
renderTo: 'content',
activeTab: 0,
deferredRender:true,
defaults:{ height: 500 },
listeners: {
tabchange: function (tabPanel,newTab) {
if( newTab.getId() == 'landingTab' ) {
currentTab = 1;
//this is the initial load
}
}
},
items:[{
id: 'landingTab',
title:"Booking Summary & Inventory View",
layout: 'fit',
items: landingPanel
}]
});
var landingPanel = new Ext.Panel({
layout:'border',
items: [{
region:'east',
width: 500,
layout: 'fit',
border: false,
items: chartPanels
},{
region:'center',
layout: 'fit',
border: false,
items: gridPanels
}]
});
var gridPanels = new Ext.Panel({
layout:'border',
items: [{
region: 'north',
height: panelHeightLandingPage,
layout: 'fit',
border: false,
items : {
title: 'Chassis Pool Maintenance',
// region:'west',
html: 'This is Panel 1',
width: screen.availWidth-600
}
},{
region: 'center',
layout: 'fit',
border: false,
items : {
title: 'Chassis Pool Maintenance',
// region:'west',
html: 'This is Panel 1',
width: screen.availWidth-600
}
}]
});
//This contains the charts layout
var chartPanels = new Ext.Panel({
layout:'border',
items: [{
region:'north',
title: 'Booking Summary Chart',
height: panelHeightLandingPage,
layout: 'fit',
border: true,
id: 'pie',
contentEl:'pieChart',
autoScroll: true
},{
region: 'center',
title: 'Inventory View Chart',
layout: 'fit',
border: true,
id: 'bar',
contentEl: 'barGraph',
autoScroll: true
}]
});
});
</script>
</head>
<body>
</body>
</html>
You are getting this issue because of your DOM is not created. For more details you can refer this links sencha forum to understand Uncaught TypeError: Cannot read property 'dom' of null this error.
In your case this line renderTo: 'content' is creating error.
In this FIDDLE, I have used your code and made some change as per your requirement. Hope this will help you or guide you to solve your problem.
CODE SNIPPET
Ext.onReady(function() {
var panelHeightLandingPage = (screen.height / 2) - 150,
gridPanels = new Ext.Panel({
layout: 'border',
items: [{
region: 'north',
height: panelHeightLandingPage,
layout: 'fit',
border: false,
items: {
title: 'Chassis Pool Maintenance',
// region:'west',
html: 'This is Panel 1',
width: screen.availWidth - 600
}
}, {
region: 'center',
layout: 'fit',
border: false,
items: {
title: 'Chassis Pool Maintenance',
// region:'west',
html: 'This is Panel 1',
width: screen.availWidth - 600
}
}]
}),
chartPanels = new Ext.Panel({ //This contains the charts layout
layout: 'border',
items: [{
region: 'north',
title: 'Booking Summary Chart',
height: panelHeightLandingPage,
layout: 'fit',
border: true,
id: 'pie',
// contentEl: 'pieChart',
autoScroll: true
}, {
region: 'center',
title: 'Inventory View Chart',
layout: 'fit',
border: true,
id: 'bar',
// contentEl: 'barGraph',
autoScroll: true
}]
}),
landingPanel = new Ext.Panel({
layout: 'border',
items: [{
region: 'east',
width: 500,
layout: 'fit',
border: false,
items: chartPanels
}, {
region: 'center',
layout: 'fit',
border: false,
items: gridPanels
}]
}),
tabPanelLayout = new Ext.TabPanel({
id: 'tabPanel',
activeTab: 0,
deferredRender: true,
defaults: {
height: 500
},
listeners: {
tabchange: function(tabPanel, newTab) {
if (newTab.getId() == 'landingTab') {
currentTab = 1;
//this is the initial load
}
}
},
items: [{
id: 'landingTab',
title: "Booking Summary & Inventory View",
layout: 'fit',
items: landingPanel
}, {
title: 'Second Tab' //Only for test.
}]
}),
viewPort = new Ext.Viewport({
//renderTo:document.body, you can put renderTo here aslo
layout: 'border',
autoScroll: true,
items: [{
// The header bar.
region: 'north',
layout: 'fit',
margins: '0 0 0 0',
border: false,
// contentEl: 'header',
autoHeight: true
}, {
region: 'center',
layout: 'fit',
border: false,
margins: '5 5 5 5',
items: [tabPanelLayout],
//contentEl: 'content'
}]
});
//you can put renderTo here aslo like this.
viewPort.render(Ext.getBody());
});

Resizable treepanel in window in ExtJS

I have a Treepanel:
treepanel = Ext.define('filteredTree', {
extend: 'Ext.tree.Panel',
title: 'Filtered Tree',
store: store,
width: 784,
height: 550,
buttons: [
{
text: 'Select',
handler: function () {
var panel = this.up('treepanel');
//...selection of value
}
}
]
//...Here is search mechanism
});
and the window in which it's displayed. The window is resizable:
win = Ext.create('widget.window', {
title: 'Выбор значения из словаря',
header: {
titlePosition: 2,
titleAlign: 'center'
},
closable: true,
closeAction: 'hide',
maximizable: true,
width: 800,
minWidth: 350,
height: 600,
tools: [{ type: 'pin' }],
theme:"classic",
layout: {
type: 'border',
padding: 5
},
items: [
Ext.create('filteredTree')
]
});
I'd like to see if the window size changes the size of the panel also changes. How can I do that?
Change the layout of the window to fit.
Panel will occupy the complete space inside the window and resizes accordingly.You can remove height and width from the tree panel.
Ext.create('Ext.window.Window', {
title: 'Выбор значения из словаря',
header: {
titlePosition: 2,
titleAlign: 'center'
},
closable: true,
closeAction: 'hide',
maximizable: true,
width: 600,
minWidth: 350,
height: 400,
layout:'fit',
items: [
{xtype:'treepanel',
padding:5,
title: 'Filtered Tree',
buttons: [
{
text: 'Select',
handler: function () {
var panel = this.up('treepanel');
}
}
]}
]
}).show();

ExtJS how to use renderTo config to render a component to another specific container

I am learning ExtJS MVC
I want to click button then create a panel in specific container. But I am confuse about the renderTo config. I don't know how to render to right side container.
My codes as below.
First I define two container in Viewport
Ext.define('MyTest.view.Viewport', {
extend: 'Ext.container.Viewport',
layout: 'border',
requires: [
'MyTest.view.button.TestButton',
],
items: {
xtype: 'container',
itemId: 'main',
region: 'center',
border: false,
layout: {
type: 'hbox',
pack: 'start',
align: 'stretch'
},
items: [{
xtype: 'container',
itemId: 'left',
style: 'background-color: black;',
flex: 1,
items: [{
xtype: 'testbtn'
}]
}, {
xtype: 'container',
itemId: 'right',
flex: 1
}]
}
});
Button in view
Ext.define('MyTest.view.button.TestButton', {
extend: 'Ext.button.Button',
alias: 'widget.testbtn',
initComponent: function() {
var me = this;
Ext.apply(this, {
height: 100,
width: 100
});
me.callParent(arguments);
}
});
And click event in controller
Ext.define('MyTest.controller.Button', {
extend: 'Ext.app.Controller',
views: ['MyTest.view.button.TestButton'],
refs: [{
ref: 'testbtn',
selector: 'testbtn'
}],
init: function() {
this.control({
'testbtn': {
click: this.test
}
});
},
test: function() {
Ext.create('Ext.panel.Panel', {
height: 200,
width: 400,
renderTo: Ext.getBody()
});
}
});
Now it just can render to body. How to render it in right side container?
Thanks a lot
You can use the add method to add to the items array of a panel or container.
For example:
Ext.ComponentQuery.query('#westPanel')[0].add({ html:'Some New Component Here.' });
and here is the full code for a more in-depth example:
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.panel.Panel',{
renderTo:Ext.getBody(),
height:800,
layout:'border',
tbar:[{
text:'Add Html To East Region',
handler: function(btn){
Ext.ComponentQuery.query('#westPanel')[0].add({
html:'Oh, Hello.'
});
}
}],
defaults:{
xtype:'panel'
},
items:[{
region:'center',
html:'Center Panel'
},{
region:'west',
width:400,
itemId:'westPanel',
items:[]
}]
});
}
});
And a fiddle for demonstration of the working code

need to remove horizontal border from the tbar menu

I have a bunch of tbar items displayed in new lines. It works fine.
But the only issue I am having is that displays a horizontal border between each tbars.
How can I remove that?
items: [
{
xtype: 'panel',
id: 'navi',
region: 'west',
collapsible: false,
title: 'Navigation',
bodyStyle: 'background-color: #BFCBD5',
width: 155,
animCollapse: true,
minHeight: 600,
items: [
{
border:0,
tbar: [
{
xtype: 'button',
text: 'Home',
textAlign:'left',
width: 140,
align:'left',
//bodyStyle: 'background-color:#BFCBD5;',
handler: function() {
document.location.href = BasePath;
}
}
]
},
{
border:0,
tbar: [
{
xtype: 'button',
text: 'Dashboard',
textAlign:'left',
width: 140,
handler: function() {
document.location.href="http://www.dtvdashboard.com";
}
}
]
},
{
xtype: 'text',
padding: '64 0 0 0',
text: "Logged in as:",
textAlign:'left',
style : "color:#3E546B;font-style:italic;font-size: 11px;",
width: 140,
handler: function() {
document.location.href="";
}
},
]
}
]
EDIT: I added bodyBorder:false, that kinda removed the border line. But i still see lighter shade of the border
There is plenty of possibilities to remove that border.
you can remove tbar and stick to the buttons only (example: http://jsfiddle.net/kKjuC/1/)
you can render links as plain html and attach click handler to each one or to the container or just simply add href to links (example: http://jsfiddle.net/YeyET/1/)
you can use DataView

Categories

Resources