How can I set the row height in a Sencha Touch List object?
I'm using HTML to format the row, rows get taller with multiple lines, but how do I set the row height?
Thanks,
Gerry
To edit the List elements default height, you have two ways to do it:
Create your own Sencha Theme with SASS (The official Sencha way to do it).
Override the Sencha Touch Theme CSS.
In the first case you only need to edit the $global-row-height variable value like, for example.
$global-row-height: 100px;
If you want to override the CSS class directly with an additional CSS file, you can do it adding a new rule just like this:
.x-list .x-list-item {
min-height: 100px;
}
If you want to set the list Height of a single list you have to set your css class in this way:
.myList .x-list-item {
min-height: 100px;
}
and add the cls config param to your list definition like this
var list = new Ext.List({
cls: 'myList',
...
...
});
You can also use the list config property itemHeight,like this:
var list = new Ext.List({
itemHeight: 25, //to set row height to 25 pixels
...
...
});
However, I always suggest to learn SASS. It's really easy and it really worth learning.
Hope this helps.
Since Sencha Touch 2.1 you can use list config property itemHeight (more info here). Just for information, it's also possible in NestedList object by using listConfig property.
Use the below code to change the height of list item in Sencha Touch.
{
xtype: 'list',
id: 'myList',
//Below two properties to change the default height
//default = 47 chaged to 30 below
variableHeights: true,
itemHeight: 30 ,
itemTpl: '{title}',
data: [
{ title: 'Item 1' },
{ title: 'Item 2' },
{ title: 'Item 3' },
{ title: 'Item 4' }
]
}
Incase somebody is still looking for the answer in Sencha Touch 2.4.1, here it comes:
listeners: [
{
event: 'painted',
order: 'before',
fn : function() {
// Set the height based on the number of items in the list!
var itemCount = this.itemsCount,
itemHeight = this.getViewItems()[0].element.getHeight(), // Works!
heightOfList = itemCount * itemHeight;
this.setHeight(heightOfList);
}
}
]
I am adding a listener for the painted method inside of my listView. I'm not sure if it matters, if you add the listener at the position of before, or after, but before made more sense to me.
I am simply taking the count of items in the list and multiplying it with the actual height of a list item element. I assume that all list items have the same height in the final list (this will always be the case for my list).
I tried the same approach with
itemHeight = this.getInnerItems()[0].element.getHeight() // Does NOT work
but that wouldn't work, because the elements would have a height of 0px at this points.
The code above works!
Related
I am using a tab panel (Ext.tab.Panel) that has 4 tabs and on one of the child screens when the user make a selection from a radio button group, I would like the tab panel to refresh itself (i.e. load new text, new icons). How can I force the tab Panel (which is the core navigational element of the app) to refresh?
I have tried setting the show: function() { } method on the view as follows:
Ext.define('MyApp.view.Main', {
extend: 'Ext.tab.Panel',
...
show: function() {
this.callParent();
... reload stuff
}
});
The tabs/icons in a Ext.tab.Panel make up the items property of the component. To change these tabs/icons you must change the items.
Use setItems(items) to effectively change the tabs/icons of the Ext.tab.Panel inside your listener.
var tabpanel = Ext.getCmp('tabpanelid'); // Get appropriate panel using its id
// Removes the current tabs, and inserts the following 2 tabs
tabpanel.setItems([
{
title: 'Tab1',
iconCls: 'info',
html: 'Foo'
},
{
title: 'Tab2',
iconCls: 'reply',
html: 'Bar'
}
);
Check out a working example here.
UPDATE: To modify one of the current items, use getItems(), modify the appropriate items, and call setItems(items).
Updated Example
I'm creating an app with some custom gauges using Rally SDK 2.0. This requires some custom HTML. I took a rake-compiled app.html file from the examples as a starting point. Using JustGage for my gauges. Here is my launch function.
launch: function () {
var info = this.getStoriesForProject(); //Gets some aggregate info
$('#header label').html(info.Title);
var g = new JustGage({
id: "devgauge",
value: info.DevPercent,
levelColors: ['#f80404', '#f8f804', '#50ed0e'],
min: 0,
max: 100,
title: "Dev %"
});
this.add('foo');
},
Then I added some custom HTML in app.html.
Now, if i run this without the code "this.add('foo')", the app adds a new div in the body with class="x-container" and puts my custom HTML outside that div effectively hiding it.
If i use the "this.add('foo') it does NOT create the div class=x-container and it shows my widget just fine.
What is the PROPER way to accomplish what I'm attempting using the 2.0 sdk? I realize the add method is for adding Ext components, but somehow calling this is causing my HTML to render ok. Looking at some apps we developed in the old SDK, using the custom HTML worked just fine in those.
Ext likes to know what is going on layout-wise and often gets confused if you're manually manipulating the dom beneath it without its knowledge. Usually if we have some known set of initial layout we add those via the items collection on the app:
Ext.define('My.App', {
extend: 'Rally.app.App',
items: [
{
xtype: 'container',
itemId: 'header'
},
{
xtype: 'container',
itemId: 'devguage'
}
]
});
Then inside of launch you can add content to those like so:
this.down('#devguage').add({
//some other component
});
You can always just drop all the way down to the element level though as well:
this.down('#header').getEl().dom //the raw html element
By default apps use an auto layout, so any items should flow as you would expect with normal html.
Or, instead of using itemId, you can set the id of the container's element using its id property:
Ext.define('My.App', {
extend: 'Rally.app.App',
items: [
{
xtype: 'container',
id: 'header'
},
{
xtype: 'container',
id: 'devguage'
}
]
});
The resulting html elements will use those ids, which allows you to target them directly with your own custom rendering.
I'm a newbie to all the Sencha Touch stuff, but until now I'm very enthousiastic about it's capabilities. There is one problem, i somehow can't solve.
I would like to use a Tpl (XTemplate) for a calender view. The idea is to create a div element for every appointment, which i can place within containers to layout them. Somehow i can't get the dataview to work.
I've stripped down my code to the bare minimum: a panel containing a DataView. When i use the itemTpl, everything works fine. But when I use the tpl (with or without the XTemplate) i don't see anything. I checked if it was just a display malfunction (searched for the XXX from the template), but that's not the case.
This is my code:
Ext.define('InfoApp.view.CalendarDay', {
extend: 'Ext.Panel',
xtype: 'calendarday',
requires: [ 'InfoApp.store.sAppointments'],
config: {
title: 'Dag',
layout: 'fit',
items: [
{
xtype: 'dataview',
store: 'appointmentStore',
//itemTpl: [ 'XXX {day} {course}' ] --> Works
tpl: new Ext.XTemplate('<tpl for=".">XXX {day} {course}</tpl>')--> Doesn't Work...
}
]
}
});
Thanks in advance for any suggestions or improvements!
Assuming ST2 and not ST1
From http://docs.sencha.com/touch/2-0/#!/api/Ext.Component-cfg-tpl and the comments on the tpl: config in the docs, it appears there's a bug when using a remote store. Even if your store has data it. tpl: apparently only works right now if your data is hardcoded in data:[]
you can use itemTpl: new XTemplate(), or itemTpl: XTemplate.from('someid') or you can defer specifying until afterwards, grab your dataview and go dv.setItemTpl(new XTemplate()), etc.
Tanks #brink for your answer.
It took me a couple of days, but this worked for me:
// Load the store
var store = Ext.getStore('appointmentStore');
// Get the current range of the store
var data = store.getRange();
// Create a custom template
var tpl = new Ext.XTemplate(<tpl for=".">{day} {course}</tpl>);
// Loop through the data array
var showData = array();
for(var i=0;i<data.length;i++){
showData.push(data[i].data);
}
// Get the panel by ID and push the html template
var panel = Ext.getCmp('appointmentspanel');
panel.updateHtml(tpl.applyTemplate(showData));
I have a panel (layout:'vbox') with two items; a panel and a list.
Code
this.currentFolderPnl = new Ext.Panel({
cls:'document-current-folder-panel',
html:'/'
});
this.list = new Ext.List({
scroll: 'vertical',
cls:'document-list',
id: 'document-list',
store: app.stores.Document,
itemTpl: app.templates.document
});
app.views.DocumentList.superclass.constructor.call(this, {
selectedCls : "x-item-selected",
dockedItems: [{
xtype: 'toolbar',
ui:'dark',
title: 'Documents',
items:[this.backBtn,{xtype:'spacer'},this.newBtn]
}],
layout: {type:'vbox',align:'stretch'},
items: [
this.currentFolderPnl,
this.list
]
});
I have tried many things but nothing worked. Could somebody tell me what to do.
Thanks
A scroll can only appear while the child element is larger in size (either height or width or both) than the parent element. Because you are using a vbox layout, it expects height for each component. So, a list scroll will come while it fits inside a panel.
Now for your case, two options can be there:
Option 1:
You can provide a height to the first panel (which still you didn't provide) and add another panel after that with following details:
{
flex : 1,
layout : 'fit',
items : [this.list]
}
This will fit the list within second panel and the scroll will come automatically.
Option 2:
Here you use a default layout (AutoContainerLayout) i.e. not providing any layout. And your above combination will work (better give a height to the first panel). Remove scrolling from list and add scroll vertical to main panel. This way:
this.currentFolderPnl = new Ext.Panel({
...
height : 50
});
this.list = new Ext.List({
scroll: FALSE,
....
});
app.views.DocumentList.superclass.constructor.call(this, {
scroll : 'vertical',
...
});
I didn't test the above option but this should work fine.
I'm new to Sencha Touch and the Ext JS logic. Actually, I'm displaying a list of items containing two fields (title, type) grouped by default alphabetically by first character of the title and I added a button to a toolbar that I want it to switch the grouping to be by type. I tried to programmatically set the getGroupString function in the buton handler in this way :
var toolbar = new Ext.Toolbar({
dock: 'top',
title: 'Toolbar',
items: [{
text: 'By type',
handler: function() {
MyApp.MyStore.getGroupString = function(record) {
return record.get('type');
};
MyApp.itemsList.update();
}
}]
});
But that seems just to not work. Any help ?
Thanks
Just wanted to close the question as I have already answered it
MyApp.itemsList.refresh();