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);
}
});
Related
I am new to sencha touch. I am creating a app in which i am using a html . When that span is clicked a function in controller should be called . I have attached the view and controller with this question.
View
Ext.define('SlideNav.view.Viewport', {
extend: 'Ext.Container',
xtype: 'app_viewport',
requires: [
'Ext.TitleBar'
],
config: {
fullscreen: true,
layout: 'hbox',
items : [
{
docked: 'top',
xtype: 'panel',
height: 40,
style:'background:white ;height:40px;color:black',
items:[
{
html:'<div><span style="padding:10px;position:absolute" id="TopNews">Top News</span><span style="padding:13px;position:absolute;right:10px;font-size:12px">MORE</span></div>'
}
],
listeners: {
initialize:function(){
this.fireEvent('onPopulateDashBoardData', this);
}
/* tap: {
fn: function(event, el){ console.log("tapped!");
this.fireEvent('onPopulateDashBoardData', this);
},
element: 'element',
delegate: '#TopNews'
}*/
}
},
{
xtype : 'main',
cls: 'slide',
// Needed to fit the whole content
width: '100%'
}, {
xtype : 'navigation',
width : 250
}]
}
});
controller.js
Ext.define('SlideNav.controller.App',{
extend: 'Ext.app.Controller',
config:{
refs:{
app_viewport: 'app_viewport',
main : 'main',
navigation : 'navigation',
navBtn : 'button[name="nav_btn"]',
},
control : {
app_viewport:{
onPopulateDashBoardData:'toggleNav'
},
navBtn : {
tap : 'toggleNav'
},
navigation : {
itemtap : function(list, index, target, record){
this.toggleNav();
console.log(record);
alert(record._data.title);
}
}
}
},
/**
* Toggle the slide navogation view
*/
toggleNav : function(){
var me = this,
mainEl = me.getMain().element;
console.log('hai');
if (mainEl.hasCls('out')) {
mainEl.removeCls('out').addCls('in');
me.getMain().setMasked(false);
} else {
mainEl.removeCls('in').addCls('out');
me.getMain().setMasked(true);
}
}
});
In the above question , i want to click a text with id TopNews from and want to call a function toggleNav in controller. I tried to fire a event with the name onPopulateDashBoardData and tried to use that event in the controller. But it is also not working . What should you know.
The way you are referring the text is wrong.
Do this:-
items:[{
name: 'top_news', // add this name for referring
html:'<div><span style="padding:10px;position:absolute" id="TopNews">Top News</span><span style="padding:13px;position:absolute;right:10px;font-size:12px">MORE</span></div>'
}]
Controller:-
refs:{
menu: container[name='top_news']
},
control : {
menu : {
initialize: function(container) {
container.element.on({
tap: 'toggleNav',
scope: this,
delegate: '#TopNews'
});
}
}
}
I have put two buttons inside a tab Panel in Sencha Touch 2 application. The code is given below:
var btnAttendance = Ext.create('Ext.Button', {
text: 'Take Attendance',
padding: 10,
width: 200,
handler: function () {
alert('a');
}
});
var btnAddUser = Ext.create('Ext.Button', {
text: 'Add User',
padding: 10,
width: 200,
handler: function () {
alert('a');
}
});
var buttonContainer = Ext.create('Ext.Panel', {
fullscreen: true,
title: 'Home',
defaults: {
margin: 5
},
layout: {
type: 'vbox',
align: 'center'
},
padding: 10,
items: [
btnAttendance,
btnAddUser
]
});
Ext.application({
requires: [
'Ext.tab.Panel'
],
launch: function () {
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
buttonContainer,
{
title: 'Present',
items: {
html: '2',
centered: true
},
cls: 'present'
},
{
title: 'Absent',
items: {
html: '3',
centered: true
},
cls: 'absent'
}
]
});
}
});
I have tried modifying the handler function as:
handler: function (button, event)
But this also doesn't work.
Thanks,
Nitin
You need to put all your code inside Ext.application... and launch:function(){...}.... Your code is working fine. See demonstration here.
But then again, buttonContainer is not really being added to any tab panel. If you change the tab, you can see buttonContainer is gone once to change the tabs. If you want to add it inside any tab do this-
First -
Set fullscreen:false to you buttonContainer panel.
var buttonContainer = Ext.create('Ext.Panel', {
fullscreen: false,
....... //rest of the code.
And suppose you want to add those buttons in Present tab. You can do this with following--
Ext.Viewport.add({
xtype: 'tabpanel',
items: [
{
title: 'Present',
cls: 'present',
items: [
{
html: '2',
centered: true
},
buttonContainer
]
},
{
title: 'Absent',
items: {
html: '3',
centered: true
},
cls: 'absent'
}
]
});
Here, buttonContainer is added as an item inside present tab only. You can switch the tabs and can see buttons there with correct event handler.
See this demo here
If you follow MVC architecture, your job becomes much easier writing application having multiple views and user interactions. ST is all about MVC and it's good practice to follow it.
I am new to sencha. Almost spent 2 day to understand sencha routing/history support to implement android back button. but ended up with blank screen always although navigation is working. Please help me to find out what wrong am i doing or what is wrong with my application architecture.
app.js
Ext.application({
name: "WorkFlow",
models: [],
stores: [],
controllers: ["WFController"],
views: ["LoginForm","WorkList"],
launch: function () {
var loginForm = {
xtype: "loginform"
};
var workList = {
xtype: "worklist"
};
Ext.Viewport.add([loginForm,workList]);
// set up a listener to handle the back button for Android
if (Ext.os.is('Android')) {
document.addEventListener("backbutton", Ext.bind(onBackKeyDown, this), false);
function onBackKeyDown(e) {
e.preventDefault();
// you are at the home screen
if (Ext.Viewport.getActiveItem().xtype == loginForm.xtype ) {
navigator.app.exitApp();
}else {
this.getApplication().getHistory().add(Ext.create('Ext.app.Action', {
url: 'loginForm'
}));
}
}
}
}
});
LoginForm.js
var formPanel = null;
Ext.define("WorkFlow.view.LoginForm", {
extend: "Ext.form.Panel",
alias: "widget.loginform",
initialize: function () {
this.callParent(arguments);
formPanel = Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [{
xtype: 'titlebar',
title: 'Login',
docked: 'top'
},
{
xtype: 'fieldset',
items: [
{
xtype: 'textfield',
name : 'username',
label: 'Username',
},
{
xtype: 'passwordfield',
name : 'password',
label: 'Password',
},
{
xtype: 'textfield',
name : 'deviceId',
label: 'Device Id',
}
]
}]
});
formPanel.add({
xtype: 'toolbar',
docked: 'bottom',
layout: { pack: 'center' },
items: [
{
xtype: 'button',
text: 'Login',
handler: this.onLoginTap,
scope: this
},
{
xtype: 'button',
text: 'Cancel',
handler: function() {
formPanel.reset();
}
}
]
});
},
onLoginTap: function() {
this.fireEvent("loginCommand", this);
},
});
WorkList.js
Ext.define("WorkFlow.view.WorkList", {
extend: "Ext.form.Panel",
alias: "widget.worklist",
config:{
html: 'This is worklist...',
}
});
WFController.js
Ext.define("WorkFlow.controller.WFController", {
extend: "Ext.app.Controller",
config: {
refs: {
loginForm: "loginform",
workList: "worklist",
},
control: {
loginForm: {
loginCommand: "onLoginCommand",
}
},
routes: {
'loginForm': 'activateLoginFormPage'
}
},
activateLoginFormPage: function(){
Ext.Viewport.animateActiveItem(this.getLoginForm(), this.slideRightTransition);
},
slideLeftTransition: { type: 'slide', direction: 'left' },
slideRightTransition: { type: 'slide', direction: 'right' },
onLoginCommand: function () {
var values = formPanel.getValues();
window.plugins.AuthPlugin.authenticate(values.username,values.passwordvalues.deviceId,values,
function loginCallBack(result){
if(result=="PASSWORD_MATCH"){
loginForm.onLoginSuccess();
}
});
},
onLoginSuccess: function(){
this.getApplication().getHistory().add(Ext.create('Ext.app.Action', {
url: 'loginFormroute/workList'
}));
Ext.Viewport.animateActiveItem(this.getWorkList(), this.slideRightTransition);
},
launch: function () {
},
init: function () {
}
});
Not totally sure of what you are trying to accomplish, but if it is just regular navigation (press back to return to previous tab etc.) then you do not need to bind anything to the android back button. You should use routes and create a history item for every step the user takes.
Example: I have an app with two tabs, in one of the tabs there is a list of locations and in the second one there is a map with the same locations marked. Pressing on wither a list item or a location in the map generates the same details screen. So this is what I got to get this to work:
Routes:
routes: {
'tab/:tabId': 'gotoTab',
'details/:stnId': 'viewDetails'
},
Important part: ensure that you create history items for each step, I basically have two in this app, one for changing tabs and one for opening a details page.
So, tabs:
//If I change to the 'map' tab, it will navigate the browser to myapp.com/#tab/map
// and therefore creating a history item.
onTabpanelActiveItemChange: function(container, value, oldValue, options) {
this.getApplication().getHistory().add(new Ext.app.Action({
url: 'tab/' + value.id
}), true);
},
Similar for my details page, only it is a function that is called from two seperate handlers (one for the list and one for the map):
showDetails: function(record, staticUrl, doUpdate) {
/*some logic stripped out*/
this.getApplication().getHistory().add(new Ext.app.Action({
url: 'details/' + record.data.id
}), true);
}
After this you are more or less ready to go, if you can guarantee that users always start at the main page. If you enable deep-linking etc. than you will need to restore a state for those links. e.g. a #/tab/map/ link should open the app with the map tab active.
If we take my details page as an example, we have a few things to do. First of all re-create history (press back on details page returns to tab-list by default in my app) and then ensure that stores are loaded and so on.
So as a final example, my viewDetails route:
var store = Ext.StoreManager.get("dcStations");
//recreate history
this.getApplication().getHistory().add(new Ext.app.Action({
url: 'tab/list'
}), true);
this.getApplication().getHistory().add(new Ext.app.Action({
url: 'details/' + stnId
}), true);
//make sure the store is loaded, then show the details page with passed id
store.on("load", function() {
this.showDetails(Ext.StoreManager.get("dcStations").getById(stnId));
}, this);
Hope that this boosts your efforts in getting started with routes and history management
i have four separete view, adding these four view in single tabview as shown below.
Tab View Code:
Ext.define("SLS.BRND.WEB.view.MainTabbarView", {
extend: 'Ext.tab.Panel',
xtype: 'MainTabbarView',
requires: ['Ext.data.proxy.JsonP', 'Ext.TitleBar', 'Ext.Video', 'SLS.BRND.WEB.view.GallerysView', 'SLS.BRND.WEB.view.FloorView'],
config: {
tabBarPosition: 'bottom',
items: [
{
xclass: "SLS.BRND.WEB.view.GlobalNavigationView",
docked: "top",
scrollable: false
},
{
xclass: 'SLS.BRND.WEB.view.ApartmentView'
},
{
xclass: 'SLS.BRND.WEB.view.SpecificationView'
},
{
xclass: 'SLS.BRND.WEB.view.FloorView'
},
{
xclass: 'SLS.BRND.WEB.view.GallerysView'
}
]
}
});
In controller onbuttontap function i am calling above 'MainTabbarView' page as shown below. i have set setActiveItem(0); to display first tabitem among four i.e (xclass: 'SLS.BRND.WEB.view.ApartmentView'). when i set like this setActiveItem(0) it will dispaly first view page but without data(blank screen).if i set like this setActiveItem(1), it will dispaly second view page with data. then i thought may be problem in first page, so i have changed order of page view in 'MainTabbarView'. again i set setActiveItem(0) then it showing active page but without data. i have keep on changed setActiveItem(0) to 1,2,3 its working fine and also data displaying. but for the setActiveItem(0) data is not displaying. can any help me . how to resolve this issue. thank you
Controller Code :
Ext.define("SLS.BRND.WEB.controller.ApartmentController", {
extend: "Ext.app.Controller",
requires: ['Ext.data.proxy.JsonP'],
config: {
refs: {
projectsPage: "projectspage",
mainTabbarView: "MainTabbarView",
},
control: {
projectsPage: {
BtnApartments: "onAptButtonTap"
}
}
},
onAptButtonTap: function () {
var ApartmentTabbar = this.getMainTabbarView();
ApartmentTabbar.setActiveItem(0);
Ext.Viewport.animateActiveItem(ApartmentTabbar, this.slideLeftTransition);
},
activateNotesList: function () {
Ext.Viewport.animateActiveItem(this.getHomepage(), this.slideRightTransition);
},
slideRightTransition: { type: 'slide', direction: 'right' },
slideDownTransition: { type: 'flip', direction: 'down' },
slideLeftTransition: { type: 'fade', direction: 'left' }
});
Your onAptButtonTap function is not in the right place, you put it in the config as you should put it after the config like so :
...
config: {
refs: {
projectsPage: "projectspage",
mainTabbarView: "MainTabbarView",
},
control: {
projectsPage: {
BtnApartments: "onAptButtonTap"
}
},
...
},
onAptButtonTap: function () {
var ApartmentTabbar = this.getMainTabbarView();
ApartmentTabbar.setActiveItem(0);
Ext.Viewport.animateActiveItem(ApartmentTabbar, this.slideLeftTransition);
},
...
I have two views. The User view has some text and a button. I want to use that button to switch to the second view. But i don't know how this works with sencha touch 2. When i press the button on the "UserView" (which is the first view), then i get the following error:
Uncaught Error: SYNTAX_ERR: DOM Exception 12
This is basically how my code looks right now:
app.js
Ext.Loader.setConfig({ enabled: true });
Ext.setup({
viewport: {
autoMaximize: false
},
onReady: function() {
var app = new Ext.Application({
name: 'AM',
controllers: [
'Main'
]
});
}
});
The Main controller
Ext.define('AM.controller.Main', {
extend: 'Ext.app.Controller',
views : ['User'],
init: function() {
this.getUserView().create();
this.control ({
'#new': {
tap: function() {
alert('aaaa');
}
}
});
}
});
And the two views:
Ext.define('AM.view.User', {
extend: 'Ext.Container',
config: {
fullscreen:true,
items: [{
xtype: 'button',
text: 'New',
id: 'new'
}
],
html: 'Testing<br />'
}
});
2nd view
Ext.define('AM.view.New', {
extend: 'Ext.Container',
config: {
fullscreen: true,
html: 'w00t'
}
});
Here is your application written the way it should be. Here are a few notes about the changes I made:
You should call Ext.application instead of Ext.setup when creating your MVC application.
All root views should be defined inside your app.js.
You no longer need to use this.control() in your controllers. You can simply use the control configuration in the config block.
You should define all views in the views config of Ext.application.
Instead of creating the view in init, do it in launch. This is components should be added into the view.
app/view/User.js
Ext.define('AM.view.User', {
extend: 'Ext.Container',
config: {
items: [
{
xtype: 'button',
text: 'New',
id: 'new'
}
],
html: 'Testing<br />'
}
});
app/view/New.js
Ext.define('AM.view.New', {
extend: 'Ext.Container',
config: {
html: 'w00t'
}
});
app/controller/Main.js
Ext.define('AM.controller.Main', {
extend: 'Ext.app.Controller',
config: {
control: {
'#new': {
// On the tap event, call onNewTap
tap: 'onNewTap'
}
}
},
launch: function() {
// When our controller is launched, create an instance of our User view and add it to the viewport
// which has a card layout
Ext.Viewport.add(Ext.create('AM.view.User'));
},
onNewTap: function() {
// When the user taps on the button, create a new reference of our New view, and set it as the active
// item of Ext.Viewport
Ext.Viewport.setActiveItem(Ext.create('AM.view.New'));
}
});
app.js
Ext.application({
name: 'AM',
// Include the only controller
controllers: ['Main'],
// Include all views
views: ['User', 'New'],
// Give the Ext.Viewport global instance a custom layout and animation
viewport: {
layout: {
type: 'card',
animation: {
type: 'slide',
direction: 'left',
duration: 300
}
}
}
});
I also suggest you checkout the great guides over on the Sencha Touch API Docs, as well as checking out the Sencha Forums as they are very active and are a great source of information.