Sencha Touch 2 - setActiveItem of card layout inside navigationview issue - sencha-touch-2

I have an Ext.Panel with a card layout nested inside a navigation view. I did this to easily switch between a map and a list without having to pop and then push a whole different view (basically to avoid the animation). So, I have a button in the navigationBar that fires an action in the controller. This initial view, with a list, load fine, but the controller code to switch between the views (using setActiveItem()) does not work. No error message. I found something about a bug where you have to call show(). Although this works, it overlays the new activeItem (the Map, in this case) on top of the navigaionBar! (see screenshot). Also, if I just change activeItem to 1 in the config of the wrapper manually, it shows the map just fine, same as the list.
My wrapper panel looks like this:
Ext.define(ViewInfos.VendorWrapper.ViewName,{
extend: 'Ext.Panel',
id: ViewInfos.VendorWrapper.PanelId,
xtype: ViewInfos.VendorWrapper.Xtype,
config:
{
layout: 'card',
title: Resources.VendorsNearby,
activeItem: 0,
items: [
{
xtype: ViewInfos.VendorList.Xtype, //Initially shown, a list
},
{
xtype: ViewInfos.VendorMap.Xtype, //What I'm trying to show, a map
}
]
}
});
and here is my controller code:
Ext.define('OrderMapper.controller.VendorWrapper', {
extend: 'Ext.app.Controller',
config: {
refs: {
vendorMap: ViewInfos.VendorMap.Xtype,
vendorList: ViewInfos.VendorList.Xtype,
vendorWrapper: ViewInfos.VendorWrapper.Xtype,
main: ViewInfos.Main.Xtype,
vendorToggleButton: (ViewInfos.Main.Xtype + ' button[action=vendorViewToggle]')
},
control: {
vendorToggleButton:{
tap: function(){
var curView = this.getVendorWrapper().getActiveItem().id;
//active view == VendorList
if(curView == 'VendorList'){
//this shows up in the console
console.log('vendorToggleButton tapped, switching to map');
this.getVendorWrapper().setActiveItem(1);
//without this line, the view doesn't even change
this.getVendorWrapper().show();
this.getVendorToggleButton().setText('List');
}
//active view == VendorMap
else if (curView == 'VendorMap'){
console.log('vendorToggleButton tapped, switching to list');
this.getVendorWrapper().setActiveItem(0);
this.getVendorToggleButton().setText('Map');
}
}
}
}
}
And here is the screenshot of the wonky view that happens on this.getVendorWrapper().show()
Also, I tried changing the wrapper to a Carousel (instead of a regular panel with a card layout), and the carousel will swipe to change list/map but setActiveItem() STILL doesn't work.

I'm currently working on a navigation.View where there is basically 4 main views from where you can push other subview. I did it like this :
Ext.define('App.view.Navigation', {
requires: [
...
],
xtype: 'mainviews',
extend: 'Ext.navigation.View',
config: {
cls: 'content',
layout:{animation:false}, // or whatever animation you want for push and pop
navigationBar: {
...
},
items: [{
xtype: 'container',
layout:'card',
items: [{
xtype: 'mainview1',
},{
xtype: 'mainview2',
},{
xtype: 'mainview3',
},{
xtype: 'mainview4',
}]
}]
}
});
Then it's really easy to either set the active item of the navigation view or push subviews
For instance, in a controller it would be
this.getMainviews().setActiveItem(X); // X = 0,1,2 or 3
and
this.getMainviews.push(view); // view = the view your want to push
and these is the references :
refs:{
mainviews: 'mainviews'
}
Hope this helps

First of all, if you just want to avoid the animation on push/pop, add this config to your navigation view:
layout: {
animation: null
}
Generally, you should not call .show() on items that are inside your Ext.navigation.View instance. They will be added to Ext.Viewport directly, thus appearing to be on top of the navigation bar.
Have a look at this JSFiddle example, might give you a hint.

Related

How to animate dataview items in sancha touch 2

I am a newbie in sancha touch 2, Playing with kitchensink example that comes with sancha touch sdk kitchensink/index.html#demo/inlinedataview
UI for Inline Dataview
View
/* Here we are adding a dataview to a container
* which(dataview) contains images.
*/
Ext.define('Kitchensink.view.InlineDataView', {
extend: 'Ext.Container',
requires: ['Kitchensink.model.Speaker'],
config: {
layout: 'fit',
items: [{
xtype: 'dataview',
scrollable: true,
inline: true,
itemTpl: '<img src="{photo}">',
store: 'Speakers'
}]
}
});
Question
I want to animate those images while they are being added to dataview in a way that they(each one of them individually) seems to fading in at a random place before showing the upper view.
Similar to http://boedesign.com/demos/jsquares/ example1
Sancha Doc Reference or A hint or how to do, will do it, but if you can paste some reference code that would be great.
I saw that no one replied to this in 8 months, and it still comes up in google:
so thought i provide a simple solution.
in your dataview override the doRefresh function
doRefresh: function ()
{
this.callParent(arguments);
this.animateItems();
},
then in your customer after-function (this.animateItems())
call:
var viewItems = this.getViewItems();
then roll some animations on them :)
i've created a plugin that attempts to simplify this.
hope it can help someone: http://sunnyjacob.co.uk/blog/animating-items-in-a-sencha-touch-dataview/
S.

Sencha Touch 2.0: Universal Ext.TitleBar title not changing

I am trying to create a universal titlebar with a back button for my application. I am including it in the various views by using {xclass:mUserStories.view.titlebar}.
Here is the code for the titlebar:
Ext.define('mUserStories.view.titlebar', {
extend: 'Ext.TitleBar',
id: 'narwhal',
config: {
docked: 'top',
// id: 'narwhal',
title: 'CHW Module',
items: [{
ui: 'back',
text: 'Back',
id: 'backButton'
// hidden: true
}]
}
})
However, when I try to dynamically change the toolbar when switching to different pages, the console.log of the titlebar says the _title has changed but the text on the titlebar and the "hidden" property of the button does not change.
Here is the code for the logic that occurs when the button is pressed to switch the page:
toPage: function (arg) {
var t = Ext.getCmp('narwhal');
var b = Ext.getCmp('backButton');
console.log(t,b)
if (arg === PAGES.PATIENT_LIST) {
t.setTitle('Patient List');
b.setHidden(true)
}
Ext.getCmp('viewPort').setActiveItem(arg);
}
I have also tried to include a ref at the top for Narwhal : '#narwhal' and use var t = this.getNarwhal(), but this does not work either.
I am not sure if the problem lies with where the id is being kept, how the id is being called, or because the page is not refreshing properly. Any advice would help!
Thank you for your time :)
I have had the same situation in my project.
I managed to get everything to work like you want it by having a controller owning a reference to the title bar and listening to activeItemChange on my tabPanel.

How to add interactive, dynamic components on a fixed location outside of all views in a Sencha Touch application

How to add interactive, dynamic components on a fixed location outside of all views in a Sencha Touch application.
With the menu at the top, I would like to add controls to the bottom of the app that control audio, display other random information and rotate imagery. This pane should not hide/move/refresh/etc. when changing views via the menu, in essence it should be separated from the rest of the application. It is highly preferred to be able to use the sencha 'audio' xtypes.
Should I implement this:
Straight into index.html
Somehow add it in the view which holds the menu as well
Some other magical way
The magical way is... Docking ( outside the rest of the app, probably means you want to doc on the viewport ).
http://docs.sencha.com/touch/2-0/#!/api/Ext.Component-cfg-docked
var button = Ext.create('Ext.Button', {
text: 'Button',
id: 'rightButton'
});
Ext.create('Ext.Container', {
fullscreen: true,
items: [
{
docked: 'top',
xtype: 'titlebar',
items: [
button
]
}
]
});
Ext.create('Ext.Panel', {
html: 'Floating Panel',
left: 0,
padding: 10
}).showBy(button);
For your top view, I would use something along the lines of a Ext.TabPanel though.
http://docs.sencha.com/touch/2-0/#!/api/Ext.tab.Panel

sencha touch textfield clear event

I'm trying to implement a list filter in a text field in sencha touch. For example, I'd have a bunch of contacts, and when I typed in the field, it might filter by name. When I click the circular X button to clear the textfield, I'd like to reset the filter to filter none of the contacts.
The problem is, I can't seem to figure out a way to detect the click on the clear button. There doesn't appear to be any type of event, and I can't seem to hack in a workaround.
If anyone has any idea how to detect a textfield clearing in sencha touch, I'd be much obliged.
I've tried in safari and xcode simulator, and am using sencha touch 1.1.0. Am I missing something? Is this not an issue when it's actually a mobile app?
You can listen for tap events on clearIconContainerEl inside the text field or override the onClearIconTap method.
Ext.setup({
icon: 'icon.png',
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
glossOnIcon: false,
onReady: function() {
var searchField = new Ext.form.Search({
name : 'search',
placeHolder: 'Search',
useClearIcon: true,
onClearIconTap: function() {
if (!this.disabled) {
this.setValue('');
console.log('onClearTap: Clear button tapped!');
}
}
});
var viewport = new Ext.Panel({
fullscreen: true,
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [searchField]
}]
});
console.log(searchField.useClearIcon);
searchField.mon(searchField.clearIconContainerEl, {
scope: searchField,
tap: function() {
if (!this.disabled) {
console.log('clearIconContainerEl: Clear button tapped!');
}
}
});
}
});
For sencha touch 2.0 users:
If your using new mvc structure, you can use this in the controller init
this.control({
'#yourTextFieldId clearicon': {
tap: function(){console.log('ClearICON tapped');}
}
....
)};
The problem is the little X is not added in by sencha touch. It is a feature of the "search" input with html5. To capture this event you need to look for the search event. How I solved this was I edited sencha-touch.js
I modified -
if (this.fieldEl) {
this.mon(this.fieldEl, {
focus: this.onFocus,
blur: this.onBlur,
keyup: this.onKeyUp,
paste: this.updateClearIconVisibility,
mousedown: this.onBeforeFocus,
scope: this
});
to be -
if (this.fieldEl) {
this.mon(this.fieldEl, {
focus: this.onFocus,
blur: this.onBlur,
keyup: this.onKeyUp,
paste: this.updateClearIconVisibility,
mousedown: this.onBeforeFocus,
search: this.onSearch,
scope: this
});
inside of Ext.form.Text = Ext.extend(Ext.form.Field, { ...
Now in my implementation of the searchfield I can make a function called onSearch which will be called when the "search" event is called. Note that the "search" event is not only called for the X but for some things like the enter key. The bottom line is sencha touch 1.1 does not check for this event at all and it is the only time the X fires an event so the only solution is to modify sencha-touch.js.

Sencha Touch nested floating panels with carousels

I've only got so far trying to achieve what i've mocked in the screenshot.
Basically, i have a fullscreen reports panel that has 6 panels nested within it. Each of these panels (i'll call them tiles, as that makes more sense) need to be shown at the same time (used the layout:'fix') for the main panel.
Each tile will have a carousel within it that gets it's items populated by means of a single ajax call, if the ajax call returns 3 items then the carousel will have 3 items etc.
I'm having trouble getting the tiles arranged properly, so that they are all shown neatly, and more importantly in a way that will work when the device goes from landscape to portrait mode.
Without worrying about the carousel part too much, trying to get the tiles arranged properly within the panel is a pain. I can pretty much get there with css, by floating... but the first panel always looks messed up. I've since done some some reading trying to achieve a more "sencha" way of doing this.
var rep1 = new PortalDashboard.views.Reportimagetile;
var rep2 = new PortalDashboard.views.Reportimagetile;
var rep3 = new PortalDashboard.views.Reportsinglefigtile
var rep4 = new PortalDashboard.views.Reportimagetile;
var rep5 = new PortalDashboard.views.Reportimagetile;
var rep6 = new PortalDashboard.views.Reportimagetile;
PortalDashboard.views.Dashboardcard = Ext.extend(Ext.Panel, {
title: 'Dashboard',
html: '',
cls: 'card5',
layout: 'fit',
iconCls: 'team',
styleHtmlContent: true,
initComponent: function () {
Ext.apply(this, {
items: [
rep1, rep2, rep3, rep4, rep5, rep6]
});
PortalDashboard.views.Dashboardcard.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('dashboardcard', PortalDashboard.views.Dashboardcard);
--
PortalDashboard.views.Reportsinglefigtile = Ext.extend(Ext.Panel, {
html: '',
cls: 'dashtilecontent',
initComponent: function () {
Ext.apply(this, {
html: '<h1>99.99%</h1>'
});
PortalDashboard.views.Reportsinglefigtile.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('reportimagetile', PortalDashboard.views.Reportsinglefigtile);
Fit layout is used to show a single item at a time so using it as the layout for your dashboard panel won't work. Besides writing a custom layout to achieve the 3x2 tile effect in your mock up I would set the layout of the dashboard to
layout: {
type: 'vbox',
align: 'center',
pack: 'center'
}
so now any items you add will be in the center of the panel body and stack vertically.. so add 2 panels for each of the rows and on those panels use an hbox layout and add 3 cards to each of those panels
layout: {
type: 'hbox',
align: 'center',
pack: 'center'
}
(those align or pack settings might not suit your needs if you plan to have different sizes on different boxes, in which case you'll need to use the flex property to give the boxes the proportions you want)