Shopware backend new article tab, key sent, value not - javascript

I have a task to create simple plugin for shopware to extend article with new tab and few fields in it. I did it some way, code is below, but i have a big problem:
after entering data for article on click on save button action is triggered, ajax call made, in networks section in browser I can see fields key but there is no value.
Request params look like this:
name: bla bla
myfield: <--- problem
category: some category etc..
Things worked well when fields was in original tabs.
app.js:
// {block name="backend/article/application"}
// {$smarty.block.parent}
// {include file="backend/article/controller/controller.js"}
// {/block}
model:
// {block name="backend/article/model/article/fields"}
//{$smarty.block.parent}
{ name: 'madeby', type: 'string' },
{ name: 'columna', type: 'string' },
{ name: 'colona', type: 'string' },
{ name: 'blabla', type: 'string' },
// {/block}
and the main part window.js:
// {block name="backend/article/view/detail/window"}
// {$smarty.block.parent}
// {namespace name="backend/etsy_attribute/window"}
Ext.define('Shopware.apps.Article.view.detail.Window.etsy_connector.Window', {
override: 'Shopware.apps.Article.view.detail.Window',
/**
* Override creatMainTabPanel method and add your custom tab here.
* To extend the tab panel this function can be override.
*
* #return Ext.tab.Panel
*/
createMainTabPanel: function () {
var me = this, result;
result = me.callParent(arguments);
me.registerAdditionalTab({
title: 'Etsy Tab',
tabConfig: { disabled: false },
contentFn: function (article, stores, eOpts) {
eOpts.tab.add({
tab:
me.etsyTab = Ext.create('Ext.container.Container', {
region: 'center',
padding: 10,
title: 'Etsy Tab',
disabled: false,
name: 'additional-tab',
//cls: Ext.baseCSSPrefix + 'etsy-tab-container',
items: [
me.createEtsyPanel()
]
}),
xtype:
me.etsyTab,
config:
me.etsyTab
});
},
scope: me
});
//result.add(me.etsyTab);
return result;
},
createEtsyPanel: function () {
var me = this;
me.etsyFormPanel = Ext.create('Ext.form.Panel', {
name: 'etsy-panel',
bodyPadding: 10,
autoScroll: true,
defaults: {
labelWidth: 155
},
items: [
me.createEtsyFieldSet()
]
});
return me.detailContainer = Ext.create('Ext.container.Container', {
layout: 'fit',
name: 'main',
title: me.snippets.formTab,
items: [
me.etsyFormPanel
]
});
},
createEtsyFieldSet: function () {
//var me = this;
return Ext.create('Ext.form.FieldSet', {
layout: 'anchor',
cls: Ext.baseCSSPrefix + 'article-etsy-field-set',
defaults: {
labelWidth: 155,
anchor: '100%',
translatable: true,
xtype: 'textfield'
},
title: 'Etsy connection content',
items: [
{
xtype: 'textfield',
name: 'blabla',
height: 100,
fieldLabel: 'blabla'
},
{
xtype: 'textfield',
name: 'columna',
height: 100,
fieldLabel: 'columna'
},
{
xtype: 'textfield',
name: 'colona',
height: 100,
fieldLabel: 'colona'
},
{
xtype: 'textfield',
name: 'madeby',
height: 100,
fieldLabel: 'madeby'
}
]
});
}
});
// {/block}
My question is:
Why no value is sent in request for my added fields in new tab?
Thanks.

You need also add controller for handle your tab.
//{block name="backend/article/controller/detail" append}
Ext.define('Shopware.apps.Article.controller.detail.etsy_connector.Base', {
override: 'Shopware.apps.Article.controller.Detail',
onSaveArticle: function(win, article, options) {
var me = this;
me.callParent([win, article, options]);
console.log(me);
console.log(me.getMainWindow());
//You need to find your own form
console.log(me.getMainWindow().detailContainer);
console.log(me.getMainWindow().detailContainer.getForm().getValues());
var myVariables = me.getMainWindow().detailContainer.getForm().getValues();
//Or merge your data with article data
var params = Ext.merge({}, me.getMainWindow().detailForm.getForm().getValues(), myVariables);
//Send to your own controller to handle
Ext.Ajax.request({
method: 'POST',
url: '{url controller=EtsyConnector action=save}',
params: myVariables
});
}
});
//{/block}

Related

Binding viewModel property with variable

Intro:
I need to call the backend controller to see if the user is admin. If the user is NOT admin, hide the toolbar in the application. Currently the var is successfully changing; However, it is changing after the view is already created causing the view to always have the toolbar visable.
Problem:
Need to check backend to see if user is in the admin group.
Need to return true if they are in admin group
MyCode:
var adminBool = false;
function CheckAdmin() {
debugger;
var a;
Direct.Report.IsAdmin(this.results, a);
debugger;
};
function results(result, constructor, c, d, e, f, g, h) {
debugger;
this.adminBool= result.adminUser; //returns bool
}
Ext.define('Ext.View.MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.AdministrationViewModel',
init: this.CheckAdmin(),
data: {
addNew: true,
update: true,
gridData: null,
isAdmin: this.adminBool
}
});
Synopsis:
Call the backend controller for admin status
Return bool
Update viewModel with bool respectively
ViewModel property,'isAdmin', will bind with hidden property to hide unwanted actions for non admins
UPDATE:
Basically I need a way to delay "isAdmin: this.adminBool" check to after the backend call is finished.
As you are using ViewModel.
So you can use set() method to update your viewmodel field.
I have created an sencha fiddle demo using viewmodel. You can check, how it is working in fiddle. In this fiddle I have not used any API, it just example regarding of ViewModel. Hope this will help you to solve your problem or achieve your requirement.
//ViewModel
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.AdministrationViewModel',
data: {
isAdmin: true
}
});
//Panel
Ext.create('Ext.panel.Panel', {
title: 'ViewModel example',
width: '100%',
renderTo: Ext.getBody(),
viewModel: 'AdministrationViewModel',
layout: {
type: 'vbox', // Arrange child items vertically
align: 'stretch', // Each takes up full width
padding: 10
},
defaults: {
margin: 10
},
items: [{
xtype: 'combo',
height: 40,
fieldLabel: 'Choose Admin or user',
emptyText: 'Choose Admin or user',
labelAlign: 'top',
store: {
fields: ['name', 'value'],
data: [{
"value": true,
"name": "Admin"
}, {
"value": false,
"name": "User"
}]
},
queryMode: 'local',
displayField: 'name',
valueField: 'value',
listeners: {
select: function (combo, record) {
var viewModel = combo.up('panel').getViewModel(),
isAdmin = record.get('value');
//If selected value is {Admin} then we will show toolbar otherwise in case of {User} hide
viewModel.set('isAdmin', !isAdmin);
}
}
}, {
xtype: 'toolbar',
width: '100%',
height: 50,
padding: 10,
bind: {
hidden: '{isAdmin}'
},
items: [{
// xtype: 'button', // default for Toolbars
text: 'Admin',
}, {
xtype: 'splitbutton',
text: 'Split Button'
},
// begin using the right-justified button container
'->', // same as { xtype: 'tbfill' }
{
xtype: 'textfield',
name: 'field1',
emptyText: 'enter search term'
},
// add a vertical separator bar between toolbar items
'-', // same as {xtype: 'tbseparator'} to create Ext.toolbar.Separator
'text 1', // same as {xtype: 'tbtext', text: 'text1'} to create Ext.toolbar.TextItem
{
xtype: 'tbspacer'
}, // same as ' ' to create Ext.toolbar.Spacer
'text 2', {
xtype: 'tbspacer',
width: 50
}, // add a 50px space
'text 3'
]
}]
});

Get form filed by using reference

I have a form as follows
this.stdForm = new Ext.form.Panel(this.createStdForm());
this.stdForm.getForm().load({
params: { action: 'load', id: 1234, dep: 'std' },
success: this.formLoaded,
scope: this
});
createStdForm: function () {
var flds = {
items: [
{ fieldLabel: 'Roll Number', name: 'ROLL_NUMBER', xtype: 'displayfield' } }
]
};
var fldSet = {
title: 'Student Information',
xtype: 'panel',
defaultType: 'fieldset',
defaults: { autoHeight: true, baseCls: 'x-fieldset-noborder', reference:'RollNumber'},
items: [flds]
};
return {
layout: 'column',
border: false,
defaults: {
border: false
},
url: this.getUrl(),
items: [
col1
]
};
}
and on formloaded function, I am trying to get reference of roll number field
formLoaded:function (form, action) {
form.getreferences('RollNumber') // not working
form.lookupreference(); // not working
}
Can anybody tell me what I am doing wrong.
In your example - just add referenceHolder: true to the panel:
If true, this container will be marked as being a point in the
hierarchy where references to items with a specified reference config
will be held. The container will automatically become a
referenceHolder if a controller is specified. See the introductory
docs for Ext.container.Container for more information about references
& reference holders.
Working example: https://fiddle.sencha.com/#fiddle/1d7t

Combo box do not select Value from drop down

I am using ExtJs to create a combobox.
Here is my code:
Ext.define('Form.FormTypeDialog', {
extend : 'Ext.Window',
id: 'formTypeDialog',
formId: null,
callbackFunction : null,
modal: true,
statics : {
show : function(formId, callback) {
Ext.create(Form.FormTypeDialog", {
formId : formId,
callbackFunction : callback
}).show();
}
},
constructor : function(config) {
var me = this;
Ext.apply(this, {
buttons : [
{
text:"#{msgs.form_create_dialog_button_cancel}",
cls : 'secondaryBtn',
handler: function() {
me.close();
}
},
{
text:"#{msgs.form_create_dialog_button_next}",
handler: function() {
// Get selected form type
}
}
]
});
this.callParent(arguments);
},
initComponent:function() {
this.setTitle("#{msgs.form_create_dialog_title}");
this.setHeight(175);
this.setWidth(327);
var formTypeStore = Mystore.Store.createRestStore({
url : getRelativeUrl('/rest/form/formTypes'),
root: 'objects',
fields: ['name','value']
});
this.form = new Ext.form.Panel({
style:'padding:15px;background-color:#fff' ,
border:false,
bodyBorder:false,
items:[
new Ext.form.Label({
text: "#{msgs.form_create_dialog_select_type_label}",
margin: "25 10 25 5"
}),
new Ext.form.ComboBox({
id: 'createformTypeCombo',
margin: "8 10 25 5",
allowBlank: false,
forceSelection: true,
editable:false,
store: formTypeStore,
valueField: 'value',
displayField: 'name',
width: 260,
emptyText: '#{msgs.form_create_dialog_select_type}'
})
]
});
this.items = [
this.form
];
this.callParent(arguments);
}
});
I am creating this window on a xhtml page on a button click using :
Form.FormTypeDialog.show(null, showFormWindowCallBack);
It works fine and combo box is displayed and I can select value.
But if I open and close it 4 times, then in next show it shows the values but It do not allow me to select the last two value. I can only select first value.
Please suggest.
Note: I have tried copying and executing this code in forms of other pages of my application. But behavior is same in all cases.
This combobox is on a Ext.Window.
EDIT:
JSON RESPONSE FROM Rest:
{"attributes":null,"complete":true,"count":3,"errors":null,"failure":false,"metaData":null,"objects":[{"name":"Application
Provisioning Policy Form","value":"Application"},{"name":"Role
Provisioning Policy Form","value":"Role"},{"name":"Workflow
Form","value":"Workflow"}],"requestID":null,"retry":false,"retryWait":0,"status":"success","success":true,"warnings":null}
I have re-created this code, I had some errors showing in Firefox using your code directly so I've changed some things.
Running the code below and calling Ext.create("Form.FormTypeDialog", {}).show(); in the console window, then closing the window and repeating does not replicate this issue. Could you try using the code I have and see if you still have the same problem.
Ext.application({
name: 'HelloExt',
launch: function () {
Ext.define('Form.FormTypeDialog', {
extend: 'Ext.Window',
id: 'formTypeDialog',
formId: null,
callbackFunction: null,
modal: true,
constructor: function (config) {
var me = this;
Ext.apply(this, {
buttons: [
{
text: "#{msgs.form_create_dialog_button_cancel}",
cls: 'secondaryBtn',
handler: function () {
me.close();
}
},
{
text: "#{msgs.form_create_dialog_button_next}",
handler: function () {
// Get selected form type
}
}
]
});
this.callParent(arguments);
},
initComponent: function () {
this.setTitle("#{msgs.form_create_dialog_title}");
this.setHeight(175);
this.setWidth(327);
var myData = [
["Application Provisioning Policy Form", "Application"],
["Role Provisioning Policy Form", "Role"],
["Workflow Form", "Workflow"],
];
var formTypeStore = Ext.create("Ext.data.ArrayStore", {
fields: [
'name',
'value'
],
data: myData,
storeId: "myStore"
});
this.form = Ext.create("Ext.form.Panel", {
style: 'padding:15px;background-color:#fff',
border: false,
bodyBorder: false,
items: [
Ext.create("Ext.form.Label", {
text: "#{msgs.form_create_dialog_select_type_label}",
margin: "25 10 25 5"
}),
Ext.create("Ext.form.ComboBox", {
id: 'createformTypeCombo',
margin: "8 10 25 5",
allowBlank: false,
forceSelection: true,
editable: false,
store: formTypeStore,
valueField: 'value',
displayField: 'name',
width: 260,
emptyText: '#{msgs.form_create_dialog_select_type}'
})
]
});
this.items = [
this.form
];
this.callParent(arguments);
}
});
Ext.create('Ext.Button', {
text: 'Click me',
renderTo: Ext.getBody(),
handler: function() {
Ext.create("Form.FormTypeDialog", {}).show();
}
});
}
});
You can also play around with this code using / forking from this Fiddle
It is not clear what your problem is.
I use remote combo follows:
Ext.define('ComboRemote', {
extend: 'Ext.form.ComboBox',
xtype: 'ComboRemote',
emptyText: 'empty',
width: 75,
displayField: 'name',
valueField: 'id',
store: {
model: 'ComboModel',
proxy: {
type: 'rest',
url: '/serv/Res',
extraParams: {
query: ''
},
reader: {
root: "result", type: 'json'
}
},
autoLoad: true,
},
queryMode: 'remote',
pageSize: false,
lastQuery: '',
minChars: 0});
Ext.define('ComboModel', {
extend: 'Ext.data.Model',
fields: [
'id',
'name'
]});
I hope to help
Try these possible solutions
1. Make AutoLoad property for store as true.
2. Add delay of some ms

Uncaught TypeError: Cannot read property 'dom' of undefined

How to solve this error Uncaught TypeError: Cannot read property 'dom' of undefined in extjs?
I`m using dnd and put dnd code into layout browser
code :
// Generic fields array to use in both store defs.
var fields = [{
name: 'id',
type: 'string',
mapping: 'id'
}, {
name: 'lab_name',
type: 'string',
mapping: 'lab_name'
}, {
name: 'lab_address1',
type: 'string',
mapping: 'lab_address1'
}, {
name: 'lab_address2',
type: 'string',
mapping: 'lab_address2'
}, {
name: 'lab_poskod',
type: 'string',
mapping: 'lab_poskod'
}, {
name: 'lab_bandar',
type: 'string',
mapping: 'lab_bandar'
}, {
name: 'lab_negeri',
type: 'string',
mapping: 'lab_negeri'
}, {
name: 'lab_tel',
type: 'string',
mapping: 'lab_tel'
}, {
name: 'lab_fax',
type: 'string',
mapping: 'lab_fax'
}];
// create the data store
var gridStore = new Ext.data.JsonStore({
fields: fields,
autoLoad: true,
url: '../industri/layouts/getLab.php'
});
// Column Model shortcut array
var cols = [{
id: 'name',
header: "Id",
width: 10,
sortable: true,
dataIndex: 'id'
}, {
id: 'name',
header: "Laboratory Name",
width: 200,
sortable: true,
dataIndex: 'lab_name'
}, {
id: 'name',
header: "Laboratory Name",
width: 200,
sortable: true,
dataIndex: 'lab_address1'
}];
// declare the source Grid
var grid = new Ext.grid.GridPanel({
ddGroup: 'gridDDGroup',
store: gridStore,
columns: cols,
enableDragDrop: true,
stripeRows: true,
autoExpandColumn: 'name',
width: 325,
margins: '0 2 0 0',
region: 'west',
title: 'Data Grid',
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true
})
});
// Declare the text fields. This could have been done inline, is easier to read
// for folks learning :)
var textField1 = new Ext.form.TextField({
fieldLabel: 'Laboratory Name',
name: 'lab_name'
});
// Setup the form panel
var formPanel = new Ext.form.FormPanel({
region: 'center',
title: 'Generic Form Panel',
bodyStyle: 'padding: 10px; background-color: #DFE8F6',
labelWidth: 100,
margins: '0 0 0 3',
width: 325,
items: [textField1]
});
var displayPanel = new Ext.Panel({
width: 650,
height: 300,
layout: 'border',
padding: 5,
items: [
grid,
formPanel
],
bbar: [
'->', // Fill
{
text: 'Reset Example',
handler: function() {
//refresh source grid
gridStore.loadData();
formPanel.getForm().reset();
}
}
]
});
// used to add records to the destination stores
var blankRecord = Ext.data.Record.create(fields);
/****
* Setup Drop Targets
***/
// This will make sure we only drop to the view container
var formPanelDropTargetEl = formPanel.body.dom;
var formPanelDropTarget = new Ext.dd.DropTarget(formPanelDropTargetEl, {
ddGroup: 'gridDDGroup',
notifyEnter: function(ddSource, e, data) {
//Add some flare to invite drop.
formPanel.body.stopFx();
formPanel.body.highlight();
},
notifyDrop: function(ddSource, e, data) {
// Reference the record (single selection) for readability
var selectedRecord = ddSource.dragData.selections[0];
// Load the record into the form
formPanel.getForm().loadRecord(selectedRecord);
// Delete record from the grid. not really required.
ddSource.grid.store.remove(selectedRecord);
return (true);
}
});
var tabsNestedLayouts = {
id: 'tabs-nested-layouts-panel',
title: 'Industrial Effluent',
bodyStyle: 'padding:15px;',
layout: 'fit',
items: {
border: false,
bodyStyle: 'padding:5px;',
items: displayPanel
}
};
If you try and render a component to a dom element that isn't found (or dom ID that isn't found) you'll get that error. See the example below to reproduce the error - then comment out the bad renderTo and uncomment the renderTo: Ext.getBody() to resolve the issue.
see this FIDDLE
CODE SNIPPET
Ext.onReady(function () {
// Generic fields array to use in both store defs.
var fields = [{
name: 'id',
type: 'string',
mapping: 'id'
}, {
name: 'lab_name',
type: 'string',
mapping: 'lab_name'
}, {
name: 'lab_address1',
type: 'string',
mapping: 'lab_address1'
}, {
name: 'lab_address2',
type: 'string',
mapping: 'lab_address2'
}, {
name: 'lab_poskod',
type: 'string',
mapping: 'lab_poskod'
}, {
name: 'lab_bandar',
type: 'string',
mapping: 'lab_bandar'
}, {
name: 'lab_negeri',
type: 'string',
mapping: 'lab_negeri'
}, {
name: 'lab_tel',
type: 'string',
mapping: 'lab_tel'
}, {
name: 'lab_fax',
type: 'string',
mapping: 'lab_fax'
}];
// create the data store
var gridStore = new Ext.data.JsonStore({
fields: fields,
autoLoad: true,
url: '../industri/layouts/getLab.php'
});
// Column Model shortcut array
var cols = [{
id: 'name',
header: "Id",
width: 10,
sortable: true,
dataIndex: 'id'
}, {
id: 'name',
header: "Laboratory Name",
width: 200,
sortable: true,
dataIndex: 'lab_name'
}, {
id: 'name',
header: "Laboratory Name",
width: 200,
sortable: true,
dataIndex: 'lab_address1'
}];
// declare the source Grid
var grid = new Ext.grid.GridPanel({
ddGroup: 'gridDDGroup',
store: gridStore,
columns: cols,
enableDragDrop: true,
stripeRows: true,
autoExpandColumn: 'name',
width: 325,
margins: '0 2 0 0',
region: 'west',
title: 'Data Grid',
selModel: new Ext.grid.RowSelectionModel({
singleSelect: true
})
});
// Declare the text fields. This could have been done inline, is easier to read
// for folks learning :)
var textField1 = new Ext.form.TextField({
fieldLabel: 'Laboratory Name',
name: 'lab_name'
});
// Setup the form panel
var formPanel = new Ext.form.FormPanel({
region: 'center',
title: 'Generic Form Panel',
bodyStyle: 'padding: 10px; background-color: #DFE8F6',
labelWidth: 100,
margins: '0 0 0 3',
width: 325,
items: [textField1]
});
var displayPanel = new Ext.Panel({
width: 650,
height: 300,
layout: 'border',
renderTo:Ext.getBody(),
padding: 5,
items: [
grid,
formPanel
],
bbar: [
'->', // Fill
{
text: 'Reset Example',
handler: function () {
//refresh source grid
//gridStore.loadData();
formPanel.getForm().reset();
}
}
]
});
// used to add records to the destination stores
var blankRecord = Ext.data.Record.create(fields);
/****
* Setup Drop Targets
***/
// This will make sure we only drop to the view container
var formPanelDropTargetEl = formPanel.body.dom;
var formPanelDropTarget = new Ext.dd.DropTarget(formPanelDropTargetEl, {
ddGroup: 'gridDDGroup',
notifyEnter: function (ddSource, e, data) {
//Add some flare to invite drop.
formPanel.body.stopFx();
formPanel.body.highlight();
},
notifyDrop: function (ddSource, e, data) {
// Reference the record (single selection) for readability
var selectedRecord = ddSource.dragData.selections[0];
// Load the record into the form
formPanel.getForm().loadRecord(selectedRecord);
// Delete record from the grid. not really required.
ddSource.grid.store.remove(selectedRecord);
return (true);
}
});
var tabsNestedLayouts = {
id: 'tabs-nested-layouts-panel',
title: 'Industrial Effluent',
bodyStyle: 'padding:15px;',
layout: 'fit',
items: {
border: false,
bodyStyle: 'padding:5px;',
items: displayPanel
}
};
});
It means that the object which you expect to have the dom attribute is undefined.
EDIT:
The error generates at this line:
formPanel.body.dom
It means that the formPanel is not rendered because you are trying to access its body property. This property is Available since: Ext 4.1.3
I'm seeing a similar error in code that executes for validation. What I'm doing has nothing to do with directly accessing the DOM, however I'm still getting a similar condition. The answer above is incomplete, the dom property is available on some ui elements in 3.x...
in earlier versions of Extjs (3.x) the property is mainBody.dom and not body.dom
directly from the source of hasRows() for grids in 3.4:
var fc = this.**mainBody.dom**.firstChild;
return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';

Accessing Android phone contacts with phonegap and Sencha Touch

please I'm trying to get a list of all the contacts on my phone with the following code.
var App = new Ext.Application({
name: 'SmsthingyApp',
useLoadMask: true,
launch: function () {
Ext.data.ProxyMgr.registerType("contactstorage",
Ext.extend(Ext.data.Proxy, {
create: function(operation, callback, scope) {
},
read: function(operation, callback, scope) {
},
update: function(operation, callback, scope) {
},
destroy: function(operation, callback, scope) {
}
})
);
Ext.regModel("contact", {
fields: [
{name: "id", type: "int"},
{name: "givenName", type: "string"},
{name: "familyName", type: "string"},
{name: "emails", type: "auto"},
{name: "phoneNumbers", type: "auto"}
]
});
Ext.regStore('contacts',{
model: "contact",
proxy: {
type: "contactstorage",
read: function(operation, callback, scope) {
var thisProxy = this;
navigator.contacts.find(
['id', 'name', 'emails', 'phoneNumbers', 'addresses'],
function(deviceContacts) {
//loop over deviceContacts and create Contact model instances
var contacts = [];
for (var i = 0; i < deviceContacts.length; i++) {
var deviceContact = deviceContacts[ i ];
var contact = new thisProxy.model({
id: deviceContact.id,
givenName: deviceContact.name.givenName,
familyName: deviceContact.name.familyName,
emails: deviceContact.emails,
phoneNumbers: deviceContact.phoneNumbers
});
contact.deviceContact = deviceContact;
contacts.push(contact);
}
//return model instances in a result set
operation.resultSet = new Ext.data.ResultSet({
records: contacts,
total : contacts.length,
loaded : true
});
//announce success
operation.setSuccessful();
operation.setCompleted();
//finish with callback
if (typeof callback == "function") {
callback.call(scope || thisProxy, operation);
}
},
function (e) { console.log('Error fetching contacts'); },
{multiple: true}
);
}
}
});
Ext.regModel('Sms', {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
{ name: 'date', type: 'date', dateFormat: 'c' },
{ name: 'title', type: 'string' },
{ name: 'message', type: 'string' }
],
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'title', message: 'Please select a contact for this sms.' }
]
});
Ext.regStore('SmsStore', {
model: 'Sms',
sorters: [{
property: 'date',
direction: 'DESC'
}],
proxy: {
type: 'localstorage',
id: 'sms-app-localstore'
},
getGroupString: function (record)
{
if (record && record.data.date)
{
return record.get('date').toDateString();
}
else
{
return '';
}
}
});
SmsthingyApp.views.ContactsList = new Ext.List({
id: 'ContactsList',
layout: 'fit',
store:'contacts',
itemTpl: '{givenName} {familyName}',
listeners: {'render': function (thisComponent)
{
SmsthingyApp.views.ContactsList.getStore().load();
}
},
onItemDisclosure: function (record) {
//Ext.dispatch({
// controller: SmsthingyApp.controllers.contacts,
// action: 'show',
// id: record.getId()
//});
}
});
SmsthingyApp.views.contactsListContainer = new Ext.Panel({
id: 'contactsListContainer',
layout: 'fit',
html: 'This is the sms list container',
items: [SmsthingyApp.views.ContactsList],
dockedItems: [{
xtype: 'toolbar',
title: 'Contacts'
}]
});
SmsthingyApp.views.smsEditorTopToolbar = new Ext.Toolbar({
title: 'Edit SMS',
items: [
{
text: 'Back',
ui: 'back',
handler: function () {
SmsthingyApp.views.viewport.setActiveItem('smsListContainer', { type: 'slide', direction: 'right' });
}
},
{ xtype: 'spacer' },
{
text: 'Save',
ui: 'action',
handler: function () {
var smsEditor = SmsthingyApp.views.smsEditor;
var currentSms = smsEditor.getRecord();
// Update the note with the values in the form fields.
smsEditor.updateRecord(currentSms);
var errors = currentSms.validate();
if (!errors.isValid())
{
currentSms.reject();
Ext.Msg.alert('Wait!', errors.getByField('title')[0].message, Ext.emptyFn);
return;
}
var smsList = SmsthingyApp.views.smsList;
var smsStore = smsList.getStore();
if (smsStore.findRecord('id', currentSms.data.id) === null)
{
smsStore.add(currentSms);
}
else
{
currentSms.setDirty();
}
smsStore.sync();
smsStore.sort([{ property: 'date', direction: 'DESC'}]);
smsList.refresh();
SmsthingyApp.views.viewport.setActiveItem('smsListContainer', { type: 'slide', direction: 'right' });
}
}
]
});
SmsthingyApp.views.smsEditorBottomToolbar = new Ext.Toolbar({
dock: 'bottom',
items: [
{ xtype: 'spacer' },
{
text: 'Send',
handler: function () {
// TODO: Send current sms.
}
}
]
});
SmsthingyApp.views.smsEditor = new Ext.form.FormPanel({
id: 'smsEditor',
items: [
{
xtype: 'textfield',
name: 'title',
label: 'To',
required: true
},
{
xtype: 'textareafield',
name: 'narrative',
label: 'Message'
}
],
dockedItems:[
SmsthingyApp.views.smsEditorTopToolbar,
SmsthingyApp.views.smsEditorBottomToolbar
]
});
SmsthingyApp.views.smsList = new Ext.List({
id: 'smsList',
store: 'SmsStore',
grouped: true,
emptyText: '<div style="margin: 5px;">No notes cached.</div>',
onItemDisclosure: function (record)
{
var selectedSms = record;
SmsthingyApp.views.smsEditor.load(selectedSms);
SmsthingyApp.views.viewport.setActiveItem('smsEditor', { type: 'slide', direction: 'left' });
},
itemTpl: '<div class="list-item-title">{title}</div>' +'<div class="list-item-narrative">{narrative}</div>',
listeners: {'render': function (thisComponent)
{
thisComponent.getStore().load();
}
}
});
SmsthingyApp.views.smsListToolbar = new Ext.Toolbar({
id: 'smsListToolbar',
title: 'Sent SMS',
layout: 'hbox',
items:[
{xtype:'spacer'},
{
id:'newSmsButton',
text:'New SMS',
ui:'action',
handler:function()
{
var now = new Date();
var smsId = now.getTime();
var sms = Ext.ModelMgr.create({ id: smsId, date: now, title: '', narrative: '' },'Sms');
SmsthingyApp.views.smsEditor.load(sms);
SmsthingyApp.views.viewport.setActiveItem('smsEditor', {type: 'slide', direction: 'left'});
}
}
]
});
SmsthingyApp.views.smsListContainer = new Ext.Panel({
id: 'smsListContainer',
layout: 'fit',
html: 'This is the sms list container',
dockedItems: [SmsthingyApp.views.smsListToolbar],
items: [SmsthingyApp.views.smsList]
});
SmsthingyApp.views.viewport = new Ext.Panel({
fullscreen: true,
layout: 'card',
cardAnimation: 'slide',
items:[
SmsthingyApp.views.contactsListContainer,
SmsthingyApp.views.smsListContainer,
SmsthingyApp.views.smsEditor
]
});
}
})
I'm using eclipse and LogCat tab keeps marking this red
02-08 11:11:58.741: E/Web Console(13886): Uncaught TypeError: Cannot read property 'contacts' of undefined at file:///android_asset/www/app.js:35
I'm guessing this has something to with why I can't see the contacts in the contactsListContainer.
Any help please?
I'm not a Sencha expert but I do know that this line:
var App = new Ext.Application({
will cause problems with PhoneGap as we also declare a variable called App. It would be better to change that line to be something like:
var myApp = new Ext.Application({
to avoid the name conflict.
If that doesn't resolve your problem I suggest you read over my post on searching contacts. I'd make sure I could successfully search for contacts before adding in Sencha.

Categories

Resources