I have a model:
Ext.define('CrudTest.model.User', {
extend: 'Ext.data.Model',
idProperty: 'Id',
fields: [
{ name: 'Id', type: 'int' },
{ name: 'Name', type: 'string' },
{ name: 'PhoneNumber', type: 'int' },
{ name: 'Address', type: 'string' },
{ name: 'StateId', type: 'int', reference: 'State' },
],
validators: [
{ type: 'presence', field: 'Name', message: 'define name, please' },
{ type: 'length', field: 'PhoneNumber', max: 8, messsage: 'lower than 8 digit' },
],
proxy: {
type: 'ajax',
api: {
create: 'home/new',
read: 'home/users',
update: 'home/Edit',
destroy: 'home/Delete'
},
},
});
and a form that load data to form by loadRecord() and my handler code for submit button is:
var form = this.up('form').getForm();
if (form.isValid()) {
form.getRecord().save();
}
it make a post request through my proxy model good. but the body of request just have dirty(edited) fields. why i don't have other fields?
but in request body i have just dirty fields. why? i know updateRecord() uses getFieldValues([onlyDirty=false]), how can send all fields values?
I use extjs 5
Finally find the problem. Ext.data.writer.Writer has a config property writeAllFields
So i change the proxy to this:
proxy: {
writer:{ writeAllFields:true },
type: 'ajax', //also works with type: 'direct',
api: {
create: 'home/new',
read: 'home/users',
update: 'home/Edit',
destroy: 'home/Delete'
},
You can set crtical: true on the Model to any fields you always want written whether changed or not, e.g.
{ name: 'title', type: 'string', critical: true }
Related
This is my first time using a javascript framework, I would like to implement MVVM in my EXT JS application and the data is coming from my WEB API (ASP.NET FRAMEWORK).
My problem is that, I don't seem to understand how to fully use viewModel which looks up to my store. I successfully bound my ViewModel in my grid but now I don't know how to update the selected record using a form (modal) and sync my store (send update request through API)
I have a feeling that I'm doing it the wrong way. I don't know how to do this in fiddle so I'll just paste my code here.
Genre.js [Model]
Ext.define('VAM2.model.Genre', {
extend: 'VAM2.model.Base',
alias: 'model.genre',
fields: [
{name: 'GenreId', type: 'int'},
{name: 'Code', type: 'string'},
{name: 'CreatedBy', type: 'string'},
]
});
Genre.js [Store]
Ext.define('VAM2.store.Genre', {
extend: 'Ext.data.Store',
alias: 'store.genre',
model: 'VAM2.model.Genre',
autoLoad: false,
pageSize: 10,
storeId: 'GenreId',
proxy : {
type : 'rest',
actionMethods : {
read : 'GET'
},
cors:true,
url: 'https://localhost:44332/api/Genre/GetGenresExtJs',
api:{
create: 'https://localhost:44332/api/Genre/CreateGenreExtJS',
read: 'https://localhost:44332/api/Genre/GetGenresExtJs',
update: 'https://localhost:44332/api/Genre/EditGenreExtJS',
destroy: 'https://localhost:44332/api/Genre/CreateGenreExtJS'
},
useDefaultXhrHeader: false,
reader: {
type : 'json',
headers: { 'Accept': 'application/json' },
allDataOptions: {
associated: true,
persist: true
},
rootProperty : 'data',
totalProperty: 'total'
},
}
});
GenreViewModel.js - I'm not sure if this is okay but the read is working
Ext.define('VAM2.view.genre.GenreViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.genre',
requires:[
'VAM2.model.Genre'
],
stores: {
myGenres : {
model: 'VAM2.model.Genre',
autoLoad: true,
proxy : {
type : 'rest',
actionMethods : {
read : 'GET'
},
cors:true,
url: 'https://localhost:44332/api/Genre/GetGenresExtJs',
api:{
create: 'https://localhost:44332/api/Genre/CreateGenreExtJS',
read: 'https://localhost:44332/api/Genre/GetGenresExtJs',
update: 'https://localhost:44332/api/Genre/EditGenreExtJS',
destroy: 'https://localhost:44332/api/Genre/CreateGenreExtJS'
},
useDefaultXhrHeader: false,
reader: {
type : 'json',
headers: { 'Accept': 'application/json' },
allDataOptions: {
associated: true,
persist: true
},
rootProperty : 'data',
totalProperty: 'total'
},
}
}
},
data:{
title:'Sample Binding'
},
formulas: {
currentRecord: {
bind: {
bindTo: '{groupGrid.selection}', //--> reference configurated
//--> on the grid view (reference: groupGrid)
deep: true
},
get: function(record) {
return record;
},
set: function(record) {
if (!record.isModel) {
record = this.get('records').getById(record);
}
this.set('currentRecord', record);
}
}
}
});
View -- This is where it gets confusing. I don't know how to put the bounded data from grid to a form modal and then save and sync my store.
Ext.define('VAM2.view.genre.GenreList', {
extend: 'Ext.container.Container',
xtype: 'myGenreList',
requires: [
'VAM2.view.genre.GenreController',
'VAM2.view.genre.GenreViewModel',
'Ext.grid.column.Boolean',
'Ext.form.field.Checkbox',
'Ext.form.field.TextArea',
'Ext.form.field.Text'
],
controller: "genre",
viewModel: {
type: "genre"
},
width:'100%',
layout: {
type: 'vbox',
pack: 'start',
align: 'stretch'
},
style: {
backgroundColor: '#f5f5f5'
},
items: [{
xtype: 'grid',
reference: 'groupGrid', //--> used in the viewmodel,
bind: {
title: '{title}',
store: '{myGenres}'
},
columns: [{
text:'GenreIdField',
id:'GenreIdField',
dataIndex:'GenreId',
hidden:true
},{
text: 'Code',
dataIndex: 'Code',
flex:1
}, {
text: 'Created By',
dataIndex: 'CreatedBy',
flex: 1
}],
listeners:{
select:'onGenreSelected_FORMA' //--> I'm thinking this will trigger
//-> a form (modal) containing the data to update
}
}]
});
A fiddle example would be great! Thank you!
Screenshot:
This is where I would like to display form modal that can sync/update my store when I modify some data.
To do store.sync() you need to set values on the record first.
Example is without ViewModel:
https://fiddle.sencha.com/#fiddle/3isg&view/editor
select: function (grid, record) {
console.log(record);
let win = Ext.create("Ext.window.Window", {
title: 'Edit',
modal: true,
autoShow: true,
width: 400,
height: 500,
controller: {},
items: [{
xtype: 'form',
reference: 'form',
fieldLabel: 'name',
items: [{
xtype: 'textfield',
name: 'name'
}]
}],
buttons: [{
text: 'cancel',
handler: function () {
win.close();
}
}, {
text: 'save',
handler: function () {
var values = this.lookupController().lookup('form').getValues();
record.set(values);
grid.getStore().sync({
scope: this,
success: function () {
win.close();
Ext.toast({
html: 'Well done',
align: 't'
});
},
failure: function () {
Ext.toast({
html: 'Problem occurred',
align: 't'
});
}
});
}
}],
listeners: {
afterrender: function () {
this.lookupController().lookup('form').loadRecord(record);
}
}
})
}
I'm trying to use the Dynamic Linq Helper libraries from Kendo. The parameter map function on the grid does not have the correct parameters to send to the controller.
The parameterMap options have:
{"take":10,"skip":0,"page":1,"pageSize":10}
but according to the example, it should have take, skip, sort, filter, which is not in the parameterMap function or getting passed to the server.
I'm following the example here
http://www.telerik.com/blogs/kendo-ui-open-sources-dynamic-linq-helpers
And also looked other examples, my grid is set up the same as the others.
The only difference being, this is a Web API single page app, not MVC. However, this shouldn't make a difference in what the Grid class is passing to it's parameterMap function.
What is going on here?
$("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "http://localhost/biahost/query/projectStatuses",
dataType: "application/json",
type: "POST",
contentType: "application/json; charset=utf-8"
//data:{}
},
parameterMap: function (options) {
debugger;
//options only contain {"take":10,"skip":0,"page":1,"pageSize":10}
return kendo.stringify(options);
}
},
schema: {
data: "Data",
total: "Total",
model: {
fields: {
NAME: { type: "string" },
CODE: { type: "string" },
STATUS: { type: "string" },
COMMENTS: { type: "string" },
INSERTS: { type: "string" },
UPDATES: { type: "string" },
TOTAL_UPDATES: { type: "string" },
LAST_ACTION_DATE: { type: "string" }
//UnitId: { type: "string" },
//UnitName: { type: "string" }
}
}
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
filterable: true,
sortable: true,
pageable: true,
columns: projectStatusColumns
});
var projectStatusColumns = [
{
field: 'NAME',
label: 'Res name',
hidden: true,
},
{
field: 'CODE',
label: 'Code'
},
{
field: 'STATUS',
label: 'Status'
},
{
field: 'COMMENTS',
label: 'Comments'
}
,
{
field: 'INSERTS',
label: 'Inserts'
}
,
{
field: 'UPDATES',
label: 'Updates'
}
,
{
field: 'TOTAL_UPDATES',
label: 'Total Updates'
}
,
{
field: 'LAST_ACTION_DATE',
label: 'Last Action Date'
}
];
had the same problem so i looked it up and here i am. You just need to return "options" which contains the parameter map as it is, if you stringify it will become a json object which cannot be defined in a url.
Hope i'm not too late!
Java application sends to the front the following json data:
{"data":[{"id":1,"name":"","password":"xxxxxxxxxxxxxxxxxxx","roles":[{"id":1,"name":"Administrator"}],"username":"admin"}]}
In the front I have an user model like the following:
Ext.define('App.store.Users', {
extend: 'Ext.data.Store',
fields: [
{name: 'id', type: 'auto'},
{name: 'name', type: 'auto'},
{name: 'password', type: 'auto'},
{name: 'roles', type: 'auto'},
{name: 'username', type: 'auto'},
],
autoLoad: true,
proxy: {
type: 'ajax',
url: '/web/user',
reader: {
type: 'json',
root: 'data'
}
}
});
Edit:
I updated the code and this way the data is loaded.
Also i made a grid so I can show the results.
Ext.define('App.view.Home', {
extend: 'Ext.panel.Panel',
alias: 'widget.home',
title: 'Home',
layout: 'fit',
items: [
{
xtype: 'gridpanel',
store: 'Users',
title: 'Users grid',
columns: [
{text: 'Id', dataIndex: 'id' },
{text: 'Username', dataIndex: 'username', width : 200 },
{text: 'Role', dataIndex: 'roles', width : 200 },
{text: 'Name', dataIndex: 'name', width : 200 },
]
}
]
});
Now the question that remains is that the grid is showing [object Object] how could i be showing the part that i want from that object, as the name of the role
You need to change the reader type to JSON, This code is working for me:
Fiddle
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('Users', {
extend: 'Ext.data.Store',
fields: ['id', {
name: 'username',
type: 'string'
}, {
name: 'name',
type: 'string'
}],
autoLoad: true,
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
rootProperty: 'data'
}
}
});
Ext.create("Users", {
listeners: {
load: function() {
console.log("Loaded " + this.getCount() + " records");
}
}
});
}
});
I also removed the mappings as I don't think that you need them.
EDIT
In regards to the data showing in a grid, the 'roles' property in the JSON data is an array, that's why it's showing in the grid as object, I've updated the fiddle to show a possible way to get this information, But it's not the recommended method. You should probably look at associations in ExtJs for this.
Reviewing the guide on the Data Package may also help with this.
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('Users', {
extend: 'Ext.data.Store',
fields: [{
name: 'id',
type: 'int'
}, {
name: 'username',
type: 'string'
}, {
name: 'name',
type: 'string'
}, {
name: 'roles',
type: 'auto'
}],
autoLoad: true,
proxy: {
type: 'ajax',
url: 'data1.json',
reader: {
type: 'json',
root: 'data'
}
},
listeners: {
load: function(store, records) {
console.log("Loaded " + this.getCount() + " records");
}
}
});
var users = Ext.create("Users");
Ext.define('App.view.Home', {
extend: 'Ext.panel.Panel',
alias: 'widget.home',
title: 'Home',
layout: 'fit',
items: [{
xtype: 'gridpanel',
store: users,
title: 'Users grid',
columns: [{
text: 'Id',
dataIndex: 'id'
}, {
text: 'Username',
dataIndex: 'username',
width: 200
}, {
text: 'Role',
dataIndex: 'roles',
width: 200,
renderer: function(v, metadata) {
return v[0].name;
}
}, {
text: 'Name',
dataIndex: 'name',
width: 200
}]
}]
});
Ext.create('App.view.Home', {
renderTo: Ext.getBody()
});
}
});
I am very new to sencha touch, and i am using Architect. I have a controller "RegisterUser"(controlleractiontap) which has a function.. when i fill in some user data and I click register button in my formview it will write the user to my local database.
I have a model called "userModel" which contains the following:
fields: [
{
name: 'Username',
type: 'string'
},
{
name: 'Password',
type: 'string'
},
{
name: 'Firstname',
type: 'string'
},
{
name: 'Lastname',
type: 'string'
},
{
name: 'Phonenumber',
type: 'string'
},
{
name: 'Email',
type: 'string'
}
],
validations: [
{
type: 'presence',
field: 'Username'
},
{
type: 'email',
field: 'Email'
},
{
type: 'length',
field: 'PhoneNumber',
max: 10,
min: 10
}
the problem: how do i call my validators in the controller so it will validate the fields in my form?
if i missing some information to make it more clear just let me now.
Thanks in advance!
var val=Ext.create('talkbag.model.Registration',new Ext.getCmp("registration").getValues());
where "registration" is the id assigned to the view that extends Ext.form.Panel
var check=val.validate();
now you can check like this if (!check.isValid())
The load of JsonDaten not work. It just shows the loading Notice
Model.js:
ps.models.Event = Ext.regModel("ps.models.Event", {
fields: [
{name: "id", type: "int"},
{name: "date", type: "string"},
{name: "kat", type: "string"},
{name: "name", type: "string"},
{name: "location", type: "string"},
]
});
ps.stores.event = new Ext.data.Store({
model: "ps.models.Event",
proxy: {
type: 'scripttag',
url: 'http://www.asfdasdf.com/eventkalender/eventlist/format/json',
reader: {
type: 'json'
}
},
autoLoad: true
});
View.js:
items: [{
xtype: 'list',
emptyText: 'Keine Events verfügbar',
itemTpl: '{name}',
//grouped: true,
scroll: 'vertical',
fullscreen: true,
store: ps.stores.event
}
Whats wrong?
Thank you for your support!!
Probably this is because of incorrect json format (you could check for errors by pressing CTRL+Shift+J in Chrome)
Try to follow this tutorial http://www.sencha.com/learn/legacy/Tutorial:Creating_JSON_Data_in_PHP
UPDATE
You need to add root:'events' to you proxy's reader:
ps.stores.event = new Ext.data.Store({
model: "ps.models.Event",
proxy: {
type: 'scripttag',
url: 'http://www.asfdasdf.com/eventkalender/eventlist/format/json',
reader: {
type: 'json',
root: 'events'
}
},
autoLoad: true
});
You may also want to account for any errors and timeouts with the below:
ps.stores.event = new Ext.data.Store({
model: "ps.models.Event",
proxy: {
type: 'scripttag',
url: 'http://www.asfdasdf.com/eventkalender/eventlist/format/json',
reader: {
type: 'json',
root: 'events'
},
timeout: 3000, //milliseconds
listeners: {
exception:function(proxy, response){
console.error(response.responseText);
}
}
},
autoLoad: true
});