Defining a Panel and instantiating it in a viewport - javascript

I am trying to get Ext.define & Ext.create working in Sencha touch 2, so that I can define everything in my library and just create stuff pre-configured.
However, Ext.define is not doing what I would expect it to in anything I've tried.
Why does the following code not create a panel inside the viewport with the field label "Tame"?
Ext.define('mobi.form.Login',{
extend:'Ext.form.Panel',
items: [{
xtype: 'textfield',
name: 'Tame',
label: 'Tame'
}
]
});
Ext.application({
viewport: {
layout:'fit'
},
launch: function(){
var form = Ext.create('Ext.form.Panel', {
items: [{
xtype: 'textfield',
name: 'name',
label: 'Name'
}
]
});
Ext.Viewport.add(Ext.create('mobi.form.Login')); // This doesnt add anything to the viewport
Ext.Viewport.add(form); //magically this works
}
})

When using Ext.define, all configurations must go inside the config block. So your code should look like this:
Ext.define('mobi.form.Login',{
extend:'Ext.form.Panel',
config: {
items: [{
xtype: 'textfield',
name: 'Tame',
label: 'Tame'
}
]
}
});
In general the only exceptions to this are:
extend
requires
xtype
singleton
alternateClassName
Anything else should be inside the config object, but remember, only when using Ext.define.

It looks like you are trying to use the sencha MVC concept but this is wrong if this is your only piece of code.
First create the following folder structure:
MyAppFolder
index.html (include the sencha lib here)
app.js (main file)
app (folder)
controller
Main (main controller)
model (optional if no model is defined)
store (optional if no model is defined)
view
Viewport.js (your main viewport)
resources
css
style.css (your custom style)
images (your icons and images if you have)
Then in your app.js you would define something like this:
// enable loader for dynamic loading of .js classes
Ext.Loader.setConfig({
enabled : true,
paths : {
}
});
/**
* Better performance is achived when knowing which .js classes we need to load prior to execution of this class.
*/
Ext.require([
]);
/**
* This is the definition of our mobile application.
* The name of this app is MVCTest.
*/
Ext.application({
name : 'MVCTest',
controllers : ['Main'],
views : ['Viewport'],
launch : function() {
Ext.create('MVCTest.view.Viewport');
}
});
Then your main controller:
Ext.define('MVCTest.controller.Main', {
extend : 'Ext.app.Controller',
config : {
refs : {
viewport : 'mvctest-viewport'
}
}
});
Then your viewport would look something like this, according to your example:
Ext.define('MVCTest.view.Viewport', {
extend : 'Ext.Container',
xtype : 'mvctest-viewport',
config : {
fullscreen : true,
layout : 'card',
items:
[
{
xtype: 'textfield',
name: 'name',
label: 'Name'
},
{
xtype: 'mvctest-tame'
}
]
}
});
By specifying the xtype mvctest-tame it will search for this xtype and add this in as a new item to this card. So you need the tame view:
Ext.define('MVCTest.view.Login',{
extend:'Ext.form.Panel',
xtype: 'mvctest-tame',
items: [{
xtype: 'textfield',
name: 'Tame',
label: 'Tame'
}
]
});
And do not forget to add the Login view to the app.js..

Related

how to navigate page in sencha touch2?

I am new in sencha touch and i am refer this project for learning purpose.
In this project, i am trying to add login module, if login is successful then the other things is display (which is already in project).
I made changes in app.js file and load login form(this is worked).
app.js :
ToolbarDemo = new Ext.Application({
name: "ToolbarDemo",
launch: function() {
this.views.Home = new this.views.Home();
//this.views.viewport = new this.views.Viewport();
//this.views.homecard = this.views.viewport.getComponent('home');
}
});
and In Home.js, i create login screen and if username is not blank i want to redirect it to Viewport.js which contain other pages.
I try some things which is commented in if blocks.
Home.js :
ToolbarDemo.views.Home = Ext.extend(Ext.form.FormPanel, {
fullscreen: true,
title: 'Login',
cls:'Loginscreen',
id:'loginFormPanel',
items:
[
{
html: '<div align="center"><img style="height: 100px; width: 100px;" src="stylesheets/images/main-logo.png" /></div>'
},
{
xtype: 'fieldset',
items: [
{
xtype: 'textfield',
name : 'name',
id:'name',
placeHolder : 'User Name',
},{
xtype: 'passwordfield',
name : 'password',
placeHolder : 'Password',
}
]
},
{
xtype: 'button',
text: 'Login',
cls:'LogingButton',
ui: 'confirm',
itemId:'loginbutton',
handler: function() {
var name = Ext.getCmp('name').getValue();
//var pass = Ext.getCmp('password').getValue();
if(name != '')
{
//ToolbarDemo.app.switchMainView('ToolbarDemo.view.Viewport');
//Ext.Viewport.setActiveItem(Ext.create('ToolbarDemo.view.Viewport'));
//this.redirectTo('Viewport');
//var firststep = Ext.create('ToolbarDemo.view.Viewport');
//Ext.Viewport.setActiveItem(firststep);
/*ToolbarDemo = new Ext.Application({
name: "ToolbarDemo",
launch: function() {
this.views.viewport = new this.views.Viewport();
this.views.homecard = this.views.viewport.getComponent('home');
}
});*/
alert("aa");
}
}
}
],
});
Viewport.js :
ToolbarDemo.views.Viewport = Ext.extend(Ext.TabPanel, {
fullscreen: true,
xtype: 'viewport',
initComponent: function() {
Ext.apply(this, {
tabBar: {
dock: 'bottom',
layout: {
pack: 'center'
}
},
items: [
{ xtype: 'homecard', id: 'home' },
{ xtype: 'searchcard' },
{ xtype: 'actioncard' },
{ xtype: 'logincard' },
{ xtype: 'settingscard' },
{ xtype: 'morecard' }
]
});
ToolbarDemo.views.Viewport.superclass.initComponent.apply(this, arguments);
}
});
so how to navigate the page? I am try this and this but it is not helped.
another quetion:
I am also refer other tutorials and also the official website of sencha in which they use controller,model and view type patterns and in my project there is no controller.
so which types of coding format should i follow that helped me to understand senchatouch?
Is my project is good for practice?
I refer diff. tutorials and i become confused. so what shoud i do?
Thanks in advance.
Read the 4th point - Animate and activate containers from a common function from this article Sencha Touch coding guidelines you should follow: Part 1 and you will understand how to do this. We generally have a common function in our Utility class that takes care of page navigation.
Regarding Sencha Touch practice, it seems you still lack some understanding. You should find a good book and spend some time understanding the basic concepts. Here is a good tutorial on how to create a Sencha Touch app: How to Create a Sencha Touch 2 App
If you want an advanced tutorial, here is a thorough tutorial that provides a step-by-step app development process:
Create a Location-Aware Site with Sencha Touch
Create a Location-Aware Site with Sencha Touch – Displaying Locations

Sencha Tap listener not firing

I have a test application with a couple of views. I am trying to invoke a simple 'tap' listener on my buttons. Even though the controller is instantiated and launched, the tap event does not seem to fire.
Here's my app.js
Ext.application({
name: 'MyApp',
requires: [
'Ext.MessageBox',
'Ext.form.FormPanel',
'Ext.navigation.View'
],
views: [
'Main',
'Tasks'
],
controllers: [
'Main'
],
models: [
'Task',
'Schedule'
],
stores: [
'Tasks',
'Schedules'
],
launch: function() {
// Destroy the #appLoadingIndicator element
try{
Ext.fly('appLoadingIndicator').destroy();
}catch(err){
console.warn("[CUSTOMWARN]Could not destroy loading indicator because of -- \n"+err);
}
var DEBUG=false;
if(!DEBUG){
// Initialize the main view
Ext.Viewport.add(Ext.create('MyApp.view.Main'));
}
}
});
Main.js -- controller
Ext.define('MyApp.controller.Main', {
extend: 'Ext.app.Controller',
requires: [
'MyApp.view.Main'
],
init: function(){
// download and parse data from server here.
console.log('controller initiated!');
},
config: {
refs: {
loginBtn: 'button[action=login]'
},
control: {
loginBtn: {
tap: 'loginBtnHandler'
}
}
},
loginBtnHandler: function(){
this.callParent(arguments);
Ext.Msg.alert('here');
}
});
Main.js -- view
Ext.define('MyApp.view.Main', {
extend: 'Ext.navigation.View',
alias: 'customnavigationview',
requires: [
'MyApp.form.Login'
],
config: {
navigationBar: {
hidden: true
},
items: [
{
xtype: 'logincard',
flex: 1
}
],
}
});
Login.js -- for xtype: 'logincard'
Ext.define('MyApp.form.Login', {
extend: 'Ext.form.Panel',
xtype: 'logincard',
requires: [
'Ext.field.Password',
'Ext.field.Email',
'Ext.form.FieldSet',
'Ext.field.Toggle',
'Ext.Label'
],
// id: 'loginForm',
config: {
items: [
{
xtype : 'label',
html : 'Login failed. Please enter correct credentials.',
itemId : 'signInFailedLabel',
hidden : true,
hideAnimation : 'fadeOut',
showAnimation : 'fadeIn',
style : 'color:#990000;',
margin : 10
},
{
title: 'Please log in',
xtype: 'fieldset',
items:[
{
xtype: 'textfield',
name : 'username',
label: 'UserName'
},
{
xtype: 'passwordfield',
name : 'password',
label: 'Password'
}
]
},
{
xtype: 'fieldset',
items: [
{
xtype : 'togglefield',
name : 'rememberLogin',
label : 'Remember Me '
}
]
},
{
xtype : 'button',
id : 'loginSubmitBtn',
itemId : 'loginSubmitItemBtn',
text : 'Login',
ui : 'action',
action : 'login',
margin : 10
}
]
}
});
Any help would be highly appreciated!
EDIT: So I tried to use Ext.ComponentQuery.query("#loginSubmitBtn") and on printing the output on console, I can see that it is pointing to the correct button. Here's the output.
0: Class
_badgeCls: "x-badge"
_baseCls: "x-button"
_disabledCls: "x-item-disabled"
_floatingCls: "x-floating"
_hasBadgeCls: "x-hasbadge"
_hiddenCls: "x-item-hidden"
_icon: false
_iconAlign: "left"
_itemId: "loginSubmitItemBtn"
_labelCls: "x-button-label"
_margin: 10
_pressedCls: "x-button-pressing"
_pressedDelay: 0
_styleHtmlCls: "x-html"
_text: "Login"
_ui: "action"
action: "login"
badgeElement: Class
bodyElement: Class
config: objectClass
currentUi: "x-button-action"
element: Class
eventDispatcher: Class
getEventDispatcher: function () {
getId: function () {
getObservableId: function () {
getUniqueId: function () {
iconElement: Class
id: "loginSubmitBtn"
initConfig: function (){}
initialConfig: Object
initialized: true
innerElement: Class
managedListeners: Object
observableId: "#loginSubmitBtn"
onInitializedListeners: Array[0]
parent: Class
referenceList: Array[4]
refreshFloating: function () {
refreshSizeState: function () {
renderElement: Class
rendered: true
textElement: Class
usedSelectors: Array[1]
__proto__: Object
length: 1
**EDIT 3: ** Found it! See answer here: Sencha Tap listener not firing
The listener for a button tap should be just 'tap' instead of 'itemtap'
tap: 'loginBtnHandler'
Hope it helps-
I think I've had this problem in the past. Try qualifying the ref in the controller with the view name to narrow the query down:
loginBtn: 'logincard button[action=login]'
Not the best, but should work:
First remove the tap listener on the controller. Also remove the 'action' property on the button, and set the handler on the button:
{
xtype : 'button',
id : 'loginSubmitBtn',
itemId : 'loginSubmitItemBtn',
text : 'Login',
ui : 'action',
//action : 'login',
margin : 10,
handler : function () {
MyApp.app.getController('Main').loginBtnHandler()
}
}
Ok, this is weird, but I found out why my buttonclick was not being handled properly. I usually use Google Chrome as my testing browser with web inspector on. I downloaded Safari and tried the same code and it worked like its supposed to. I looked at both the browsers, and the only difference was that Chrome had web inspector on, while Safari didn't. I closed the web inspector in Chrome and the button handler worked great (without reloading). I restarted the browser, pushed the inspector to a separate window, none of them worked. However, Safari works great even with inspector on. Probably a Chrome bug?
Google Chrome version: 27.0.1453.110
*EDIT: * I had the touch emulation turned on in the web inspector. With this turned on, we have to close the web inspector for the touch event to register. Otherwise, we have to turn off the touch emulation to register for the events while the web inspector is open.
TL;DR: Close your web inspector in Chrome before testing, if you have touch emulation turned on.

Sencha Touch 2 Ext.List - programmatically add detail view

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 :)

Sencha Touch 2: data intigration or how to share dynamic information between sencha and javascript

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.

Sencha Touch 2 - TabPanel does not work in MVC designed App

simple question for you today...
This works:
var carousel = Ext.create('Ext.Carousel', {
fullscreen: 'true',
//load in views view clean instantiation using
// the widget.alias's defined in each view... yea
// For some reason, putting flex on these components... oh...
// Have to call directly in by just the xtype since these are just
// references..
items: [
{
xtype: 'Main'
},
{
xtype: 'CommentList'
}
]
This does NOT work:
var tabpanel = Ext.create('Ext.TabPanel', {
fullscreen: 'true',
tabBarPosition: 'bottom',
defaults: {
styleHtmlContent: true
},
//load in views view clean instantiation using
// the widget.alias's defined in each view... yea
// For some reason, putting flex on these components... oh...
// Have to call directly in by just the xtype since these are just
// references..
items: [
{
xtype: 'Main',
title: 'The Main',
iconCls: 'user'
},
{
xtype: 'CommentList',
title: 'Comments',
iconCls: 'user'
}
]
});
As you can see, they are pretty much the same except one is a TapPanel (with the required default configs added) and the other is a carousel.
Everything else is exactly the same.... This is in the app.js of my Sencha Touch 2.0 app designed following the MVC architecture.
The result of the not-working TabPanel is that I only see the first view (Main) and no tab-bar appears in the bottom of the screen.
Any ideas what my problem might be?
I am not sure if this is an issue but in my code the line is:
Ext.create("Ext.tab.Panel", {
Not:
Ext.create('Ext.TabPanel', {
Fullscreen should be fullscreen: true instead of fullscreen: 'true'. You could also add this code to make them switch:
cardSwitchAnimation: {type: "fade", duration: 1000},
layout: "card",
Didn't test it, but it worked for me (got it from a snippet of my own code)

Categories