Problem displaying nested model data in Sencha Touch XTemplate - javascript

I am using Sencha Touch to display nested (associated) model data in a list template but I can only get the root model data to display. My models are an Appointment which belongs to a Customer, and Customers have many Appointments. My model code:
Customer = Ext.regModel('Customer', {
hasMany: { model: 'Appointments', name: 'appointments' },
fields: [
{ name: 'id', type: 'integer' },
{ name: 'firstName', type: 'string' },
{ name: 'lastName', type: 'string' },
{ name: 'email', type: 'string' },
{ name: 'secondary_email', type: 'string' },
{ name: 'homePhone', type: 'string' },
{ name: 'mobilePhone', type: 'string' },
{ name: 'dob', type: 'date', dateFormat: 'Y-m-d' },
{ name: 'allowLogin', type: 'boolean' },
{ name: 'emailReminders', type: 'boolean' },
{ name: 'reminders_to_stylist', type: 'boolean' },
{ name: 'fullName',
convert: function(value, record) {
var fn = record.get('firstName');
var ln = record.get('lastName');
return fn + " " + ln;
} }
]
});
Appointment = Ext.regModel('Appointment', {
belongsTo: { model: 'Customer', name: 'customer' },
fields: [
{ name: 'id', type: 'string' },
{ name: 'startTime', type: 'date', dateFormat: 'c' },
{ name: 'customer_id', type: 'integer' },
{ name: 'startTimeShort',
convert: function(value, record) {
return record.get('startTime').shortTime();
}
},
{ name: 'endTimeShort',
convert: function(value, record) {
return record.get('endTime').shortTime();
}
},
{ name: 'endTime', type: 'date', dateFormat: 'c' }
]
});
And my panel using an xtype: list looks like:
var jsonPanel = {
title: "Appointments",
items: [
{
xtype: 'list',
store: appointmentStore,
itemTpl: '<tpl for="."><span id="{id}">{startTimeShort} - {endTimeShort} <tpl for="customer"><span class="customer">{firstName}</span></tpl></span></tpl>',
singleSelect: true,
onItemDisclosure: function(record, btn, index) {
Ext.Msg.alert('test');
}
}
]
};
The nested data gets loaded from JSON and appears to be loading correctly into the store - when I debug the appointment store object loaded from the Appointment model, I see that the appointment.data.items array objects have a CustomerBelongsToInstance object and that object's data object does contain the correct model data. The startTime and endTime fields display correctly in the list.
I have a suspicion that I am either not using the item template markup correctly, or perhaps there is some weird dependency where I would have to start from the model that has the "has many" association rather than the "belongs to" as shown in the kitchen sink demo.
I wasn't able to find any examples that used this type of association so any help is appreciated.

Looks like your Customer hasmany association is assigning Appointments when it should be appointment which is the name of that model.

Related

How to implemented a nested and associated model-json into selectfield in Sencha Touch?

I have a store with associated model and I need to include values of this associated model into selectfield component in Sencha Touch.
Here my parent model:
Ext.define('x.customer.model.CustomerModel', {
extend: 'Ext.data.Model',
requires:[
'x.customer.model.CustomerTemplateModel'
],
config: {
useCache: false,
idProperty: 'id',
fields: [
{
name: 'id',
type: 'string'
},
{
name: 'address',
type: 'string'
},
{
name: 'name',
type: 'string'
},
{
name: 'type',
type: 'int'
}
],
associations: [
{
type: 'hasMany',
associatedModel: 'Survey.customer.model.CustomerTemplateModel',
ownerModel: 'Survey.customer.model.CustomerModel',
associationKey: 'templates',
autoLoad: true,
name: 'templates'
}
]
}
});
and the children model:
Ext.define('x.customer.model.CustomerTemplateModel', {
extend: 'Ext.data.Model',
requires:[],
config: {
useCache: false,
rootProperty: 'templates',
fields: [
{
name: 'text',
type: 'string'
},
{
name: 'value',
type: 'string'
}
]
}
});
store:
requires: ['Survey.customer.model.CustomerModel'],
config: {
model: 'Survey.customer.model.CustomerModel',
proxy: {
type: 'ajax',
reader: {
type: 'json',
rootProperty: 'customers'
}
}
}
Currently the json has this structure:
{
"id": "00000001",
"address": "Antsy Road",
"name": "asfas",
"phone": "55555",
"openSurveys": 7,
"templates": [
{
"text": "123",
"value": "Template 1"
}
],
"type": 1,
"withSurveys": true
},
how to implement data included in the "templates" nested json in a selectfield?
thank you in advance
Once your store loaded and if you have one custommer:
var templatesData = []; // What will be inserted to the ComboBox
for (var i=0; i < custommers[0].get('templates').length; i++) { // Running threw the values and populating templatesData
var templateModel = custommers[0].get('templates')[i];
var templateCombo = {
text: templateModel.data.text,
value: templateModel.data.value
};
templatesData.push(templateCombo);
}
// Setting the values to the combobox
Ext.getCmp('myCombo').setStore(Ext.create("Ext.data.Store", {
model: 'x.customer.model.CustomerTemplateModel',
data :templatesData
}));
This is not a unique solution, you could create a new instance of store as well. Here is more information about how setting the "store" property for a combobox : http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.form.field.ComboBox-cfg-store

Extjs 5, data model association & load nested data

trying to make this work....
I want to load nested data on two object model
Ext.application({
name : 'MyApp',
launch : function() {
Ext.define('MyApp.model.Address', {
extend: 'Ext.data.Model',
entityName: 'Address',
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'addressLine',
type: 'string'
},
{
name: 'city',
type: 'string'
},
{
name: 'created',
type: 'date',
dateFormat: 'time',
persist: false
}
]
});
Ext.define('MyApp.model.User', {
extend: 'Ext.data.Model',
entityName: 'User',
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'address',
reference: 'Address'
},
{
name: 'name',
type: 'string'
},
{
name: 'lastname',
type: 'string'
},
{
name: 'created',
type: 'date',
dateFormat: 'time',
persist: false
}
]
});
var user = new MyApp.model.User({
"id": 1,
"name": "Pedro",
"lastname": "Carbonell",
"address": {
"id": 1,
"addressLine": "Bailen 22",
"city": "Barcelona",
"created": 1420668866000
},
"created": 1420668866000
});
console.info(user);
console.info(user.getAddress());
}});
It's result on no error when created the user, but when I access to associated data via user.getAddress() it returned an exception:
Uncaught Error: The model ID configured in data ("[object Object]") has been rejected by the int field converter for the id fieldext-all-debug.js
Try to define proxy like memory or localstorage on model definitions, but the result it is the same.
Ext fiddle: https://fiddle.sencha.com/#fiddle/h2d
Any help will be appreciated!
Solved, but only find this solution: when use loadRawData...
var store = new Ext.data.Store({
model: MyApp.model.User
});
store.loadRawData({
"id": 1,
"name": "Pedro",
"lastname": "Carbonell",
"address": {
"id": 1,
"addressLine": "Bailen 22",
"city": "Barcelona",
"created": 1420668866000
},
"created": 1420668866000
});
console.info(store.first());
console.info(store.first().getAddress());
sample at this new fiddle: https://fiddle.sencha.com/#fiddle/h4e
you'r right, ext is a bit flaky, very....
I've been playing around with the code in your fiddle and not been able to get the association working the official way as of yet.
I simulated the functionality using this code:
Ext.define('MyApp.model.User', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int'
}, {
name: 'name',
type: 'string'
}, {
name: 'lastname',
type: 'string'
}, {
name: 'created',
type: 'date',
dateFormat: 'time',
persist: false
}],
getAddress: function() {
if ('undefined' === this.data.address) {
return null;
}
return Ext.create('Address', this.data.address);
}
});
Basically I've removed the association and created a custom function to create a model record based off of the raw data passed in, You could also return a new, empty model if the address data does not exist instead of null, I used null as it's easier to determine whether you have a valid address record or not.
As already mentioned - this is not the official way to do this, I will have another play around with the fiddle and post a better solution once I find it, this may help in the meantime.
Using the original code, I made a few modifications and now it appears to be working.
Ext.application({
name : 'MyApp',
launch : function() {
Ext.define('MyApp.model.Address', {
extend: 'Ext.data.Model',
//entityName: 'Address',
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'addressLine',
type: 'string'
},
{
name: 'city',
type: 'string'
},
{
name: 'created',
type: 'date',
dateFormat: 'time',
persist: false
}
],
hasMany: 'User'
});
Ext.define('MyApp.model.User', {
extend: 'Ext.data.Model',
//entityName: 'User',
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'name',
type: 'string'
},
{
name: 'lastname',
type: 'string'
},
{
name: 'created',
type: 'date',
dateFormat: 'time',
persist: false
}
],
hasMany: { model: 'Address', name: 'Address' }
});
var user = new MyApp.model.User({
"id": 1,
"name": "Pedro",
"lastname": "Carbonell",
"address": {
"id": 1,
"addressLine": "Bailen 22",
"city": "Barcelona",
"created": 1420668866000
},
"created": 1420668866000
});
console.info(user);
console.info(user.data.address);
}
});
Is this the sort of thing you're after? I set Address manually on the User model. Not ideal but it's interpreted correctly as a record then.
Ext.define('MyApp.model.Address', {
extend: 'Ext.data.Model',
entityName: 'Address',
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'addressLine',
type: 'string'
},
{
name: 'city',
type: 'string'
},
{
name: 'created',
type: 'date',
dateFormat: 'time',
persist: false
}
]
});
Ext.define('MyApp.model.User', {
extend: 'Ext.data.Model',
entityName: 'User',
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'addressId',
reference: 'Address'
},
{
name: 'name',
type: 'string'
},
{
name: 'lastname',
type: 'string'
},
{
name: 'created',
type: 'date',
dateFormat: 'time',
persist: false
}
]
});
var user = new MyApp.model.User({
"id": 1,
"name": "Pedro",
"lastname": "Carbonell",
"created": 1420668866000
});
var addr = new MyApp.model.Address({
"id": 1,
"addressLine": "Bailen 22",
"city": "Barcelona",
"created": 1420668866000
});
user.setAddress(addr);
console.info(user);
console.info(user.getAddress());

Sencha Javascript Insert to Array First Index

I requesting products from my web service. And i want insert to object array's first index the new item.
my lounch function :
NewMobile.globals = {
mesaj: 'selam',
action: '',
server: '192.168.50.70',
branchCode: '0',
activeTable: '',
activeFolio: '0',
activeTableGroup: '',
activeMustGroup: -1,
activePid: 0,
activeMustGroupString: 0,
activeMustDesc: '',
activeMustArray: [],
activeCampProduct: '',
products: undefined,
rePrint: '',
activePax: 1,
uuid: 'tanimsiz',
activeSkin: 'Krem',
version:undefined,
minVersion:132
};
Its my request.
NewMobile.globals.products = Ext.create('NewMobile.store.PorductStore');
NewMobile.globals.products.setProxy({url: "http://" + NewMobile.globals.server + ':1002/zulu/newmobile/data.aspx?act=getAllProducts'});
NewMobile.globals.products.getProxy();
NewMobile.globals.products.load(function(a, records, c, d, e){
if (c !== true)
{
Ext.Viewport.setMasked(false);
Ext.Msg.alert('uyarı', NewMobile.message.connectionError, Ext.emptyFn);
return;
}
else
{
if(NewMobile.globals.version!==undefined)
{
if(NewMobile.globals.version.MinorRevision>=NewMobile.globals.minVersion)
{
var PopulerProducts=Ext.create('NewMobile.model.Products',
{ id:-65000,
name:"SIK KULLANILANLAR",
groupId:200000,
color:"#FFC673",
type:1,
order:-1,
mustModGroups:0,
mustModGrpCount:0
}
);
NewMobile.globals.products.unshift(PopulerProducts);
}
}
}
});
Product Model :
Ext.define('NewMobile.model.Products', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
config: {
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'name',
type: 'string'
},
{
name: 'groupId',
type: 'int'
},
{
name: 'price',
type: 'float'
},
{
name: 'color'
},
{
name: 'type',
type: 'int'
},
{
name: 'mustModGrpCount'
},
{
name: 'mustModGroups'
},
{
name: 'order',
type: 'int'
},
{
name: 'campCount',
type: 'int'
},
{
name: 'stockCode'
},
{
name: 'populer',
type: 'boolean'
}
]
}
});
Chrome console giving this error.
Object [object Object] has no method 'unshift'
I assume that your NewMobile.store.PorductStore is extending Ext.store.Store. To add items to a store you can either use the add or insert method.
add will add the items to the end of the store so what you want to use is insert and specify the index to be 0. Something like this:
myStore.insert(0, newRecord)
To keep the sorting use addSorted. Inserts the passed Record into the Store at the index where it should go based on the current sort information.
myStore.addSorted(newRecord)
You can read more about how to use stores in Ext.js here: http://docs.sencha.com/extjs/4.2.0/#!/api/Ext.data.Store

Making sure an ExtJS checkboxfield updates its model

I have inherited an ExtJs4 project, and I've got a fairly basic question.
I have a view that has a newly added checkbox field as one of the items, like so:
{
boxLabel: 'Test Message?',
xtype: 'checkboxfield',
id: 'cbTextMessage',
checked: false,
name: 'testMessage',
inputValue: true,
uncheckedValue: false
}
When the record is active, this value changes to the appropriate checked or unchecked state. When creating a new record, the value is set to the value of the checkbox. However, when editing an existing record, the model never gets updated to any value other than the original value.
The model:
Ext.define('PushAdmin.model.Message', {
extend: 'Ext.data.Model',
idProperty: 'id',
requires: ['Proxy.ParameterProxy'],
fields: [
{ name: 'id', type: 'int' },
{ name: 'games', type: 'auto',
convert: function(data, model) {
data = ( data && !Ext.isArray(data) ) ? [data] : data;
return data;
}
},
{ name: 'msgEnglish', type: 'string' },
{ name: 'msgFrench', type: 'string' },
{ name: 'msgSpanish', type: 'string' },
{ name: 'testMessage', type: 'bool' },
{ name: 'sendAt', type: 'date' },
{ name: 'note', type: 'string'},
{ name: 'status', type: 'string' },
],
proxy: {
type: 'rest',
url: '/apnsadmin/rest/Message',
pageParam: undefined,
startParam: undefined,
limitParam: undefined,
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
}
}
});
And finally this is the function that gets called when the save button is clicked.
click: function () {
var grid = this.getQueuedMessagesGrid();
var sm = grid.getSelectionModel();
var selectedRecord = sm.getCount() > 0 ? sm.getSelection()[0] : undefined;
this.getMessageForm().getForm().updateRecord();
var newRecord = this.getMessageForm().getForm().getRecord();
if (selectedRecord!=undefined) {
console.log(selectedRecord);
console.log(newRecord);
selectedRecord.save();
} else {
// New record!
console.log("Saving new record");
grid.getStore().add(newRecord);
newRecord.save();
}
this.getMessageForm().setDisabled(true);
this.getMessageForm().getForm().reset();
}
},
I am aware that things are probably not the proper ExtJS way to do things, but since this is mostly working I am trying not to have to rewrite large chunks of it. I'd just like to know what I'm doing wrong in adding this checkbox/boolean field to the form.

ExtJS 3.3 Format.Util.Ext.util.Format.dateRenderer returning NaN

The Store
var timesheet = new Ext.data.JsonStore(
{
root: 'timesheetEntries',
url: 'php/scripts/timecardEntry.script.php',
storeId: 'timesheet',
autoLoad: true,
fields: [
{ name: 'id', type: 'integer' },
{ name: 'user_id', type: 'integer' },
{ name: 'ticket_number', type: 'integer' },
{ name: 'description', type: 'string' },
{ name: 'start_time', type: 'string' },
{ name: 'stop_time', type: 'string' },
{ name: 'client_id', type: 'integer' },
{ name: 'is_billable', type: 'integer' }
]
}
);
A section of my GridPanel code:
columns: [
{
id: 'ticket_number',
header: 'Ticket #',
dataIndex: 'ticket_number'
},
{
id: 'description',
header: 'Description',
dataIndex: 'description'
},
{
id: 'start_time',
header: 'Start',
dataIndex: 'start_time',
renderer: Ext.util.Format.dateRenderer('m/d/Y H:i:s')
}
...
From the server, I receive this JSON string:
{
timesheetEntries:[
{
"id":"1",
"user_id":"1",
"description":null,
"start_time":"2010-11-13 11:30:00",
"stop_time":"2010-11-13 15:50:10",
"client_id":null,
"is_billable":"0"
}
My grid panel renders fine. However, my start and stop time columns read 'NaN/NaN/NaN NaN:NaN:NaN' and I don't know why.
If your data has "2010-11-13 11:30:00" shouldn't your format be 'Y-m-d H:i:s'?
EDIT: Sorry, the grid config should be OK -- I was referring to the dateFormat value in your store's field definition, which should be 'Y-m-d H:i:s' so that your incoming data can be properly mapped to your column model. You should also include type: 'date'. You're not showing your store config, but the problem is likely one of those things being wrong.
Try this
function renderDate(v,params,record)
{
var dt = new Date(v);
if (!isNaN(dt.getDay())) {
return dt.format('d/m/Y');
}
return '-';
}
A very simple way to do it:
return Ext.util.Format.date(val,'m/d/Y');

Categories

Resources