I am using the MVC architecture (i have gone through the docs on MVC, but i am still lost here) and i need to know how to populate the records on to my Label. I know that i have to get this done by Stores.
I have loaded the values from the store, but unable to display it on my Panel for some reason. here's my code;
Most of the examples/books demonstrates how to display in a grid, but not a label (I know it has to be the same logic, but i am lost). And it shows how to write to a DB/JSON file and not display the values.
I need to display the COUNTRYNAME in the Label text. This is an example code that i am doing to understand this, can some one help me ?
Ext.define ('ProjectDisplayExample.model.Country',{
extend: 'Ext.data.Model',
//
fields:['countryid','countryname']
//
});
STORE
Ext.define('ProjectDisplayExample.store.Country',{
extend:'Ext.data.Store',
model:'ProjectDisplayExample.model.Country',
remoteGroup:true,
proxy: {
actionMethods : {
read : 'POST',
},
type: 'ajax',
url : '/server/country.php'
}
});
VIEW
Ext.define('ProjectDisplayExample.view.CountryWindow', {
extend: 'Ext.window.Window',
alias: 'widget.countrywindow',
...........
initComponent: function() {
var st = Ext.getStore('Country');
st.load();
this.items = [
{
items: [
{
xtype: 'panel',
region: 'north',
items: [{
xtype: 'label',
// NEED TO DISPLAY COUNTRT NAME FROM THE STORE HERE
}]
}]
}
UPDATE
var store = ... // Your store
store.on('load', function() {
// here store is loaded and you can do anything you want with it
console.log('store is loaded. number of records = ', store.getCount());
}, this, { single: true });
store.load; // I ADDED THIS LINE.................... <---------
UPDATE 2
this.items = [
{
items: [
{
xtype: 'panel',
region: 'north',
items: [{
xtype: 'label',
name : f
}]
}]
I will not post a code sample to exactly solve your question, but I will give you couple points:
Store contains array or records. So you can't just say give me country name from the store. You need first to get a record, for example: var r = store.getAt(0), and only after that you can get countyname field var f = r.get('countryname').
Load() method is asynchronous, so you can just execute it somewhere in the code and assume that for the very next line your store is ready. You need to subscribe to the load event, something like:
var store = ... // Your store
store.on('load', function() {
// here store is loaded and you can do anything you want with it
console.log('store is loaded. number of records = ', store.getCount());
}, this, { single: true });
store.load();
Labels as in xtype: label are actually very rarely used in ExtJs. What exactly are you trying to display in that panel? But anyhow... after you get data out of the store you can use something like update() or setValue() or any other method to update component.
Hope this helps...
Related
I want to create checkbox group from store populated from an array.
Here is my store.
var checklistStore = new Ext.data.Store({
data: arraySubT,
fields: ['id', 'boxLabel']
});
and currently my checkbox group in only getting displayed from an array and not store.
xtype: 'checkboxgroup',
fieldLabel: 'Checklist',
columns: 1,
vertical: true,
listeners: {
change: function(field, newValue, oldValue, eOpts){
}
},
items: checkboxconfigs
However I want to make it displayed from store.How can I achieve this?
[EDIT]
For your and my convenience, I made a general component which you can use. It may need some tuning regarding the store events that it reacts to. Find it in this fiddle.
[/EDIT]
You have to do it manually:
renderCheckboxes:function() {
checkboxgroup.removeAll();
checkboxgroup.add(
checklistStore.getRange().map(function(storeItem) {
return {
// map the storeItem to a valid checkbox config
}
})
);
}
and repeat that over and over and over again when the store data changes. That is, you have to attach to the store events:
checklistStore.on({
load:renderCheckboxes,
update:renderCheckboxes,
datachanged:renderCheckboxes,
filterchange:renderCheckboxes,
...
})
Maybe you will overlook some events you have to attach to, but sooner or later you will have all edge cases covered.
Here is working fiddle for you.
Just loop through store data with Ext.data.Store.each() method and setup your checkbox group items.
var _checboxGroupUpdated = function() {
// Use whatever selector you want
var myCheckboxGroup = Ext.ComponentQuery.query('panel checkboxgroup')[0];
myCheckboxGroup.removeAll();
myStore.each(function(record) {
myCheckboxGroup.add({
boxLabel: record.get('fieldLabel'),
inputValue: record.get('value'),
name: 'myGroup'
});
});
}
// Add all listeners you need here
myStore.on({
load: _checboxGroupUpdated,
update: _checboxGroupUpdated,
datachanged: _checboxGroupUpdated
// etc
});
EDIT
It turns out that a store cannot have duplicate IDs. When i remove this field, All records display - which means the grid is not respecting the pageSize
I'm having an issue getting all my store records to display in my grid. The data is returning appropriately from a JSON request, and the pagingtoolbar behaves correctly.
Here's my store:
var store = Ext.create('Ext.data.Store', {
storeId : 'resultsetstore',
autoLoad : false,
model : model,
pageSize : itemsPerPage, // 3
proxy: {
type : 'ajaxwithpayload', //custom ajax proxy to read 'jsonData'
url : 'MCApp',
jsonData: searchquery,
reader: {
type : 'json',
root : 'elements'
}
}
});
I load the store here, and all the correct results are returned:
store.load({
params: { start: 0, limit: itemsPerPage },
callback : function(records, operation, success) {
if(success) {
mainresponse = operation.response.responseText;
if( mainresponse.length == 0 ){
alert('No results returned');
return;
}
var jsonResponse = Ext.JSON.decode(mainresponse);
}
else {
alert('Search Failed: Could not reach the server');
}
And lastly, a simple grid with pagingtoolbar:
var grid = Ext.create('Ext.grid.Panel', {
title: 'Test Data',
store: store,
columns: [{
text: 'Technical Name',
dataIndex: 'tech'
}, {
text: 'ID',
dataIndex: 'element.id'
}, {
text: 'Name',
dataIndex: 'name',
mapping: 'element.name'
}, {
text: 'View',
dataIndex: 'view'
}, {
text: 'Description',
dataIndex: 'description'
}],
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
pageSize: itemsPerPage,
dock: 'bottom',
displayInfo: true
}],
renderTo: Ext.getBody()
});
The problem here is that not all of my results load into the grid. It seems that when a duplicate ID is encountered, it cuts the results short. That may not be the problem, just my guess
In my logs I see all the data I need returned. In the picture below, I should have 3 rows with the same Element ID 001, however only one is displayed:
Another thing to note is that when I click the Next Button on my pagingtoolbar, the results do not change, and it also reads as a POST on my console. I'm not sure if it's supposed to do that or be a GET?
I used lightning bolts to show how shocking it is that this isn't working
Any ideas?
A very important thing to note is that the server is responsible for paging not ExtJS. The server must not return all rows, but only the rows of the current page. You server side code must take in account the parameters page, start and limit for getting the client side to work.
I think that, beside the duplicated ids, is the main reason for your problems. It is especially the reason, why you see the same data on page one and on page two:
ExtJs asks the server for the data of page 1 and gets all rows. Later, ExtJs asks the server for the data of page 2 and gets again the same rows. This cannot work.
This might be the case when you are giving name property as "id" in the fields array of your Model. try to change that.
So I'm trying to put items dynamically to the panel that has slidenavigation feature:
// FlyoutNavigation.js
Ext.define("APN.view.FlyoutNavigation", {
id: "flyoutNavigationPanel",
extend: 'Ext.ux.slidenavigation.View',
Here is the initialisation of the view in another view:
// MainViewContainer.js
this.home = "Some var"
this.flyout = Ext.create('APN.view.FlyoutNavigation', {
id: 'flyoutNavigationPanel',
home: this.home
});
Than I'm trying to use this variable in the this.config.items section, however that doesn't work, it seems that Sencha compiles everything first and than initialiases the components, I might be wrong, I'm really new to Sencha Framework.
So here is the view where the home variable is used:
Ext.define("APN.view.FlyoutNavigation", {
id: "flyoutNavigationPanel",
extend: 'Ext.ux.slidenavigation.View',
xtype: 'flyoutnavigation',
requires: [
... heaps of things omitted ...
],
initialize: function () {
this.callParent();
this.setupDynamicItems();
},
config: {
items: [
{
itemId: 'nav_home',
id: 'homeView',
items: [{
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: this.home, // - that's the place where UNDEFINED occurs
flex: 1
}
],
},
So this.home is undefined...
One possible solution
Comming from this question: How to dynamically create xtype templates in Sencha Touch
I decided to put all the code in this.config.items.add({ ... my items ... }) however Ext.ux.slidenavigation.View looks like gave me the BUG! :( as the initialise method occurs after the binding methods on items of FlyoutNavigation view.
Here is the message from of the bug: Uncaught TypeError: Cannot read property 'raw' of undefined View.js:310 which is basically this line: if (Ext.isFunction(item.raw.handler)) {
So my questions would be
How to get the instance variable in the config.items section? If that's possible, than all is OK
Or do you know the work around of this issue?
Thanks
I don't think you can use this.config when defining the class, instead you can use initialize function as I told you earlier. So you should be able to do this:
initialize : function() {
var me = this;
var home = me.config.home;
me.add({
itemId: 'nav_home',
id: 'homeView',
items: [{
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: home,
flex: 1
}
],
});
}
OR if you have defined homeView in parent class, you can do this:
initialize : function() {
var me = this;
var home = me.config.home;
me.down('#homeView').add({
xtype: 'articlelist',
id: 'latestNews',
feedUrlName: home,
flex: 1
});
}
I have recently develop a sencha app about displaying categories/sub categories. It displayed the main categories, but does not display the sub categories on clicking any category.
My store is--
Ext.define('listdemo.store.Sections', {
extend : 'Ext.data.Store',
config : {
autoLoad: true,
model: 'listdemo.model.Sections',
proxy:{
type : 'ajax',
url:'http://localhost/catt.php',
reader:{
type:'json',
rootProperty:'categories'
}
}
}
});
Model code is------
Ext.define('listdemo.model.Sections', {
extend: 'Ext.data.Model',
config: {
fields: ['categories_id', 'categories_name','subcategories'],
}
});
And the view is----
Ext.define('listdemo.view.Main',{
extend: 'Ext.NestedList',
xtype:'main',
requires: [
'Ext.TitleBar',
'Ext.dataview.List',
'Ext.data.Store',
'Ext.dataview.NestedList'
],
config:{
title: 'Categories',
//store:'Sections',
items:[
{
xtype:'list',
itemTpl:'{categories_name}',
title:'Categories',
store:'Sections',
}
]
}
});
My php file returns----
{"categories":[{"categories_id":"1","categories_name":"Hardware","subcategories":[{"categories_id":"4","categories_name":"Graphics
Cards"},{"categories_id":"5","categories_name":"Printers"},{"categories_id":"6","categories_name":"Monitors"},{"categories_id":"7","categories_name":"Speakers"},{"categories_id":"8","categories_name":"Keyboards"},{"categories_id":"9","categories_name":"Mice"},{"categories_id":"16","categories_name":"Memory"},{"categories_id":"17","categories_name":"CDROM
Drives"}]},{"categories_id":"2","categories_name":"Software","subcategories":[{"categories_id":"18","categories_name":"Simulation"},{"categories_id":"19","categories_name":"Action"},{"categories_id":"20","categories_name":"Strategy"}]},{"categories_id":"3","categories_name":"DVD
Movies","subcategories":[{"categories_id":"10","categories_name":"Action"},{"categories_id":"11","categories_name":"Science
Fiction"},{"categories_id":"12","categories_name":"Comedy"},{"categories_id":"13","categories_name":"Cartoons"},{"categories_id":"14","categories_name":"Thriller"},{"categories_id":"15","categories_name":"Drama"}]}]}
What will I do to display the sub categories under main categories.
You need to update your model definition to include field types, and register a custom data type to use for subcategories.
Start by including this before the models load:
Ext.data.Types.ARRAY = {
type: 'Array'
};
Next update your model to look like this:
Ext.define('listdemo.model.Sections', {
extend: 'Ext.data.Model',
config: {
fields: [{
name: 'categories_id',
type: 'int'
},{
name: 'categories_name',
type: 'string'
},{
name: 'subcategories'
type: Ext.data.Types.ARRAY
}]
}
});
Now once your store loads, check the records manually via the web console to ensure the array of subcategories is saved. You will need to add a listener for itemtap on the list, and then grab the subcategories and either:
-Reload the original store manually with the subcategories array. This should refresh the list, but you will lose the original store and there won't be any card animation.
-Set up a second list/store that will be reloaded manually with the subcategories, which will allow for the change card animation and maintain the original store for back navigation.
give your store the Store Id
2.pass the parameter categories_name and select the subcategory whose parent directory is categories_name
success: function (response)
{
searchresponse2 = Ext.JSON.decode(response.responseText);// getting response from server
//searchresponse2 is array storing 1st result in array index[0]
searchresponse2=searchresponse2[0];
var categoriesid=searchresponse2.categories;//getting 1st
values"categories_id":"1","categories_name":"Hardware"
var categoriesname=searchresponse2.categories_name;
del_categoriesid=[];//declaring array
del_categoriesname=[];
for(var i= 0;i<searchresponse2.length;i++)
{
del_categoriesid[i]=searchresponse2[i].categories;
del_categoriesname[i]=searchresponse2[i].categories_name;
}// looping through all values
for(var j= 0;j < searchresponse2.length;j++)
{
Ext.getStore('storeid').add({categories:del_categoriesid[j], categories_name:del_categoriesname[j]});
}// adding the values of the result in store
I have a list:
{
xtype: 'list',
itemTpl: '{name}',
sorters: 'name',
getGroupString: function(record)
{
return record.get('name')
},
indexBar:true,
grouped: true,
store: {
fields: ['name', 'url'],
data: centres
},
itemConfig: {
tpl: '{url}'
},
listeners: {
itemtap:function(data,index){
var record = data.getStore().getAt(index);
redirect_url = record.raw.url
// the record that has been clicked.
window.location = redirect_url
}
}
}
I want to group the list by name. But results are not being grouped.
the sorters (takes an array of Strings), getGroupString are part of the store. The store also needs a model to back it.
I'm not sure what you're trying to do with both itemTpl and itemConfig displaying two different things, if you want to show the name property in the list then you just need the itemTpl.
See the KitchenSink List example:
http://docs.sencha.com/touch/2-0/#!/example/kitchensink/index.html
User Interface --> List and hit the Source button on the upper right hand corner.