I currently have a simple extJS Grid which is pulling data from a server and presenting it to the viewer. I would like to grab the value of the selected row, and then pass it to another PHP script for processing in order to display the results in another grid.
var roleInformationStore = Ext.create('Ext.data.Store', {
autoLoad: true,
autoSync: true,
model: 'RoleInformation',
proxy: {
type: 'ajax',
url: 'data.php',
reader: {
type: 'array',
},
writer: {
type: 'json'
}
}
});
var roleInformationGrid = Ext.create('Ext.grid.Panel', {
store: roleInformationStore,
width: '100%',
height: 200,
title: 'Roles',
columns: [
{
text: 'Name',
flex: 1,
width: 100,
sortable: false,
hideable: false,
dataIndex: 'role'
}
],
listeners: {
cellclick: function(view, td, cellIndex, record, tr, rowIndex, e, eOpts) {
roleInformationStore.proxy.extraParams = record.get('role');
//Ext.Msg.alert('Selected Record', 'Name: ' + record.get('role'));
}
}
});
Using the listener in the current grid, I am able to get the value and show it using the alert method. Any suggestions on how to accomplish this?
Thanks
For this to work, extraParams has to be an object of key-value string pairs, because an URI has to be something like data.php?key1=value1&key2=value2.
Style-wise, Sencha advises to use getters and setters, whenever possible.
Together, you get:
var store = Ext.getStore("roleInformationStore");
store.getProxy().setExtraParam("myRoleParamKey",record.get('role'));
store.load();
In PHP, you would get the parameter then using
$role = $_GET['myRoleParamKey'];
You can of course substitute myRoleParamKey for any alphanumeric literal you want, but make sure you use the same key on both server and client side. ;-)
Docs: setExtraParam
Related
Fiddle with the problem is here https://fiddle.sencha.com/#view/editor&fiddle/2o8q
There are a lot of methods in the net about how to locally filter grid panel that have paging, but no one is working for me. I have the following grid
var grid = Ext.create('Ext.grid.GridPanel', {
store: store,
bbar: pagingToolbar,
columns: [getColumns()],
features: [{
ftype: 'filters',
local: true,
filters: [getFilters()],
}],
}
Filters here have the form (just copy pasted part of my filters object)
{
type: 'string',
dataIndex: 'name',
active: false
}, {
type: 'numeric',
dataIndex: 'id',
active: false
},
The store is the following
var store = Ext.create('Ext.data.Store', {
model: 'Store',
autoLoad: true,
proxy: {
data: myData,
enablePaging: true,
type: 'memory',
reader: {
type: 'array',
}
},
});
Here myData - comes to me in the form of
["1245", "Joen", "Devis", "user", "", "email#com", "15/6/2017"],
["9876", "Alex", "Klex", "user", "", "email#com", "15/6/2017"],[...
Also I have the the pagingToolbar
var pagingToolbar = Ext.create('Ext.PagingToolbar', {
store: store, displayInfo: true
});
So all the elements use the store I declared in the top. I have 25 elements per grid page, and around 43 elements in myData. So now I have 2 pages in my grid. When I am on first page of grid and apply string filter for name, for example, it filters first page (25 elements), when I move to 2d page, grid is also filtered, but in scope of second page. So as a result each page filters seperately. I need to filter ALL pages at the same time when I check the checkbox of filter, and to update the info of pagingToolbar accordingly. What I am doing wrong?
Almost sure that it is a late answer, but I have found the local store filter solution for paging grid you are probably looking for:
https://fiddle.sencha.com/#fiddle/2jgl
It used store proxy to load data into the grid instead of explicitly specify them in store config.
In general:
create empty store with next mandatory options
....
proxy: {
type: 'memory',
enablePaging: true,
....
},
pageSize: 10,
remoteFilter: true,
....
then load data to the store using its proxy instead of loadData
method
store.getProxy().data = myData;
store.reload()
apply filter to see result
store.filter([{ property: 'name', value: 'Bob' }]);
See President.js store configuration in provided fiddle example for more details.
Hope it helps
In an angular app I have a page that displays several Kendo-grids based on the data retrieved from an http request. The data comes back as json.
This is the function that executes on successful data retrieval. This is within a controller, and ctrl is the "this" object on the controller scope. Moment is a JavaScript library for managing dates. The only thing it's doing here is formatting as strings the date (MM/DD/YYYY) and the time (hh:mm A).
function (data) {
ctrl.dateGroups = {};
var currentDate = '';
data.Data.forEach(function (item) {
item.Date = item.StartDateTime ? moment(item.StartDateTime).format(HC_APP_CONFIG.dateFormat) : '';
item.ClockInTime = item.StartDateTime ? moment(item.StartDateTime).format(HC_APP_CONFIG.timeFormat) : '';
if ( angular.isEmpty(item.EndDateTime) ||
item.EndDateTime === '' ||
item.EndDateTime.format(HC_APP_CONFIG.dateFormat).match(HC_APP_CONFIG.badLocalDatePattern) !== null ){
item.ClockOutTime = '';
item.EndDateTime = '';
} else {
item.ClockOutTime = moment(item.EndDateTime).format(HC_APP_CONFIG.timeFormat);
}
var currentDate = 'd'+item.Date;
if (ctrl.dateGroups.hasOwnProperty(currentDate) &&
ctrl.dateGroups[currentDate].length > 0) {
ctrl.dateGroups[currentDate].push(item);
} else {
ctrl.dateGroups[currentDate] = [item];
}
});
}
The function (successfully) takes each returned item and puts it into an object as part of arrays named after the date, so that all items from Jan 14th, for example, end up in one array, and another for Jan 15th, etc.
This displays in the page with this loop:
<div class="col-sm-12" ng-repeat="(key,value) in punchList.dateGroups">
<h2 class="punch-heading">{{key.substring(1)}}</h2>
<div hc-grid id="grid-{{key}}"></div>
</div>
The result is a series of grids, each corresponding to a date and containing all the items for that date. This again, is successful.
The grid configuration:
gridConfig = {
uiOptions: {},
autoBind: false,
sortable: {
mode: 'single'
},
height: 'auto',
columnMenu: false,
filterable: false,
dataSource: {
type: 'json',
serverPaging: true,
serverFiltering: true,
serverSorting: true,
pageSize: HC_APP_CONFIG.defaultPageSize,
schema: {
data: 'Data',
total: 'TotalCount',
model: {
id: 'ShiftId',
fields: {
EmployeeName: {
type: 'string'
},
EmployeeCode: {
type: 'string'
},
JobName: {
type: 'string'
},
ClockIn: {
type: 'string'
},
ClockOut: {
type: 'string'
}
}
}
}
},
columns: [
{
field: 'EmployeeName',
title: 'Name',
sortable: false
},
{
field: 'EmployeeCode',
title: 'Employee Code',
sortable: false
},
{
field: 'JobName',
title: 'Job',
sortable: false
},
{
field: 'ClockInTime',
title: 'Clock In'
},
{
field: 'ClockOutTime',
title: 'Clock Out'
}
]
}
The problem is when I sort by the Clock In or Clock Out columns (the only sortable columns). At this point, the grid structure (pagination indicator, column heads, etc) remain in tact but the data disappears.
I'm using Kendo UI v2015.1.429
Kendo UI grids support direct server interaction via a built-in AJAX system for making API calls. It appears that setting serverSort:true may tell the Kendo UI grid to drop the current data model and query the server for newly sorted data (which it expects the server to provide). Since you are not using direct server interaction with the grid, it probably drops the model but then has no way to get a new one.
There is a sortable:true option that may be what you need for client side sorting of the existing data.
Link to Kendo UI grid server-side sorting article
Given data in the form:
var grid_data = [ {Hello: 'World'}, {Jesus:'Navas'} ]
I wish to draw a grid like so:
The grid shows with 2 rows but with no data, I can't find the problem in the following code:
var grid_store = Ext.create('Ext.data.Store', {
fields: [
{name: 'Property'},
{name: 'Value'}
],
data: grid_data
});
// create the Grid
var grid_view = Ext.create('Ext.grid.Panel', {
store: grid_store,
renderTo: 'info_panel',
stateful: true,
stateId: 'stateGrid',
columns: [
{
text : 'Property',
width : 100,
sortable : true,
dataIndex: 'Property'
},
{
text : 'Value',
width : 80,
sortable : false,
dataIndex: 'Value'
}
],
height: 350,
width: 600,
title: 'Array Grid',
viewConfig: {
stripeRows: true
}
});
Renders to:
<div id="info_panel"></div>
If you're wondering how I got the example image, I changed the store to an ArrayStore and re-formatted the data into arrays, but I'd prefer to miss out that step and insert the data as-is.
edit:
I think what I'm really asking for is a way to alert extjs to use the JSON keys as values, as opposed to most of the grid examples out there that take the form:
{value: 'Hello'}, {property: 'World'}
As one of the commenters and your edit suggested, your grid is built to consume a json with 'Property' and 'Value' being the keys for the json objects. I don't know if it's possible for you to change the source of the data to send in the reformatted json, but if not, you can always just run a quick loop to do so after receiving the data:
var new_data = [];
Ext.each(grid_data, function(obj) {
for (var prop in obj) {
new_data.push({
Property: prop,
Value: obj[prop]
});
}
}, this);
I am newbie to EXT and I am having problem with reloading EXT 4 tree. I have been trying with:
Ext.tree.getLoader().load(tree.root);
Ext.tree.load(tree.root);
Ext.tree.getRootNode().reload();
Ext.tree.TreePanel.root.reload();
Ext.data.TreeStore.reload();
And nothing helped, I hope someone could clarify this to me, here is the code:
Edit: I have added complete code, as you can see everything is inside extOnReady method, I have removed var before var tree and still I got the same result
Ext.QuickTips.init();
var store = Ext.create('Ext.data.TreeStore',{
proxy: {
type: 'ajax',
url: 'url1'
},
root: {
text: 'TOPP',
id: '1',
expanded: true
},
folderSort: true,
sorters: [{
property: 'text',
direction: 'ASC'
}]
});
tree = Ext.create('Ext.tree.Panel',{
id:'company_tree',
store: store,
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop'
}
},
renderTo: 'tree-div',
height: 300,
width: 766,
title: gettext('Companies'),
useArrows: true,
dockedItems: [{
xtype: 'toolbar',
items: [ {
text: gettext('Collapse All'),
handler: function(){
tree.collapseAll();
}
}]
}]
});
var loadingMask = new Ext.LoadMask(Ext.get('tree-div'),{
msg: gettext("Loading...")
});
tree.on('itemmove', function(tree, oldParent, newParent, index, options){
if(confirm(gettext('Are you sure you want to move this company?'))){
loadingMask.show();
Ext.Ajax.request({
scope: this,
url: 'url2/',
success:function(){
loadingMask.hide();
},
params: {
'ajaxAction[moveNode]': '',
index: index,
nodeid: tree.data.id,
parentNodeID: newParent.data.id,
oldParentNodeID: oldParent.data.id
}
});
}else{
Ext.getCmp('company_tree').getStore.load();
}
});
Also I have tried to reload through console[Ext.getCmp('company_tree').getStore.load();] and it worked. When I try it through code it returns an error regarding fly function
n is null
[Break On This Error]
Ext.fly(n.firstChild ? n.firstChild : n).highlight(me.dropHighlightColor);
Are you really trying to call these methods directly on Ext.tree namespace or Ext.tree.TreePanel class? If so you really need to educate yourself on the difference between objects and classes.
And don't just attempt to guess what a method might be named. Had you looked it up from the manual you would have found out that there is no such method as reload on Tree, TreeStore or TreeView.
What you need to call to reload the tree is the load method of TreeStore:
tree.getStore().load();
I use an editorgrid to edit elements from a JsonStore. The JsonStore uses a HttpProxy to update the backend database.
My problem is that the backend API expects fromTs and toTs to be Unix timestamps, but when a record is updated, the resulting http post contains a date formatted like this: Wed Oct 20 00:00:00 UTC+0200 2010
I've searched the API documentation for a parameter to control the post format, but I've not been able to find anything. Is there a simple way to do this?
myJsonStore = new Ext.data.JsonStore({
autoLoad: true,
autoSave: true,
proxy: new Ext.data.HttpProxy({
api: {
create: '/create/',
read: '/read/',
update: '/update/',
destroy:'/destroy/'
}
}),
writer: new Ext.data.JsonWriter({
encode: true,
writeAllFields: true
}),
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'fromTs', type: 'date', dateFormat:'timestamp'},
{name: 'toTs', type: 'date', dateFormat:'timestamp'}
]
});
The editorgrid is configured like this:
{
xtype: 'editorgrid',
clicksToEdit: 1,
columns: [
{header: "Id", dataIndex: 'id', editable: false},
{header: "From", dataIndex: 'fromTs', editor: new Ext.form.DateField({format: 'd.m.Y', startDay: 1}), xtype: 'datecolumn', format: 'd.m.Y'},
{header: "To", dataIndex: 'toTs', editor: new Ext.form.DateField({format: 'd.m.Y', startDay: 1}), xtype: 'datecolumn', format: 'd.m.Y'}
],
store: myJsonStore
}
I know this case is old, but I found a solution to this problem that I never came around to post here.
I added a listener to the proxy's beforewrite event, and manipulated the post params there
proxy: new Ext.data.HttpProxy({
api: {
create: '/create/',
read: '/read/',
update: '/update/',
destroy:'/destroy/'
},
listeners: {
beforewrite: function(proxy, action, record, params) {
var fromTs = record.data.fromTs;
var toTs = record.data.toTs;
if(record.data.fromTs) record.data.fromTs = fromTs.format('U');
if(record.data.toTs) record.data.toTs = toTs.format('U');
// Update record to be sent
// root = store.reader.root
params.root = Ext.util.JSON.encode(record.data);
// Restore record
record.data.fromTs = fromTs;
record.data.toTs = toTs;
}
}
})
You might be able to hook into the validateedit event or afteredit event of your EditorGridPanel and convert the user-entered-value back into a timestamp using a Date parsing method. I'm guessing that EditorGridPanel is updating the records in the store verbatim without converting them back into timestamps, so you have to do that manually. So I'm thinking maybe something like:
grid.on('validateedit', function(event) {
if (isDateColumn(column)) {
event.record.data[event.field] = dateToTimestamp(event.value);
}
}
The problem is that the JsonWriter does not respect the dateFormat field used in your JsonReader. This post describes the issue along with some code that will address it. You can find it here.