Sencha Touch 2.0 Controller refs attribute not working? - model-view-controller

i am wondering about the 'refs' attribute of Sencha Touch class 'Ext.app.Controller'.
I saw a video tutorial where a simple contactForm was built. No i've tried to build a contact form for my app and i get an error: 'Uncaught TypeError: Object [object Object] has no method 'getContactForm''
Here's my controller
Ext.define('MyFirstApp.controller.Main', {
extend: 'Ext.app.Controller',
views: ['Viewport', 'Home'],
refs: [
{
ref: 'contactForm',
selector: '#contactForm'
}
],
init: function() {
this.control({
'button[action=submitContact]': {
tap: 'submitContactForm'
}
});
},
submitContactForm: function() {
var form = this.getContactForm();
form.submit({
url: 'contact.php'
});
}
});
I guess it's something wrong with the 'refs', in the video that guy said the "getContactForm" method will be created because of the "ref" attribute of "contactForm" but it doesn't. What am i doing wrong here?..Thanks for help!

The refs attribute property changed from Sencha Touch 2.0 developer preview version to beta/final version. So, what you wrote were correct for dev preview but presently it just name value pair. For your case:
refs: {
contactForm: '#contactForm'
}

I agree with jeremygerrits, I can't be sure that's the correct syntax for defining refs.
Based on the documentation, I would rather do it like this:
Ext.define('MyFirstApp.controller.Main', {
extend: 'Ext.app.Controller',
views: ['Viewport', 'Home'],
config: {
refs: {
contactForm: '#contactForm'
}
}
init: function() {
this.control({
'button[action=submitContact]': {
tap: 'submitContactForm'
}
});
},
submitContactForm: function() {
var form = this.getContactForm();
form.submit({
url: 'contact.php'
});
}
});
See also: http://docs.sencha.com/touch/2-0/#!/guide/controllers

It looks as though you may have the refs configured wrong. Here's a simple controller:
Ext.define('App.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
main: 'mainpanel'
}
}
});
mainpanel is an xtype or could be a css selector and main will give you getMain() like what was talked about in the video.

Related

Extjs4 add click event to a container and handle it in a controller

{xtype : 'container',
id:'leaderPhotoContainer',
listeners:{click: {
element: 'el', //bind to the underlying el property on the panel
fn: function(e,panel,obj){ //click function
console.log('click el'); //It will work.
obj.fireEvent('click');
//if I adding my code here ,it is worked ,but I want to fire this event to the controller ,and be handled there.
//How I can get the 'container' here ?
//container.fireEvent('click') I guess it will work.
}
}}}
Can someone help me? Thank you.
listeners:{click: {
element: 'el', //bind to the underlying el property on the panel
fn: function(e,panel,obj){ console.log('click el');
this.down('#leaderPhotoContainer').fireEvent('click');
}
,scope:this//It must be a upper container.
}
Maybe It is a silly way to slove it,but It is worked . Is there a better way?
You can bind your event in your controller.
//...
init: function () {
this.control({
'yourpanel': {
afterrender: function(panel) {
panel.mon(panel.el, 'click', this.foo);
}
}
});
},
foo: function() {
console.log('Foo');
}
//...

jQuery Mobile iScrollView error

I am using jQuery Mobile and iScrollview together,
I used iscrollView
The scrolling work fine.
Problem 1:
when I click on a input text/password field, I get an extra box overlapping the whole elements, which has the same content as the input.
same problem found in
here no solution
Problem 2:
when navigating to next page, the previous page remains behind new page and when tap the mobile screen the previous page goes off from the device. this is not happening in the webbrowsers.
Any suggestions,
code for main.js
require.config({
paths: {
jquery: '../lib/jquery',
'jquery.mobile-config': 'helper/jqm-config',
'jquery.mobile': '../lib/jquery.mobile-1.2.1.min',
underscore: '../lib/underscore-min',
backbone: '../lib/backbone-min',
templates: '../templates',
text: 'helper/text',
config: 'helper/config',
'backbone.subroute': '../lib/backbone.subroute',
'cookie': '../lib/jquery.cookie',
'maskInput': '../lib/Jquerymaskinput',
'iscroll': '../lib/iscroll',
'iscrollview': '../lib/jquery.mobile.iscrollview',
}
,
shim: {
'underscore': {
exports: "_"
},
'backbone': {
//These script dependencies should be loaded before loading
//backbone.js
deps: ['jquery', 'underscore'],
//Once loaded, use the global 'Backbone' as the
//module value.
exports: 'Backbone'
},
'jquery.mobile-config': ['jquery'],
'jquery.mobile': ['jquery', 'jquery.mobile-config'],
'backbone.subroute': ['jquery', 'underscore', 'backbone'],
//'backbone.oauth':['jquery','underscore','backbone'],
'iscroll': {
deps: ['jquery.mobile']
},
'iscrollview': {
deps: ['iscroll']
},
'config': {
exports: 'Config'
}
}
});
requirejs(['jquery', 'iscroll', 'jquery.mobile', 'iscrollview'], function($, iScroll) {
var elements = jQuery(document).find(":jqmData(iscroll)");
elements.iscrollview();
});
require([
'app'
], function(App) {
App.initialize();
});
for router
define([
'jquery',
'underscore',
'backbone',
'backbone.subroute'
], function($, _, Backbone) {
var AppRouter = Backbone.Router.extend({
routes: {
// general routes
'': 'defaultAction',
'login':'login',
'menu': 'mainMenu',
// Default
'*actions': 'defaultAction'
}
});
var initialize = function() {
$('.back').live('click', function(event) {
event.preventDefault();
window.history.back();
return false;
});
var app_router = new AppRouter;
app_router.on('route:defaultAction', function(actions) {
require(['views/home/register'], function(RegisterView) {
// We have no matching route, lets display the home page
console.log('At defaultAction');
var registerView = new RegisterView();
registerView.render();
/// this.changePage(loginView, 'slide');
});
});
app_router.on('route:login', function(actions) {
require(['views/home/login'], function(LoginView) {
// We have no matching route, lets display the home page
console.log('At defaultAction');
var loginView = new LoginView();
loginView.render();
/// this.changePage(loginView, 'slide');
});
});
app_router.on('route:mainMenu', function(actions) {
require(['views/home/menu'], function(MainMenuView) {
console.log('At mainMenu::router');
var mainMenuView = new MainMenuView();
mainMenuView.render();
// this.changePage(mainMenuView, 'slide');
});
});
Backbone.history.start();
};
return {
initialize: initialize
};
});
I rewrite the codes but, its more or less solved my problem updated the jqm to 1.3 and jquery to 1.9.
rewrite all css files.
Navigation to next page is fine
and at least its working now.
Thanks to Omar who helped me.
gracias mi amigo

Handle tapStart Event on a button

I have an app with a carousel. On all of the carousel pages there are elements such as buttons and datepickers. I would like to handle the tapStart event on each of these elements using Sencha Touch but I haven't been able to find anything to allow me to do this.
Does anyone have an idea?
UPDATE
I asked this question on the Sencha Forums as well. Here is the link to the Sencha Forum thread: http://www.sencha.com/forum/showthread.php?262804-Handle-tapStart-Event-on-a-button&p=963782#post963782
You can try using touchstart which can be bound to any element including button
I figured out a solution to my problem with help from the Sencha Touch Forums.
First I used the initConfig function to initialize my configuration of my container.
Ext.define('MyApp.view.ViewName', {
...
// Very Important, this is what I use in the controller to handle the events
xtype: 'myxtype',
...
initConfig: function () {
var me = this;
this.config = {
...
items: {
...
{
xtype: 'button',
...
listeners: {
element: 'element',
// This is where my code handles the tapstart
// (touchstart) event
touchstart: function () {
// Fire an event on the controller (me)
me.fireEvent('buttondown');
}
}
},
...
}
}
this.callParent([this.config]); // Very Important when using initConfig
}
});
Then, in my controller I added this code:
Ext.define('MyApp.controller.MainController', {
...
config: {
views: [
'ViewName',
...
],
...
},
...
init: function () {
this.control({
'myxtype': {
buttondown: this.myFunction
}
})
},
myFunction: function () {
// Do something
}
});

Why not call methods of a class

I have got a TabContainer class. This class is a extend of Ext.tab.Panel.
The create works fine, but, when i try send a message to instance Firebug says:
"TypeError: tbbar.canAddTab is not a function"
The class is:
Ext.define('KMA.view.environment.TabContainer',{
extend: 'Ext.tab.Panel',
alias: 'widget.environmenttabcontainer',
initComponent: function(){
[...]
this.callParent(arguments);
},
createTab: function(aTitle,aToolTip,anItem){
return {
title: aTitle,
itemId: aTitle + "Tag",
tabconfig: {
title: aTitle,
tooltip: aToolTip,
items: anItem
}
};
},
openTabs: function(){
return this.getItems().length;
},
maxOpenTabs: function(){
return 7;
},
canAddTab: function(){
return (this.openTabs() < this.maxOpenTabs());
},
addTab: function(aTabCfg){
this.add(aTabCfg);
}
});
My example code is:
var tbbar = Ext.ComponentQuery.query('environmenttabcontainer');
console.log(tbbar);
console.log(tbbar.canAddTab());
In the first "console.log" Firebugs show the instance of TabContainer, and show the methods of the class. But, why not work ?. Any idea ?
I am guessing it is not working because Ext.ComponentQuery.query returns an array.
This works:
var t = new KMA.view.environment.TabContainer();
Ext.ComponentQuery.query('environmenttabcontainer')[0].canAddTab
> function (){
return (this.openTabs() < this.maxOpenTabs());
}
Is there a reason why you are using a component query instead of having a direct reference ?

How give parameters to ExtJS controller from Ext.application

Actually I'm creating my first ExtJS 4 MVC application. Following the application guide from documentation, I initialize my controller like that :
Ext.application({
name: 'RateManagement',
appFolder: 'softcom',
context: null,
constructor: function(context) {
this.context = context;
},
launch: function() {
Ext.create('Ext.Panel', {
layout: 'fit',
renderTo: 'rate-management',
items: [
{
xtype : 'ratelist'
},
{
xtype : 'rateedit'
}
]
});
},
controllers: [
'Rate'
],
});
But for future ajax call, my controller need to know the ajaxUrl which is coming from Liferay 6. In Liferay, I can get URL like that :
<portlet:resourceURL var="listRates" escapeXml="false" id="listRates"></portlet:resourceURL>
<script type="text/javascript">
var rateContext = {
contextPath: '<%=request.getContextPath()%>',
listRatesUrl : '${listRates}',
strings: strings
};
</script>
My idea is to pass the var rateContext to my controller "Rate".
Any Idea?
Thank you!!
Concept of passing variable from app to controller looks wrong to me. Instead I would create getter somewhere in your app config
Ext.application({
// ...
context: null,
getContext: function() {
return this.context;
},
constructor: function(context) {
this.context = context;
},
// ...
});
And then you can get it from controller using:
this.application.getContext()
But if you would like to use approach of passing variable to controller you always can use
yourApp.getController("Rate") (you can do it in your lounch method) in order to access the controller.

Resources