I have a gridpanel on a panel window that loads a certain store:
xtype: 'gridpanel',
store: custStore,
viewConfig: {
loadMask: false,
enableTextSelection: true
},
hideHeaders: false,
bodyBorder: true,
id: 'playerslist-grid-id',
itemId: 'playerslist-grid-id',
viewConfig: {
deferEmptyText: false,
emptyText: 'No records yet'
},
columns: [{
text: 'Customer',
dataIndex: 'username',
flex: 1
}, {
header: '',
xtype: 'actioncolumn',
itemId: 'remove-player-btn',
width: 50,
sortable: false,
resizable: false,
menuDisabled: true,
hidden: bHide,
items: [{
icon: 'resources/img/x.png',
tooltip: 'Remove Player',
scope: oMe
}],
editor: {
xtype: 'text',
name: 'deleteRow'
}
}]
The custStore variable is handled like this.
var oMe = this;
oController = EcommBackoffice.Global.app_var.getController('CustomerTagsController'),
cStore = oController.getCustomerListStore(),
cDetails = cStore.first(),
customers = [];
customers = cDetails.get('customers');
var custStore = Ext.create('Ext.data.ArrayStore', {
model: 'CustomerList',
data: customers
});
I needed to put it in an array store as the data object is nested like so:
{
id: 1,
name: 'test',
description: 'test',
customers: [{
id: 001,
username: 'bob'
}, {
id: 001,
username: 'terese'
}, {
id: 001,
username: 'dab'
}, {
id: 001,
username: 'bba'
}, {
id: 001,
username: 'hello'
}]
}
On my controller I process a function that places custStore to it and other parameters before a request.
click: function() {
oController.addPlayerToTag(newPlayer, tagId, custStore);
}
Problem: How do I reload custStore on the gridpanel I'm on after a successful callback? I tried using custStore.load() but nothing happened.
If I understand correctly, you get a new array of customers back from the server and need to refresh the grid with that array. In that case I think you need to call setData on the custStore, passing in the new array of customers. Not sure if 4.2 has this method. If not, try setting custStore.data property.
If that alone doesn't work, try also calling reconfigure on the grid, passing in the custStore.
Related
I have this json data:
{
id: 1,
name: 'something',
description: 'somethingsomething',
customers: [{
id: 1,
username: 'cust1'
}, {
id: 2,
username: 'cust2'
}]
}
While I have no problems displaying the first three fields on the gridpanel, I however have an issue retrieving the array object for the customers field. My model goes like this:
fields: [
'id', {
name: 'name',
sortType: Ext.data.SortTypes.asUCString
},
'permanent', {
name: 'description',
Type: Ext.data.SortTypes.asUCString
}, {
name: 'customers',
Type: Ext.data.SortTypes.asUCString
}, {
name: 'username',
Type: Ext.data.SortTypes.asUCString,
mapping: 'customers[0].username'
}
]
When I try to access customers[0].username, it only retrieves the ones on that specified index. Removing the index number returns undefined as I assume it is looking for what index to return from. How do I properly retrieve all of customers: [] and display it to my grid where it is structured as:
{
xtype: 'gridpanel',
store: oStore,
viewConfig: {
loadMask: false,
enableTextSelection: true
},
hideHeaders: false,
bodyBorder: true,
columns: [{
text: 'Customer',
dataIndex: 'username',
flex: 1
}, {
header: '',
xtype: 'actioncolumn',
itemId: 'remove-player-btn',
width: 50,
sortable: false,
resizable: false,
menuDisabled: true,
items: [{
icon: 'resources/img/x.png',
tooltip: 'Remove Player',
scope: oMe
}],
editor: {
xtype: 'text',
name: 'deleteRow'
}
}]
}
You can use convert function available in model.This convert function is used for some calculation purpose & map response data for our needs.For example I will map username as below:
fields: [
{
name:'username',
convert:function(value,model)
{
return model.data.customers.username;
}
}
]
Use same technique for id field.Reply if any issues.
My code is as follows (I can post more if it would help you help me!):
//var store = myGrid.getStore();
var store = Ext.data.StoreManager.get("CountrySpecificStore")
console.log(store);
The console gives me this upon execution of the lines above:
[Ext.Loader] Synchronously loading 'CountrySpecific'; consider adding
Ext.require('CountrySpecific') above Ext.onReady
ext-dev.js:8894 GET
[localhost]/extjs/CountrySpecific.js?_dc=1395952634289 404 (Not
Found)
ext-dev.js:10587 Uncaught Error: [Ext.Loader] Failed loading
synchronously via XHR: 'CountrySpecific.js'; please verify that the
file exists. XHR status code: 404 ext-dev.js:10857
Instead of http://localhost/extjs/CountrySpecific.js?_dc=1395952634289 it should be calling my proxy which is defined as:
Ext.define('RateManagement.store.CountrySpecificStore', {
extend: 'Ext.data.Store',
model: 'RateManagement.model.CountrySpecific',
proxy: {
type: 'rest',
format: 'json',
url: '/intake/sap/rates/CountrySpecific'
},
autoSync: true,
autoLoad: true
});
How can I make it call http://localhost/intake/sap/rates/CountrySpecific?
Note: I am using ExtJS 4.2.1.
Edit: Here is my Grid, where I am using using the store:
Ext.define('RateManagement.view.Grids.CountrySpecificGrid', {
extend: 'Ext.grid.Panel',
requires:['Ext.ux.CheckColumn'],
xtype: 'CountrySpecificGrid',
store: 'RateManagement.store.CountrySpecificStore',
plugins: [{
clicksToMoveEditor: 1,
autoCancel: false,
ptype: 'rowediting',
pluginId: 'rowediting'
}],
tbar: [{
text: 'Add Rate',
handler: function(button) {
var myGrid = button.up('grid');
//console.log(myGrid);
var myPlugin = myGrid.getPlugin('rowediting');
myPlugin.cancelEdit();
var r = Ext.create('CountrySpecific', {
id: '',
hostCountryId: '',
hostCountry: '',
rate: 0,
currencyId: '',
rateTypeId: '',
frequencyCode: '',
perFamilyMember: '',
familySize: 0
});
//var store = myGrid.getStore();
var store = Ext.data.StoreManager.get("CountrySpecificStore")
console.log(store);
// todo: create guid and add to store
store.insert(0, r);
myPlugin.startEdit(0, 0);
}
}],
features: [{
ftype: 'filters',
encode: false,
local: true,
filters: [
{ type: 'string', dataIndex:'hostCountry' },
{ type: 'numeric', dataIndex:'rate' },
{ type: 'string', dataIndex:'currencyId' }
]
}],
columns: [
{text: 'Host Country', dataIndex: 'hostCountry', width:150},
{text: 'Rate', dataIndex: 'rate', xtype: 'numbercolumn',
editor: { xtype: 'numberfield', allowBlank: false, minValue: 0, blankText: 'Rate is required.', invalidText: 'Rate must be positive.' }},
{text: 'Rate Currency', dataIndex: 'currencyId', xtype: 'currency-column' },
{text: 'Frequency', xtype: 'rate-type-column' },
{text: 'PerFamilyMember', dataIndex: 'perFamilyMember', xtype: 'checkcolumn',
editor: {xtype: 'checkbox',cls: 'x-grid-checkheader-editor'}},
{text: 'Family Size', dataIndex: 'familySize',
editor: { xtype: 'numberfield', minValue: 0, invalidText: 'Family Size must be positive.' }}
]
});
It seems like you're using the StoreManager to get a store, which hasn't been registered before, so he tries to dynamically load the definition.
Since the only information he got is "CountrySpecificStore" he tries to find this class in the ExtJS directory.
You have to require the store class in the class that calls Ext.data.StoreManager.get("CountrySpecificStore")
My problem was I needed to declare my model variable like this:
var r = Ext.create('RateManagement.model.CountrySpecific', {
id: '',
hostCountryId: '',
hostCountry: '',
rate: 0,
currencyId: '',
rateTypeId: '',
frequencyCode: '',
perFamilyMember: '',
familySize: 0
});
Then, I was able to simply:
var store = myGrid.getStore();
I have a nested list in my application, and when users make a selection they are taken to a detailCard with some options. One of these options is to "confirm" their selection. Once confirmed, the selection should be removed from the list. This works on the server side, so if the app is refreshed the selection is gone. However I was hoping to remove the selection in the treeStore itself and refresh the view somehow so that users can immediately see the effect of their confirmation. I was following a tutorial for nestedList that I can't seem to find anymore, and this code is based on that:
var itemId = '';
Ext.define('MyApp.view.MainView',
{
extend: 'Ext.tab.Panel',
xtype: 'main',
alias: "widget.mainview",
requires: [
'Ext.dataview.NestedList',
'Ext.data.proxy.JsonP'
],
config:
{
tabBarPosition: 'bottom',
items: [
{
xtype: 'nestedlist',
title: 'Listings',
iconCls: 'home',
displayField: 'listingValue',
scrollable: true,
detailCard:
{
xtype: 'panel',
scrollable: true,
styleHtmlContent: true,
items: [
{
xtype: 'fieldset',
readOnly: true,
title: 'Schedule Information:',
items: [
{
name: 'from',
id: 'from',
xtype: 'textareafield',
label: 'From',
readOnly: true
},
{
name: 'to',
id: 'to',
xtype: 'textareafield',
label: 'To',
readOnly: true
},
{
name: 'moreInfo',
id: 'moreinfo',
xtype: 'textfield',
label: 'More Info',
readOnly: true
},
]
},
{
xtype: 'container',
flex: 1,
items: [
{
xtype: 'button',
text: 'Confirm',
action: 'confirmSelection',
margin: '10 5',
padding: '5',
ui: 'confirm'
}]
}]
},
listeners:
{
itemtap: function (nestedList, list, index,
element, post)
{
var detailCard = this.getDetailCard();
detailCard.setHtml('');
itemId = post.get('id');
Ext.getCmp('from').setValue(post.get(
'from'));
Ext.getCmp('to').setValue(post.get('to'));
Ext.getCmp('moreinfo').setValue(post.get(
'moreinfo'));
}
},
store:
{
type: 'tree',
fields: [
'id', 'from', 'to', 'fromcity', 'tocity',
'time', 'address',
{
name: 'leaf',
defaultValue: true
},
{
name: 'listingValue',
convert: function (value, record)
{
listingValue = '$<b>' + record.get(
'address') + '</b> ' + record
.get('fromcity') + ' to ' +
record.get('tocity');
return listingValue;
}
}
],
root:
{
leaf: false
},
proxy:
{
type: 'jsonp',
url: 'http://myURL.com/page.php?action=go',
reader:
{
type: 'json',
rootProperty: 'root'
}
}
}
},
{
title: 'Dashboard',
iconCls: 'action',
items: [
{
docked: 'top',
xtype: 'titlebar',
title: 'Dashboard'
},
]
}]
}
});
I have no idea what to do at this point, because the store is set up in the view and I'm not sure how to access it in my controller. I learned about treeStore.removeAll() and treeStore.load(), but how can I call those functions in a controller when the store is set up without any type of reference name? Is there a way I can remove the user's selection and display the view, or perhaps reload the view altogether so it can retrieve the new list from the server?
Because my list is on the first page of my app, I managed to get away with window.location.reload(); and reloading the whole app. Its not the most elegant solution, but the changes are reflected.
I won't accept my own answer just yet in case someone comes along with a better solution.
I am trying to create a grid with store having PagingMemoryProxy.
Pagination is working and I can see as well as change all pages
but the loadmask won't disappear so I am not able to edit the grid data.
here is my code
Ext.require('Ext.ux.data.PagingMemoryProxy');
var data = {
Accounts: [{
id: 1,
name: 'Ed Spencer'
}, {
id: 2,
name: 'Abe Elias'
}, {
id: 3,
name: 'Tom Elias'
}]
};
Ext.define('Account', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'string'
}, {
name: 'name',
type: 'string'
}]
});
var store = Ext.create('Ext.data.Store', {
storeId: 'myStore',
pageSize: 2,
model: 'Account',
data : data,
proxy: {
type: 'pagingmemory',
reader: {
type: 'json',
root: 'Accounts'
}
},
});
var pagingBar = new Ext.PagingToolbar({
store: store,
displayInfo: true,
displayMsg: 'Displaying Accounts {0} - {1} of {2}',
emptyMsg: "No Accounts to display"
});
var grid = new Ext.create('Ext.grid.Panel', {
title: 'Accounts',
store: store,
columns: [{
header: 'Id',
dataIndex: 'id',
editor: 'textfield'
}, {
header: 'Name',
dataIndex: 'name',
flex: 1,
editor: {
xtype: 'textfield',
allowBlank: false
}
}],
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 1,
pluginId: 'rowEditing'
})],
height: 200,
width: 400,
loadMask: false,
renderTo: "editor-grid",
bbar: pagingBar
});
Store load event is getting fired and I can see greyed out data behind the loading mask
Firbug is showing no error.
I am using Extjs 4.1.3. Any idea what's the problem.
Thanks in advance
Looks like a known bug, think its fixed in Extjs 4.2.1
As a temporary fix, you can hide the mask 'on store load' using
grid.getView().setLoading(false);
Sample here : https://fiddle.sencha.com/#fiddle/1v9
I have based this off of the Sencha example; however, instead of using a url to fill the store, I have tried to create an empty one and add an item to it. When I load the page, the item is successfully shown in the panel; however, I receive an error saying
Line: 18
Error: Unable to get value of the property 'dataSource': object is null or undefined
My model looks like this:
Ext.define('Ext.model.Test', {
extend: 'Ext.data.Model',
fields: [
{ name: 'testName', type: 'string' },
{ name: 'hasTestPassed', type: 'bool' },
{ name: 'hasFix', type: 'bool' }
]
});
My code looks like this:
Ext.define('Ext.app.ServerChecker', {
extend: 'Ext.grid.Panel',
requires: [
'Ext.selection.CellModel',
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.form.*',
'Ext.model.Test'
],
alias: 'widget.ServerChecker',
xtype: 'cell-editing',
initComponent: function () {
this.cellEditing = new Ext.grid.plugin.CellEditing({
clicksToEdit: 1
});
Ext.apply(this, {
width: this.width,
store: new Ext.data.Store({
// destroy the store if the grid is destroyed
autoDestroy: true,
model: Ext.model.Test,
proxy: {
type: 'memory',
reader: {
type: 'json',
record: 'test'
}
},
sorters: [{
property: 'common',
direction: 'ASC'
}]
}),
columns: [{
header: 'Test Name',
dataIndex: 'testName',
flex: 1,
editor: {
allowBlank: false
}
}, {
header: 'Result',
dataIndex: 'hasTestPassed',
width: '75px',
align: 'right',
editor: {
allowBlank: false
}
}, {
xtype: 'actioncolumn',
width: 30,
sortable: false,
menuDisabled: true,
items: [{
icon: 'resources/images/icons/fam/delete.gif',
tooltip: 'Delete Plant',
scope: this,
handler: this.onRemoveClick
}]
}],
selModel: {
selType: 'cellmodel'
},
tbar: [{
text: 'Run Tests',
scope: this,
handler: this.onRunTestsClick
}]
});
this.callParent();
this.on('afterlayout', this.loadStore, this, {
delay: 1,
single: true
})
},
loadStore: function () {
this.getStore().load({
// store loading is asynchronous, use a load listener or callback to handle results
callback: this.onStoreLoad
});
},
onStoreLoad: function () {
var rec = new Ext.model.Test({
testName: 'Yipiee',
hasTestPassed: true,
hasFix: true
});
this.getStore().insert(0, rec);
this.cellEditing.startEditByPosition({
row: 0,
column: 0
});
},
onRemoveClick: function (grid, rowIndex) {
this.getStore().removeAt(rowIndex);
}
})
Any help would be greatly appreciated. I realize that I am loading data in kind of a strange spot; however, this is for testing purposes and it would appear that it should work just fine.
Thanks in advance.
You are defining the store with a memory proxy, which is expecting the store to have a data property when loading. So, when you do this.getStore().load(..) you get an error. You actually add data to the store in the load callback, usually the callback is used to do something after the store was actually loaded.
I don't really understand what you are trying to do, but if you just want to load a record directly to the store, without any processing, you don't need the proxy at all. Your loadStore function can look like this:
loadStore: function () {
var obj = {
testName: 'Yipiee',
hasTestPassed: true,
hasFix: true
};
this.getStore().add(obj);
}