I'm building an app and i've got a list loaded with some info from store, it has a lot of items in it but when I try to scroll down it scrolls back up as if there were not enough items to scroll. Here is some code:
app.views.SearchTab = Ext.extend(Ext.Panel, {
iconCls: 'search',
id: 'search',
items: {
xtype: 'list',
store: app.stores.results,
scroll: 'vertical',
itemTpl: '<div class="list_left_panel"><div class="list_photo_wrapper"><div class="list_photo"><img src="http://realio.cz/images/{link}_0s.jpg" /></div></div></div><div class="list_right_panel"><div class="list_name">{titul}</div><div class="list_info"><div>{cena} Kč</div><div class="list_info_grey">{m2} m<sup>2</sup></div><div>{typ}</div></div></div>',
onItemDisclosure: function (record) {
Ext.dispatch({
controller: app.controllers.detail,
action: 'show',
id: record.getId()
});
}
},
initComponent: function() {
app.stores.results.load();
app.views.SearchTab.superclass.initComponent.apply(this, arguments);
}
});
app.models.Results = Ext.regModel("app.models.Results", {
fields: [
{name: "titul", type: "string"},
{name: "book_id", type: "int"},
...
{name: "u", type: "int"}
]
});
app.stores.results = new Ext.data.Store({
model: "app.models.Results",
proxy: {
type: 'ajax',
url: 'http://site.com/json_list2.php?...',
reader: {
type: 'json',
root: 'markers'
}
},
autoLoad: false
});
How can i fix the list so that it scrolls correctly? Thanks.
add this library this will help you: https://github.com/Lioarlan/UxBufList-Sench-Touch-Extension
Related
I'd like to be able to add class in the Itemtpl where the Item has it's field "Answered" set to "true"
It sound's easy to me, but I don't know where to start..
I know I have to check if Answered is true in the tpl, but I don't know how to write in the template.. o.O
//model
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
idProperty: 'Name',
fields: [
{name: 'Name', type: 'string'},
{name: 'Address', type: 'string'},
{name: 'ID', type: 'int'},
{name: 'WebUrl', type: 'string'},
{name: 'InfoUrl', type: 'string'},
{name: 'Answered', type: 'boolean'},
]
}
});
//store
aStore = Ext.create('Ext.data.Store', {
model: 'User',
sorters: 'Name',
grouper: {
groupFn: function(record) {
return record.get('Name')[0];
}
}
});
//full store
store = Ext.create('Ext.data.Store', {
model: 'User',
sorters: 'Name',
grouper: {
groupFn: function(record) {
return record.get('Name')[0];
}
},
proxy: {
type: 'ajax',
url: '/Services/RestaurantList.ashx',
reader: {
type: 'json',
rootProperty: 'users'
}
},
listeners:{
load: function(){
var all = store.data.all;
aStore.setData(all.slice(0,30));
}
},
autoLoad: true
});
//the list
list = Ext.create('Ext.List', {
flex: 8,
itemTpl: ['<div class="contact">{Name}</div>'],
store: aStore,
listeners: {
itemtap: function(list, index, target, record) {
mainContainer.setActiveItem(1);
detailsPanel.setRecord(record);
},
plugins: [
{
xclass: 'Ext.plugin.PullRefreshFn',
refreshFn: function(){
store.clearData();
aStore.clearData();
store.clearFilter();
aStore.clearFilter();
store.load();
list.refresh();
}
}
],
grouped: true
});
Have you looked at the docs for XTemplate? http://docs.sencha.com/touch/2.2.1/#!/api/Ext.XTemplate. In particular, look at the "Conditional processing with basic comparison operators" section.
If you don't want to use the <tpl if=""> notation, you can also use the ternary operator:
itemTpl: new Ext.XTemplate(
'<div class="{[values.Answered ? \'answered\' : \'\']}">{Name}</div>'
),
...
First off: There are a bunch of questions about this exact thing all over the place. I have spent the better part of a day reading through them all and clearly I am still failing to understand this.
I am getting my store data from a httprequest (rather than standard ajax call) and this is working and adding my data to the store. But whatever I try, this data will not populate the list. Currently my code looks like:
Model:
Ext.define('estarCamera.model.Event', {
extend: 'Ext.data.Model',
config: {
fields: [
'Id',
'Title',
'Content',
'Image',
'Location',
'Latitude',
'Longitude',
'Radius',
'Starts',
'Expires',
'Prestart'
]
}
});
Store:
Ext.define('estarCamera.store.Events', {
extend: 'Ext.data.Store',
config: {
model: 'estarCamera.model.Event',
storeId: 'EventStore'
}
});
Data is populating the store:
var jsonResponse = JSON.parse(xhr.responseText);
if(jsonResponse.status == "Success"){
//Success
var eventsJsn = JSON.parse(jsonResponse.message);
$.each(eventsJsn, function(){
$.each(this, function(k,v){
//Events root element
$.each(this, function(k,v){
//Each 'Event' element
var eStore = Ext.getStore('EventStore');
eStore.add({
Id: this.ID,
Title: decodeURIComponent(this.Title),
Content: decodeURIComponent(this.Content),
Image: this.Image,
Location: this.Location,
Latitude: this.Latitude,
Longitude: this.Longitude,
Radius: this.Radius,
Starts: this.Starts,
Expires: this.Expires,
Prestart: this.Prestart
});
eStore.sync();
})
});
});
Ideally this will then populate:
Ext.define('estarCamera.view.Events', {
extend: 'Ext.Panel',
xtype: 'events',
requires: [
'estarCamera.store.Events',
'Ext.form.FieldSet',
'Ext.List'
],
config: {
title:'Events',
iconCls: 'star',
layout: 'vbox',
items:[
{
docked: 'top',
xtype: 'toolbar',
title: 'Active Events'
},
{
xtype: 'container',
layout: 'fit',
flex: 10,
items:[{
xtype:'list',
title: 'Events',
width: '100%',
height: '100%',
store: 'Events',
styleHtmlContent: true,
itemTpl: new Ext.XTemplate(
'<div class="outerEvent">',
'<h1>title{Title}</h1>',
'<p>{Content}</p>',
'</div>'
)
}]
}]
}
});
Does anyone know why this is happening?
OK, feeling a bit fooling now .. eventually (after an embarrassingly long time) found that this was because my list was trying to reference 'Events' which is the name of my store and how I thought it was supposed to work. Changed this to 'EventStore' (the storeid of my store) and it worked perfectly.
I would dynamically change the title of my list titlebar. This is my app.js where you can view my app (see var list where there is the toolbar item and title that I would change)
How can I do this?
Thanks.
var mainForm ;
var mainFormPanel={};
var myStore = Ext.create('Ext.data.Store', {
storeId: 'MyStore',
fields: ['txt']
}); // create()
var list= Ext.create('Ext.List', {
fullscreen: true,
store: 'MyStore',
itemTpl: '{txt}',
items: [{
xtype: 'titlebar',
docked: 'top',
title:'change dinamically this title!!!!'
}] // items (list)
}); // create()
Ext.application({
glossOnIcon: false,
autoMaximize: false,
icon: {
57: 'lib/sencha-touch/resources/icons/icon.png',
72: 'lib/sencha-touch/resources/icons/icon#72.png',
114: 'lib/sencha-touch/resources/icons/icon#2x.png',
144: 'lib/sencha-touch/resources/icons/icon#114.png'
},
phoneStartupScreen: 'lib/sencha-touch/resources/loading/Homescreen.jpg',
tabletStartupScreen: 'lib/sencha-touch/resources/loading/Homescreen~ipad.jpg',
requires: [
'Ext.tab.Panel',
'Ext.form.*',
'Ext.field.*',
'Ext.Button',
'Ext.data.Store'
],
launch: function() {
mainForm = Ext.create('Ext.form.Panel', {
xtype:'formpanel',
items: [
{
xtype: 'textfield',
name : 'distance',
label: 'Distance'
},
{
xtype: 'textfield',
name : 'quantity',
label: 'Quantity'
}
]
});
mainFormPanel={
xtype: 'toolbar',
docked: 'bottom',
layout: {
pack: 'center'
},
items: [
{
xtype: 'button',
text: 'Set Data',
handler: function() {
mainForm.setValues({
distance: '300',
quantity: '25'
})
}
},
{
xtype: 'button',
text: 'Get Data',
handler: function() {
Ext.Msg.alert('Form Values', JSON.stringify(mainForm.getValues(), null, 2));
}
},
{
xtype: 'button',
text: 'Clear Data',
handler: function() {
mainForm.reset();
}
}
]
};
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
{
//each item in a tabpanel requires the title configuration. this is displayed
//on the tab for this item
title: '1-tab',
layout:'fit',
//next we give it some simple html
items: [mainForm,mainFormPanel],
//then a custom cls so we can style it
cls: 'card1'
},
{
//title
title: '2-tab',
layout:'fit',
items: [list],
cls: 'card2'
},
{
//title
title: '3-tabs',
//the items html
items: {
html: 'mia auto',
centered: true
},
//custom cls
cls: 'card3'
}
]
});
}
});
Ext.List component's superclass is Ext.DataView., not Ext.Panel.
Hence, it is not possible to directly add / dock any item inside the Ext.List component.
So, I recommend you to wrap your Ext.List component inside Ext.Panel.
Do it like this,
var myStore = Ext.create('Ext.data.Store', {
storeId: 'MyStore',
fields: ['txt']
}); // create()
var listpanel = new Ext.Panel({
layout: 'fit', // important to make layout as 'fit'
items: [
{
xtype: 'titlebar',
id: 'myTitle',
docked: 'top',
title: 'Before Change title',
items: [
{
xtype:'button',
text:'Change Title',
align:'right',
listeners : {
tap : function() {
Ext.getCmp('myTitle').setTitle('After Title Change');
}
}
}
]
},
{
//Definition of the list
xtype: 'list',
itemTpl: '{txt}',
store: myStore,
}]
});
....
....
{
title: '2-tab',
layout:'fit',
items: [listpanel],
cls: 'card2'
},
....
....
Sample Output :-
Before changing the title
After changing the title
FYI, If you look inside the Ext.List class in Sencha Docs, you will see the following code inside initComponent() method,
if (Ext.isDefined(this.dockedItems)) {
console.warn("List: List is not a Panel anymore so you can't dock items to it. Please put this list inside a Panel with layout 'fit'");
}
I cannot figure out how I can retrieve a given Data item in a store (id-number) to send it to the "setActiveItem" method in a listener:
So I have a store - model:
Ext.regModel('PictureItem', {
fields: ['id', 'titel', 'url']
});
var pictureItems = new Ext.data.Store({
model: 'PictureItem',
data: [
{id:1, titel:'page 1', url:'http://placekitten.com/1024/768'},
{id:2, titel:'page 2', url:'http://placekitten.com/1024/768'},
{id:3, titel:'page 3', url:'http://placekitten.com/1024/768'},
]
});
Here is my menuList called "leftList":
var leftList = new Ext.List({
dock: 'left',
id:'list1',
width: 135,
overlay: true,
itemTpl: '{titel}',
singleSelect: true,
defaults: {
cls: 'pic'
},
store: pictureItems,
listeners:{
selectionchange: function (model, records) {
if (records[0]) {
Ext.getCmp('karte').setActiveItem(!!!Here the number of the selected Item
or respondend "id" in the data store!!!);
}
}
}
});
and the carousel....
var carousel = new Ext.Carousel({
id: 'karte',
defaults: {
cls: 'card'
},
items: [{
scroll: 'vertical',
title: 'Tab 1',
html: '<img class="orientation" alt="" src="img_winkel/titel_v.jpg">'
},
If I call
Ext.getCmp('karte').setActiveItem(2);
it works with the called card - but how can I get the number from the id of the selected item in the menu List /store????
By the way: what does mean:
if (records[0]) {
why [0]?
I FOUND THE ANSWER FOR MYSELF - IT'S EASY:
Ext.getCmp('karte').setActiveItem(records[0].get('id'), {type: 'slide', direction: 'left'});
The secret to get the record-entry is ".get()":
records[0].get('arrayfield')
So now I can change the activeItem in the carousel easely...
I try to get an editable list with this code:
var isEditing = false;
new Ext.Application({
launch: function(){
new Ext.Panel({
//layout: 'card',
fullscreen: true,
items: new Ext.List({
id: 'myList',
store: new Ext.data.Store({
fields: ['myName'],
data: [{ myName: 1 }, { myName: 2 }, { myName: 3}]
}),
itemSelector: '.x-list-item',
multiSelect: true,
itemTpl: '<span class="name">{myName}</span>',
tpl: new Ext.XTemplate(
'<tpl for=".">' +
'<div class="x-list-item">' +
'<tpl if="this.isEditing()">' +
'<img src="images/delete.gif" ' +
'onclick="Ext.getCmp(\'myList\').myDeleteItem({[xindex-1]})" ' +
'style="vertical-align: middle; margin-right: 15px;"/>' +
'</tpl>' +
'{myName}</div>' +
'</tpl>',
{
compiled: true,
isEditing: function () {
console.log('isEditing (tpl):' + isEditing)
return isEditing;
}
}),
myDeleteItem: function (index) {
var store = this.getStore();
var record = store.getAt(index);
console.log('removing ' + record.data.myName);
store.remove(record);
},
listeners: {
itemtap: function () {
if (isEditing){
console.log('isEditing: ' + isEditing);
return;
}
},
beforeselect: function () {
console.log('isEditing: before ' + !isEditing);
return !isEditing;
}
}
}),
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
layout: { pack: 'right' },
items: [
{
xtype: 'button',
text: 'Edit',
handler: function () {
var list = Ext.getCmp('myList');
if (!isEditing)
list.mySelectedRecords = list.getSelectedRecords();
isEditing = !isEditing;
this.setText(isEditing ? 'Save' : 'Edit');
list.refresh();
if (!isEditing)
list.getSelectionModel().select(list.mySelectedRecords);
}
}]
}]
});
}
});
but its not working like it should. If I press the EDIT button there is no delete-image and so there is no deleted item....
There are 3 things that I can see:
The Template is rendered once, you will need to call .refresh() or .refreshNode() on the list to update any item templates. The better way to accomplish this would be to hide the delete button via CSS and display it when the 'edit' button is clicked.
There is probably a naming conflict between the isEditing variable declared at the top and the isEditing function reference. It is very confusing to have these two things named the same, and can lead to problems with variable scoping.
The click event that you are looking for may be intercepted by the parent list item and Sencha Touch is turning it into a 'itemtap' event on the list item.
I was not able to delete until I added an id field without a datatype to my model. I don't know why as it should know which record to delete via the index.
Ext.regModel('Setting', {
fields: [
{name: 'id'}, // delete works after adding
{name: 'name', type: 'string'}
],
proxy: {
type: 'localstorage',
id: 'settings'
}
Kevin