Extjs4: editable rowbody - event-handling

in my first ExtJs4 project i use a editable grid with the feature rowbody to have a big textfield displayed under each row.
I want it to be editable on a dblclick. I succeeded in doing so by replacing the innerHTML of the rowbody by a textarea but the special keys don't do what they are supposed to do (move the cursor). If a use the textarea in a normal field i don't have this problem. Same problem in IE7 and FF4
gridInfo = Ext.create('Ext.ux.LiveSearchGridPanel', {
id: 'gridInfo',
height: '100%',
width: '100%',
store: storeInfo,
columnLines: true,
selType: 'cellmodel',
columns: [
{text: "Titel", flex: 1, dataIndex: 'titel', field: {xtype: 'textfield'}},
{text: "Tags", id: "tags", flex: 1, dataIndex: 'tags', field: {xtype: 'textfield'}},
{text: "Hits", dataIndex: 'hits'},
{text: "Last Updated", renderer: Ext.util.Format.dateRenderer('d/m/Y'), dataIndex: 'lastChange'}
],
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
features: [
{
ftype: 'rowbody',
getAdditionalData: function (data, idx, record, orig) {
var headerCt = this.view.headerCt,
colspan = headerCt.getColumnCount();
return {
rowBody: data.desc, //the big textfieldvalue, can't use a textarea here 8<
rowBodyCls: this.rowBodyCls,
rowBodyColspan: colspan
};
}
},
{ftype: 'rowwrap'}
]
});
me.on('rowbodydblclick', function (gridView, el, event, o) {
//...
rb = td.down('.x-grid-rowbody').dom;
var value = rb.innerText ? rb.innerText : rb.textContent;
rb.innerHTML = '';
Ext.create('Ext.form.field.TextArea', {
id: 'textarea1',
value: value,
renderTo: rb,
border: false,
enterIsSpecial: true,
enableKeyEvents: true,
disableKeyFilter: true,
listeners: {
'blur': function (el, o) {
rb.innerHTML = el.value;
},
'specialkey': function (field, e) {
console.log(e.keyCode); //captured but nothing happens
}
}
}).show();
//...
});
damn, can't publish my own solution, looks like somebody else has to answer, anyway, here is the function that works
function editDesc(me, gridView, el, event, o) {
var width = Ext.fly(el).up('table').getWidth();
var rb = event.target;
var value = rb.innerText ? rb.innerText : rb.textContent;
rb.innerHTML = '';
var txt = Ext.create('Ext.form.field.TextArea', {
value: value,
renderTo: rb,
border: false,
width: width,
height: 300,
enterIsSpecial: true,
disableKeyFilter: true,
listeners: {
'blur': function (el, o) {
var value = el.value.replace('\n', '<br>')
rb.innerHTML = value;
},
'specialkey': function (field, e) {
e.stopPropagation();
}
}
});
var txtTextarea = Ext.fly(rb).down('textarea');
txtTextarea.dom.style.color = 'blue';
txtTextarea.dom.style.fontSize = '11px';
}
Hi Molecule Man, as an alternative to the approach above i tried the Ext.Editor.
It works but i want it inline but when i render it to the rowbody, the field blanks and i have no editor, any ideas ?
gridInfo = Ext.create('Ext.grid.Panel', {
id: 'gridInfo',
height: '100%',
width: '100%',
store: storeInfo,
columnLines: true,
selType: 'cellmodel',
viewConfig: {stripeRows: false, trackOver: true},
columns: [
{text: "Titel", flex: 1, dataIndex: 'titel', field: {xtype: 'textfield'}},
//...
{
text: "Last Updated", renderer: Ext.util.Format.dateRenderer('d/m/Y'), dataIndex: 'lastChange'
}
],
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
features: [
{
ftype: 'rowbody',
getAdditionalData: function (data, idx, record, orig) {
var headerCt = this.view.headerCt,
colspan = headerCt.getColumnCount();
return {
rowBody: data.desc,
rowBodyCls: this.rowBodyCls,
rowBodyColspan: colspan
};
}
}
],
listeners: {
rowbodyclick: function (gridView, el, event) { //werkt
editDesc(this, gridView, el, event);
}
}
})
;
function editDesc(me, gridView, el, event, o) {
var rb = event.target;
me.txt = new Ext.Editor({
field: {xtype: 'textarea'},
updateEl: true,
cancelOnEsc: true,
floating: true,
renderTo: rb //when i do this, the field becomes empty and i don't get the editor
});
me.txt.startEdit(el);
}

This is just to set the question answered, see solution above

Related

Collapse Filter Panel in dockedItems

Hello i`m struggeling with docked items im trying to collapse my filter panel but this doenst work also the colappse arrow is on the wrong side has anybody an idea how i can fix it. Im Creating an getFilterPane and return it in initComponenet as an toolbar item.
Ext.define('Shopware.apps.SDG.view.update.Grid', {
extend: 'Ext.grid.Panel',
region: 'center',
collapsible: false,
split: true,
title: 'Update Log',
getPagingBar: function () {
var me = this;
me.store = Ext.create('Shopware.apps.SdgArticleUpdateImportLog.store.SdgArticleUpdateLog');
return Ext.create('Ext.toolbar.Paging', {
store: me.store,
dock: 'bottom',
displayInfo: true,
region: 'south'
});
},
getFilterPanel: function () {
var me = this;
return Ext.create('Ext.form.Panel', {
store: me.store,
title: 'Filters',
collapsible: true,
cls: 'detail-view',
width: 300,
region: 'east',
dock: 'right',
layout: {
type: 'vbox',
pack: 'start',
align: 'stretch'
},
defaultType: 'textfield',
items: [{
fieldLabel: 'Sku',
name: '1',
allowBlank: true,
listeners: {
change: function (field, value) {
me.store.filter('sku', value);
me.store.filters.clear();
}
}
}, {
fieldLabel: 'Timestamp',
name: '2',
allowBlank: true,
listeners: {
change: function (field, value) {
me.store.filter('importTimestamp', value);
me.store.filters.clear();
}
}
}]
});
},
createFilterPanel: function () {
},
initComponent: function () {
var me = this;
me.dockedItems = [me.getPagingBar(), me.getFilterPanel(),
{
xtype: 'toolbar',
dock: 'top',
items: [
, '->',
{
xtype: 'textfield',
name: 'searchfield',
cls: 'searchfield',
width: 175,
emptyText: '{s name="CoeSeoRoute/Toolbar/Search"}Suche{/s}',
enableKeyEvents: true,
clearable: true,
checkChangeBuffer: 500,
listeners: {
change: function (field, value) {
me.store.filter('search', value);
me.store.filters.clear();
}
}
}
]
}
];
me.columns = me.getColumns();
me.callParent();
},
Try setting collapseDirection..
From the docs:
collapseDirection : String
The direction to collapse the Panel when the toggle button is clicked.
Defaults to the headerPosition
Important: This config is ignored for collapsible Panels which are direct child items of a border layout.
Specify as 'top', 'bottom', 'left' or 'right'.
Available since: 4.0.0

Submit all of grid rows with Extjs form submit

I have a grid panel in a form. Any row of the grid panel have a filefield. I want to send any row (name field and filename field) to server.
Model:
Ext.define('FM.model.DefineCode', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'filename', type: 'string'}
],
validations: [
{type: 'presence', field: 'id'},
{type: 'presence', field: 'name'},
{type: 'presence', field: 'filename'}
]
});
Store:
Ext.define('FM.store.DefineCode', {
extend: 'Ext.data.Store',
model: 'FM.model.DefineCode',
autoLoad: true,
data: []
});
View:
Ext.define('FM.view.map.DefineCode', {
extend: 'Ext.window.Window',
title: 'Define Code',
alias: 'widget.mmDefineCode',
width: 600,
modal: true,
items: [{
xtype: 'form',
items: [{
xtype: 'gridpanel',
title: 'myGrid',
store: 'DefineCode',
columns: [
{
text: 'Id',
xtype: 'rownumberer',
width: 20
}, {
text: 'Name',
dataIndex: 'name',
flex: 1,
editor:{
xtype: 'textfield'
}
}, {
text: 'File',
dataIndex: 'filename',
width: 200,
editor:{
xtype: 'filefield',
emptyText: 'Select your Icon',
name: 'photo-path',
buttonText: '',
flex: 1,
buttonConfig: {
iconCls: 'icon-upload-18x18'
},
listeners: {
change: function(e, ee, eee) {
var grid = this.up('grid');
var store = grid.getStore();
var newStore = Ext.create('FM.store.DefineCode',{});
store.insert(store.data.items.length, newStore);
}
}
},
}, {
text: '',
width: 40
}
],
height: 200,
width: 600,
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
]}
],
}],
buttons: [{text: 'OK', action: 'OK'}],
initComponent: function() {
var me = this;
Ext.apply(me, {});
me.callParent(arguments);
}
});
Controller:
...
form.submit({
url: 'icon/create',
});
When I submit form, only last row is sending to server.
Where is problem?
Why you using this ?
var newStore = Ext.create('FM.store.Path', {});
store.insert(store.data.items.length, newStore);
try using rowEditing to edit/submit 1 row data :
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 2,
clicksToMoveEditor: 1,
listeners: {
'validateedit': function(editor, e) {},
'afteredit': function(editor, e) {
var me = this;
var jsonData = Ext.encode(e.record.data);
Ext.Ajax.request({
method: 'POST',
url: 'your_url/save',
params: {data: jsonData},
success: function(response){
e.store.reload({
callback: function(){
var newRecordIndex = e.store.findBy(
function(record, filename) {
if (record.get('filename') === e.record.data.filename) {
return true;
}
return false;
}
);
me.grid.getSelectionModel().select(newRecordIndex);
}
});
}
});
return true;
}
}
});
and place it to your plugin.
I don't try it first, but may be this will help you a little.
AND this is for your controller to add a record from your grid, you need a button to trigger this function.
createRecord: function() {
var model = Ext.ModelMgr.getModel('FM.model.DefineCode');
var r = Ext.ModelManager.create({
id: '',
name: '',
filename: ''
}, model);
this.getYourgrid().getStore().insert(0, r);
this.getYourgrid().rowEditing.startEdit(0, 0);
}
check this for your need, this is look a like. You need to specify the content-type.
And for your java need, please read this method to upload a file.

Extjs Cannot read property 'dom' of null

In short, I have a login panel, which will be shown when onClick event is true, but I get error Cannot read property 'dom' of null. When I click second time - the panel is shown, but some elements of it are not shown. When I click for 3th time, the other elements has show, an last, I ger error "Cannot call method 'bringToFront' of undefined".
Ext.onReady(function() {
Ext.QuickTips.init();
Ext.ns('Site.login');
var globalKeyMap = new Ext.KeyMap(document);
globalKeyMap.accessKey = function(key, handler, scope) {
var h = function(n, e) {
e.preventDefault();
handler.call(scope || this, n, e);
};
this.on(key, h, scope);
};
var trackEnter = function(tf, e) {
if (e.keyCode == 13) {
e.stopPropagation();
doLogin();
}
}
var doLogin = function() {
var f = loginPanel.getForm();
if (f.isValid()) {
f.doAction(new Hypo.form.Action.DwrSubmit(f, {
waitMsg: 'Authentication is in progress',
invoker: function(form, cb) {
Login.login(form.getValues(), cb);
},
success: function(fp, o) {
loginForm.hide();
Ext.getBody().addClass("x-body-masked");
var w = loginForm;
w.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
w.mask.show();
if(o.result.data[0].authorities[0].authority=='ROLE_SUPERVISOR')
{
setTimeout('document.location = "AdminUsers.jsp"');
}
else if(o.result.data[0].authorities[0].authority=='ROLE_ADMIN')
{
setTimeout('document.location = "AdminUsers.jsp"');
}
else
{
setTimeout('document.location = "List.jsp"');
}
}
}));
}
}
var loginPanel = new Ext.FormPanel({
id: 'loginPanel',
labelWidth: 75, // label settings here cascade unless overridden
frame: false,
border: false,
bodyStyle:'padding:5px 5px 0',
width: 350,
defaults: {
width: 230
},
defaultType: 'textfield',
autoHeight: true,
items: [{
id: 'idxLogin',
fieldLabel: 'Login',
name: 'login',
allowBlank: false,
enableKeyEvents: true,
maxLength: 50,
listeners: {
'keypress': trackEnter
}
}, new Ext.form.TextField({
fieldLabel: 'Password',
name: 'password',
inputType: 'password',
enableKeyEvents: true,
maxLength: 50,
listeners: {
'keypress': trackEnter
}
})
]
});
var loginForm = new Ext.Window({
layout : 'fit',
width : 350,
closable : false,
modal: true,
plain : true,
title: 'User Authentication',
items: loginPanel,
autoHeight: true,
buttons: [{
text: 'OK',
handler: doLogin
},{
text: 'Cancel',
handler: function() {
loginForm.hide();
}
}],
listeners: {
'activate': function() {
setTimeout(function() {
Ext.getCmp("idxLogin").focus();
}, 100);
}
}
});
Site.login.window = loginForm;
});
Login
I tryed to add renderTo:'someDiv' and add to body a div with id "someDiv". But I received the same error message.
Please, help with that.

Removing a record from store in an editable grid

I created an editable grid with local data from Array Store. Now I put an actionColumn to delete the record from the store. But the delete is not happening and the record is still present.
Please see my code below:-
this.empdata = [
[ 'Anea etet','andreeas#jhggf.com','active' ],
[ 'Bharfdna ivasdsh','bfanas#dsgfsd.com','active' ],
[ 'Crfg gfdgdtt', 'ffigh#dfsd.com', 'away' ],
[ 'Gfdgdis Perron','geffgsp#fdhd.com', 'away' ]
];
this.employee = new Ext.data.ArrayStore({
autoSync: true,
fields : [ {
name : 'name'
}, {
name : 'email'
}, {
name : 'status'
}],
data : this.empdata
});
var cm = new Ext.grid.ColumnModel([{
header: 'Name',
dataIndex: 'name',
flex: 1,
editor: {
allowBlank: false
}
}, {
header: 'Email',
dataIndex: 'email',
flex: 1,
editor: {
allowBlank: false,
vtype: 'email'
}
}, {
header: 'Status',
dataIndex: 'status',
editor: {
allowBlank: false
}
}, {
xtype: 'actioncolumn',
width: 50,
items: [
{
icon : 'src/images.jpg',
tooltip: 'Delete record',
handler: function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
alert("Delete " + rec.get('name'),function(btn,text){
if (btn == 'ok'){
grid.getStore().removeAt(rowIndex);
grid.getStore().sync();
}
})
}
}]
}]);
this.grid = new Ext.grid.EditorGridPanel({
store: this.employee,
cm: cm,
xtype: 'editorgrid',
title: 'Employee Data',
clicksToEdit: 1,
frame: true,
stripeRows : true,
width: 1000,
height: 500,
region: 'south',
viewConfig : {
forceFit : true,
scrollOffset : 0,
}
});
this.grid.on('validateedit', function(e) {
if (e.field === 'status'){
if(!((e.value === 'active')||(e.value === 'away')||(e.value === 'offline'))){
e.cancel = true;
e.record.data[e.field] = e.originalValue;
}
}
});
var win = {
layout: {
type: 'vbox',
align: 'center',
pack: 'top',
padding: 30
},
items: [this.grid]
};
Ext.apply(this, win);
When i click on delete button,a pop-up comes up asking fro confirmation.When I click 'ok' it should delete the record,but nothing happens.
Please suggest what's wrong with the code.
You use alert in yor handler it only accepts one parameter - message. If you want confirm, the best way is to use Ext.Msg.confirm. Example:
handler: function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
Ext.Msg.confirm(
"Delete " + rec.get('name'),
"Delete " + rec.get('name'),
function(btn){
if (btn == 'yes'){
grid.getStore().removeAt(rowIndex);
grid.getStore().sync();
}
}
);
}

extjs 4 grid to tree drag drop

i am working with grid to tree drag n drop. i am able to add new node to root of tree by dragging it from grid but i dont know how to add child to node i hovered on? I spent 2 days on dis but no luck.below is my code :
Ext.define('Overdrive.view.ui.MyViewport', {
extend: 'Ext.container.Viewport',
initComponent: function () {
var me = this;
me.items = [{
xtype: 'panel',
height: 600,
layout: {
align: 'stretch',
type: 'hbox'
},
title: 'PARENT',
items: [{
xtype: 'treepanel',
border: '',
id: 'treepanel',
collapseDirection: 'left',
collapsible: true,
title: 'Items',
titleCollapse: true,
store: 'Test',
flex: 1,
viewConfig: {
listeners: {
render: function (tree) {
var dropTarget = new Ext.dd.DropTarget(tree.el, {
ddGroup: 'gridtotree',
copy: false,
notifyDrop: function (dragSource, event, data) {
var idFrom = data.records[0].data.name;
var node = Ext.getCmp('treepanel').getRootNode(); //working
node.appendChild({
'text': idFrom,
'children': []
});
}
});
}
}
}
}, {
xtype: 'panel',
height: 596,
flex: 3,
items: [{
xtype: 'panel',
height: 285,
layout: {
type: 'anchor'
}
}, {
xtype: 'gridpanel',
id: 'itemtypegrid',
title: 'Item Type',
store: 'GridTest',
enableDragDrop: true,
ddText: 'Shift Row',
columns: [{
xtype: 'gridcolumn',
width: 100,
dataIndex: 'name',
text: 'Name'
}],
viewConfig: {
plugins: [
Ext.create('Ext.grid.plugin.DragDrop', {
ddGroup: 'gridtotree',
enableDrop: true
})]
}
}]
}]
}];
me.callParent(arguments);
}
To catch the tree-node you can add this handler to Tree.Panel -> ViewConfig -> listeners:
itemmouseenter: function (view, model, htmlItem, index, e)
{
console.log(model);
},
You can save this value and use in another handler - notifyDrop