How to make Angular Gridster dynamically change column length on resizing window - angularjs

I'm having this issue where when I resize the browser window, all the elements in the grid get cluttered on top of each other. I have added the link to how it looks before and after resizing window.
After resizing
Before resizing
The gridster options are as below:
$scope.gridsterOpts = {
columns: 10, // the width of the grid, in columns
pushing: false, // whether to push other items out of the way on move or resize
floating: true, // whether to automatically float items up so they stack (you can temporarily disable if you are adding unsorted items with ng-repeat)
swapping: true, // whether or not to have items of the same size switch places instead of pushing down if they are the same size
width: 'auto', // can be an integer or 'auto'. 'auto' scales gridster to be the full width of its containing element
colWidth: 'auto', // can be an integer or 'auto'. 'auto' uses the pixel width of the element divided by 'columns'
rowHeight: 'match', // can be an integer or 'match'. Match uses the colWidth, giving you square widgets.
margins: [30, 30], // the pixel distance between each widget
outerMargin: true, // whether margins apply to outer edges of the grid
isMobile: false, // stacks the grid items if true
mobileBreakPoint: 600, // if the screen is not wider that this, remove the grid layout and stack the items
mobileModeEnabled: true, // whether or not to toggle mobile mode when screen width is less than mobileBreakPoint
minColumns: 1, // the minimum columns the grid must have
minRows: 1, // the minimum height of the grid, in rows
maxRows: 100,
defaultSizeX: 2, // the default width of a gridster item, if not specifed
defaultSizeY: 1, // the default height of a gridster item, if not specified
minSizeX: 1, // minimum column width of an item
maxSizeX: 1, // maximum column width of an item
minSizeY: 1, // minumum row height of an item
maxSizeY: 1, // maximum row height of an item
resizable: {
enabled: false,
handles: ['n', 'e', 's', 'w', 'ne', 'se', 'sw', 'nw'],
start: function(event, $element, widget) {}, // optional callback fired when resize is started,
resize: function(event, $element, widget) {}, // optional callback fired when item is resized,
stop: function(event, $element, widget) {} // optional callback fired when item is finished resizing
},
draggable: {
enabled: true, // whether dragging items is supported
handle: '.my-class', // optional selector for resize handle
start: function(event, $element, widget) {}, // optional callback fired when drag is started,
drag: function(event, $element, widget) {}, // optional callback fired when item is moved,
stop: function(event, $element, widget) {} // optional callback fired when item is finished dragging
}
};
};

try this.
scope.$on('gridster-resized', function(sizes, gridster) {
// sizes[0] = width
// sizes[1] = height
// gridster.
})

Related

Adding enabling and disabling as context menu on a grid in extjs

Hi I have added one context menu on my grid which will perform the enable and disable functionality for selected row. I am new to ExtJs. I have added below listener for the grid. How to add enable and disable functionality for the grid row?
listeners: {
itemcontextmenu: function (grid, record, item, index, e) {
var contextMenu = Ext.create('Ext.menu.Menu', {
controller: 'grid-controller',
width: 165,
plain: true,
items: [{
text: 'Disable',
listeners: {
click: {fn: 'disable', extra: record}
},
}]
});
e.stopEvent();
contextMenu.showAt(e.getXY());
}
}
This is not a copy-paste answer, but going through the following steps with doing your own research you can solve your problem.
1. Create the context menu only once and destroy it
In you code, the context menu is created every time when the user opens up the menu on the grid. This is not good. Instead, create the context menu only once when the grid is created, and destroy it when the grid is destroyed. Something like this:
Ext.define('MyGrid', {
extend: 'Ext.grid.Panel',
initComponent : function() {
this.callParent();
this.MyMenu = Ext.create('Ext.menu.Menu', {
items: [...]
});
this.on({
scope : this,
itemcontextmenu : this.onItemContextMenu
});
},
onDestroy : function() {
if (this.MyMenu) {
this.MyMenu.destroy();
}
},
onItemContextMenu : function(view, rec, item,index, event) {
event.stopEvent();
this.MyMenu.showAt(event.getXY());
}
});
2. Store enabled / disabled state in the record
For the next step to work, records in your grid must contain whether the corresponding row is enabled or disabled. In the context menu, when user selects enabled / disabled, store this status like this, get record of the row where the context menu was displayed from:
record.set('myDisabledState', true); // or false
It is important to store the disabled state (and not enabled), because when your grid initially is rendered, these values won't be in the records, so record.get('myDisabledState') will evaluate to FALSE, and that is the desired behaviour, if you want to start with every row being able to be selected.
3. Disable selection
Now you can add a beforeselect listener to your grid, see documentation. This listeners receives record as parameter, and if you return false from this listener, the selection will be canceled. So in this listener simply add:
listeners: {
beforeselect: function ( grid, record, index, eOpts ) {
return !record.get('myDisabledState');
}
}
4. Apply formatting - OPTIONAL
It is likely that you want to add different formatting for disabled rows, for example grey colour. The easiest way to do it is to add a custom CSS style to your Application.scss file:
.my-disabled-row .x-grid-cell-inner {
color: gray;
}
Finally add getRowClass configuration to your grid, it will receive the current record being rendered, and you can return the above custom CSS style when the row is disabled:
Ext.define('MyGrid', {
// your grid definition
,
viewConfig: {
getRowClass: function (record, rowIndex, rowParams, store) {
if (record.get('myDisabledState')) {
return "my-disabled-row";
}
}
}
});
In this last part, when row is not disabled, it will return nothing, so default formatting will be used.

gridster c3 charts auto resizing issue

I am facing problem with c3 charts sizing issue with in gridster. Can any one help me how can I make there charts to be properly auto resized according to the gridster box they are in? Please find the Plunker
I have given size in options :
size: {
height: 100,
width: 100
}
If I remove this size property the charts are going out of box. But they are too small in gridster boxes. How can I make these chart to automatically occupy the full height and width of the gridster boxes that they are in?
The options you are using:
size: {
height: 100,
width: 100
}
are setting the height and width of the svg element to 100px instead of 100%
I tried
size: {
height: '100%',
width: '100%'
}
Which will successfully set the width to 100% but somehow the height will be set to 320px
So if you add this to your css:
.c3 svg {
width: 100%;
height: 100%;
}
That will solve your sizing issue.
EDIT
Just a small change to set up an initial size and some comments added to your controller on the resize - stop event handler, where you will need to add some resizing of your charts based on the new sizes. See it here
resizable: {
enabled: true,
handles: ['n', 'e', 's', 'w', 'ne', 'se', 'sw', 'nw'],
// optional callback fired when resize is started
start: function(event, $element, widget) {},
// optional callback fired when item is resized,
resize: function(event, $element, widget) {},
// optional callback fired when item is finished resizing
stop: function(event, $element, widget) {
// here should update the size according to the widget size
// widget.sizeX (* 160px) and widget.sizeY (* 160px)
// and further adjustments
}
},
I had a similar problem not long ago. What I did is use scale(), but it doesn't work on firefox.
Basically find the width when loading, and make a new scale when the user changes the screen size (or any other event like resizing your containers).
add this at the bottom of your plunker :
<script>
let width = window.innerWidth;
window.addEventListener('resize', (event) => {
let newWidth = window.innerWidth;
let ratio = newWidth / width;
let ctnr = document.getElementById('widget1');
ctnr.style.transform = "scale(" + ratio + ")";
});
</script>
That will scale widget 1. Of course you might have to play with the numbers a bit to find what works for you.
The widget will stay in place however; thus if you want it to be aligned on the left you can use in your css :
transform-origin: 0;
I hope this helps.
Use nvd3 plugin this is same as c3 plugin also this smoothly works with gridster, Please find the below link
https://krispo.github.io/angular-nvd3/#/dashboard

Extjs Anchor Layout using offsets

What is the offset configuration actually doing that makes panel 2 to show incompletely when the panel 1 is resized vertically?
Ext.onReady(function(){
var myWin = Ext.create('Ext.window.Window',{
height : 300,
width : 300,
layout : 'anchor',
border : false,
anchorSize : 400,
items : [
{
title : 'panel 1',
anchor: '-50, -150',
frame : true
},
{
title : 'panel 2',
anchor: '-10, -150', // how is this config working?
frame : true
}
]
});
myWin.show();
});
https://fiddle.sencha.com/#fiddle/64r
Thanks in advance.
from ExtJS docs...
// two values specified
anchor: '-50 -100' // render item the complete width of the container
// minus 50 pixels and
// the complete height minus 100 pixels.
// one value specified
anchor: '-50' // anchor value is assumed to be the right offset value
// bottom offset will default to 0
So possibly you're resizing the window to a size smaller than 150 (that is 300 - the specified anchor) pixels.. so "the complete height minus 150 pixels" will actually result in cropping of the item inside that container.
It would be much better to see some example of what you're trying to achieve and a fiddle of how it's working now though.
EDIT
You're setting the height of both components to be "the size of the window" minus some fixed amount (50) of pixels. If the window grows to 500 pixels "tall" then you get two panels that are 450 pixels tall. That's why the second panel always overflows the window.
It's all in the portion of docs that I posted earlier though. You may want to try some other layouts too, maybe nested layouts, for example: an anchor layout inside an hbox layout.
Ext.create("Ext.Window", ({
height : 300,
width : 300, items : [
{
title : 'Panel1',
anchor : '-50, -150',
frame : true
},
{
title : 'Panel2',
anchor : '-10, -150',
frame : true
}
]
}));
Panel1 Width = 288px - 50px = 238px
Panel1 Height = 285px - 150px = 135px
Panel2 Width = 288px - 10px = 278px
Panel2 Height = 285px - 150px = 135px

editor alternate tip message

I am trying to set 2 different tool tip message for 2 cells of single column,but on run time single tip message will be applied that is if am clicking on cell with respect to condition of if clause then same tip message will be forwarded to rest of the cells,if i navigate from 1 st cell to 2 cell message will not change 1 st cell message will carry forwards and vise versa if i move from 2nd cell to 1 cell 2nd tip message will remain same for rest of the cells.
celldblclick : function(grid, rowIndex, columnIndex, e) {
var ed = grid.getColumnModel().getCellEditor(columnIndex,rowIndex) || {};
ed = ed.field || {};
if (rowIndex == 0 && columnIndex == 2) {
ed.qtipText="SAMPLE1";
} else {
ed.qtipText="SAMPLE2";
}
}
To get them to display differently I normally attach a function to the tooltip beforeshow method which updates the tooltip before it is displayed:
// add tooltips to grid
myGrid.getView().on('render', function(view) {
view.tip = Ext.create('Ext.tip.ToolTip', {
target: view.el,
delegate: view.itemSelector,
trackMouse: true,
minWidth: 0,
maxWidth: 800,
dismissDelay: 0,
showDelay: 800,
renderTo: Ext.getBody(),
listeners:{
beforeshow: function updateTipBody(tip){
text = view.getRecord(tip.triggerElement).get('tooltip')
tip.setWidth(text.length * 5);
tip.update(text);
}
}
});
});
In the above example I had my tooltips defined for each record in the datastore itself, that is why I call text = view.getRecord(tip.triggerElement).get('tooltip') ('tooltip' is the column in my datastore with the tooltip text). But you could implement whatever logic you want in the beforeshow listener function as long as you call tip.update(yourLogic) at the end.

Is it possible to use Ext.Resizable on a 'width: 100%' element?

When I apply Ext.Resizable with parameters wrap: true, handles: 's' to an Ext.form.TextArea with width: 100%, the text area loses its width. More specifically, the width is reset to sth. like default width in pixels. Is it possible to cleanly make Ext.Resizable just not touch width at all and operate on element's height only? I checked that not touching width would work fine in principle by replacing (in FireBug) explicit widths on the text area and wrapping div back with 'width: 100%'.
I'm trying to achieve effect similar to SO's question/answer text area, which can be resized for height.
Isn't anchoring an option, with layout:'fit' on a panel and anchor:'100%' on the textarea the width should stay at 100%.
The drawback is that you are required to wrap everything in a panel and possibly also use ext components (like Ext.form.Textarea)
ref: http://www.sencha.com/deploy/dev/examples/form/anchoring.html
Try this:
Ext.onReady(function(){
var el = Ext.getBody().createChild({
tag: 'div',
style: 'width: 600px;'
});
var area = new Ext.form.TextArea({
renderTo: el,
style: 'width: 100%'
});
new Ext.Resizable(area.el, {
wrap: true,
handles: 's',
height: area.getHeight(),
});
});
Here is my hackish subclass I eventually used.
ExtOverrideUtils = {
setSizeIgnoreWidth: function (width, height, animate)
{
this.setHeight ((typeof width == 'object' ? width.height : height), animate);
},
intercept: function (func, overrides)
{
return function ()
{
var value = func.apply (this, arguments);
if (value) {
for (var name in overrides)
value[name] = overrides[name];
}
return value;
};
}
}
NoWidthResizable = Ext.extend (Ext.Resizable,
{
constructor: function (el, config)
{
el = Ext.get (el);
el.setSize = ExtOverrideUtils.setSizeIgnoreWidth;
el.wrap = ExtOverrideUtils.intercept (el.wrap, { setSize: ExtOverrideUtils.setSizeIgnoreWidth });
NoWidthResizable.superclass.constructor.call (this, el, config);
}
});
Usage from a custom subclass of Ext.form.TextArea (though I guess it can be used just as normal Ext.Resizable, for arbitrary element):
this._resizer = new NoWidthResizable (this.el,
{ wrap: true,
handles: 's',
minHeight: 30,
pinned: true,
dynamic: true });

Resources