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
Related
I have cart and products global variable.
Products can have multiple attributes.
Here is a code
var products = [
{
name: 'Table',
price: 200,
attributes: [
{
name: 'Height',
type: 'text',
default_value: '',
},
{
name: 'Width',
type: 'text',
default_value: '',
}
],
},
{
name: 'Chair',
price: 150,
attributes: [
{
name: 'Height',
type: 'text',
default_value: '',
},
{
name: 'Width',
type: 'text',
default_value: '',
},
{
name: 'Company',
type: 'text',
default_value: ''
}
],
}
];
var cart = {
products: [],
};
//console.log('Initial cart',cart);
//add product to cart
let p = Object.assign({},products[0]);
cart.products.push(p);
//console.log('First cart', cart);
//change price
cart.products[0].price = 20;
//console.log('products',products);
//console.log('second cart',cart);
//change attribute of product
cart.products[0].attributes[0].value = 5;
This code changes global products value attributes instead of cart attributes.
Please help me to solve this issue.
From MDN
Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.
And as products[0] is an object in your data that's why you are facing this shallow copy issue
Instead you can use
let p = JSON.parse(JSON.stringify(products[0]));
var products = [{
name: 'Table',
price: 200,
attributes: [{
name: 'Height',
type: 'text',
default_value: '',
},
{
name: 'Width',
type: 'text',
default_value: '',
}
],
},
{
name: 'Chair',
price: 150,
attributes: [{
name: 'Height',
type: 'text',
default_value: '',
},
{
name: 'Width',
type: 'text',
default_value: '',
},
{
name: 'Company',
type: 'text',
default_value: ''
}
],
}
];
var cart = {
products: [],
};
//console.log('Initial cart',cart);
//add product to cart
let p = JSON.parse(JSON.stringify(products[0]));
cart.products.push(p);
//console.log('First cart', cart);
//change price
cart.products[0].price = 20;
console.log('products',products);
console.log('second cart',cart);
You create only shallow copy with Object.assign, which leads to accessing the same objects in a memory through copied reference.
If I need to modify object that is passed by reference or is global and I dont want to mutate it for all other functions/parts of the code, I use this: https://lodash.com/docs/4.17.10#cloneDeep
let p = _.cloneDeep(products[0]);
I am struggling to find ways how to preserve data to local storage but seems no luck on my side now. I can successfully add/ remove items in store however, whenever i try to refresh nor reload the page (google chrome) looks like no data found in store.
Here is my code:
Model: Pendingmodel.js
Ext.define('mysample.model.PendingModel', {
extend: 'Ext.data.Model',
config: {
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'ALIAS'
},
{
name: 'OBJECT'
},
{
name: 'DATETIME'
},
{
name: 'FIELDVALUE'
}
],
proxy: {
type: 'localstorage',
id: 'PendingModelProxy'
}
}
});
Store: Pendingstore.js
Ext.define('mysample.store.PendingStore', {
extend: 'Ext.data.Store',
requires: [
'mysample.model.PendingModel'
],
config: {
autoLoad: true,
model: 'mysample.model.PendingModel',
storeId: 'PendingStore'
}
});
Controller:
onDraftCommand: function (form, isTapped) {
var isValid = true;
var me = this, getForm = me.getLeadsView();
var pendingItems = getForm.getValues();
var cleanItems = getForm.getValues();
cleanItems['reset'] = function() {
for (var prop in this) {
delete this['reset'];
delete this['eventParameter'];
this[prop] = '';
}
}
if(isTapped == true && isValid == true) {
Ext.Msg.confirm('Message', 'Are you sure you want to save this on draft?', function (btn) {
switch (btn) {
case 'yes':
var date = new Date(), id = date.getUTCMilliseconds();
var obj = {
'ALIAS': 'leadsview',
'OBJECT': 'Leads Form',
'id': id,
'DATETIME': date,
'FIELDVALUE': pendingItems,
};
console.log('Leads pending store');
console.log(obj);
Ext.data.StoreManager.lookup('PendingStore').add(obj);
Ext.data.StoreManager.lookup('PendingStore').sync();
console.log(Ext.data.StoreManager.lookup('PendingStore'));
//clear form
cleanItems.reset();
getForm.setValues(cleanItems);
//Ext.getCmp('signatureField').removeImage();
break;
default:
break;
}
});
}
}
Add a identifier strategy inside your model as below.
Ext.define('mysample.model.PendingModel', {
extend: 'Ext.data.Model',
config: {
identifier: 'uuid', // add this
fields: [
{
name: 'id',
type: 'int'
}
],
proxy: {
type: 'localstorage',
id: 'PendingModelProxy'
}
}
You need to add the unique identifier in your model, like this:-
Ext.define('mysample.model.PendingModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.identifier.Uuid'
],
config: {
identifier: {
type: 'uuid',
isUnique: true
},
fields: [
{
name: 'id',
type: 'int'
},
{
name: 'ALIAS'
},
{
name: 'OBJECT'
},
{
name: 'DATETIME'
},
{
name: 'FIELDVALUE'
}
],
proxy: {
type: 'localstorage',
id: 'PendingModelProxy'
}
}
});
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.
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.
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');