I try to use itemSelector in extjs4.2 but i don't know i can configure two store. The first multiselect panel is populate by a store, and the second had another too.
I need to save the variation in a DB because the stores that i use is ajax-proxy datastore.
This is my itemselector:
{
xtype: 'itemselector',
id:'itemselector',
name:'userRoles',
anchor:'100%',
store: dsRoles,
toStore: dsUserRoles,
valueField:'id',
displayField:'name',
/*here there is a problem*/
value: dsUserRoles,
msgTarget: 'side',
fromTitle : 'Available',
toTitle : 'Selected'
}
The value in the 'Selected field' is coming from a query and is not static like in the all the example i found.
EDIT: the toStore property doesn't work, and today this component make me crazy: when i load the window which contain a tabPanel which contain the itemselector for the secondTime this is what is render:
Whith Chrome i found this error Uncaught TypeError: Cannot read property 'internalId' of undefined
Any help is helpfull.
Problem has been resolved! I changed the source code!(ItemSelector.js)
here it is,
initComponent: function() {
var me = this;
me.ddGroup = me.id + '-dd';
me.callParent();
// bindStore must be called after the fromField has been created because
// it copies records from our configured Store into the fromField's Store
//me.bindStore(me.store); //don't need to bind
},
createList: function(title, store){ //add a parameter named store
...
store: store, //use the passed store
...
}
...
me.fromField = me.createList(me.fromTitle, me.store);
me.toField = me.createList(me.toTitle, me.toStore);
Related
I have a problem with dgrid.... I have an AccordionContainer, and in each ContentPane of it,
I place a dgrid. The problems with the dgrid are:
1- Error with scroll: when scrolling down, in certain moment the scroll "skips" and jumps into the end and there's no way to scroll up and show the first records.
(I have seen in Firebug the error TypeError: grid._rows is null when the scroll fails).
2- Trying to change a value: sounds like no dgrid-datachange event is emitted,
no way to capture the event after editing a value.
I think these errors has to do with having dgrid inside layouts (dgrid inside ContentPane, inside AccordionContainer). I also included the DijitRegistry extension but even with this extensions I can't get
rid of this errors.
I have prepared this fiddle which reproduces the errors:
https://jsfiddle.net/9ax3q9jw/5/
Code:
var grid = new (declare([OnDemandGrid, DijitRegistry,Selection, Selector, Editor]))({
collection: tsStore,
selectionMode: 'none',
columns:
[
{id: 'timestamp', label:'Timestamp', formatter: function (value,rowIndex) {
return value[0];
}},
{id: 'value', label: 'Value',
get: function(value){
return value[1];
},
editor: "dijit/form/TextBox"
}
],
showHeader: true
});
grid.startup();
grid.on('dgrid-datachange',function(event){
alert('Change!');
console.log('Change: ' + JSON.stringify(event));
});
//Add Grid and TextArea to AccordionContainer.
var cp = new ContentPane({
title: tsStore.name,
content: grid
},"accordionContainer");
Any help will be appreciated,
Thanks,
Angel.
There are a couple of issues with this example that may be causing you problems.
Data
The store used in the fiddle is being created with an array of arrays, but stores are intended to work with arrays of objects. This is the root of the scrolling issue you're seeing. One property in each object should uniquely identify that object (the 'id' field). Without entry IDs, the grid can't properly keep track of the entries in your data set. The data array can easily be converted to an object array with each entry having timestamp and value properties, and the store can use timestamp as its ID property (the property it uses to uniquely identify each record).
var records = [];
var data = _globalData[0].data;
var item;
for (var i = 0; i < data.length; i++) {
item = data[i];
records.push({
timestamp: item[0],
value: item[1]
});
}
var tsStore = new declare([Memory, Trackable])({
data: records,
idProperty: 'timestamp',
name: 'Temperature'
});
_t._createTimeSeriesGrids(tsStore);
Setting up the store this way also allows the grid column definitions to be simplified. Using field names instead of IDs will allow the grid to call formatter functions with the corresponding field value for each row object.
columns: [{
field: 'timestamp',
label: 'Timestamp',
formatter: function (value) {
return value;
}
}, {
field: 'value',
label: 'Value',
formatter: function (value) {
return value;
},
editor: "dijit/form/TextBox"
}],
Loading
The fiddle is using declarative widgets and Dojo's automatic parsing functionality to build the page. In this situation the loader callback does not wait for the parser to complete before executing, so the widgets may not have been instantiated when the callback runs.
There are two ways to handle this: dojo/ready or explicit use of the parser.
parseOnLoad: true,
deps: [
...
dojo/ready,
dojo/domReady!
],
callback: function (..., ready) {
ready(function () {
var _t = this;
var _globalData = [];
...
});
}
or
parseOnLoad: false,
deps: [
...
dojo/parser,
dojo/domReady!
],
callback: function (..., parser) {
parser.parse().then(function () {
var _t = this;
var _globalData = [];
...
});
}
Layout
When adding widgets to containers, use Dijit's methods, like addChild and set('content', ...). These typically perform actions other than just adding a widget to the DOM, like starting up child widgets.
var cp = new ContentPane({
title: tsStore.name,
content: grid
});
registry.byId('accordionContainer').addChild(cp);
instead of
var cp = new ContentPane({
title: tsStore.name,
content: grid
}, "accordionContainer");
In the example code a ContentPane isn't even needed since the dgrid inherits from DijitRegistry -- it can be added directly as a child of the AccordionContainer.
This will also call the grid's startup method, so the explicit call in the code isn't needed.
registry.byId('accordionContainer').addChild(grid);
It also often necessary to re-layout the grid's container once the grid has been initially rendered to ensure it's properly sized.
var handle = grid.on('dgrid-refresh-complete', function () {
registry.byId('accordionContainer').resize();
// only need to do this the first time
handle.remove();
});
I am extending extjs Container component and making a custom component but when i am adding an item using add function it's giving an error that the add function doesn't exist for my custom component. How can this happen since add function is available for Container and my component is extending that. Here's the code
var row = Ext.define('TableRow',{
extend: 'Ext.container.Container',
layout: {
type: 'table',
columns: 10
}
});
row.add(); // This line is giving error saying add function is not available for row
Ext.define() is for defining a class. Once the class has been defined, it can be instantiated by calling Ext.create('TableRow');
Ext.define('TableRow',{
extend: 'Ext.container.Container',
layout: {
type: 'table',
columns: 10
}
});
var row = Ext.create('TableRow');
row.add();
I am new to Sencha Touch so I am still struggling with the usage of stores.
I have created this store which I am successfully using to populate a list:
Ext.define('EventApp.store.events',{
extend: 'Ext.data.Store',
config: {
model: 'EventApp.model.event',
autoLoad: true,
storeId: 'events',
proxy:{
type:'ajax',
url: './resources/EventData.json',
reader: {
type: 'json',
rootProperty: 'events'
}
}
}
});
As I mentiones this store works correctly when referenced from a list and I can display the contents of it. Therefore I am assuming the store is correctly defined.
Unfortunately when I try to access the store from a controller for one of my views (which will be used to populate the items of a carousel) I don't seem to get any data back from the store. The code I am using is the following:
onEventCarouselInitialize : function(compon, eOptions) {
var past = compon.getPast();
var eventsStore = Ext.getStore('events');
eventsStore.each(function(record){
console.log('Record =',record); //<-- this never gets executed.
},this);
}
I have tried executing an eventsStore.load() on an eventsStore.sync() but I never seem to get any elements available in the store.
What am I missing?
Thanks
Oriol
What i have understand is, perhaps your store data has not been loaded when you are accessing it. So put you each() function on store inside this for delaying 500ms:
Ext.Function.defer(function(){
// Put each() here
}, 500);
Have a try by delaying more or less.
I have an itemselecor inside a grid, and i have an combobox that should reload only the store inside the itemselector( the value fields should remain intact)
Here is the itemselector
var grid = Ext.widget('form', {
id: 'grid',
title: '',
width: 600,
bodyPadding: 10,
renderTo: 'itemselectorproduto',
items: [{
xtype: 'itemselector',
name: 'itemselector',
id: 'itemsel',
anchor: '100%',
imagePath: '/ux/images/',
store: store,
displayField: 'Nome',
valueField: 'ID',
value: vitrine,
allowBlank: true,
msgTarget: 'side'
}]
});
I tried to call the normal store.load(), but it have no effect and it shows no error on the console
If needed i will post more of the code, but i think just this should be enough
Thanks,
Looking through the code if ItemSelector it doesn't look like it supports any changes in the store once it's been binded. It basically creates local copies of the data. And if you call bindStore method to assign different store - it will erase your selection.
You can always improve code in ItemSelector to allow such behavior. It should not be a problem. You can subscribe to datachanged or load event of the store when binding to it, and then handle situation when store data is changed.
Actually i think the best way to do such thing is using ItemSelector`s "populateFromStore". Sure except of extending item selector. In case of extending you should look on the "onBindStore" function of the ItemSelector.
onBindStore: function(store, initial) {
var me = this;
if (me.fromField) {
me.fromField.store.removeAll()
me.toField.store.removeAll();
// Add everything to the from field as soon as the Store is loaded
if (store.getCount()) {
me.populateFromStore(store);
} else {
me.store.on('load', me.populateFromStore, me);
}
}
}
So as you see in case of the empty store it hooks to the load event. And it should be like this:
onBindStore: function(store, initial) {
var me = this;
if (me.fromField) {
me.fromField.store.removeAll()
me.toField.store.removeAll();
me.store.on('load', me.populateFromStore, me);
// Add everything to the from field as soon as the Store is loaded
if (store.getCount()) {
me.populateFromStore(store);
}
}
}
I have a simple test app where I have a carousel that will instantiate multiple of the same type of grid, each grid having it's own copy of a store.
Carousel:
Ext.define('App.view.TopPageCarousel', {
extend: 'Ext.Carousel',
xtype : 'app-toppagecarousel',
requires: ['Ext.Carousel', 'App.view.TopPageGrid'],
config: {
title: 'Top Pages',
items: [{
xtype : 'app-toppagegrid',
title : 'titleA'
},{
xtype : 'app-toppagegrid',
title : 'titleB'
}]
}
});
At first I was defining the store in the grid as a property in its config and I have the controller listening for store changes, just to let me know it was being loaded. The ajax call is made and the grid was populated. However, All grid's were populated with the same data even though unique data was being returned with each call.
Then I found a post that said I needed to instantiate the stores as the grid is being populated, like so:
constructor : function() {
var me = this;
Ext.apply(me, {
store : me.buildStore()
});
me.callParent(arguments);
me.store.load({params : {ufq : this.title}});
},
buildStore : function() {
return Ext.create('App.store.Links');
}
This sort of works. The ajax call is being made, but the grid isn't being populated now and I am not seeing the console.log("Store loaded"); being executed that I placed in the controller. What am I doing wrong?
It turns out in ST2 instead of using Ext.create, the best thing to do is (in my particular instance, not as a standard):
constructor : function() {
this.callParent(arguments);
Ext.setStore('App.store.Links');
},
Using Ext.getStore & Ext.setStore are necessary now if you want a lot of the benefits that go along with events & the store manager.