Push Pop operations in Naviagtion view Sencha Touch - sencha-touch-2

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();
}
}
]
});
}

Related

Multiple tap issue in navigation view

I am using Navigation view. Initially it has one item(view) that contains a button. On tapping this button, a second view pushes in the navigation view. If the user intentionally or by accident double tap the button, it pushes second view two times. How can i solve this problem?
I have tried the buffer configuration as specified in this link http://docs.sencha.com/touch/2.3.0/#!/guide/events but problem with this solution is that it invokes the listener after the buffer time even on the first tap.
Here is sample code to demonstrate the issue.
Navigation View
Ext.define('Many.view.Main', {
extend: 'Ext.navigation.View',
xtype: 'main',
config: {
items: [
{
xtype:'firstView'
}
]
}
});
First View
Ext.define('Many.view.FirstView', {
extend: 'Ext.Panel',
xtype: 'firstView',
config: {
title: 'First View',
items: [
{
xtype: 'button',
id:'myButton',
text: 'Push Second View'
}
]
}
});
Second View
Ext.define('Many.view.SecondView', {
extend: 'Ext.Panel',
xtype: 'secondView',
config: {
items: [
{
docked: 'top',
xtype: 'titlebar',
title: 'Second View'
}
]
}
});
Controller
Ext.define('Many.controller.Main', {
extend : 'Ext.app.Controller',
config : {
refs : {
myNavigationView : 'main',
myButton :'main #myButton'
},
control : {
myButton : {
tap : 'pushSecondView'
}
}
},
pushSecondView: function () {
var secondView = Ext.create('Many.view.SecondView');
this.getMyNavigationView().push(secondView);
}
});
Just add a condition whether that view exists in the viewport or not.
Add a reference in the controller like this:-
refs : {
myNavigationView : 'main',
myButton :'main #myButton',
secondView : 'secondView'
}
And add the condition:-
pushSecondView: function () {
if(!this.getSecondView()){
var secondView = Ext.create('Many.view.SecondView');
this.getMyNavigationView().push(secondView);
}
}
Here's how I do it:
/**
* This method will be called from every item in the app that can be double tapped to push multiple items.
*
* #returns {Boolean}
*/
ENSURE_NO_DOUBLE_TAP : function(classNameToPush) {
if (Ext.getClassName(Ext.getCmp('navigationview').getActiveItem()) == classNameToPush) {
console.log("Prevented DoubleTap.");
return false;
}
return true;
}
Then from any controller that uses navigationView.push({'theViewImPushing'}):
if (!ENSURE_NO_DOUBLE_TAP('App.view.TheViewImPushing')) {
return;
}
I keep a Statics singleton class around to call the ENSURE_NO_DOUBLE_TAP method from...but you could use it wherever fits.

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.

Navigation view is not rendering the items correctly

The view doesnt render properly . It only shows the button . What am i doing wrong here ?
Ext.application({
name: 'App',
models: ['Picture'],
stores: ['Pictures'],
views: ['Picture'],
requires: [
'Ext.carousel.Carousel',
'Ext.data.proxy.JsonP'
],
launch: function() {
var titleVisible = false,
info, carousel;
carousel = Ext.create('Ext.Carousel', {
store: 'Pictures',
direction: 'horizontal',
listeners: {
activeitemchange: function(carousel, item) {
info.setHtml(item.getPicture().get('title'));
}
}
});
info = Ext.create('Ext.Component', {
cls: 'apod-title',
top: '50',
left: 0,
right: 0
});
var view = Ext.create('Ext.NavigationView', {
title:'Paramore',
items: [carousel,info,{xtype:'button',text:'help'}]
});
Ext.Viewport.add(view);
--- some code ----
});
}
});
.I also tried this
var view = Ext.create('Ext.NavigationView', {
title:'Test',
items : [
{
xtype : 'container',
title : 'test',
scrollable : 'vertical',
items : [carousel,info]
}
There are a few issues with your code:
Ext.Carousel does not support the store configuration. You can learn how to do this here.
The items specified in a navigation view is the initial stack of items when released. So if you put in 3 items, the last item will be visible and the Back button will be visible. When you press the back button, it will remove that last item and there will be 2 items in the items stack.
You probably shouldn't put a Ext.Button directly inside a NavigationView. Doing this will make the button stretch to the size of the NavigationView, making it look pretty bad.
If you remove the reference to a store and listeners from your Carousel, your example works as expected. Here is the code I used to make it work. I just commented out broken code:
Ext.application({
name: 'App',
// models: ['Picture'],
// stores: ['Pictures'],
// views: ['Picture'],
requires: ['Ext.carousel.Carousel', 'Ext.data.proxy.JsonP'],
launch: function() {
var titleVisible = false,
info, carousel;
carousel = Ext.create('Ext.Carousel', {
// store: 'Pictures',
direction: 'horizontal',
items: [{
html: 'one'
}, {
html: 'two'
}, {
html: 'three'
}]
// listeners: {
// activeitemchange: function(carousel, item) {
// // info.setHtml(item.getPicture().get('title'));
// }
// }
});
info = Ext.create('Ext.Component', {
cls: 'apod-title',
top: '50',
left: 0,
right: 0
});
var view = Ext.create('Ext.NavigationView', {
title: 'Paramore',
items: [carousel, info,
{
xtype: 'button',
text: 'help'
}]
});
Ext.Viewport.add(view);
}
});

Sencha Touch itemtap

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.