I am new to ExtJS and I find documentation confusing, I need to get the first data from store, which I get from the report. How to do it correctly?
this.divisionList = new ....SimplestReportCombo({
fieldLabel: "Division",
allowBlank: false,
valueField: 'KEY',
displayField: store.load.get(0),
width: 200,
reportID: 'USER_ACCESS',
store : new Ext.data.ArrayStore({
fields: [{name: 'KEY'}],
data: [{name: 'VALUE'}]
}
)
});
Javascript Stores mostly resembles RDBMS tables. They have in memomy storage and they are helpful to perform various grid level operation like sorting , paging , shuffling , editing etc.
Lets come to your code now,
You dont need to load store get its elements.If you requirement is only to select 1st ellement from store then you can do that using getAt function like below:
this.divisionList = new ....SimplestReportCombo({
fieldLabel: "Division",
allowBlank: false,
valueField: 'KEY',
displayField: store.getAt(0),
width: 200,
reportID: 'USER_ACCESS',
store : new Ext.data.ArrayStore({
fields: [{name: 'KEY'}],
data: [{name: 'VALUE'}]
}
)
});
or else you can also use following store method if you want to render mere 1st element:
store.first()
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
Oof that was a long title.
In my current project I have a grid that holds a set of workshop records. For each of these workshops there is a set of rates that apply specifically to the given workshop.
My goal is to display a combobox for each row that shows the rates specific to that work shop.
I've got a prototype that works for the most part up on sencha fiddle, but there's something off about how the selection values are being created:
Ext.define('Rates',{
extend: 'Ext.data.Store',
storeId: 'rates',
fields: [
'rateArray'
],
data:[
{
workshop: 'test workshop 1',
rateArray: {
rate1: {show: "yes", rate: "105", description: "Standard Registration"},
rate3: {show: "Yes", rate: "125", description: "Non-Member Rate"},
rate4: {show: "yes", rate: "44", description: "Price for SK tester"}
}
},
{
workshop: 'test workshop 2',
rateArray: {
rate1: {show: "yes", rate: "10", description: "Standard Registration"},
rate2: {show: "yes", rate: "25", description: "Non-Member Registration"}
}
}
]
});
Ext.define('MyGrid',{
extend: 'Ext.grid.Panel',
title: 'test combo box with unique values per row',
renderTo: Ext.getBody(),
columns:[
{
xtype: 'gridcolumn',
text: 'Name',
dataIndex: 'workshop',
flex: 1
},
{
xtype: 'widgetcolumn',
text: 'Price',
width: 200,
widget:{
xtype: 'combo',
store: [
// ['test','worked']
]
},
onWidgetAttach: function (column, widget, record){
var selections = [];
Ext.Object.each(record.get('rateArray'), function (rate, value, obj){
var desc = Ext.String.format("${0}: {1}", value.rate, value.description);
// according to the docs section on combobox stores that use 2 dimensional arrays
// I would think pushing it this way would make the display value of the combobox
// the description and the value stored the rate.
selections.push([rate, desc]);
});
console.log(selections);
widget.getStore().add(selections);
}
}
]
});
Ext.application({
name : 'Fiddle',
launch : function() {
var store = Ext.create('Rates');
Ext.create('MyGrid',{store: store});
}
});
In the grid widget that I'm using for the combobox I'm using the onWidgetAttach method to inspect the current row's record, assemble the rate data from the record into 2 dimensional array, and then setting that to the widget's store.
When I look at the sencha docs section on using a 2 dimensional array as the store, it states:
For a multi-dimensional array, the value in index 0 of each item will be assumed to be the combo valueField, while the value at index 1 is assumed to be the combo displayField.
Given that, I would expect the combo box to show the assembled description (e.g.
"$150: Standard Registration") and use the object key as the actual stored value (e.g. "rate1").
What I'm actually seeing is that the display value is the rate and I'm not sure how sencha generates the combobox selections to see how the selection is being rendered out.
Is my assumption about how the 2-dimensionally array gets converted to the store wrong?
Well, your question is suffering from the XY problem. Because what you really want to do is the following:
You want to create a decent store for your combo, using a well-defined model with the meaningful column names you already have in "rateArray", then you define displayField and valueField accordingly, and in onWidgetAttach, just stuff the "rateArray" object into that store using setData.
Sth. along the lines of
xtype: 'widgetcolumn',
text: 'Price',
width: 200,
widget:{
xtype: 'combo',
store: Ext.create('Ext.data.Store',{
fields:['rate','description','show']
filters:[{property:'show',value:"yes"}]
}),
displayField:'description',
valueField:'rate',
onWidgetAttach: function (column, widget, record){
widget.getStore().setData(record.get("rateArray"));
}
},
I am trying to populate a combobox with a list of Project names. I am able to successfully get all Project names, but I cannot seem to figure out how to add them as a custom set of data to a combobox. I have looked into using the other types of comboboxes (Iteration, Portfolio, Attribute, etc), but they don't seem to have the capabilities to add custom data to their drop down list (unless I am mistaken). Here is the code that I am using for my combo box:
this.down = this.add({
xtype: 'rallycombobox',
storeConfig: [{
model: 'Project',
autoLoad: true,
fieldLabel: 'Projects:',
data: this.project_names,
width: field_width
}]
});
When trying to run with this code, I get a "Uncaught TypeError: Cannot call method 'getProxy' of undefined. I cannot figure out how to get it to work. I have also tried it with the following:
this.down = this.add({
xtype: 'rallycombobox',
model: 'Project',
fieldLabel: 'Projects:',
data: this.project_names,
width: field_width
});
I still end up with the same error. Can anyone help me with what I am doing wrong? Thanks!
If you already have a list of Projects in hand that you'd like to use in a ComboBox, instead of a Rally ComboBox I'd recommend just using the Ext ComboBox. The Rally ComboBox is designed to populate its store by querying the data from rally - thus the getProxyerror you are seeing when trying to mix and match the Rally WSAPI store with local data.
The setup might look something like the following.
// The data store containing the list of Projects
var projectStore = Ext.create('Ext.data.Store', {
fields: ['_ref', 'Name'],
data : [
{"_ref": "/project/12345678910", "Name": "Project 1"},
{"_ref": "/project/12345678911", "Name": "Project 2"},
{"_ref": "/project/12345678912", "Name": "Project 3"}
//...
]
});
// Create the combo box, attached to the Projects data store
this.projectSelector = Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose Project',
store: projectStore,
queryMode: 'local',
displayField: 'Name',
valueField: '_ref',
listeners:{
scope: this,
select: function(combobox) {
// Do stuff here
console.log('Ref of Project Selected: ' + this.projectSelector.getValue());
}
}
});
this.down('#projectSelectorContainer').add(this.projectSelector);
Hopefully this is helpful. Let us know if there's follow-on questions.
This might help you:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
//Write app code here
var projectStore = Ext.create('Rally.data.WsapiDataStore',{
model: 'project',
fetch: ['Name','ObjectID'],
autoLoad: true,
// filters:[{
// property:'ObjectID',
// operator:'=',
// value: __PROJECT_OID__
// }],
listeners:{
load: function(store,records,success){
this._updateCombo(store);
},
scope: this
}
});
console.log('/project/',__PROJECT_OID__);
},
_loadCombo: function(myStore){
this._myCombo = Ext.create('Ext.form.ComboBox',{
fieldLabel: 'Choose Project',
store: myStore,
queryMode: 'remote',
displayField: 'Name',
valueField: 'Name',
listeners: {
select: function(combobox,records){
console.log(records[0]["data"]["Name"]);
}
},
scope:this
});
this.add(this._myCombo);
},
_updateCombo: function(myStore){
if(this._myCombo === undefined){
this._loadCombo(myStore);
}else{
this._myCombo.clearValue();
}
}
});
I try to use ComboBox on FormPanel, it is defined like this:
{
xtype: 'combo',
name: 'Reasons',
store: new Ext.data.ArrayStore({
id: 0,
fields: ['myId', 'displayText'],
data: [
[1, 'Reason 1'],
[2, 'Second Reason'],
[3, 'Something else']
]
}),
typeAhead: false,
mode: 'local',
valueField: 'myId',
displayField: 'displayText',
allowBlank: false,
editable: false,
forceSelection: true
}
I would like to act like a ordinary select element, when I have editable as false I not able to re-select anymore, when as true ( default ) I need to remove selection ( by backspace or delete ) in order to re-select.
What else I should turn off in order to downgrade combobox to select or shpuld I consider to use other component instead ?
My concern is if I really need ordinary select (not quite ordinary - ability to have store and manipulate options is very cool) - combo seems to me next level element what got too many features which I need to turn off and combo is rendered as input with arrow down image what trigger all action.
My question is:
Is it ExtJS element what is using HTML select tag, acting as select, rendering as select ?
The trick is to use triggerAction: 'all' - it forces the combo dropdown to show all items when you click the down-arrow icon (trigger).
That's probably the most counter-intuitive config option of ExtJS. And it's impossible to figure out what it really does by reading the docs. And like you say, to get a simple combo, you have to specify a myriad of config options, just to turn the fancy stuff off.
The ExtJS guys have promised to fix this in ExtJS 4, but until then I suggest you create your own ComboBox class that's configured the way most often needed in your app. For example I have something like this in my current project:
/**
* Simple combo, that just allows to choose from a list of values.
*/
var StaticComboBox = Ext.extend(Ext.form.ComboBox, {
mode: 'local',
triggerAction: 'all',
editable: false,
valueField: 'value',
displayField: 'label',
/**
* #cfg {[[String]]} data
* Items in combobox as array of value-label pairs.
*/
data: [],
initComponent: function() {
this.store = new Ext.data.ArrayStore({
fields: ['value', 'label'],
data: this.data
});
StaticComboBox.superclass.initComponent.call(this);
}
});
Having that, I can create a simple combo with just a few lines:
new StaticComboBox({
name: 'Reasons',
data: [
[1, 'Reason 1'],
[2, 'Second Reason'],
[3, 'Something else']
]
});
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.