When I delete any current row, the next row and pagination has to get updated in the empty row. But it is not updating the pagination but the url is passing in network correctly. When I refresh the page, the empty row is replaced by the next row.
List.js:
/**
* This view is an example list of people.
*/
Ext.define('CRUD.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'home',
requires: [
'CRUD.store.Personnel',
'CRUD.view.main.MainController',
'Ext.toolbar.Paging',
],
title: 'Heroes',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
layout: 'fit',
fullscreen: true,
store: {
type: 'personnel',
},
selModel: {
pruneRemoved: false
},
selType: 'cellmodel',
columns: [{
text: 'Name',
align: 'center',
dataIndex: 'name',
sortable: true,
flex: 1,
editor: {
xtype: 'textfield',
selectOnFocus: true,
allowBlank: false
}
},
{
text: 'Email',
align: 'center',
dataIndex: 'email',
sortable: true,
flex: 1,
editor: {
xtype: 'textfield',
selectOnFocus: true,
allowBlank: false
}
},
{
text: 'Phone',
align: 'center',
dataIndex: 'phone',
sortable: true,
flex: 1,
editor: {
xtype: 'textfield',
selectOnFocus: true,
allowBlank: false
}
},
{
text: 'Save',
align: 'center',
xtype: 'actioncolumn',
items: [{
icon: 'http://icons.iconarchive.com/icons/oxygen-icons.org/oxygen/128/Actions-document-edit-icon.png',
xtype: 'submit',
handler: function(grid, rowIndex, colIndex, item, e, record) {
Ext.Msg.confirm("Confirmation", "Do you want to Save?", function(btnText) {
if (btnText === "yes") {
Ext.Ajax.request({
url: 'http://localhost:8080/edit?id=' + record.data.id + '&name=' + record.data.name + '&email=' + record.data.email + '&phone=' + record.data.phone,
method: 'POST', //this is the url where the form gets submitted
useDefaultXhrHeader: false,
success: function(response) {
store.load()
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action);
}
});
}
});
}
}],
}, {
text: 'Delete',
xtype: 'actioncolumn',
align: 'center',
items: [{
icon: 'http://www.freeiconspng.com/uploads/delete-button-png-27.png',
xtype: 'submit',
// handler: function(grid, rowIndex, colIndex, item, e, record) {
// console.log(record.data.id)
// // Ext.Msg.confirm('Confirmation', 'Are you sure?', function(btnText) {
// // if (btnText === 'yes') {
// // Ext.Ajax.request({
// // url: 'http://localhost:8080/del/' + record.data.id,
// // method: 'DELETE', //this is the url where the form gets submitted
// // useDefaultXhrHeader: false,
// // cors: true,
// // success: function(form, action) {
// // store.load()
// // },
// // failure: function(form, action) {
// // Ext.Msg.alert('Failed', action);
// // }
// // });
// // }
// // })
// }
}],
listeners: {
click: 'onDeleteClick'
}
}
],
bbar: Ext.create('Ext.PagingToolbar', {
xtype: 'pagingtoolbar',
displayInfo: true,
doRefresh: function() {
this.doLoad(this.cursor);
},
}),
// columns: [
// { text: 'Name', dataIndex: 'name', flex: 1 },
// { text: 'Email', dataIndex: 'email', flex: 1 },
// { text: 'Phone', dataIndex: 'phone', flex: 1 }
// ],
// listeners: {
// select: 'onItemSelected',
// },
});
Store:
Ext.define('CRUD.store.Personnel', {
extend: 'Ext.data.Store',
alias: 'store.personnel',
model: 'CRUD.model.User',
fields: [
'name', 'email', 'phone'
],
// data: [
// { name: 'Jean Luc', email: "jeanluc.picard#enterprise.com", phone: "555-111-1111" },
// { name: 'Worf', email: "worf.moghsson#enterprise.com", phone: "555-222-2222" },
// { name: 'Deanna', email: "deanna.troi#enterprise.com", phone: "555-333-3333" },
// { name: 'Data', email: "mr.data#enterprise.com", phone: "555-444-4444" }
// ],
autoLoad: { offset: 0, limit: 5 },
pageSize: 5,
proxy: {
type: 'ajax', //cross domain calls - json parser
enablePaging: true,
url: 'http://localhost:8080/list',
useDefaultXhrHeader: false,
startParam: 'offset',
limitParam: 'limit',
reader: {
totalProperty: 'total',
rootProperty: 'items'
},
listeners: {
//this is used to construct the proxy url before the load is done
// beforeload: {
// fn: function() {
// var me = this;
// me.updateProxyURL(); //write this function yourself
// }
// }
}
},
// proxy: {
// type: 'memory',
// reader: {
// type: 'json',
// }
// },
});
Controller.js
/**
* This class is the controller for the main view for the application. It is specified as
* the "controller" of the Main view class.
*
* TODO - Replace this content of this view to suite the needs of your application.
*/
Ext.define('CRUD.view.main.MainController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
store: {
type: 'personnel',
},
onClick: function(grid) {
Ext.Msg.alert("tesdt")
},
onDeleteClick: function(selModel, record, index, options, grid, store) {
//Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
Ext.Msg.confirm({
title: 'Confirm',
msg: 'Are you sure?',
buttons: Ext.Msg.OKCANCEL,
fn: this.onConfirm,
icon: Ext.MessageBox.QUESTION,
config: {
grid: grid,
action: 'del',
store: store
}
});
},
onConfirm: function(btn, text, opt) {
console.log(opt.config.action)
if (btn === 'ok') {
//
opt.config.grid.item.remove();
Ext.Ajax.request({
url: 'http://localhost:8080/' + opt.config.action + '/' + opt.config.grid.record.data.id,
// method: 'DELETE', //this is the url where the form gets submitted
useDefaultXhrHeader: false,
success: function(form, action) {
opt.config.store.load({
start: 0,
limit: 5
})
},
failure: function(form, action) {
},
listeners: {
doRefresh: function() {
this.doLoad(this.cursor);
},
}
});
}
}
});
Please find the screenshot here
Doing grid.getStore().reload() should be sufficient.
BTW. The doRefresh listener is weird. Are you sure you wanted this as Ext.Ajax.request config? This doesn't make sense to me.
Related
The total number of rows is correctly showing in pagination but Pagination is not updating the view when the next button is clicked.
I'm new to Sencha. In Mysql, I'm returning all rows. So that I can limit in client side. If I limit the rows in backend, I cannot have all the rows in client side.
View: List.js
/*** This view is an example list of people.
*/
Ext.define('CRUD.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'home',
requires: [
'CRUD.store.Personnel'
],
title: 'Heroes',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
layout: 'fit',
fullscreen: true,
store: {
type: 'personnel',
},
columns: [
{ text: 'Name', dataIndex: 'name', sortable: true, flex: 1 },
{ text: 'Email', dataIndex: 'email', sortable: true, flex: 1 },
{ text: 'Phone', dataIndex: 'phone', sortable: true, flex: 1 }
],
bbar: {
store: {
type: 'personnel',
},
xtype: 'pagingtoolbar',
displayInfo: true
},
// columns: [
// { text: 'Name', dataIndex: 'name', flex: 1 },
// { text: 'Email', dataIndex: 'email', flex: 1 },
// { text: 'Phone', dataIndex: 'phone', flex: 1 }
// ],
listeners: {
select: 'onItemSelected',
},
});
Store: Personnel.js
Ext.define('CRUD.store.Personnel', {
extend: 'Ext.data.Store',
alias: 'store.personnel',
model: 'CRUD.model.User',
id: 'list',
fields: [
'name', 'email', 'phone'
],
// data: [
// { name: 'Jean Luc', email: "jeanluc.picard#enterprise.com", phone: "555-111-1111" },
// { name: 'Worf', email: "worf.moghsson#enterprise.com", phone: "555-222-2222" },
// { name: 'Deanna', email: "deanna.troi#enterprise.com", phone: "555-333-3333" },
// { name: 'Data', email: "mr.data#enterprise.com", phone: "555-444-4444" }
// ],
autoLoad: {
start: 0,
limit: itemsPerPage
},
buffered: true,
pageSize: itemsPerPage,
remoteSort: true,
proxy: {
type: 'jsonp', //cross domain calls - json parser
url: 'http://localhost:8080/list',
enablePaging: true,
reader: {
type: 'json',
totalProperty: 'total'
},
},
// proxy: {
// type: 'memory',
// reader: {
// type: 'json',
// }
// },
});
bbar: {
store: {
type: 'personnel',
},
xtype: 'pagingtoolbar',
displayInfo: true
},
I have removed store inside bbar and it works. Thanks for being cooperative.
The way you're using the store, ExtJS will do a request every time you change the page, sending the page number parameter to the URL set to the store.
If you want to do client-side pagination using ExtJS, you must set your store's proxy type to memory, load your data into the store and then ExtJS Grid will handle pagination as you expect.
Do an Ext.Ajax.Request like that:
Ext.Ajax.request({
url: 'http://localhost:8080/list',
success: function(response) {
dataStore.setProxy({
type: "memory",
enablePaging: true,
data: Ext.JSON.decode(response.responseText) //here you need to adapt to your response structure
});
dataStore.load();
}
});
For cross domain, you can make a call to Ext.data.JsonP.request() method and process the response as shown in the code below:
Ext.data.JsonP.request({
url: 'data1.json',
success: function (response) {
var myData = [];
Ext.Array.forEach(response.data, function (item) {
myData.push({
name: item.name,
email: item.email,
phone: item.phone
});
});
store.setProxy({
type: "memory",
enablePaging: true,
data: myData
});
store.load();
}
});
Check this fiddle for complete working example.
I have been working with web desktop example in ExtJS5. The example has static data and no events. I wanted to implement a click event on 'Remove Something' button on grid window. Here is my modified code:
Ext.define('SampleApp.view.main.GridWindow', {
extend: 'Ext.ux.desktop.Module',
requires: [
'Ext.data.ArrayStore',
'Ext.util.Format',
'Ext.grid.Panel',
'Ext.grid.RowNumberer'
],
init: function () {
this.launcher = {
text: 'Grid Window',
iconCls: 'icon-grid'
};
},
controller: 'gridwindow',
createWindow: function () {
var desktop = this.app.getDesktop();
var win = desktop.getWindow('grid-win');
if (!win) {
win = desktop.createWindow({
id: 'grid-win',
title: 'Grid Window',
width: 740,
height: 480,
iconCls: 'icon-grid',
animCollapse: false,
constrainHeader: true,
layout: 'fit',
items: [
{
border: false,
xtype: 'grid',
store: mock.view.main.GridWindow.getDummyData(),
columns: [{ xtype: 'rownumberer', sortable: false, text: "S.N.", width: 70 }, {
id: 'topic',
text: "Topic",
dataIndex: 'gridTopic',
flex: 1,
align: 'center'
}, {
text: "Author",
dataIndex: 'gridAuthor',
flex: 1,
align: 'center',
sortable: true
}, {
text: "Replies",
dataIndex: 'gridReplies',
align: 'center',
flex: 1,
sortable: true
}, {
id: 'last',
text: "Last Post",
dataIndex: 'gridLastPost',
flex: 1,
align: 'center',
sortable: true
}]
}
],
tbar: [{
text: 'Add Something',
tooltip: 'Add a new row',
iconCls: 'add'
}, '-', {
text: 'Options',
tooltip: 'Modify options',
iconCls: 'option'
}, '-', {
text: 'Remove Something',
tooltip: 'Remove the selected item',
iconCls: 'remove',
listeners: {
click: 'onDeleteClick'
}
}]
});
}
return win;
},
statics: {
getDummyData: function () {
var _store = Ext.create('Ext.data.Store', {
fields: [
{ name: 'gridId', type: 'int' },
{ name: 'gridTopic', type: 'string' },
{ name: 'gridAuthor', type: 'string' },
{ name: 'gridReplies', type: 'string' },
{
name: 'gridLastPost', type: 'date', convert: function (value) {
var _date = new Date(value);
return Ext.Date.format(_date, "Y-m-d H:i:s");
}
}
]
});
var _responseText;
Ext.Ajax.request({
async: false,
url: 'http://localhost/sampleapp/getusers',
method: 'GET',
success: function (resp) {
_responseText = Ext.decode(resp.responseText);
_store.loadData(_responseText);
}
});
return _store;
}
}
});
I am unable to handle 'onDeleteClick' event inside the controller. Here is the controller definition:
Ext.define('SampleApp.view.main.GridWindowController', {
extend: 'Ext.app.ViewController',
alias: 'controller.gridwindow',
onDeleteClick: function (button, evt) {
alert('Clicked');
}
});
Can someone point out the mistake. How can this event be handled?
Ext.ux.desktop.Module does not accept controller config option.
Use your controller on an Ext.Component — in your case either the grid or the window.
I have a combobox for State that successfully filters in Rally. The code below works. I want to add an enhancement and have the combobox default to 'In Progress'. I added defaultValue but it has no effect. Thanks for your help.
Rally.onReady(function() {
Ext.define('Rally.example.CustomStoreGrid', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
Ext.create('Rally.data.wsapi.Store', {
model: 'defect',
autoLoad: true,
limit: 1000,
pageSize: 1000,
listeners: {
load: this._onDataLoaded,
scope: this
},
fetch: ['FormattedID', 'Name', 'Severity', 'State', 'InProgressDate', 'c_PlannedDeliveryVersion']
});
},
_onSelect: function() {
var grid = this.down('rallygrid'), store = grid.getStore();
store.clearFilter(true);
store.filter(this._getStateFilter());
},
_getStateFilter: function() {
return {
property: 'State',
operator: '=',
defaultValue: 'In Progress',
value: this.down('#priorityComboBox').getValue()
};
},
_onDataLoaded: function(store, data) {
var records = _.map(data, function(record) {
//Perform custom actions with the data here
//Calculations, etc.
return Ext.apply({
// Age: Math.round(((new Date() - record.get('InProgressDate')) / 86400000) * 10) / 10;
}, record.getData());
});
this.add({
xtype: 'rallyfieldvaluecombobox',
itemId: 'priorityComboBox',
fieldLabel: 'Filter by State:',
model: 'defect',
// multiSelect: true,
field: 'State',
listeners: {
select: this._onSelect,
// ready: this._onLoad,
scope: this
}
});
this.add({
xtype: 'rallygrid',
showPagingToolbar: false,
showRowActionsColumn: false,
editable: false,
store: Ext.create('Rally.data.custom.Store', {
limit: 1000,
pageSize: 1000,
data: records
}),
columnCfgs: [
{
xtype: 'templatecolumn',
text: 'ID',
dataIndex: 'FormattedID',
width: 100,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1
},
{
text: 'Severity',
dataIndex: 'Severity'
},
{
text: 'State',
dataIndex: 'State'
},
{
text: 'Planned Delivery Version',
dataIndex: 'c_PlannedDeliveryVersion',
flex: 0.25
},
{
text: 'In Progress Date',
dataIndex: 'InProgressDate',
xtype: 'datecolumn',
format:'Y-m-d'
},
{
text: 'Age',
dataIndex: 'InProgressDate'
,
renderer: function(value) {
return Math.round(((new Date() - value) / 86400000) * 10) / 10;
}
}
]
});
}
});
Rally.launchApp('Rally.example.CustomStoreGrid', {
name: 'Custom Store Grid Example'
});
});
Using value config property sets the default value:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
items:{ html:'App SDK 2.0rc3 Docs'},
launch: function() {
this.add({
xtype: 'rallyfieldvaluecombobox',
model: 'UserStory',
field: 'ScheduleState',
value: 'In-Progress'
});
}
});
I have following code:
function selectClassWindow() {
classes = Ext.create('Ext.tree.Panel', {
store: Ext.create('Ext.data.TreeStore', {
autoLoad: true,
autoSync: true,
fields: ['id','name', 'description','cost'],
proxy: {
type: 'ajax',
api: {
read: '/otp/getClass/'
}
},
root: {
name: 'Name1',
id: 0,
expanded: true
},
listeners: {
load: function (tree, node, records) {
node.eachChild(function (childNode){
childNode.set('checked',false);
});
}
}
}),
border: false,
rootVisible: false,
useArrows: true,
hideHeaders: true,
height: window.MaxHeightWindows,
xtype: 'listTree',
columns: [
{
xtype: 'treecolumn',
text: 'Name2',
flex: 1,
sortable: true,
dataIndex: 'name'
},</code>
Want to add here!
{
xtype: 'customspinner',
fieldLabel: 'How Much Beer?',
step: 6
}
]
})
classes.on('itemdblclick', function() {
selectedNode = classes.getSelectionModel().getSelection()
if (selectedNode[0] && selectedNode[0].isLeaf()) {
selectedClass = selectedNode[0].data.id
selectWindow.close()
if((window.selectedNode[0].parentNode&&selectedNode[0].parentNode.data.name == 'Text1')||
(window.selectedNode[0].parentNode.parentNode&&selectedNode[0].parentNode.parentNode.data.name == 'Text1')||
(window.selectedNode[0].parentNode.parentNode.parentNode&&selectedNode[0].parentNode.parentNode.parentNode.data.name == 'Text1')){
selectReasonWindow()
}else{
Ext.Ajax.request({
url: '/defect/updateDeparture/'+rec.data.id,
params: {
class_id: selectedClass,
reason_id: 0
},
success: function(result,response) {
if (window.departureGrid) {
departureGrid.store.load()
}
if (window.departureFullList) {
departureFullList.store.load()
}
if(window.logs){
logs.setValue(result.responseText)
}
if (window.crashDepartureList) {
crashDepartureList.store.load()
}
}
})
}
}
})
emptyPanel = Ext.create('Ext.panel.Panel', {
border: false,
flex: 1,
items: [classes]
})
selectWindow = Ext.create('Ext.window.Window', {
title: 'Name3',
width: 750,
border: false,
layout: {
type: 'hbox',
},
resizable:false,
collapsible: false,
constrain: true,
modal:true,
plain:true,
items: [emptyPanel],
buttons: [{
text: 'Ok',
handler: function() {
selectedNode = classes.getSelectionModel().getSelection()
if (selectedNode[0] && selectedNode[0].isLeaf()) {
selectedClass = selectedNode[0].data.id
selectWindow.close()
if((window.selectedNode[0].parentNode&&selectedNode[0].parentNode.data.name == 'Text1')||
(window.selectedNode[0].parentNode.parentNode&&selectedNode[0].parentNode.parentNode.data.name == 'Text1')||
(window.selectedNode[0].parentNode.parentNode.parentNode&&selectedNode[0].parentNode.parentNode.parentNode.data.name == 'Text1')){
selectReasonWindow()
}else{
Ext.Ajax.request({
url: '/defect/updateDeparture/'+rec.data.id,
params: {
class_id: selectedClass,
reason_id: 0
},
success: function(result,response) {
if (window.departureGrid) {
departureGrid.store.load()
}
if (window.departureFullList) {
departureFullList.store.load()
}
if(window.logs){
logs.setValue(result.responseText)
}
if (window.crashDepartureList) {
crashDepartureList.store.load()
}
}
})
}
}
}
},{
text: 'Close',
handler: function() {selectWindow.close()}
}]
}).show();
}
and i want add column "customspinner" to Ext.tree.Panel, but i get Uncaught TypeError: Object [object Object] has no method 'setSortState'. What's wrong?
In finally need something like this
There are a couple of things that are getting in your way:
grids do not support components in the cells (yet), they will soon.
For now you can use http://skirtlesden.com/ux/component-column
Tree already has a loading mask that is triggered by default on node load.
If you just want to add a spinner somewhere in your page just follow the Loading Mask component docs. Essentially any dom element can be targeted with mask/unmask calls.
I'm new with Sencha Touch 2 and I've got a trouble using nested list:
toolbar duplicates along with back button, so at the end of nested list I have 3 toolbars with 3 back buttons. I guess that the reason is that I create Ext.nestedList for each detailed card, useToolbar:false doesn't fix the problem because then I can't go to previous list. Maybe back button needs to be overwritten but I've got no idea of that. Any help would be very useful. Here is top part of code:
Ext.define('ListItem', {
extend: 'Ext.data.Model',
config: {
fields: ['text'],
},
});
var treeStore = Ext.create("Ext.NestedList", {
fullscreen: true,
tabBarPosition: 'bottom',
title: 'Now-Yakutsk',
iconCls: 'star',
displayField: 'title',
layout: 'card',
store: {
type: 'tree',
id: 'ListCard',
fields: [
'title','code',
{name: 'leaf', defaultValue: true}
],
root: {
leaf: false
},
proxy: {
type: 'jsonp',
url: 'http://now/catlist.php',
reader: {
type: 'json',
rootProperty: 'cat'
}
}
},
listeners: {
leafitemtap: function(nestedList, list, index, target, record) {
var treeStore2 = Ext.create("Ext.NestedList", {
fullscreen: true,
tabBarPosition: 'bottom',
//useToolbar:false,
//leaf: true ,
iconCls: 'star',
displayField: 'title',
store: {
type: 'tree',
id: 'detailCard',
fields: [
'title','code','link',
{name: 'leaf', defaultValue: true}
],
root: {
leaf: false
},
proxy: {
type: 'jsonp',
url: 'http://now/catlist2.php',
reader: {
type: 'json',
rootProperty: 'cat'
}
}
},
detailCard: { useToolbar:true,
xtype: 'panel',
scrollable: true,
styleHtmlContent: true
},
listeners: {
leafitemtap: function(nestedList, list, index, target, record) {
var cin = Ext.create("Ext.NestedList", {
fullscreen: true,
tabBarPosition: 'bottom',
//useToolbar:false,
//title: 'Blog',
iconCls: 'star',
displayField: 'list',
store: {
type: 'tree',
fields: [
'name', 'link', 'list', 'image', 'adress', 'banner',
{name: 'leaf', defaultValue: true}
],
root: {
leaf: false
},
proxy: {
type: 'jsonp',
url: 'http://now/cinemalist.php',
reader: {
type: 'json',
rootProperty: 'cinema'
}
}
},
detailCard: {
xtype: 'panel',
scrollable: true,
styleHtmlContent: true
},
listeners: {
leafitemtap: function(nestedList, list, index, element, post) {
this.getDetailCard().setHtml(post.get('banner'));
}
}
});
and the screenshot:
http://piccy.info/view3/4985552/cdfd1dcca3928d4a5d4b4b41ba060b1f/
found solution in case someone else has the same problem
-the point is hiding and showing the toolbar playing with active deactive methods
for example in parent we create
listeners: { activate : function() {
//this.getToolbar().hide();
tb = this.getToolbar();
} ,
deactivate: function() {
//this.getToolbar().hide();
}
then in child we put
listeners: {
activate : function() {
tb1 = this.getToolbar();
tb1.hide();
tb.show();
//this.getToolbar().hide();
} ,
deactivate: function() {
//tb.show();
//alert('dd');
//this.getToolbar().hide();
}
and so on ...