extj4 grid doesn't fit in container panel - layout

I have a grid with data, contained in a panel which also hold a title and a smaller summary grid.
the panel has layout fit and therefore the title and first grid, which is the summary grid, are displayed just fine. But the grid in question has more records than can be shown on the screen and its component height is not adjusted to the size of the panel which always fits with the height of the browser window.
What I would like to have is that the grid component's height, like the panel, is adjusted to its parent so that the scrollbar inside the grid body will show up.
My code is similar to this (initComponent is of an extension to Ext.panel.Panel):
(header in this code means the summary grid)
initComponent: function (config) {
var config = {
border: false,
hidden: false,
hideMode: "display",
padding: '5',
layout: "fit"
}
Ext.apply(this, Ext.apply(this.initialConfig, config));
this.callParent(arguments);
title = Ext.create("Ext.panel.Panel", {
html: '<h2>title</h2>',
padding: '5',
border: false
});
// the stores for the grids are created here
var storeHdr = DataStoreFactory.CreateStore("GetHeaderP", DataStoreFactory.fieldsCollection.Default);
var storeBdy = DataStoreFactory.CreateStore("GetBodyP", DataStoreFactory.fieldsCollection.Default);
var grdHeader = Ext.create("Ext.grid.Panel", {
store: storeHdr,
columns: getHeaderColumns(),
columnLines: true,
autoHeight: false,
autoWidth: false,
enableHdMenu: false,
enableColumnMove: false,
enableColumnResize: false,
disableSelection: true,
trackMouseOver: false,
sortable: false
});
var grdBody = Ext.create("Ext.grid.Panel", {
id: id,
store: storeBdy,
columns: getBodyColumns(),
columnLines: true,
autoHeight: false,
autoWidth: false,
autoScroll: true,
scroll: "vertical",
enableColumnMove: false,
enableColumnResize: false,
enableHdMenu: false,
trackMouseOver: false,
disableSelection: true
});
},
var headerGridContainer = Ext.create("Ext.panel.Panel", {
layout: "fit",
border: false,
items: [grdHeader]
});
var bodyGridContainer = Ext.create("Ext.panel.Panel", {
layout: "fit",
border: false,
items: [grdBody]
});
this.add(title);
this.add(headerGridContainer);
this.add(bodyGridContainer);
storeHdr.load();
storeBdy.load();
this.doLayout();
}
I hope someone can help me with this. Thanks in advance
edit - screenshots how it is and how it should be. Realtime Data is removed or blotted out, since it is private and doesn't matter for the problem.
this is how it is
this is how it should be

You're using layouts in a wrong way. First, your main container has layout 'fit' which supposed to be used when you have single item inside - http://docs.sencha.com/ext-js/4-0/#!/api/Ext.layout.container.Fit - and you have few items.
Second, try to avoid over-nesting. You're wrapping your grids into panels and then put these panels inside container. Is there a reason for that?
Please post a screenshot of what you have and what you want to have and we will help you figure out layouts that you need to use for this.
Update:
Try to use layout: 'hbox' in your main container. And specify flex: 1 for the main (bottom) grid if you want it to fill the rest of the screen. Son basically you would have something simliar to this (in you main container):
{
layout: 'hbox',
..
items: [{
xtype: 'panel', // header
height: 100,
},
{
xtype: 'grid', // first grid
height: 200
},
{
xtype: 'grid', // second grid
flex: 1
}]
}

Related

Angular google charts color country on click

I am using the GeoChart of angular-google-charts. This is my code:
type="GeoChart";
columnNames = [
[{type: 'string', role: 'data'}]
]
data = [
['India'],
['Australia'],
['Germany'],
['United States'],
['Brazil'],
['Canada'],
['France'],
['Russia']
];
options = {
backgroundColor: '#17263c',
datalessRegionColor: '#242f3e',
legend: 'none',
tooltip: {
isHtml: true,
textStyle: {
color: 'black'
}
},
colors: ['#46127A', '#1102BB', '#1633C4', '#3185CE']
};
dynamicResize = true;
<google-chart #chart
[title]="title"
[type]="type"
[data]="data"
[columnNames]="columnNames"
[options]="options"
[dynamicResize]="dynamicResize"
style="width: 100%; height: 100%;">
</google-chart>
As you can see there is the array data (which will be saved in a database lateron)
What I now want to do is to change the color of a country on click. There are two things I don't know:
How do I know where I click on the map? If I click on Germany for example how does my program know that it should run pushCountry("Germany") for example and if I click on France pushCountry("France")
How do I really push the countrys so that they are displaxed immediately? For testing I created a button calling the function this.data.push(['Germany']) and logged the array, Germany was added but the color in my chart did not change.
Thank you for your help!

Restrict qtip2 inside a container

How to keep all the qtips inside a container (I have already tried position.container, position.viewport and position.adjust.method) without any luck, my best guess is that I am not using them correctly.
Update:1 I have created a sample app with more details on below url
http://secure.chiwater.com/CodeSample/Home/Qtip
Update:2 I have created jsfiddle link too. http://jsfiddle.net/Lde45mmv/2/
Please refer below screen shot for layout details.
I am calling the area shown between two lines as $container in my js code.
So far I have tried tweaking viewport, adjust method but nothing helped. I am hoping this is possible and I would greatly appreciate any help.
Below is my javascript code which creates qtip2.
//Now create tooltip for each of this Comment number
$('#cn_' + num).qtip({
id: contentElementID,
content: {
text: .....
var $control = $('<div class="qtip-parent">' +
' <div class="qtip-comment-contents">......</div>' +
' <div class="clearfix"></div>' +
' <div class="qtip-footer"><span class="qtip-commenter">...</span><span class="pull-right">...</span></div>' +
'</div>'
);
return $control;
},
button: false
},
show: 'click',
hide: {
fixed: true,
event: 'unfocus'
},
position: {
my: 'top right',
at: 'bottom right',
target: $('#cn_' + num),
container: $container,
//viewport: true,
adjust: { method: 'shift none' }
},
style: {
tip: {
corner: true,
mimic: 'center',
width: 12,
height: 12,
border: true, // Detect border from tooltip style
//offset: 25
},
classes: 'qtip-comment'
},
events: {
show: function (event, api) {
...
},
hide: function (event, api) {
...
}
}
});
Example of jalopnik page which shows what I am looking for (FWIW jalopnik example doesn't use qtip2).
I don't think qtip API supports this functionality. I ended up re-positioning the tooltip on visible event.
I have updated the demo page and jsfiddle link below is code for doing this.
events: {
visible: function (event, api) {
var $qtipControl = $(event.target);
$qtipControl.css({ 'left': contentPosition.left + "px" });
var $qtipTipControl = $qtipControl.find(".qtip-tip");
var $target = api.get("position.target");
$qtipTipControl.css({ "right": 'auto' });
//I am using jquery.ui position
$qtipTipControl.position({
my: "center top",
at: "center bottom",
of: $target
});
}
}
Problem with this approach is that there is noticeable jump when I re-position the qTip. But in lack of any other option for time being I will settle with this.
The ideal approach would be to allow callback method thru position.adjust currently it only supports static values for x and y, if a method was allowed here it would make things much smoother.

Pass render args to next route

I am developing a NodeJS app using Express 3.0 with Swig as my template engine. What I would like to accomplish is the passing of render arguments to the next route. I want to this because I have certain site components which exist on every single page of my site (sidebar, navbar, footer, etc). Each and every one of these components has widgets and links that toggle on and off. Right now I am doing the following to toggle these widgets:
response.render('network.html', {
activeTab: 'network',
username: request.session.username,
bread_current: 'Network',
page_title: 'Your Network',
page_subtitle: 'Mordrum',
widgets: {
navbar: {
chats: {
enabled: true,
color: 'blue',
icon: 'chatbubble'
}, messages: {
enabled: true,
color: 'red',
icon: 'mail'
}, users: {
enabled: true,
color: 'green',
icon: 'person'
}
}
}
})
There is a lot of arguments there (within the widgets object) that I end up repeating numerous times within my code (once for each route). I was wondering if there is a way to pass args to the next route.
If the data is static (it doesn't change over the course of running your app), use app.locals to store it. Any data stored in there will automatically become available to any templates:
app.locals.widgets = {
navbar: {
chats: {
enabled: true,
color: 'blue',
icon: 'chatbubble'
}, messages: {
enabled: true,
color: 'red',
icon: 'mail'
}, users: {
enabled: true,
color: 'green',
icon: 'person'
}
}
};
If the data does change, use res.locals instead. Any data stored there will also be available for any templates, but only during the lifetime of a single request. Any middleware can also access it (and change it if necessary).
The express way of doing this is to set them on res. Presumably you have a Widget1 middleware. That will set res.widget1.options and then call next(). Then another middleware will set res.widget2.options, and so on.

Hide US on google geochart when region is set to Canada

I need to hide US on geo chart, when region is set to Canada:
google.load('visualization', '1', {'packages': ['geochart']});
google.setOnLoadCallback(drawVisualization);
function drawVisualization() {var data = new google.visualization.DataTable();
data.addColumn('string', 'Country');
data.addColumn('number', 'Value');
data.addColumn({type:'string', role:'tooltip'});var ivalue = new Array();
data.addRows([[{v:'CA-BC',f:'CA-BC'},0,'Test']]);
var options = {
backgroundColor: {fill:'#FFFFFF',stroke:'#FFFFFF' ,strokeWidth:0 },
colorAxis: {minValue: 0, maxValue: 0, colors: ['#0000ff',]},
legend: 'none',
backgroundColor: {fill:'#FFFFFF',stroke:'#FFFFFF' ,strokeWidth:0 },
datalessRegionColor: '#f5f5f5',
displayMode: 'markers',
enableRegionInteractivity: 'true',
resolution: 'provinces',
region:'CA',
keepAspectRatio: true,
width:700,
height:500,
tooltip: {textStyle: {color: '#444444'}, trigger:'focus'}
};
var chart = new google.visualization.GeoChart(document.getElementById('visualization'));
chart.draw(data, options);
}
http://jsfiddle.net/jk171505/VJtBR/
With the API options, you can't really do it.
You can use advanced CSS selectors to hide the SVG shapes.
Add this CSS and it will hide the US shapes:
#visualization path:nth-child(237), #visualization path:nth-child(236) {
display:none;
}
http://jsfiddle.net/cmoreira/mMadX
I have built a page with some information on how to use this and other CSS techniques with the Google Geochart API. In case it helps, here's the link: http://cmoreira.net/interactive-world-maps-demo/advanced-customization/

Extjs tabpanel with big complex objects or dynamically loaded objects

I have some problem with complex objects on tabpanel.
I have 2 complex objects with stores, windows, grids, trees and etc. Here is the beginning of the object:
Ext.define('Ext.app.DocumentsContainer', {
extend: 'Ext.container.Container',
initComponent: function(){
var documentsStore = Ext.create('Ext.data.Store', {
And I have tabpanel with 2 panels(one for each object).
full code of viewport with tabpanel:
Ext.create('Ext.container.Viewport', {
layout: 'border',
padding: '5',
items: [
{
xtype: 'container',
region: 'north',
height: 50
},
{
xtype: 'tabpanel',
activeTab: 0,
region: 'center',
width: 100,
items: [
{
xtype: 'panel',
title: 'Documents',
layout: 'border',
items: Ext.create('Ext.app.DocumentsContainer'),
},{
xtype: 'panel',
title: 'Transmittals',
layout: 'border',
items: [Ext.create('Ext.app.TransmittalsContainer')],
}]
}
],
});
When I testing my page, a have a problem, because somehow data from one object dysplays in grid in another object, or doesnt dysplay at all.
But both objects working correctly one at a time.
I think, I can fix it by dynamically loading objects when tab is opened, but dont know how can I do it.
Any suggestions?
Without knowing the internals of your two components Ext.app.DocumentsContainer and Ext.app.TransmittalsContainer one cannot reliably answer your question. Perhaps you assign the same ID to two different internal components - that's most often the reason for mixed up data.
Secondly, Frederic is right - you're overnesting your components. Both panels inside the tabpanel are unnecessary because you can put your components directly into the tabpanel as illustrated by Frederic. However, if you insist to keep your panels, try changing the layout to fit because that layout-type handles single-item-components (sized the single component to fit into the parent frame).
You are overnesting the tabpanel. The tabpanels items will automatically stretch their content. So it might just work for you.
Do this instead. Change DocumentContainer to pe panel (so it can have a title. )
Ext.define('Ext.app.DocumentsContainer', {
extend: 'Ext.panel.Panel',
initComponent: function(){
var documentsStore = Ext.create('Ext.data.Store', {
And change you tabpanel to this. I also deleted the width on your center region. center regions fills out the rest of the border layouts space automatically.
Ext.create('Ext.container.Viewport', {
layout: 'border',
padding: '5',
items: [
{
xtype: 'container',
region: 'north',
height: 50
},
{
xtype: 'tabpanel',
activeTab: 0,
region: 'center',
items: [
Ext.create('Ext.app.DocumentsContainer', {title:'Documents'}),
Ext.create('Ext.app.TransmittalsContainer', {title:'Transmittals'})
]
}
],
});
Also. as Stefan mentioned. Never ever use id´s in your ExtJS4 code. They are evil and will freck your result up eventually. itemId or just simple Ext.DomQuery is the way to do it.

Resources