Related
ExtJs drag drop example using Grid to Grid
How to implement drag and drop plugin so that we can drag data from one grid and can drop it to another and vice versa in ExtJs
The following explained program will work as drag and drop between two grids
<!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.require([ 'Ext.grid.*', 'Ext.data.*', 'Ext.dd.*' ]);
// Creation of data model
Ext.define('StudentDataModel', {
extend : 'Ext.data.Model',
fields : [ {
name : 'name',//Name of the column
mapping : 'name'//Name to map the columns
},
{
name : 'age',
mapping : 'age'
}, {
name : 'marks',
mapping : 'marks'
} ]
});
Ext.onReady(function() {
// Store data
var myData = [ {
name : "Smith",
age : "20",
marks : "90"
}, {
name : "Alen",
age : "18",
marks : "95"
}, {
name : "Mike",
age : "20",
marks : "68"
}, {
name : "Jon",
age : "21",
marks : "86"
}, {
name : "Keven",
age : "22",
marks : "57"
} ];
// Creation of first grid store
var firstGridStore = Ext.create('Ext.data.Store', {
model : 'StudentDataModel',
data : myData
});
// Creation of first grid
var firstGrid = Ext.create('Ext.grid.Panel', {
multiSelect : true,
viewConfig : {
plugins : {
ptype : 'gridviewdragdrop',
dragGroup : 'firstGridDDGroup',
dropGroup : 'secondGridDDGroup'
},
listeners : {
drop : function(node, data, dropRec, dropPosition) {
var dropOn = dropRec ? ' ' + dropPosition + ' '
+ dropRec.get('name') : ' on empty view';
}
}
},
store : firstGridStore,
columns : [ {
header : "Student Name",
dataIndex : 'name',
id : 'name',
flex : 1,
sortable : true
}, {
header : "Age",
dataIndex : 'age',
flex : .5,
sortable : true
}, {
header : "Marks",
dataIndex : 'marks',
flex : .5,
sortable : true
} ],
stripeRows : true,
title : 'First Grid',
margins : '0 2 0 0'
});
// Creation of second grid store
var secondGridStore = Ext.create('Ext.data.Store', {
model : 'StudentDataModel'
});
// Creation of second grid
var secondGrid = Ext.create('Ext.grid.Panel', {
viewConfig : {
plugins : {
ptype : 'gridviewdragdrop',
dragGroup : 'secondGridDDGroup',
dropGroup : 'firstGridDDGroup'
},
listeners : {
drop : function(node, data, dropRec, dropPosition) {
var dropOn = dropRec ? ' ' + dropPosition + ' '
+ dropRec.get('name') : ' on empty view';
}
}
},
store : secondGridStore,
columns : [ {
header : "Student Name",
dataIndex : 'name',
id : 'name',
flex : 1,
sortable : true
}, {
header : "Age",
dataIndex : 'age',
flex : .5,
sortable : true
}, {
header : "Marks",
dataIndex : 'marks',
flex : .5,
sortable : true
} ],
stripeRows : true,
title : 'Second Grid',
margins : '0 0 0 3'
});
// Creation of a panel to show both the grids.
var displayPanel = Ext.create('Ext.Panel', {
width : 600,
height : 200,
layout : {
type : 'hbox',
align : 'stretch',
padding : 5
},
renderTo : 'panel',
defaults : {
flex : 1
},
items : [ firstGrid, secondGrid ],
dockedItems : {
xtype : 'toolbar',
dock : 'bottom',
items : [ '->', {
text : 'Reset both grids',
handler : function() {
firstGridStore.loadData(myData);
secondGridStore.removeAll();
}
} ]
}
});
});
</script>
</head>
<body>
<div id="panel"></div>
</body>
</html>
Knowledge from :
https://www.tutorialspoint.com/extjs/extjs_drag_drop.htm
I have created a data model naming StudentDataModel, which has
name,age,marks as its attributes .
Created a store called myData ie data to be inserted inside grid and a grid store called firstGridStore and secondGridStore
implemented a listener and plugin
now both [ firstGrid, secondGrid ] inside
displayPanel('Ext.Panel')
I have explained it to my best knowledge . I welcome any changed or explanation to improvise the example.
You have an example in sencha Kitchen Sink - two way drag and drop from one GridPanel to another: http://examples.sencha.com/extjs/5.1.0/examples/kitchensink/#dd-grid-to-grid
I want to achieve something like this :
http://jsfiddle.net/mgill21/3HJXX/2/
But I whenever I drop a node from grid into the treecolumn (as a leaf node) I get errors such as node.updateInfo() is undefined and other node related undefined method.
Here is my code:
Ext.namespace('Ext.ux.window.ConfigureMobileApp');
Ext.require([ 'Ext.grid.*', 'Ext.data.*', 'Ext.dd.*' ]);
var firstGridStore = Ext.create('Ext.data.Store', {
storeId : 'formStore',
fields : [ 'name', 'type', 'itemId' ],
data : [ {
name : "Michael Scott",
itemId : 7,
type : "Management"
}, {
name : "Dwight Schrute",
itemId : 2,
type : "Sales"
}, {
name : "Jim Halpert",
itemId : 3,
type : "Sales"
}, {
name : "Kevin Malone",
itemId : 4,
type : "Accounting"
}, {
name : "Angela Martin",
itemId : 5,
type : "Accounting"
} ]
});
// declare the source Grid
var firstGrid = Ext.create('Ext.grid.Panel', {
viewConfig : {
plugins : {
ptype : 'gridviewdragdrop',
ddGroup : 'selDD'
}
},
store : Ext.data.StoreManager.lookup('formStore'),
columns : [ {
text : "Name",
flex : 1,
sortable : true,
dataIndex : 'name'
}, {
text : "Type",
width : 70,
sortable : true,
dataIndex : 'type'
} ],
stripeRows : true,
title : 'First Grid',
margins : '0 2 0 0',
width : 200
});
Ext.define('Resource', {
extend : 'Ext.data.Model',
fields : [ {
name : "name",
type : "string"
}, {
name : "type",
type : "string"
} ]
});
var store1 = Ext.create('Ext.data.TreeStore', {
storeId : 'treeStore',
fields : [ 'name', 'type', 'itemId' ],
root : {
expanded : true,
children : [ {
itemId : 171,
type : "comedy",
name : "Mr Bean",
children : [ {
leaf : true,
itemId : 171,
type : "actor",
name : "Rowan Atkinson"
} ],
}, {
itemId : 11,
type : "fantasy",
name : "Harry Potter",
children : [ {
itemId : 11,
leaf : true,
type : "actress",
name : "Emma Watson",
} ]
}, {
itemId : 173,
type : "Action",
name : "Fast and Furious",
children : [ {
itemId : 174,
type : "actor",
name : "Dwayne Johnson",
children : [ {
leaf : true,
itemId : 175,
type : "wrestler",
name : "The Rock"
} ]
} ]
} ]
}
});
Ext.define('Ext.ux.window.TreeGrid', {
extend : 'Ext.tree.Panel',
title : 'Demo',
height : 300,
rootVisible : true,
singleExpand : true,
store : Ext.data.StoreManager.lookup('treeStore'),
columns : [ {
xtype : 'treecolumn',
text : 'Name',
dataIndex : 'name',
width : 200
}, {
text : 'Type',
dataIndex : 'type'
} ],
initComponent : function() {
this.callParent();
},
viewConfig : {
plugins : {
ptype : 'treeviewdragdrop',
ddGroup : 'selDD'
},
listeners : {
beforedrop : function(node, data) {
debugger;
data.records[0].set('leaf', true);
data.records[0].set('expanded', false);
data.records[0].set('checked', true);
},
drop : function(node, data, dropRec, dropPosition) {
// firstGridStore.store.remove(data.records[0]);
}
}
}
});
var secondTree = Ext.create('Ext.ux.window.TreeGrid');
Ext.define('Ext.ux.window.ConfigureMobileApp', {
extend : 'Ext.window.Window',
title : 'Configure Mobile App',
height : 600,
width : 600,
layout : 'hbox',
modal : true,
closeAction : 'hide',
items : [ firstGrid, secondTree ]
});
Please help. Stuck since a very long time.
To help u out with this error i m sending u two links .These are not the proper solution but will surely guide u a way for that.
First Link
Second Link
Here is the store :
Ext.define( 'LFinanceCRM.store.Prospect', {
extend : 'Ext.data.Store',
buffered : false,
autoLoad : true,
remoteFilter : true,
storeId : 'prospect-store',
proxy : {
type : 'ajax',
url : 'services/getProspect.php',
filterParam : undefined,
limitParam : undefined,
startParam : undefined,
pageParam : undefined,
idParam : 'id',
reader : {
type : 'json',
root : 'prospect'
}
},
fields : [
{ name : 'id' },
{ name : 'value' }
],
constructor : function(){
this.callParent( arguments );
console.log( 'new ' + this.self.getName());
}
});
Here is the PHP code:
<?php
include_once 'db.php';
header( "Content-type: application/json; charset=utf-8" );
$id = #mysql_real_escape_string($_GET['id']);
$link = db_open();
$query = "SELECT name, value FROM Pairs WHERE id = '$id'";
$result = #mysql_query( $query, $link );
$pairs = array();
if( $result ) {
while( $row = mysql_fetch_assoc( $result )) {
$item = Array();
$item['id' ] = $row['name' ];
$item['value'] = $row['value'];
$pairs[] = $item;
}
}
$response = array( 'prospect' => $pairs );
print json_encode( $response );
#mysql_free_result( $result );
#mysql_close( $link );
?>
Here is the JSON received from PHP:
{prospect:[
{id:'aaa',value:'vvvv'},
{id:'bbb',value:'vvvv'},
...
{id:'yyy',value:'vvvv'},
{id:'zzz',value:'vvvv'},
}]
Here is the view:
Ext.define( 'LFinanceCRM.view.RawDataView', {
extend : 'Ext.grid.Panel',
requires :[],
alias : 'widget.raw-data-view',
autoScroll : true,
title : 'Données brutes',
columnLines : true,
viewConfig : { stripeRows : true },
store : Ext.data.StoreManager.lookup( 'prospect-store' ),
columns : [{
text : 'Nom',
dataIndex : 'name',
sortable : false,
width : '29%'
},{
text : 'Valeur',
dataIndex : 'value',
sortable : true,
width : '70%'
}],
constructor : function() {
this.callParent( arguments );
console.log('new ' + this.self.getName());
}
});
I use the MVC pattern supported by Sencha app build tool, here is the controller:
Ext.define( 'LFinanceCRM.controller.Main', {
extend : 'Ext.app.Controller',
id : 'theController',
onNonLuesSelectionChanged : function( panel, selected, eOpts ) {
console.log('onNonLuesSelectionChanged: ' + selected[0].data.id );
this.getStore('Prospect').load({
id : selected[0].data.id,
callback : function( records, operation, success ) {
var pairs = [];
for( var i = 0; i < records.length; ++i ) {
pairs.push( records[i].data );
}
Ext.ComponentQuery.query('client-view')[0].getForm().setValues( pairs );
Ext.ComponentQuery.query('immo-view' )[0].getForm().setValues( pairs );
}
});
},
onSavePairs : function() {
console.log('onSavePairs');
},
...
onMail : function() {
console.log('onMail');
},
...
stores : ['Prospect'],
constructor : function(){
this.callParent( arguments );
console.log( 'new ' + this.self.getName());
this.control({
'#ProspectsTableNonLues' : { selectionchange : this.onNonLuesSelectionChanged },
...
'#savePairsButton' : { click : this.onSavePairs },
...
'#mail' : { click : this.onMail },
});
}
});
Nothing is displayed yet!
My question is : how can I transform the data from store to feed the view with them?
Your LFinanceCRM.view.RawDataView config is not properly defined.
You should create an instance of Store to assign to the grid panel -
store : Ext.data.StoreManager.lookup( 'prospect-store' ),
should be changed to
store : Ext.create("LFinanceCRM.store.Prospect"),
Also in columns config, dataIndex should be "id" for the first column instead of "name"
{
text : 'Nom',
dataIndex : 'name',
sortable : false,
width : 200
}
should be changed to
{
text : 'Nom',
dataIndex : 'id',
sortable : false,
width : 200
}
Replace your LFinanceCRM.view.RawDataView code with this -
Ext.define( 'LFinanceCRM.view.RawDataView', {
extend : 'Ext.grid.Panel',
alias : 'widget.raw-data-view',
autoScroll : true,
title : 'Données brutes',
columnLines : true,
viewConfig : { stripeRows : true },
store : Ext.create("LFinanceCRM.store.Prospect"),
columns : [{
text : 'Nom',
dataIndex : 'id',
sortable : false,
width : 200
},{
text : 'Valeur',
dataIndex : 'value',
sortable : true,
width : 200
}],
constructor : function() {
this.callParent( arguments );
console.log('new ' + this.self.getName());
}
});
To avoid double request to the server and some other reasons, I prefer share the instance of the store betweens several views.
As pointed out by Prasad K, a mistake between name and id must be corrected.
As pointed in the documentation of Sencha Extjs4.2.2, when a store is instantiated by a controller, its id is the name of its class, even an id is set (bug?).
So the code becomes:
Ext.define( 'LFinanceCRM.view.RawDataView', {
extend : 'Ext.grid.Panel',
alias : 'widget.raw-data-view',
autoScroll : true,
title : 'Données brutes',
columnLines : true,
viewConfig : { stripeRows : true },
store : 'Prospect',
columns : [{
text : 'Nom',
dataIndex : 'id',
sortable : false,
width : '29%'
},{
text : 'Valeur',
dataIndex : 'value',
sortable : true,
width : '70%'
}],
constructor : function() {
this.callParent( arguments );
console.log('new ' + this.self.getName());
}
});
And it works!
(Sorry in advance if the post is to long, I just add all the code that is involved in the problem, then I think it could be easier to get an answer)
Hello, I'm encountering a problem when I try to update a store in extjs 4.
To back up a little I'm developing a general grid where you can send the columns you need and also a the fields in a window to add new rows to the grid, then this is the general grid:
Ext.define('masterDataGridControls', {
extend : 'Ext.grid.Panel',
id : 'panelWin',
windowItems : null,
addWin : null,
initComponent : function() {
var me = this;
Ext.applyIf(me, {
dockedItems : [{
xtype : 'toolbar',
dock : 'top',
items : [{
xtype : 'button',
id : 'btn_delete',
iconCls : 'deleteIcon',
tooltip : 'Delete row or group',
handler : function() {
var selection = me.getView()
.getSelectionModel()
.getSelection()[0];
if (selection) {
store.remove(selection);
}
}
}, {
xtype : 'button',
id : 'btn_add',
iconCls : 'addIcon',
tooltip : 'Add row or group',
handler : me.addToList
}]
}]
});
me.callParent(arguments);
},
getAddWindow : function() {
if (!this.addWin) {
this.addWin = new windowPop({
formItems : this.windowItems,
idParent : this.config.id,
record : this.store.model.prototype
});
}
return this.addWin;
},
addToList : function() {
var addWindow = this.findParentByType().findParentByType()
.getAddWindow();;
addWindow.show();
}
});
And I have the class windowPop that is the one who receives the fields, display them and save the data:
Ext.define("windowPop", {
extend : "Ext.window.Window",
formPanel : null,
formItems : null,
record : null,
idParent : null,
initComponent : function() {
var me = this;
me.formPanel = new Ext.form.Panel({
items : this.formItems,
layout: 'anchor'
});
Ext.applyIf(me, {
resizable : false,
closable : false,
width : 300,
minWidth : 300,
minHeight : 200,
y : 150,
layout : 'fit',
plain : true,
modal : true,
items : [me.formPanel],
buttons : [{
text : "i_Save",
handler : function() {
console.info(me.record);
me.formPanel.getForm().updateRecord(me.record);
Ext.getCmp(me.idParent).fireEvent("winSave",me.record);
me.formPanel.getForm().reset();
me.hide();
}
}, {
text : 'i_Cancel',
handler : function() {
me.formPanel.getForm().reset();
me.hide();
}
}]
});
me.callParent(arguments);
}
});
And I have my specific grid, where I define a data.model and for now I'm using a fixed store, but later on will be replace by the one I get from the server:
Ext.define('userKeys', {
extend : 'Ext.data.Model',
fields : [{
name : 'text',
type : 'string'
}, {
name : 'description',
type : 'string'
}, {
name : 'group',
type : 'string'
}]
});
var store = Ext.create('Ext.data.Store', {
model: 'userKeys',
data : [{
text : "que mamera",
description : "asdfasdf",
group : 'homework'
}, {
text : "book report",
description : 'hola',
group : 'homework'
}, {
text : "alegebra",
description : "haha",
group : 'homework'
}, {
text : "buy lottery tickets",
description : "kajsdf",
group : 'homework'
}]
});
Ext.define('ConfigInterfacesUserKeys', {
extend : 'masterDataGridControls',
initComponent : function() {
var me = this;
me.columns = [{
id : 'cl_input',
header : 'i_Text',
dataIndex : 'text',
width : 220
}, {
header : 'i_Description',
dataIndex : 'description',
width : 130
}, {
header : 'i_group',
dataIndex : 'group',
width : 130
}];
me.windowItems = [{
xtype : 'textfield',
id : 'txt_sendTime',
fieldLabel : 'text',
margin : '5 0 0 5',
style : 'font-weight:bold',
labelWidth : 120,
name : 'text'
}, {
xtype : 'textfield',
id : 'txt_waitTime',
fieldLabel : 'description',
margin : '5 0 0 5',
style : 'font-weight:bold',
labelWidth : 120,
name : 'description'
}, {
xtype : 'textfield',
id : 'txt_group',
fieldLabel : 'group',
margin : '5 0 0 5',
style : 'font-weight:bold',
labelWidth : 120,
name : 'group'
}];
me.store = store;
me.callParent(arguments);
}
})
The Problem
When I try to save the fields as you see in the windowPop class Im doing this:
me.formPanel.getForm().updateRecord(me.record);
But I get the next error:
this[this.persistenceProperty] is undefined
I tracked down the error and I find that all start when in the function updateRecord try to set the object to the store:
updateRecord: function(record) {
var fields = record.fields,
values = this.getFieldValues(),
name,
obj = {};
fields.each(function(f) {
name = f.name;
if (name in values) {
obj[name] = values[name];
}
});
record.beginEdit();
**record.set(obj);**
record.endEdit();
return this;
}
I don't know if it is something wrong when I send the model to the window from the general grid, I sent it this way:
record : this.store.model.prototype
Then I'm not sure if its because the model I'm sending its not well forme.
I've been searching the internet but I can't find a proper answer then it will be really helpful if you can guide me in the right way.
Thanks
I don't know if it is something wrong when I send the model to the
window from the general grid
I believe it is. You are sending not an empty instance (which should be sent) but a class' prototype. Try to send:
record : new this.store.model()
When i ran this EXTJS code,i got an error 'this.proxy' is null or not an object. Can you help me out regarding this,plzz ?
var myData = [
['J', 'MD'],
['A', 'VA'],
['S', 'DC'],
['M', 'DE'],
['B', 'NJ'],
['N', 'CA'],
['S', 'RT'],
['S', 'CG']
];
var store = new Ext.data.ArrayStore({
totalProperty : 8,
autoLoad : {
params : {
start : 0,
limit : 4
}
},
fields : [ {
name : 'fullName'
}, {
name : 'state'
} ]
});
store.loadData(myData);
var grid = new Ext.grid.GridPanel({
store : store,
columns : [ {
id : 'fullName',
header : "FullName",
width : 160,
sortable : true,
dataIndex : 'fullName'
}, {
header : "State",
width : 75,
sortable : true,
dataIndex : 'state'
} ],
stripeRows : true,
autoExpandColumn : 'fullName',
height : 350,
width : 600,
title : 'Array Grid',
bbar : new Ext.PagingToolbar({
store : store,
pageSize : 4,
displayInfo : true
}),
viewConfig : {
forceFit : true
}
});
You cannot at the same time use memory proxy and autoLoad config as well as store.load. autoLoad config and store.load can only be used with proxies that are intended for actual loading of data like Ajax proxy.
However, you can use Direct proxy. In this case you will have to create your direct-function which will play role of server-side.
var myData = [
['J', 'MD'],
...
];
var myDirectfn = function(opts, fn, proxy){
var start = opts.start, end = opts.page*opts.limit;
var data = [];
if (end > myData.length)
end = myData.length;
for (var i = start; i < end; i++)
data.push(myData[i]);
fn(0, {status: true, result: data});
};
//Why am I doing this? I don't know, but otherwise store will throw exception
myDirectfn.directCfg={method : {}};
var store = new Ext.data.Store({
//totalProperty : 8,
pageSize: 4,
proxy: {
type: 'direct',
directFn: myDirectfn,
reader: {type: 'array'}
},
fields : [ {name : 'fullName'}, {name : 'state'} ]
});
And here is fiddle to play arround with.
UPDATE
For extjs3 Direct Proxy method would look like this:
var myDirectfn = function(opts, fn, proxy) {
var start = opts.start,
end = opts.limit+opts.start,
data = [];
if (end > myData.length) end = myData.length;
for (var i = start; i < end; i++)
data.push(myData[i]);
data.total = myData.length;
fn(data, {
status: true,
result: data
});
};
myDirectfn.directCfg = {
method: {len:1}
};
var store = new Ext.data.ArrayStore({
proxy: new Ext.data.DirectProxy({
directFn: myDirectfn
}),
fields: [{
name: 'fullName'},
{
name: 'state'}]
})
store.load({params: {start: 0, limit: 4}});
Here is demo. And also it appears that you can utilise memory proxy with loading by using this plugin