I have a grid Panel with 4 columns, one of these is numeric (number up to 4 digit), and I would like to sort the row by this colum. My problem is Ext JS sorts the rows as if the column was textual, so 5 is sorted after 3000.
I tried to use a numberColumn instead of a normal column (specifying the x-type in the columns of the GridPanel), but it doesn't change the sorting.
Thus I tried to format the numbers so 5 would appear like 0005, and 0005 would be before 3000. But the format options of the numberColumn do not appear to let me specify a minimal number of digit (in Java, using NumberFormat, 0000 would work, but here it doesn't).
So I put a renderer to force my number to appear with 4 digits, it works, but it seems that the sort method use the values before beeing rendered, wich is quite logical.
I'm stuck after trying all my ideas, does anyone have a clue?
If you're using a remote store sort, then the sorting is done remotely (the database, like mysql). So what is the type of column on the database for that field? If it's a char or varchar, then that's the issue.
I've had a similar issue, the column type doesn't fix this. To have a proper ordering the type in model should be numeric.
1) Set your field type as integer in model definition.
Ext.define('myModel', {
extend: 'Ext.data.Model',
fields: [{ name: 'myField', type: 'int' }]
});
2) Create a Store using that model.
var myStore = Ext.create('Ext.data.Store',{
model: 'myModel'
});
3) Define a GridPanel using the store and link your field as dataIndex into columns definition.
Ext.create('Ext.grid.Panel',{
store: myStore,
columns: [{
header: 'Numbers', dataIndex: 'myField'
}]
});
I encountered a similar problem where by exj grids sort by each digit in your number, so for example a list might be reordered to 1, 2, 22, 3, 4, 41, 5... for what its worth, i found in extjs4, that defining the type as int in the model did the trick, I havent specified the local or remote sort but it seems to be working...
Ext.define('ExtMVC.model.Contato', {
extend: 'Ext.data.Model',
fields: [{'id', type: 'int'}, 'name', 'phone', 'email']
});
This is my code that connects to a MySQL. I followed this -> {'id', type: 'int'}, and it work out fine... Thank you all! I'm using Ext js 4.2.x
Related
ExtJs does not expect the same response from the server to confirm updating rows than ExtJs 4.
I have a table with a string id:
Ext.define('App.Product', {
extend: 'Ext.data.Model',
fields: [
{name: 'productid', type: 'string'},
{name: 'ord', , type: 'int'},
(...)
],
idProperty: 'nrproduit'
})
Upon saving the changes, the ExtJs client sends the modified data to the server:
[{"ord":1,"productid":"SG30301"},{"ord":3,"productid":"SG30100"}]
In ExtJs 4.2, it expected the server to send the full data of the two products back, like this:
{
"success":true,
"data":[{
"nrproduit":"SG30100",
"ord":3,
"author":"...",
"editor":"...",
(...)
},{
"nrproduit":"SG30301",
"ord":3,
"author":"...",
"editor":"...",
(...)
}]
}
In ExtJs 6.2, this no longer works. I get the error
Uncaught Error: Duplicate newKey "SG30100" for item with oldKey "SG30301"
Apparently, the client does not take into account the idProperty, but seems to expect the order of the row to be the same in the response as in the request.
Is there a way to force the client to take into account the ids sent back from the server ? Or is it necessary to change the server code ? Is there somewhere documentation on what exactly changed between ExtJs 4.2 and 6.2 in respect to data synchronization between client and server, that go into these details ?
ExtJS considers the order because ids can change, e.g. during insert operations (if the id is generated server-side). To allow for that, in the general case, ExtJS expects to receive the results from the server in the same order in which the records were sent.
However, there's more to it. Under certain circumstances, it uses the id, not the order. You can read Operation.doProcess to find how ExtJS does what it does, and possibly override it if you require a different behaviour.
Edit: It uses the id when the model has the property clientIdProperty, else it uses the order. So, it is enough to add it like this:
Ext.define('App.Product', {
extend: 'Ext.data.Model',
fields: [
{name: 'productid', type: 'string'},
{name: 'ord', , type: 'int'},
(...)
],
idProperty: 'nrproduit',
clientIdProperty: 'nrproduit'
})
Another alternative solution, if you don't want to change the server side code to handle the clientIdProperty property is to disable the batch mode (with batchActions: false) and all your requests are handled one by one.
This is prevent the error "extjs Ext.util.Collection.updateKey(): Duplicate newKey for item with oldKey". With his approach, you will loose some efficiency.
You have to add this to your model:
...
proxy: {
type: 'direct',
extraParams: {
defaultTable: '...',
defaultSortColumn: '...',
defaultSordDirection: 'ASC'
},
batchActions: false, // avoid clientIdProperty
api: {
read: 'Server.Util.read',
create: 'Server.Util.create',
update: 'Server.Util.update',
destroy: 'Server.Util.destroy'
},
reader: {
Just adding clientIdProperty on Model definition solved the issue.
Some more info. Same problem has been asked on sencha forum but solution is not mentioned there. Here is the link to that discussion-
https://www.sencha.com/forum/showthread.php?301898-Duplicate-newKey-quot-x-quot-for-item-with-oldKey-quot-xx-quot
Some help please.
I'm trying to display a xtype depending on value that i get from database.
I have created the store to fetch data from my server side, and it receives only boolean value true or false nothing else.
var hidden= Ext.create('Ext.data.Store',
{
fields: ['hidden'],
autoLoad: true,
proxy:
{
type: 'ajax',
url: 'hidden/compare',
reader:
{
type: 'json',
root: 'data'
}
}
});
Here is the example what i want, but i don't know what to add instead value_from_the_store
text: 'Now you see me, now you don't',
xtype: value_from_the_store == false ? 'hidden' : 'textfield',
If you look at the docs for Ext.data.Store, you'll see several functions that allow you to access the data in the store.
Ext.data.Store
I'm not sure which record you want to access, or if there is only one record, but you can get records by index using getAt, or by ID using getById. You can get the first record using first. There are also several find functions, which allow you to search for a specific record.
Since you said there is only one record, you could just use first. You'll also need to get the specific field in the record using get('hidden').
xtype: hidden.first().get('hidden') ? 'hidden' : 'textfield',
Here, you can try this fiddle - https://fiddle.sencha.com/#fiddle/lho
I've created this fiddle in Ext 5 but you can still make it work in 4. Hope this helps.
Here is the same fiddle for Ext 4.2 - https://fiddle.sencha.com/#fiddle/lji
And in the fiddle, instead of calling the function, you can even do this -
xtype: store.getAt([0]).get('hidden')? 'hidden' : 'textfield'
Another way of fetching the value from the store is by -
store.findRecord('hidden', 'true').get('hidden')
store.findRecord('fieldName', 'Either a string that the field value should begin with, or a RegExp to test against the field.')
Here's your link to the API doc
Can someone help me to figure out a way to arrange the columns irrelevant of it columns array positioning? For example, in below grid columns array i just want to display Phone as 1st column and Name as 2nd column. How can i achieve that programmatically?
Columns Array:-
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email'
}, {
text: 'Phone',
dataIndex: 'phone'
}]
While debugging the grid column config with Chrome developer tools, i figured out a parameter "fullColumnIndex" which value getting increased for every column. But specifying that explicitly doesn't make any difference :(
Thanks!
You can do it by using reconfigure method. Docs — http://docs.sencha.com/extjs/5.1/5.1.0-apidocs/#!/api/Ext.panel.Table-method-reconfigure
Here is the description of this method:
reconfigure( [store], [columns] )
Reconfigures the grid / tree with a new store/columns. Either the store or the > columns can be omitted if you don't wish to change them.
The enableLocking config should be set to true before the reconfigure method is > executed if locked columns are intended to be used.
Parameters
store : Ext.data.Store (optional)
The new store. You can pass null if no new store.
columns : Object[] (optional)
An array of column configs
I am having trouble with extjs rendering the line chart below. Specifically, the last six values are null which are (correctly) not shown on the series line but (incorrectly) have a marker dot displayed for them (see top right of the image below).
I am pulling the graph data from a database as json:
// data store fields
Ext.define('Graphs', {
extend: 'Ext.data.Model',
fields: [
{name: 'the_quota', type: 'int'},
{name: 'count_pt_year', type: 'int'},
{name: 'date_string', type: 'string'}
]
});
// get the graph data
var graphStore = Ext.create('Ext.data.Store', {
model: 'Graphs',
proxy: {
type: 'ajax',
url: 'sqlRequest.jsp?queryName=events_getGraph',
timeout: 160000,
reader: 'json'
},
autoLoad:false
});
If I change the query to return these null values as blanks instead ('') then the json reader converts them to zeros and the values display as zero along the bottom of the graph with a series line, which is worse then having the markers plastered to the ceiling without a series line.
I haven't been able to find any config option in Ext.chart.Series to hide null values on the graph. Nor have I been able to find a config option in Ext.data.Store to return blanks as blanks and not "0".
Looking for some other workaround.
Or has anyone resolved these issues from within the library itself (ext-all.js)?
There's a config option under Ext.data.Field called useNull. If the data received cannot be parsed into a number, null will be used instead. As of right now I can't recall if that alone will fix the problem, and I have a memory of once using a custom convert function that went something like this:
convert: function(value){
if(typeof value !=== 'number') // or other similar conversion
return undefined;
return value;
}
If this doesn't work, you may need to customize your store/reader to completely exclude records containing the undesirable null value.
EDIT - Using useNull looks like this: {name: 'someName', type: 'int', useNull: true}
I am having trouble figuring out what I need to do to load the columns for an ExtJS grid dynamically. I want to be able to send the column headers as JSON and have the grid take that and generate the columns needed.
More specifically, I am wanting to do this using the GroupingHeader plugin, but I really just want to figure out how to do it without the added complexity of the GroupingHeader plugin first and then I can tackle that problem :)
Here is some sample JSON data that I have for the column headers:
[
{
"run_id":"110207gad",
"iterations":[
"1_14",
"2_16",
"3_18",
"4_20",
"5_22"
]
},{
"run_id":"110207gae",
"iterations":[
"1_14",
"2_16",
"3_18",
"4_20",
"5_22"
]
}
]
This is the data that I would need to do the grouping, where the run_id would be the grouped header and the iterations would be the column headers. Right now, I'm happy just getting the iterations to show up as columns and then I can work on getting the grouping to work.
If anyone could point me in the right direction or give me some hints on where to begin, that would be extremely helpful! I'm not beyond figuring this out on my own, but I just need a little bump to get started because I can't seem to figure out from looking at the ExtJS examples and doing some Google searches.
I suggest you look at the source code of the ExtJS example.
http://dev.sencha.com/deploy/dev/examples/grid/array-grid.js
It should give you a fair amount of information to get started.
You can start from this format, pass it from your server:
{"success":true,"message":"Loaded data","data":[{"run_id":1,"iterations":"1"},{"run_id":2,"iterations":"2"},{"run_id":3,"iterations":"3"}]}
Then your reader will look like this:
var reader = new Ext.data.JsonReader({
totalProperty: 'total',
successProperty: 'success',
idProperty: 'run_id',
root: 'data',
messageProperty: 'message'
}, [
{name: 'run_id'},
{name: 'iterations', allowBlank: false}
]);