Sencha Touch itemtap - sencha-touch

I have a list of contacts that sencha touch is displaying in a list. Then when you click a name in the list it should slide to the right and say Hello {contact name}! but when it slides over right now it just says Hello !on line 29 is where the action is happening for item tap i belive the problem is here. I just dont know how to format it correctly. Below is my source code.
ListDemo = new Ext.Application({
name: "ListDemo",
launch: function() {
ListDemo.detailPanel = new Ext.Panel({
id: 'detailpanel',
tpl: 'Hello, {firstName}!',
dockedItems: [
{
xtype: 'toolbar',
items: [{
text: 'back',
ui: 'back',
handler: function() {
ListDemo.Viewport.setActiveItem('disclosurelist', {type:'slide', direction:'right'});
}
}]
}
]
});
ListDemo.listPanel = new Ext.List({
id: 'disclosurelist',
store: ListDemo.ListStore,
itemTpl: '<div class="contact">{firstName} {lastName}</div>',
listeners:{
itemtap: function(record, index){
ListDemo.detailPanel.update(record.data);
ListDemo.Viewport.setActiveItem('detailpanel');
}
}
});
ListDemo.Viewport = new Ext.Panel ({
fullscreen: true,
layout: 'card',
cardSwitchAnimation: 'slide',
items: [ListDemo.listPanel, ListDemo.detailPanel]
});
}
});

The first argument passed to the itemtap event isn't the record of the List item tapped, it's the DataView itself.
From the docs:
itemtap : ( Ext.DataView this, Number index, Ext.Element item,
Ext.EventObject e )
Fires when a node is tapped on
Listeners will be called with the following arguments:
this : Ext.DataView
The DataView object
index : Number
The index of the item that was tapped
item : Ext.Element
The item element
e : Ext.EventObject
The event object
You can grab the tapped record by using:
dataView.store.getAt(index); // where 'dataView' is 1st argument and 'index' the 2nd

itemtap: function(view, index, item, e) {
var rec = view.getStore().getAt(index);
ListDemo.detailPanel.update(rec.data);
}
That's how I got it to work.

Related

Push Pop operations in Naviagtion view Sencha Touch

I am trying to use a navigation view and execute the push and pop operations over it , But cant find where exactly i can define the object view , which would be used for view.push and view.pop.
cause i am getting this error that view isnt defined !
if trying to define Third_Navigate into a var view like
var view = Ext.define('MyFirstApp.view.Third_Naviagte', { .. });
then i am getting the error view.push isnt defined. Help.
Ext.define('MyFirstApp.view.Third_Naviagte', {
extend: 'Ext.navigation.View',
xtype: 'navigationview',
//itemId:'navView',
//we only give it one item by default, which will be the only item in the 'stack' when it loads
config:{
items: [
{
//items can have titles
title: 'Navigation View',
padding: 10,
//inside this first item we are going to add a button
items: [
{
xtype: 'button',
text: 'Push another view!',
handler: function() {
//when someone taps this button, it will push another view into stack
view.push({
//this one also has a title
title: 'Second View',
padding: 10,
//once again, this view has one button
items: [
{
xtype: 'button',
text: 'Pop this view!',
handler: function() {
//and when you press this button, it will pop the current view (this) out of the stack
view.pop();
}
}
]
});
}
}
]
}
]}
});
The reason your example with var view = Ext.define(...); is not working is because Ext.define unlike Ext.create doesn't return an Object instance. It should be var view = Ext.create(...);.
Alternative way to do it would be using the up method used for selecting ancestors.
In your handler function use this to get the button instance and from there you can select the navigationview like so:
handler: function() {
var view = this.up('navigationview');
view.push({
title: 'Second View',
padding: 10,
items: [
{
xtype: 'button',
text: 'Pop this view!',
handler: function() {
view.pop();
}
}
]
});
}

How to switch a view container using Sencha Touch?

How do I switch views in Sencha Touch? Currently I have a new view being shown, but it looks like it overlays onto the existing one. I think I need to hide the previous or destroy it. I was thinking of maybe using Ext.getCmp("noteslist") but this returns 'undefined' when trying to get the current container. Is this the recommended way of navigating between views or is there a better way?
App
Ext.application({
name: "NotesApp",
controllers: ["NotesController", "TestController"],
views: ["NotesListContainer"],
launch: function () {
var notesListContainer = Ext.create("NotesApp.view.NotesListContainer");
Ext.Viewport.add(notesListContainer);
}
});
Controller:
Ext.define("NotesApp.controller.NotesController", {
extend: "Ext.app.Controller",
views: [
"TestListContainer"
],
config: {
refs: {
newNoteBtn: "#new-note-btn",
saveNoteBtn: "#save-note-btn",
},
control: {
newNoteBtn: {
tap: "onNewNote"
},
saveNoteBtn: {
tap: "onSaveNote"
}
}
},
onNewNote: function () {
console.log("onNewNote");
},
onSaveNote: function () {
console.log("onSaveNote");
Ext.Viewport.add({xtype:'testlist'}).show();
// How do I remove the current one?....
},
launch: function () {
this.callParent();
console.log("launch");
},
init: function () {
this.callParent();
console.log("init");
}
});
View
Ext.define("NotesApp.view.NotesListContainer", {
extend: "Ext.Container",
config: {
items: [{
xtype: "toolbar",
docked: "top",
title: "My Notes",
items: [{
xtype: "spacer"
}, {
xtype: "button",
text: "New",
ui: "action",
id:"new-note-btn"
}, {
xtype: "button",
text: "Save",
ui: "action",
id:"save-note-btn"
}]
}]
}
Using Ext.Viewport.add you only add component to viewport, but not set it as active item. You can use Ext.Viewport.setActiveItem for add component and set it as active item in one call.
Example:
//1
Ext.Viewport.setActiveItem({xtype:'testlist'});
//or 2
//Create and add to viewport
Ext.Viewport.add({xtype:'testlist'});
//set active item by index
Ext.Viewport.setActiveItem(1);
//or 3
var list = Ext.create('NotesApp.view.NotesListContainer', {id : 'noteList'});
Ext.Viewport.add(list);
.....
//In place where you need to show list
Ext.Viewport.setActiveItem(list);
If you want to animate swiching between views then use animateActiveItem(list, {type: 'slide', direction: 'right'}) instead a setActiveItem.
It's how you can work with Ext.Viewport and any container with card layout. In the real application view can be created in one part of app(in the controller, int the app, in the view) and set as active in other part. In this case you need get link to the list by any way and use it in the setActiveItem.
There are two techniques 1 using setActiveItem and the other using navigation view...
Navigation View
Set Active item method:
var view=Ext.Viewport.add({xtype: 'testlist'});
Ext.Viewport.setActiveItem(view);
view.show(); //This is additionally done to fire showAnimation

Sencha 2 navigation view create new instance of view without replacing old one

I have a navigation view with list(A) as its item.
On clicking the list(A) item, showing new view(B).
Now the new view(B) is having one button on clicking again change to view(C).
Problem is
view(C) is same as view(B).
I am able to create the new view and push it, but not able to populate with new data.
and on coming back to view(B), I am getting the data of view(C).
How to solve this scenario.
Code:
/**
* navigationview with list(A)
*/
Ext.define('activity', {
extend: 'Ext.navigation.View',
config: {
items:[
{
grouped:true,
pinHeaders: true,
xtype:'list',
store:{
xclass:'ActivityList'
},
itemTpl:'{title}',
emptyText: 'nothing found'
}
]
}
});
/**
* child view(B) to be appeared on clicking any item in list(A).
*/
Ext.define('TaskDetails', {
extend: 'Ext.Panel',
config: {
title: 'Task',
layout: {
type: 'fit'
},
items: [
{
xtype: 'toolbar',
docked: 'top',
height: '40px',
items: [
{ xtype: 'spacer'},
{
xtype: 'segmentedbutton',
height: '30px',
items: [
{
text: 'Task Details',
pressed: true
},
{
text: 'Child Tasks',
badgeText: '0'
}
]
},
{ xtype: 'spacer'}
]
},
{
xtype: 'container',
items: [
{
xtype:'dataview',
store: {
xclass: 'TaskDetails'
},
itemTpl: 'some thing....'
},
{
xtype:'list',
store:{
xclass:'ChildTask'
},
itemTpl: 'some template...'
}
]
}
]
}
});
I am changing view in controller and want to show the same view(B)again with new data on clicking the list in view(B).
This is a feature of navigation view which you cannot circumvent. Use setActiveItem instead to push views... I had the same issue and changed to setActiveItem it gives you more control of your views than navigation view so
After you first load the view(2), the ref returns an array of 1, as it should. Refs only work if 1 component is returned.
After you load the view(2) again the ref returns an array of 2.
This means none of the listeners fire and the data doesn't load on new instances.
Refs bind to dom elements when controllers first see a view. We can't change that. This means we can't use a ref directly. We know the Ext.ComponentQuery.query is what refs rely on. Using that, we can simulate refs at runtime. I put a runtime dataview ref in the initialize() function of the controller to load the data for a new view. This seems to run every time a view is created, so it works.

Sencha Touch TabBar + page navigation. Why it's breaking?

I'm a newbie to SenchaTouch. I have started working on an App and the results are this until now: http://mobz.com.br:86. (based on the Sencha-Touch-tabs-and-toolbars-demo)
Now I started playing with it and I have difficulties to set things strait in my head.
I have lot of JQuery experience, but regarding the design of this library, the coin haven't dropped yet.
I got a TabPanel with 5 sections. I will focus only in one section cause there where my problem is.
The Problem
As you can see in my app, when one clicks an item of ingressos (tickets in English), the app loads the second panel, but load it with bugs.
It loads it without the title bar, without the Back button, and also add an empty sixth button on the right.
But if I load the second panel first, when the page loads, it loads without any UI issues.
My Code
First I declare my ViewPort
Mobz.views.Viewport = Ext.extend(Ext.TabPanel, {
fullscreen: true,
initComponent: function() {
Ext.apply(this, {
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
items: [
{ xtype: 'destaques', id: 'home' },
{ xtype: 'ingressos' },
{ xtype: 'mobilizacoes' },
{ xtype: 'locais' },
{ xtype: 'minhaconta' }
]
});
Mobz.views.Viewport.superclass.initComponent.apply(this, arguments);
}
});
Than after, at the ingressos.js file, I define the tab.
First I got the panel that will load the items into it.
Mobz.views.Ingressos = Ext.extend(Ext.Panel, {
id: "ingressos",
title: "Ingressos", //title of the page
iconCls: "arrow_right", // icon of the tab at the bottom
styleHtmlContent: true,
fullscreen: true,
layout: 'card',
initComponent: function () {
Ext.apply(this, {
dockedItems: [{
xtype: "toolbar",
title: "Ingressos"
}],
items: [Mobz.views.IngressosList]
});
Mobz.views.Ingressos.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg('ingressos', Mobz.views.Ingressos);
This is the initial item that load into the panel.
Mobz.views.IngressosList = new Ext.List({
id: 'ingressoslist',
itemTpl: IngressosList_Template,
store: Mobz.stores.IngressosStore,
onItemTap: function (subIdx) {
//Mobz.views.IngressoCinemaList.update(subIdx);
Mobz.views.viewport.setActiveItem(Mobz.views.IngressoCinemaList, { type: 'slide', direction: 'left' });
}
});
And that's the second panel.
The panel where the first panel goes to.
Mobz.views.IngressoTitle = new Ext.Panel({
id: 'ingressotitle',
tpl: IngressoTitle_Template,
data: Mobz.stores.IngressoTitle_Store
});
Mobz.views.IngressoCinemaList = new Ext.List({
id: 'ingressocinemalist',
itemTpl: IngressoCinemaList_Template,
store: Mobz.stores.IngressoCinemaListStore,
flex: 1, grouped: true,
dockedItems: [{
xtype: 'toolbar',
items: [{
text: 'Back',
ui: 'back',
handler: function () {
Mobz.views.viewport.setActiveItem(Mobz.ingressos, { type: 'slide', direction: 'right' });
}
}]
}
],
onItemDisclosure: function () {
app.views.viewport.setActiveItem(Mobz.views.IngressosHorario, { type: 'slide', direction: 'left' });
}
});
Mobz.views.Ingresso = new Ext.Panel({
id: 'ingresso',
layout: {
type: 'vbox',
align: 'fit'
},
items: [Mobz.views.IngressoHorario_IngressoECinemaTitles, Mobz.views.IngressoCinemaList]
});
That's it.
I hope some of you guys will have the patient to read all my code examples. I'll appreciate any help.
Shlomi.
First, you must understand the logic about the panels.
You have an TabPanel and you have 5 panel in it. If you run your code when you click a ticket as you described in problem, your code added a new pane to TabPanel. But you need to set active item of Ingression panel(second panel which is in tabPanel).
Now start the solution;
The second tab has a panel(I will say senchaTabItem) whose layout is card layout. And this panel has a panel in it with list of Ingressos. We want to remove this panel and replace the new panel so we should not call the tabPanel's method, we must call to senchaTabItem's method.
So if you replace below code
Mobz.views.viewport.setActiveItem(Mobz.views.IngressoCinemaList, { type: 'slide', direction: 'left' });
with working code(below code).
Mobz.views.viewport.getActiveItem().setActiveItem(Mobz.views.IngressoCinemaList, { type: 'slide', direction: 'left' });
In your site; it is at line 170 in ingressos.js
I tried and it works, I hope it helps

Difference between a TabPanel and TabBar

Hey guys I'm starting to work with Sencha Touch and it feels like the tutorials I've read/documentation is helpful. I'm trying to understand: the difference between tabbar and tabpanel and when to use them
For example I have a index panel with list items, once someone clicks it, it goes to a page with a tabbar on the bottom. am I suppose to use a new panel with a tabbar or just a tabpanel?
I was working on something similar, check out the code below. As for the difference between TabPanel and TabBar it seems that TabBar is just a component of TabPanel used for displaying and manipulating tab buttons.
The list part of the below code has been taken form sencha touch API List
Ext.setup({
onReady: function() {
Ext.regModel('Contact', {
fields: ['firstName', 'lastName']
});
var store = new Ext.data.JsonStore({
model : 'Contact',
sorters: 'lastName',
getGroupString : function(record) {
return record.get('lastName')[0];
},
data: [
{firstName: 'Tommy', lastName: 'Maintz'},
{firstName: 'Rob', lastName: 'Dougan'},
{firstName: 'Ed', lastName: 'Spencer'}
]
});
var tabPanel = new Ext.TabPanel({
tabBar:{
dock: 'bottom', // will put the menu on the bottom of the screen
layout:{
pack: 'center' // this will center the menu
}
},
items:[
{
title: 'tab 1',
html: 'TAB 1',
iconCls: "home"
},
{
title: 'tab 2',
html: 'TAB 2',
iconCls: "bookmarks",
}
]
});
var list = new Ext.List({
itemTpl : '{firstName} {lastName}',
grouped : true,
indexBar: true,
store: store,
listeners: {
itemtap:function (subList, subIdx, el, e) {
console.log(subList, subIdx, el, e);
var store = subList.getStore(),
record = store.getAt(subIdx);
if (record) {
mainPanel.setActiveItem(tabPanel, 'slide');
}
}}
});
// Main panel viewport
var mainPanel = new Ext.Panel({
fullscreen: true,
layout: 'card',
items:[list]
});
mainPanel.show();
}
});
You should be able to do it with just a tabPanel. Add a tabBar property with dock : bottom.
For the objects in your items list, add a title and iconCls so that the buttons appear with names and icons.