In Innerdata.js, i have a a tag and on tap event i navigate it to the Group.js.
Gruop.js contain some html.I try to add here navigation bar with back button. Here the only Navigation bar is display no back button. Now this is where I fall down, I can't figure out why the Back button is not display.
I am trying to add Back button in navigation bar in Group.js page so when i click this button i navigate to the Inner.js page.so what is the problem here?
Inner.js:
Ext.define('chat.view.Inner', {
extend: 'Ext.Panel',
xtype:'Inner',
config: {
items: [
{xtype:'Innerdata'}
]
}
});
Innerdata.js:
Ext.define('chat.view.Innerdata',{
extend:'Ext.Panel',
xtype:'Innerdata',
config: {
items: [
{
html:'<a class="groupimg"><img src="stylesheets/images/groupchat.png"/></a>',
listeners: [
{
element: 'element',
delegate: 'a.groupimg',
event: 'tap',
fn: function() {
console.log('One!');
Ext.Viewport.setActiveItem(Ext.create('chat.view.Group'));
}
}
]
},
]
}
});
Group.js:
Ext.define('chat.view.Group', {
extend: 'Ext.navigation.View',
//extend: 'Ext.Panel',
xtype:'Group',
config:{
items: [
{html:'<div>Hello Hello Hello Hello</div>'}
]
},
onBackButtonTap:function(){
this.callParent(arguments);
}
});
here is the screen shot of Group.js page, i am trying to add Back button in Blue bar.
I believe there is a misuse of Ext.navigation.View in your code. Please don't use it in your situation.
Here are some explanations and instructions on how you can fix this problem:
If a view, says Group.js, is a subclass of Ext.navigation.View, it works according to push/pop pattern. Please see an example here: http://docs-origin.sencha.com/touch/2.3.0/#!/api/Ext.navigation.View. That's why a navigatioin view, which you applied to Group.js, should never have a back button on the top and very first screen.
So, there's no reason to use navigationview in this case. You just need to use a simple Ext.Container instead. So change your parent class of Group.js to Ext.Container. After that, add a toolbar on the top, add the back button to it and bind a handler.
Ext.define('chat.view.Group', {
//extend: 'Ext.navigation.View',
extend: 'Ext.Container',
xtype:'Group',
config:{
items: [
{xtype: 'toolbar',
docked: 'top',
items: [
{xtype: 'button',
text: 'Back',
ui: 'back',
handler: function(){Ext.Viewport.setActiveItem(Ext.create('chat.view.Inner'));}}
]}
{html:'<div>Hello Hello Hello Hello</div>'}
]
},
});
Related
Ext JS - v 6.2.1
I'm interested in reusing a main component developed in ExtJs which i've written in different tabs of the tabpanel. The main component is composed of two child components and each of these components have their respective controllers and the child components interact among themselves. Since the event listeners are added in the controller domain the events fired in one instance of tab affects the other tabs as well.
Pseudo code of the scenario explained
*********** Views ***********
Ext.define('MainApp.view.main.Main', {
extend: 'Ext.tab.Panel',
xtype: 'mainapp-main',
controller: 'main',
...
items: [{
title: 'Main Component Instance 1',
closable: true,
items: [{
xtype: 'mainapp-maincomponent'
}]
}, {
title: 'Main Component Instance 2',
closable: true,
items: [{
xtype: 'mainapp-maincomponent'
}]
}]
});
Ext.define('MainApp.view.maincomponent.MainComponent', {
extend: 'Ext.panel.Panel',
xtype: 'mainapp-maincomponent',
controller: 'maincomponent',
...
items: [{
xtype: 'mainapp-component1'
},{
xtype: 'mainapp-component2'
}]
});
Ext.define('MainApp.view.component1.Component1', {
extend: 'Ext.panel.Panel',
xtype: 'mainapp-component1',
controller: 'component1',
...
items: [{
xtype: 'button',
cls: 'contactBtn',
scale: 'large',
text: 'Fire Event',
handler: 'onComponentButtonTapped'
}]
});
Ext.define('MainApp.view.component2.Component2', {
extend: 'Ext.panel.Panel',
xtype: 'mainapp-component2',
controller: 'component2',
...
items: [{
xtype: 'textfield',
value: 'Button is not clicked yet',
width: 500,
readOnly: true
}]
});
*********** Controllers ***********
Ext.define('MainApp.view.component1.Component1Controller', {
extend: 'Ext.app.ViewController',
alias: 'controller.component1',
onComponentButtonTapped: function (btn, eventArgs) {
this.fireEvent('component1ButtonTapped', btn, eventArgs);
}
});
Ext.define('MainApp.view.component2.Component2Controller', {
extend: 'Ext.app.ViewController',
alias: 'controller.component2',
listen: {
controller: {
'component1': {
component1ButtonTapped: 'onComponent1ButtonTapped'
}
}
},
onComponent1ButtonTapped: function(){
this.getView().down('textfield').setValue(Ext.String.format('Button tapped at {0}', Ext.Date.format(new Date(), 'Y-m-d H:i:s')));
}
});
Can somebody please suggest the correct way of addressing this used case.
More Details
The tab panel is loaded in viewport
Tab 1 has first instance of Main Component - M1
Tab 2 has second instance of Main Component - M2
Every instance of Main Component has two child components
Component1 - M1C1 > M1C1 View and M1C1 Controller
Component2 - M1C2 > M1C2 View and M1C2 Controller
Similarly for the second instance of Main Component
Component1 - M2C1 > M2C1 View and M2C1 Controller
Component2 - M2C2 > M2C2 View and M2C2 Controller
Requirement here is to restrict Actions done on M1C1 view should be processed by M1C2 Controller only.
Issue is that with the code above M2C2 Controller also listens to the event
Change handler: 'onComponentButtonTapped' to
{
xtype: 'button',
cls: 'contactBtn',
scale: 'large',
text: 'Fire Event',
listeners: {
click: 'onComponentButtonTapped',
scope: SCOPE-YOU-WANT
}
}
First, I believe you are overnesting in your MainApp.view.main.Main component and you don't use a layout for your overnesting either. That can lead to unnecessary consequences like extra layout runs and bloated DOM affecting performance.
Ok, onto your question! I don't think scope is what you're actually after here. I see it as how to properly architect your ViewControllers. While understanding this isn't your real code, I will say that in this example you don't need that Component1Controller controller. Get rid of it and the button's handler will get resolved up to the maincomponent controller which is where you can control both child items. I only say this fully knowing that your Component1Controller is likely doing other things so it's not going anywhere just to say that not all containers need controllers. It also serves what I would do in this case if Component1Controller is to stick around. Instead of firing an event on the Component1Controller instance and use the event domain to get to Component2Controller, I would fire a view event on Component1 and add a listener on your config object so that maincomponent controller gets the event to do it's thing.
That sounds messy and hard to follow so I created this fiddle.
I have created an app with some views and also there is a list button on the top left corner to display and hide list on tap event.
some how I am able to hide it on tab but don't know how to display it again. By default it should be hidden but on tap of that button it should hide and show it self depending on current property.
iconCls: 'list',
iconMask: true,
ui: 'plain',
handler: function() {
Ext.getCmp('ext-ListNavigation-1').hide();
}
And list view code
Ext.define('ov_app.store.NavigationItems', {
extend: 'Ext.data.Store',
config:{
model: 'ov_app.model.Items',
data:[
{ items:"Services"},
{ items:"Solutions"},
{ items:"About Us"},
{ items:"Why Singapore"},
{ items:"Contact Us"}
]
}
});
the user inter phase looks something like this
As you can see i what to hide and show this (services,solution, etc.. )
on tap of the list button above the list.
var list = Ext.getCmp('ext-ListNavigation-1');
if (list.isHidden()) {
list.show();
}
else {
list.hide();
}
I was wondering how to ovverride the back button on a navigation view. I tried using onBackButtonTap but it doesnt seem to work http://www.senchafiddle.com/#8zaXf
var view = Ext.Viewport.add({
xtype: 'navigationview',
onBackButtonTap: function () {
alert('Back Button Pressed');
},
//we only give it one item by default, which will be the only item in the 'stack' when it loads
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 fiddle you've mentioned works well in my local project on my machine. For some reason, it doesn't work on fiddle site. Try running it on your local project.
Still instead of using onBackButtonTap config, it's good to extend Ext.navigation.View class and override onBackButtonTap method. That way you'll have more control over whole components. You'd also like to override other configs as well. Here's what I'd use -
Ext.namespace('Ext.ux.so');
Ext.define('Ext.ux.so.CustomNav',{
extend:'Ext.navigation.View',
xtype:'customnav',
config:{
},
onBackButtonTap:function(){
this.callParent(arguments);
alert('back button pressed');
}
});
the line this.callParent(arguments) will allow component to behave in default way + the way to wanted it to behave. And if you want to completely override the back button behavior you can remove this line. Try doing both ways.
To use this custom component, you can use -
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
var view = Ext.create('Ext.ux.so.CustomNav', {
fullscreen: true,
items: [{
title: 'First',
items: [{
xtype: 'button',
text: 'Push a new view!',
handler: function() {
//use the push() method to push another view. It works much like
//add() or setActiveItem(). it accepts a view instance, or you can give it
//a view config.
view.push({
title: 'Second',
html: 'Second view!'
});
}
}]
}]
});
}
Give this a shot. It'll work for you yoo.
I’m trying to add different detail view based on taped item in list.
I have home screen that is using List component and this view is displaying ['Real estate', 'Vehicles', 'Jobs']... as menu items.
Based on selected item in list, I want to display different view.
And I want to follow MVC design pattern..
Here is some code...
App.js
Ext.application({
name: 'App',
controllers: ['Main'],
views: ['Viewport', 'HomePage'],
stores: ['HomePageItems'],
models: ['HomePageItem'],
launch: function () {
Ext.Viewport.add(Ext.create('App.view.Viewport'));
}
});
Viewport.js
Ext.define("App.view.Viewport", {
extend: 'Ext.navigation.View',
requires: [ 'App.view.realestate.Realestate',
'App.view.HomePage',
'App.view.jobs.Jobs',
'App.view.other.Other',
'App.view.vehicles.Vehicles'
],
config: {
items: [
{
xtype: 'homepage'
}
]
}
});
HomePage.js ( xtype = "homepage" )
Ext.define('App.view.HomePage', {
extend: 'Ext.List',
xtype: 'homepage',
id: 'homepage',
config: {
title: 'Oglasi',
itemTpl: '<strong>{name}</strong><p style="color:gray; font-size:8pt">{description}</p>',
store: 'HomePageItems',
onItemDisclosure: true
}
});
Main.js
Ext.define('App.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
main: '#homepage'
},
control: {
'homepage': {
disclose: 'HookUpDetailView'
}
}
},
HookUpDetailView: function (element, record, target, index, ev) {
// TO DO: I have 4 differente views to load programmaticaly based on selected item in List
//'App.view.realestate.Realestate'
//'App.view.jobs.Jobs'
//'App.view.other.Other'
//'App.view.vehicles.Vehicles'
}
});
I found one example, but it's not working for me (push method doesn't exist)
this.getMain().push({
xtype: 'realestatehome'
});
Thank in advance!
The method you're looking for is
http://docs.sencha.com/touch/2-0/#!/api/Ext.Container-method-add
this.getMain().add({xtype: 'realestatehome'});
But what you have doesnt make sense, realestatehome is a list, you can't add a component under it. You need to read about layoutsFrom the link above
Push should work. You could try something like this.
HookUpDetailView: function (list, record) {
if(record.data.description==='real estate'){
this.getRealEstate().push({
xtype: 'realestatehome',
title: record.data.description,
data. record.data
});
if(record.data.description==='Vehicles'){
this.getVehicles().push({
xtype: 'vehicles',
title: record.data.description,
data. record.data
});
}
}
And a particular view could look like
Ext.define('App.view.RealEstateHome', {
extend: 'Ext.Panel',
xtype: 'realestatehome',
config: {
styleHtmlContent: true,
scrollable: 'vertical',
tpl: [
'{description}, {example}, {example}, {example}'
]
}
});
And the refs to access your particular view should look something like
refs: {
realEstate: 'realestatehome',
vehicles: 'vehicleshome'
},
Hope that helps
I made a mistake in controller this.getMain()
get main is returning Ext.List and I need Ext.navigation.View that have 'push' method.
So... I added xtype and id to my viewport ("container")
and quick change in my controller solved my troubles...
refs: {
main: '#homepage',
container: '#container'
}
and instead of getting Ext.List object
this.getContainer().push({
xtype: 'realestatehome'
});
And this work like a charm :)
I'd like to start quick.
What is my problem:
Within ST2 I structured my application with the MVC pattern. I have a store, a model, a controler and the views (for more information scroll down).
Workflow:
I click a list item (List View with a list of elements from store)
Controller acts for the event 'itemtap'
Controller function is looking for main view and pushes a detail view
Record data will be set as data
Detail view uses .tpl to generate the output and uses the data
Problem
Now I want to add a button or link to enable audio support.
I thought about a javascript function which uses the Media method from Phonegap to play audio
and I want to add this functionality dynamicly within my detail view.
Do you have any idea how I can achive that behavoir? I'm looking for a typical "sencha" solution, if there is any.
Detail Overview of all files starts here
My list shows up some data and a detail view visualize further information to a selected record.
The list and the detail view a collected within a container, I'll give you an overview:
Container:
Ext.define('MyApp.view.ArtistContainer', {
extend: 'Ext.navigation.View',
xtype: 'artistcontainer',
layout: 'card',
requires: [
'MyApp.view.ArtistList',
'MyApp.view.ArtistDetail'
],
config: {
id: 'artistcontainer',
navigationBar: false,
items: [{
xtype: 'artistlist'
}]}
});
List
Ext.define('MyApp.view.ArtistList', {
extend: 'Ext.List',
xtype: 'artistlist',
requires: [
'MyApp.store.ArtistStore'
],
config: {
xtype: 'list',
itemTpl: [
'<div>{artist}, {created}</div>'
],
store: 'ArtistStoreList'
}
});
Detail View
Ext.define('MyApp.view.ArtistDetail', {
extend: 'Ext.Panel',
xtype: 'artistdetail',
config: {
styleHtmlContent: true,
scrollable: 'vertical',
title: 'Details',
tpl: '<h2>{ title }</h2>'+
'<p>{ artist }, { created }</p>'+
'{ audio }'+
'',
items: [
//button
{
xtype: 'button',
text: 'back',
iconCls: 'arrow_left',
iconMask: true,
handler: function() {
var elem = Ext.getCmp("artistcontainer");
elem.pop();
}
}
]
}
});
And finally the controller
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
artistContainer: 'artistcontainer',
},
control: {
'artistlist': {
itemtap: 'showDetailItem'
}
}
},
showDetailItem: function(list, number, item, record) {
this.getArtistContainer().push({
xtype: 'artistdetail',
data: record.getData()
});
}
});
Puh, a lot of stuff to Read
Here you can see an example of how to load audio from an external url with Sencha Touch "Audio" Component. Haven't work with it but I think it fits your needs. Declaring it is as simple as follows:
var audioBase = {
xtype: 'audio',
url : 'crash.mp3',
loop : true
};
Iwould reuse the component and load the songs or sound items by setting the url dynamically. By the way I tried it on Chrome and Ipad2 and worked fine but failed on HTC Desire Android 2.2 default browser.