Add row expander for second column in grid - extjs4 - grid

I am very new for extjs 4.I am facing one problem.Hope somebody will help.
I am having grid.I have added row expand in that grid.
Here is my code :
Ext.define('Citi.iv.view.portfolio.PositionsLiabilitiesGrid', {
extend : 'Ext.grid.Panel',
requires:['Ext.ux.RowExpander'],
alias : 'widget.positionsliabilitiesgrid',
headerHeight:80,
itemId : 'financialPositionsassetGrid',
margin: '0 0 10px 0',
flex : 1,
cls : 'grey_alt_grid',
scroll : 'vertical',
autoScroll: true,
emptyText : 'No Data Found',
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'<p><b>Render data here</b></p><br>'
]
}],
collapsible: true,
columns : [{
header : 'Account Descriptions',
flex : 1,
xtype : 'gridcolumn',
hideable: false,
dataIndex : 'account_description'
}, {
header : 'Account',
flex : 1,
xtype : 'gridcolumn',
hideable: false,
dataIndex : 'account'
}, {
header : 'Amount You Own',
flex : 1,
xtype : 'gridcolumn',
hideable: false,
dataIndex :'amount_you_own',
}, {
header : 'Interest Rate',
flex : 1,
xtype : 'gridcolumn',
hideable: false,
dataIndex : 'interest_rate'
}, {
header : 'Next Payment',
flex : 1,
xtype : 'gridcolumn',
hideable: false,
dataIndex : 'next_payment'
}, {
header : 'Payment Due Date',
flex : 1,
xtype : 'gridcolumn',
hideable: false,
dataIndex : 'payment_due_date'
}, {
header : 'Interest Paid',
flex : 1,
xtype : 'gridcolumn',
hideable: false,
dataIndex : 'interest_paid'
}]
});
I am getting expand on 1st column.I want add the expand icon on second column. Any idea?

You have to extend the class Ext.ux.RowExpander. The code of this class has changed between version 4.1.0 and 4.1.1 of Ext (and has been included in the core in version 4.2 as Ext.grid.plugin.RowExpander).
Here's how to do it:
/**
* A {#link Ext.ux.RowExpander} that can be positioned at any column.
*
* #xtype rowexpanderat
*/
Ext.define('Rx.grid.RowExpanderAt', function() {
var spec = {
extend: 'Ext.ux.RowExpander'
,alias: 'plugin.rowexpanderat'
/**
* Index of the column of the row expander.
*
* #cfg {Integer} [insertAt=0]
*/
,insertAt: 0
/**
* #inheritdoc
*
* Overridden to implement {#link #insertAt} config option.
*/
,addExpander: function(){
var position = this.insertAt;
this.grid.headerCt.insert(position, this.getHeaderConfig());
}
/**
* #inheritdoc
*
* Overridden to span the row body on the row expander column too.
*/
,getRowBodyFeatureData: function() {
var o = this.callParent(arguments);
o.rowBodyColspan ++;
return o;
}
/**
* #inheritdoc
*
* Overridden to remove the special styling of the row expander column
* (i.e. the gray and the right border that would overflow over the r
* ow body).
*/
,getHeaderConfig: function() {
var o = this.callParent(arguments);
o.renderer = function(value, metadata) {
return '<div class="'
+ Ext.baseCSSPrefix
+ 'grid-row-expander"> </div>';
};
return o;
}
};
// Adapt if version is less than 4.1.1
if (Ext.getVersion().isLessThan('4.1.1')) {
delete spec.addExpander;
spec.init = function(grid) {
this.callParent(arguments);
// Columns have to be added in init (after columns has been used to create the
// headerCt). Otherwise, shared column configs get corrupted, e.g., if put in the
// prototype.
grid.headerCt.insert(this.insertAt, this.getHeaderConfig());
grid.on('render', this.bindView, this, {single: true});
};
} else if (Ext.getVersion().isGreaterThan('4.1.1')) {
throw new Error('Unsupported');
}
return spec;
});
Then, you would use it this way, in your grid's config:
Ext.create('Ext.grid.Panel', {
plugins: [{
// instead of rowexpander
ptype: 'rowexpanderat'
// position at which to insert, 0-based
,insertAt: 1
// other plugin configuration...
,rowBodyTpl : [
'<p><b>Render data here</b></p><br>'
]
}]
// ... all your grid configuration
});
P.S. I haven't really tested the above code for Ext 4.1.0. If it doesn't
work for you, use the following class instead:
Ext.define('Rx.grid.RowExpanderAt', {
extend: 'Ext.ux.RowExpander'
,alias: 'plugin.rowexpanderat'
,insertAt: 0
,init: function(grid) {
this.callParent(arguments);
// Columns have to be added in init (after columns has been used to
// create the headerCt). Otherwise, shared column configs get corrupted,
// e.g., if put in the prototype.
grid.headerCt.insert(this.insertAt, this.getHeaderConfig());
grid.on('render', this.bindView, this, {single: true});
}
,getRowBodyFeatureData: function() {
var o = this.callParent(arguments);
o.rowBodyColspan ++;
return o;
}
,getHeaderConfig: function() {
var o = this.callParent(arguments);
o.renderer = function(value, metadata) {
return '<div class="' + Ext.baseCSSPrefix + 'grid-row-expander"> </div>';
};
return o;
}
});

Related

font-awesome icon in display of combobox extjs 6

I tried several ways to set an icon, in the displayfield, when an item of the combo is selected with not luck, this is the fiddle for anyone to want try to help with this. very much appreciated any light.
fiddle example
The only solution is to transform the input type combo in a div with this:
fieldSubTpl: [
'<div class="{hiddenDataCls}" role="presentation"></div>',
'<div id="{id}" type="{type}" style="background-color:white; font-size:1.1em; line-height: 2.1em;" ',
'<tpl if="size">size="{size}" </tpl>',
'<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
'class="{fieldCls} {typeCls}" autocomplete="off"></div>',
'<div id="{cmpId}-triggerWrap" class="{triggerWrapCls}" role="presentation">',
'{triggerEl}',
'<div class="{clearCls}" role="presentation"></div>',
'</div>', {
compiled: true,
disableFormats: true
}
],
Override the setRawValue method of the combo like this:
setRawValue: function (value) {
var me = this;
me.rawValue = value;
// Some Field subclasses may not render an inputEl
if (me.inputEl) {
// me.inputEl.dom.value = value;
// use innerHTML
me.inputEl.dom.innerHTML = value;
}
return value;
},
and style your fake combo div like you want.
Thats because an input on HTML can't have HTML like value inside it.
Keep attenction, the get Value method will return you the HTML inside the div, and maybe you should also override it, but thats the only one method.
You will be able to get the selected value with this method:
Ext.fly(combo.getId()+'-inputEl').dom.innerHTML.replace(/<(.|\n)*?>/gm, '');
If I were you I would like to do something like this:
combo.getMyValue();
So add this property to your combo:
getMyValue:function(){
var combo=this;
if(Ext.fly(combo.id+'-inputEl'))
return Ext.fly(combo.id+'-inputEl').dom.innerHTML.replace(/<(.|\n)*?>/gm, '');
},
Here is a working fiddle
Perhaps my solution is similar to a hack, but it works in 6.7.0 and is a bit simpler.
Tested in Chrome. Theme - Material. For another theme will require minor improvements.
Sencha Fiddle live example
Ext.application({
name: 'Fiddle',
launch: function () {
var store = new Ext.data.Store({
fields: [{
name: 'class',
convert: function (value, model) {
if (value && model) {
var name = value
.replace(/(-o-)|(-o$)/g, '-outlined-')
.replace(/-/g, ' ')
.slice(3)
.trim();
model.data.name = name.charAt(0).toUpperCase() + name.slice(1);
return value;
}
}
}, {
name: 'name'
}],
data: [{
class: 'fa-address-book'
}, {
class: 'fa-address-book-o'
}, {
class: 'fa-address-card'
}]
});
var form = Ext.create('Ext.form.Panel', {
fullscreen: true,
referenceHolder: true,
items: [{
xtype: 'combobox',
id: 'iconcombo',
queryMode: 'local',
editable: false,
width: 300,
valueField: 'class',
displayField: 'name',
store: store,
itemTpl: '<div><i class="fa {class}"></i> {name}</div>',
afterRender: () => {
var component = Ext.getCmp('iconcombo');
var element = document.createElement('div');
element.className = 'x-input-el';
element.addEventListener('click', () => component.expand());
component.inputElement.parent().dom.prepend(element);
component.inputElement.hide();
component.addListener(
'change', (me, newValue, oldValue) => {
component.updateInputValue.call(me, newValue, oldValue);
},
component
);
var method = component.updateInputValue;
component.updateInputValue = (value, oldValue) => {
method.call(component, value, oldValue);
var selection = component.getSelection();
if (selection) {
element.innerHTML =
'<div><i class="fa ' + selection.get('class') + '"></i> ' + selection.get('name') + '</div>';
}
};
}
}, {
xtype: 'button',
text: 'getValue',
margin: '30 0 0 0',
handler: function (component) {
var combo = Ext.getCmp('iconcombo');
alert(combo.getValue());
}
}]
});
form.show();
}
});

ExtJs submit menubutton values

I am trying to submit the values from the menu buttons but know this is not possible and that I have to create a hidden field and store the button values there.
Being new to ExtJs I can not seem to figure out how to do this. Below is the basic layout I used to check the button shows and I can choose a colour.
getFormItems : function() {
var me = this;
return [{
xtype : "fieldset",
title : "Items to monitor",
defaults : {
labelSeparator : ""
},
items : [{
xtype : "checkbox",
name : "cpuenable",
boxLabel : _("Will monitor CPU Temperature"),
fieldLabel : _("CPU Temperature"),
checked : false
},{
xtype : 'hiddenfield',
id : 'buttonvalues'
},{
xtype : "button",
name : "colours",
text : _("Choose Colours"),
scope : this,
style : {
marginTop : "10px",
marginBottom : "10px"
},
menu: [{
text: "Main CPU Colour",
menu: {
xtype : "colormenu",
name : "colourc",
value : "000000",
cls : "menubutton-class",
handler: function (obj, rgb) {
var colourmField = this.findField('colourc');
colourmField.setValue(rgb.toString());
alert(colourmField.getValue());
}
}
},{ and so on
Okay, here is an edit for you of my previous post. I give you an example how to fetch all child components you want inside a component:
Example extjs:
{
xtype: 'fieldset',
id: 'fsButtons',
items: [
{
xtype: 'hiddenfield',
id: 'hiddenValues'
},
{
xtype: 'button'
color: '000000'
},
{
xtype: 'button'
color: '555555'
}
]
}
Function to fill the hiddenfield:
function getButtonVars() {
var buttonVars = new Array();
//Get all components with xtype 'button' inside the fieldset with id 'fsButtons'
Ext.Array.each(Ext.ComponentQuery.query('button', Ext.getCmp('fsButtons'), function(button){
buttonVars.push(button.color);
});
Ext.getCmp('hiddenValues').setValue(buttonVars.join(',')); // concats all button values to one string: '000000,555555' etc.
}
I hope it's clear now :)
http://docs-origin.sencha.com/extjs/4.2.2/#!/api/Ext.ComponentQuery

Cannot read property 'features' of undefined when use Ext.ux.touch.grid

When i use Ext.ux.touch.grid,an error happened?
"Cannot read property 'features' of undefined "
but it only happen when i use it like this,
this.testGrid = Ext.create('Geo.view.Grid');
in file application.js,a main controller file
config: {
refs: {
main: 'mainview',
worklist: 'worklist',
testGrid: 'testGrid'
},
this is testGrid view file
Ext.define('Geo.view.Grid', {
extend : 'Ext.ux.touch.grid.List',
xtype : 'testGrid',
requires : [
'Ext.ux.touch.grid.feature.Feature',
'Ext.ux.touch.grid.feature.Editable',
'Ext.ux.touch.grid.feature.Sorter',
'Ext.field.Number',
'Geo.store.Grid'
],
config : {
title : 'Grid',
store : true,
columns : [
{
header : 'Text',
dataIndex : 'text',
width : '90%',
editor : {
xtype : 'textfield'
}
},
{
header : 'Amount',
dataIndex : 'amount',
width : '10%',
editor : {
xtype : 'numberfield'
}
}
],
features : [
{
ftype : 'Ext.ux.touch.grid.feature.Sorter',
launchFn : 'initialize'
},
{
ftype : 'Ext.ux.touch.grid.feature.Editable',
launchFn : 'initialize'
}
]
},
applyStore : function() {
return new Geo.store.Grid();
}
});
When direct use it in main view file,it's Correct
items: [
{xtype: 'dashboards'},
{xtype: 'testGrid'}
]
Who know the reason? Thanks a lot
do you set your store to autoload: true, (?)

How to delete record from grid on delete in extjs4

I am working in extjs4. I have view with grid as item with code:
{
margin : '10 0 5 100',
xtype : 'grid',
id : 'g3',
//title : 'Educational Details',
store:'qb.qbquestionoptionStore',
columns : [ {
text : 'questionId',
dataIndex : 'questionId',
flex : 1
},
{
text : 'category',
dataIndex : 'category',
flex : 1
}, {
text : 'Answer',
dataIndex : 'isAnswer',
flex : 2.5
},
{
header : 'Remove',
renderer : function(val) {
return 'Remove';
},
}
So on clicking on remove link,corresponding entry gets deleted from database. But grid is still showing that deleted entry. In controller I have code for it as-
deleterow:function(cmp)
{
cmp.mon(cmp.getEl(),'click',function(event,target)
{
if(target.id=='remove')
{
// alert("hello");
listview=Ext.getCmp('g3');
listview.on({
itemClick: function(dv, record, item, index, e,opts)
{
liststore=this.getStore('qb.qbquestioncomplexityStore').sync();
liststore.load({
params:{
id:record.data.id,
questionId:record.data.questionId
}
});
console.log(record);
console.log(" Id is "+record.data.id);
var shopCart=Ext.create('Balaee.model.qb.qbquestioncomplexityModel',
{
id:record.data.id,
questionId:record.data.questionId
});
Ext.Msg.confirm('Confirm to delete', 'Want to delete record?', function (button)
{
if (button == 'yes')
{
shopCart.destroy();
}
}); }
}); }
},this,{delegate:"a"});
},
So how to delete record from grid?.
to remove a row from gridpanel, i do something like this:
var selectedRecord = grid.getSelectionModel().getSelection()[0];
grid.getStore().each(function(rec) {
if (rec == selectedRecord) {
grid.store.remove(rec);
}
});
grid.getView().refresh();
Your code is a bit weird but I think you are nearly there:
The easiest way is when you have set a proxy to the model. You just need to call destroy(). Any stores this record is bound to will be notified.
if (button == 'yes'){
record.destroy();
shopCart.destroy();
}
If not I assume for this example that your record is only bound to one store, then you can do it like
if (button == 'yes'){
var s = record.store;
s.remove(record);
s.store.sync();
shopCart.destroy();
}

adding button returns [object][object] in EXTJS

Am having a controller which basically calls a message window that is displayed for a few seconds. Am trying to add a button to this message window, but its returning [object][object].
Controller
success : function(response) {
this.mWin = Ext.create('App.view.GenMessage');
this.mWin.addMessage(true, LANG.SUCT, LANG.SUCTxt1);
}
View
Ext.define('App.view.GenMessage', {
extend : 'Ext.panel.Panel',
alias : 'widget.genmessage',
initComponent : function() {
this.msgCt = App.genMsgCt
this.msgCt.setWidth(300);
},
addMessage : function(status, title, msg) {
if (status == false) {
delay = 3000;
} else {
delay = 2000;
}
Ext.DomHelper.append(this.msgCt, {
html : this.buildMessageBox(status, title, msg)
}, true).slideIn('t').pause(delay).ghost("t", {
remove : false
});
},
/*
* buildMessageBox
*/
buildMessageBox : function(status, title, msg) {
console.log('buildMesssage');
switch (status) {
case true :
var icon = GENHTML.tick;
break;
case false :
var icon = GENHTML.warning;
break;
}
return ['<div class="genMsgDiv">', icon,
'<div class="genMsgHd leftMargin">', title,
'</div><div class="H3 leftMargin">', msg,
'</div></div>'].join('');
}
What i did was declare a button like
var button={
id: 'button1',
text :'Button1'
}
and then add to the div class mentioned above and return
['<div class="genMsgDiv">', button].join();
But, what i see in the screen is [object][object] in place of the button.
Could anyone please tell me what am doing wrong here. Is this the correct way to add the button
EDIT
Since we cannot add a button to a div, i tried doing
var config = Ext.create(Ext.panel.Panel, {
itemId : 'GENMSGPANEL',
height : 150,
cls : 'msg effect1',
border : false,
html : '<div class="genMsgDiv">' + icon +
'<div class="genMsgHd leftMargin">'+ title +
'</div><div class="H3 leftMargin">'+ msg +
'</div></div>',
items : [{
xtype : 'panel',
//cls : 'winTitle',
}, {
xtype : 'form',
itemId : 'GENMSGFORM',
border : false,
title : '',
buttonAlign : 'center',
fieldDefaults : {
msgTarget : 'side',
labelWidth : 110,
size : 30
},
buttons : [{
text : LANG.BTYES,
iconCls : 'icon-tick-tb',
iconAlign : 'right',
cls : 'tip-btn',
action : 'genDelete',
id : 'BTYES'
}, {
text : LANG.BTNO,
iconCls : 'icon-cross-tb',
iconAlign : 'right',
cls : 'tip-btn',
action : 'notDelete',
id : 'BTNO'
}]
}]
});
return config;
But, even this did not return anything
The answer is simple: You cannot add a ExtJS Button into the html config property of a component. This one is just for plain html. ExtJS objects belongs into the items array.
Decide to place your html content into a box (xtype for component) and add this to the items array. Then you can add your button. Don't use the html at all in your case.
You may change/set any required classes. Please note that I haven't check the way you manipulate the DOM.
// you may use a layout to align them
items : [
{
xtype: 'box',
cls : 'msg effect1',
html : '<div class="genMsgDiv">' + icon +
'<div class="genMsgHd leftMargin">'+ title +
'</div><div class="H3 leftMargin">'+ msg +
'</div></div>'
},
{
xtype : 'panel',
//cls : 'winTitle',
},
...

Resources