Sencha Touch 2 - Add javascript to views - javascript

How do I use JS in a Sencha Touch view?
Ext.define('project.view.viewexample', {
extend: 'Ext.Panel',
xtype: 'asd',
config: {
styleHtmlContent: true,
scrollabe: 'vertical',
title: 'TITLE!',
Html: '<html>code and also JS?'
}
});
I have htmlcode which includes jscode (within Script-tags). It doesn't seem to work to use in this matter, am I right? I've also tried to use tpl, but it doesn't change anything.
Anyone know how to properly use JS? A somewhat better alternative would be to use it within the controller, but in that case I don't know how to pass the data.
EDIT:
I've come somewhat closer to a solution I think. This code below is clearly wrong, but maybe someone can see what I'm doing wrong:
Ext.define('projext.view.viewexample', {
extend: 'Ext.Panel',
xtype: 'gps',
config: {
styleHtmlContent: true,
scrollabe: 'vertical',
title: 'GPS',
tpl: 'Här var det GPS'
},
constructor: function() {
this.getPosition();
},
getPosition: function() {
var geo = Ext.create('Ext.util.Geolocation', {
autoUpdate: false,
listeners: {
locationupdate: function(geo) {
alert('New latitude: ' + geo.getLatitude());
},
locationerror: function(geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
if(bTimeout){
alert('Timeout occurred.');
} else {
alert('Error occurred.');
}
}
}
});
geo.updateLocation();
}
});

The html config needs to be lower-case.
Ext.define('project.view.viewexample', {
extend: 'Ext.Panel',
styleHtmlContent: true,
scrollabe: 'vertical',
title: 'TITLE!',
html: 'define your html'
});

Related

ExtJS reusable views and controllers

I just started with Extjs and I have few basic doubts.I have created a simple view(ScreenPropertiesPage) which has 1 select box and 1 custom view inside it. onchange of the select box value, view field is updated which is done in controller. I am done with creating view and controller which has listener for onchange select box value and updates associated view field.
But now the problem is : in my application I have to create 4 instances of ScreenPropertiesPage view and when onchange event is triggered from any views the textbox of 1st view is updated always. How to combine the event to specific view? What is the best procedure to combine controller and views and to reuse it(Even link to the documents from where I can learn controller view reusability is enough)? Any help is greatly appreciated.
Code skeleton for view:
Ext.define('Configurator.view.screenproperties.ScreenPropertiesPage', {
extend: 'Ext.container.Container',
alias: 'widget.screenpropertiespage',
requires: [
'Configurator.store.screenproperties.ScreenProperties'
],
autoScroll: true,
config: {
overLayMode: false
},
initComponent: function () {
var me = this;
this.items = [{
xtype: 'container',
componentCls: 'screenComboSelectorPanel',
layout: {
type: 'hbox',
align: 'center',
pack: 'center'
},
items: [{
xtype: 'combo',
store: Ext.create(
'Configurator.store.screenproperties.ScreenProperties'
),
itemId: 'screenSelector',
margin: 3,
width: 400,
listConfig: {
maxHeight: 200
},
fieldLabel: 'Screen Name',
disabledCls: 'disabledBtn',
disabled: me.getOverLayMode(),
queryMode: 'local',
emptyText: '-SELECT-',
valueField: 'screenName',
displayField: 'screenName',
forceSelection: true,
selectOnTab: true,
autoSelect: true,
height: 25,
tpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item comboContainer "><div class="rowExpanedrTextArea " style="">{screenName} </div>{[this.isExpandable(xkey,parent,values,xindex)]}</div>',
'</tpl>'
),
displayTpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'{screenName}',
'</tpl>'
)
}]
}, {
xtype: 'screenpropertieseditor',
itemId: 'messagesEditor',
margin: '25',
header: true,
frame: false,
border: true,
collectionName: 'messages',
title: 'Messages'
}]
me.callParent(arguments);
}
});
When user changes the value in combobox I want to update the screenpropertieseditor type view.
Controller for view :
Ext.define('Configurator.controller.ScreenProperties', {
extend: 'Ext.app.Controller',
refs: [{
ref: 'screenPropertiesPage',
selector: 'screenpropertiespage'
}, {
ref: 'screenSelector',
selector: 'screenpropertiespage combobox[itemId=screenSelector]'
}, {
ref: 'screenPropertiesMessagesEditor',
selector: 'screenpropertieseditor[itemId=messagesEditor]'
}, {
ref: 'screenPropertiesPage',
selector: 'screenpropertiespage'
}],
init: function (application) {
var me = this;
this.control({
'screenpropertiespage combobox[itemId=screenSelector]': {
change: this.screenPropertiesPageStoreHandler
}
});
},
screenPropertiesPageStoreHandler: function (thisObj, eOpts) {
var messagesEditor = this.getScreenPropertiesMessagesEditor();
var screenSelector = this.getScreenSelector();
var screenSelected = screenSelector.getValue();
//Screen tile store first time loading handling
if (screenSelected === undefined) {
screenSelected = screenSelector.getStore().getAt(0).data.screenName;
}
var selectedRecord = screenSelector.getStore().findRecord(
'screenName',
screenSelected, 0, false, false, true);
if (selectedRecord != undefined) {
Ext.apply(messagesEditor, {
'screenName': screenSelected
});
try {
messagesEditor.bindStore(selectedRecord.messages());
} catch (e) {}
}
}
});
ScreenPropertiesPage will hava lot more extra fields along with this. I have to create multiple instances of ScreenPropertiesPage. screenPropertiesPageStoreHandler method of Configurator.controller.ScreenProperties will be triggered whenever value changes in the combobox of any ScreenPropertiesPage view. But since my ref and selector in controller are not proper it always refers to the first ScreenPropertiesPage view.
You need to know that Controller in Extjs is singleton.
But you can force Controller in your case ScreenProperties to handle multiple instances of views. This is done by firing events from particular view instance to Controller to handle more complex logic.
Before i throw an example you need to be aware that using refs with handling multiple instance of the same view is wrong because it uses this code(it is just a wrapper): Ext.ComponentQuery.query('yourComponent')[0]; So from your view instances pool it gets first.
So you need to get rid off refs in your controller since it does not work with multiple instance of the same view.
Alright, lets make this happen and implement good way to handle multiple instances of the same view/components.
In your view:
initComponent: function () {
var me = this;
this.items = [{
xtype: 'container',
componentCls: 'screenComboSelectorPanel',
layout: {
type: 'hbox',
align: 'center',
pack: 'center'
},
items: [{
xtype: 'combo',
store: Ext.create(
'Configurator.store.screenproperties.ScreenProperties'
),
itemId: 'screenSelector',
margin: 3,
width: 400,
listConfig: {
maxHeight: 200
},
fieldLabel: 'Screen Name',
disabledCls: 'disabledBtn',
disabled: me.getOverLayMode(),
queryMode: 'local',
emptyText: '-SELECT-',
valueField: 'screenName',
displayField: 'screenName',
forceSelection: true,
selectOnTab: true,
autoSelect: true,
height: 25,
tpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item comboContainer "><div class="rowExpanedrTextArea " style="">{screenName} </div>{[this.isExpandable(xkey,parent,values,xindex)]}</div>',
'</tpl>'
),
displayTpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'{screenName}',
'</tpl>'
),
listeners: {
change: function (cmp, newValue, oldValue) {
this.fireEvent('onCustomChange',cmp,newValue, oldValue)
},
scope: this
}
}]
}
In your Controller - ScreenProperties you need to listen on this event and handle particular instance of component in view:
init: function (application) {
var me = this;
this.listen({
// We are using Controller event domain here
controller: {
// This selector matches any originating Controller
'*': {
onCustomChange: 'onCustonChangeHandler'
}
}
});
},
onCustonChangeHandler: function(componentInstance, newValue, oldValue) {
//Your complex logic here.
//componentInstance is the instance of actual component in particular view
}
In this way you can handle multiple instances of the same view with one controller since every particular component that is created in your view is passed by event.

Sencha Touch 2.x - How to load a custom view into a tab panel? Use xtype?

I am completely new to Sencha 2 Touch. This is my second day playing with it.
I have a custom class (app/view/Howdy.js):
Ext.define('MyApp.view.Howdy', {
extend: 'Ext.Panel',
xtype: 'howdy', // <--- this creates the 'howdy' xtype reference right?
requires: [
'Ext.SegmentedButton'
],
config: {
fullscreen: true,
html: ['Hello Word.'].join("")
}
});
and I am now trying to load it into a tab when clicked:
Ext.define('MyApp.view.Main', {
extend: 'Ext.tab.Panel',
config: {
fullscreen: true,
tabBarPosition: 'bottom',
items: [
{
title: 'TAB 1',
iconCls: 'star',
xtype: 'howdy', // <--- WHY IS THIS CRASHING MY APP?
},
]
}
});
If I remove the xtype declaration inside TAB 1 and replace it with an html everything works fine. As soon as I try and load my custom view into the tab all I get is a white screen in my browser and console shows no errors ???
P.S Yes everything is setup correctly already in App.js:
views: ['Howdy','Main'],
HELP PLEASE!
Late to update this thread but the solution was simply to remove the fullscreen: true declaration from inside the config in MyApp.view.Howdy.
I hope that this will help you:
MyApp.view.Howdy
Ext.define('MyApp.view.Howdy', {
extend: 'Ext.Container',
xtype: 'howdy',
requires: [
'Ext.SegmentedButton'
],
config: {
incoCls: 'star',
title: 'TAB 1',
html: ['Hello Word.'].join("")
}
});
MyApp.view.Main
Ext.define('MyApp.view.Main', {
extend: 'Ext.tab.Panel',
config: {
fullscreen: true,
tabBarPosition: 'bottom',
items: [
{xclass: 'MyApp.view.Howdy'},
]
}
});
You should use alias: widget.XTYPE
Ext.define('MyApp.view.Howdy', {
extend: 'Ext.Panel',
alias: 'widget.howdy', // <--- this creates the 'howdy' xtype reference right?
requires: [
'Ext.SegmentedButton'
],
config: {
fullscreen: true,
html: ['Hello Word.'].join("")
}
});
A couple of things. First, xtype is what you use to define the type if you're adding it instantly...if you haven't already defined it with Ext.create. If you've already created it, then you don't need it. When creating panels, each item contains all the info for itself, title, icon, everything. Then, just add the item(s) into a tabPanel:
var a = Ext.create('Ext.Panel',{
iconCls:'star',
title:'tab1',
html:'tab one content'
});
var b = Ext.create('Ext.Panel',{
iconCls:'star',
title:'tab2',
html:'tab two content'
});
var panel = Ext.create('Ext.TabPanel',{
items:[a,b]
});

Getting Model from GridPanel in ExtJS

I have a gridpanel that allows inline editing of a column. This column uses a combobox as the editor, and neither the "change" event nor the "select" event give me something usable to backtrace the edited value to get the changed row from the gridpanel.
I believe Ext floats the editor's combobox so therefore I can't do something simple like
combo.up()
To return to the grid.
Here is the grid panel from the view:
{
xtype: 'gridpanel',
title: 'Important Projects',
id: 'importantProjectsGrid',
dockedItems: [],
flex: 1,
columns: [
{ header: 'Quote Name', dataIndex: 'QuoteName', flex: 4 },
{ header: 'Quote Status', dataIndex: 'QuoteStatusID', flex: 6, editor: {
xtype: 'combobox',
editable: false,
action: 'QuoteStatus',
selectOnTab: true,
store: 'statuses',
queryMode: 'local',
displayField: 'Description',
valueField: 'Description'
} }
],
store: 'myimpprojects',
selModel: {
selType: 'cellmodel'
},
plugins: [Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})]
}
Here is the controller code pertaining to this:
init: function () {
this.control({
'[action=QuoteStatus]': {
change: function (combo, new_value, old_value, opts) {
// I need to go back up from this combobox
// to get the row that this value was edited in
// to grab an ID value from that row's data
// in order to make an ajax request
}
}
});
},
Thanks for any help!
You can monitor store's update event.
init: function () {
this.getMyimpprojectsStore().on('update', function(store, record) {
// do something with record
});
// ...
},
Try putting the listener on the CellEditing plugin. There are events for beforeedit, edit, and validateedit that receive an object containing references to the grid, the record, field, row and column indexes, and more. You should be able to check for the combobox in the event handler and handle your information from there.
Quick link to the doc page: Ext.grid.plugin.CellEditing
I'm convinced that the update plugin will handle the update automatically, through the api of the underlying store and post the data automatically to the server if the proxy as autoSync to true.
Example of the configured proxy:
Ext.define('MyApp.store.YourStore', {
extend: 'Ext.data.Store',
model: 'MyApp.model.YourGridModel',
autoSync: true, //Commits the changes realtime to the server
proxy: {
type: 'ajax',
batchActions : true, //Commits the changes everytime a value is changed if true o otherwise store the changes and batch update them in 1 single post
api: {
read: 'path/to/select',
create: 'path/to/create',
update: 'path/to/update',
destroy: 'path/to/delete'
},
reader: {
type: 'json',
root: 'results',
successProperty: 'success'
},
writer: {
type: 'json',
writeAllFields: true
},
listeners: {
exception: function(proxy, response, operation){
Ext.MessageBox.show({
title: 'REMOTE EXCEPTION',
msg: operation.getError(),
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
}
}
},
listeners: {
write: function(proxy, operation){
var response = Ext.JSON.decode(operation.response.responseText);
if(response.success == true)
{
//TODO: Proxy - Messageboxes might be a little anoying we might instead use the status bar in teh grid or something so show status of the operation
Ext.MessageBox.show({
title: this.xFileLibraryTitle,
msg: response.message,
icon: (response.success == true)? Ext.MessageBox.INFO : Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
}
}
}
});
I would look specially for the two configs: "autoSync" and "batchActions"
Hope this helps you further with your issue!

Sencha : Uncaught TypeError: Object function (){h.apply(this,arguments)} has no method 'setActiveItem'

I am using the following code in my application as an xtype. My list item is appearing the way i want but when i click on an item i have this error everytime i click on an item that is supposed to load a new page with datas : Uncaught TypeError: Object function (){h.apply(this,arguments)} has no method 'setActiveItem'. Any idea of how can i fix it? The refered items lines are commented in the code.
Here is my code :
var AppsBack = new Ext.Toolbar({
dock: 'top',
items: [{
text: 'back',
ui: 'back',
handler: function(){
Home.setActiveItem('home'); //Here is the second problem
}
}]
});
var AppsDetails = new Ext.Panel({
id: "appsdetails",
tpl: "{game}",
dockedItems: [AppsBack]
});
var AppsList = new Ext.List({
id: "appslist",
store: AppsStore,
layout: 'card',
emptyText: "No game found",
itemTpl: "{game}",
listeners: {
itemtap: function(view, index, item, e) {
var rec = view.getStore().getAt(index);
AppsDetails.update(rec.data);
AppsBack.setTitle(rec.data.game);
Home.setActiveItem('appsdetails') //Here is the first problem
}
}
});
var AppsListWrapper = new Ext.Panel({
id: "appslistwrapper",
layout: 'card',
items: [AppsList],
dockedItems: []
});
var Home = Ext.extend(Ext.Panel, {
id: "home",
iconCls: 'home',
title: 'Home',
fullscreen: true,
layout: 'card',
cardSwitchAnimation: 'slide',
initComponent: function() {
Ext.apply(this, {
items: [AppsListWrapper, AppsDetails]
});
Home.superclass.initComponent.apply(this,arguments)
}
});
Ext.reg('appsList', Home);
Thanks for your help
After a couple manipulation, i've discovered that the only reason why i am experiencing this trouble is because i am trying to extend the panel. In other terms if i use
new Ext.Panel
intead of
Ext.extend(Ext.Panel, {...
everything works fine excepted i can't use xtype in this case. Any ideas?
I figured it out!!!
MY solution consists in giving the new extended class as few arguments as possible. Therefore i divided the home extended class into two objects like this :
var Home = new Ext.Panel({
id: "home",
layout: 'card',
cardSwitchAnimation: 'slide',
items: [AppsListWrapper, AppsDetails]
});
var HomeTab = Ext.extend(Ext.Panel, {
iconCls: 'home',
title: 'Home',
layout: 'card',
initComponent: function() {
Ext.apply(this,{
items: [Home]
});
HomeTab.superclass.initComponent.apply(this,arguments);
}
});
Ext.reg('home', HomeTab);
Don't ask me how come, i won't be able to answer. I just followed my intuition ;)

GridPanel as item of tabPanel

I'm having trouble knowing if I syntactically have this setup right. From another thread, I understand to add the GridPanel to the tabBar items, which I do so below. In my App.js, I define a grid copied from the ExtJS example (here).
var grid = new Ext.grid.GridPanel({
// Details can be seen at
// http://dev.sencha.com/deploy/ext-3.4.0/docs/?class=Ext.Component?class=Ext.grid.GridPanel
});
Below that, I create an instance of my app:
appname.App = Ext.extend(Ext.TabPanel, {
fullscreen: true,
tabBar: {
ui: 'gray',
dock: 'bottom',
layout: { pack: 'center' }
},
cardSwitchAnimation: false,
initComponent: function() {
if (navigator.onLine) {
// Add items to the tabPanel
this.items = [{
title: 'Tab 1',
iconCls: 'tab1',
xtype: 'tab1',
pages: this.accountPages
}, {
title: 'Tab 2',
iconCls: 'tab2',
xtype: 'tab2',
pages: this.accountPages
},
grid];
} else {
this.on('render', function(){
this.el.mask('No internet connection.');
}, this);
}
appname.App.superclass.initComponent.call(this);
}
});
The app normally loads just fine, but with the addition of grid, it breaks and nothing loads.
Syntactically, should I be defining grid inside the app instantiation like A) grid: ..., B) this.grid = new ..., or C) as I have it as a regular var named grid?
Many thanks.
There is no inbuilt GridPanel comes with Sencha Touch. So, that Ext.grid.GridPanel will not work here. However, you can use Simoen's TouchGrid extension from here.
All the source codes are available here.

Categories