Validation data in Ext.Model - extjs

Help me please.
Models have built-in support for validations, which are executed against the validator functions in Ext.data.validations.
My code:
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [{
name: 'name',
type: 'string'
},{
name: 'age',
type: 'int'
},{
name: 'phone',
type: 'string'
},{
name: 'gender',
type: 'string'
},{
name: 'username',
type: 'string'
}],
validations: [
{
type: 'length',
field: 'name',
min: 2
},{
type: 'format',
field: 'username',
matcher: /([a-z]+)[0-9]{2,3}/
}]
});
var person = Ext.create('User', {
name: 'Eugene',
username: 'Popov',
gender: 'F',
age: 300,
Married: false
});
console.log(person.get('name'))
person.set('name','U');
console.log(person.get('name'))//U
});
I've read that the model can filter data .
What is the principle of their work?
Why I can write wrong values in my example?
Thanks!

Model validations don't reject changes by themselves. Editing a model through some other component (like stores or grid editors) may provide this feature. Validations only come into play when calling the validate or isValid methods on a model.
If your models are part of a store, you can listen for the store's update event (link to docs). From within the event handler, you can validate the model and reject any changes you want.
// Simple demonstration
store.on('update', function (store, model, operation) {
if (operation === Ext.data.Model.EDIT && !model.isValid()) {
model.reject();
}
});

Related

New records are saved in store, but show only after refresh of page

this a Sencha code which I am supposed to fix, however I don't understand why after creating new records to a store, they don't show immediately, but, only after refresh(?). Below are the relevant pieces of code.
Thank you.
Controller
click: function(button){
var window = button.up('window');
var form = window.down('form#formTemplateWindow');
if(window.action == "add"){
if(form.isValid()){
var store = this.getDataViewList().getStore();
var zones = new Array();
Ext.each(form.zones, function(value, key){
zones.push(value.data.id);
});
var record = form.getValues();
record.zones = zones;
store.add(record);
store.sync();
button.up('window').close();
}
}
Model
Ext.define("web.model.Template", {
extend: "Ext.data.Model",
fields: [
'id',
'name',
'layout_id',
{
name: 'reg_date',
type: 'date',
dateReadFormat: 'Y-m-d H:i:s',
dateWriteFormat: 'Y-m-d H:i:s'
},{
name: 'background',
type: 'auto'
},{
name: 'color1',
type: 'string'
},{
name: 'color2',
type: 'string'
},{
name: 'url',
type: 'string'
},{
name: 'degree',
type: 'string'
},{
name: 'playlists',
type: 'auto'
},{
name: 'zones',
type: 'auto'
}
]
});
Store
Ext.define("web.store.Template",{
extend:"Ext.data.Store",
autoSync: true,
autoLoad:false,
model:"web.model.Template",
proxy:{
type:"rest",
url:web.util.Config.TEMPLATE_URI,
reader:{
type:"json",
root:"result"
}
},
sorters: [
{
property: 'Name',
direction: 'ASC'
}
]
});
The server has to respond accordingly with the newly created records.
Use store.insert(index,record) method instead of store.add(record).
this inserts Model instances into the Store at the given index and fires the add event as well
store.insert(0,record);
Change autoLoad property false to true
autoLoad:true

Binding Grid and Form ExtJs 6

I have a grid populating records from view model (Ajax proxy data from Java restful web services). When I select a record in the grid form open and the fields are displayed. The records are editable using the form.
I have one tag field which is binded to a store and I should be able to populate the data associated to the record whenever the user selects a record.
"data" : [ {
"createdOn" : 1475678859000,
"updatedOn" : 1475679885000,
"updatedBy" : null,
"id" : 174,
"userName" : "ffff,
"firstName" : "gg",
"lastName" : "ggg",
"salesDepartment" : [ {
"id" : 3,
"code" : "FC",
"name" : "Fiat-Chrysler",
"departmentHead" : "xxx",
"applicationCode" : null} ],}
I need to bind the value of id from sales department object . how can I achieve this. Please help me.
{xtype: 'tagfield',
anchor: '100%',
reference: 'salesDept',
fieldLabel: 'Sales Dept\'s',
name: 'salesDepartment',
allowBlank: false,
displayField: 'name',
valueField: 'id',
bind: {
value: '{record.salesDepartmentIds}',
store: '{SalesDepartmentStore}'},
}
Tag fields are really only designed to work with arrays or comma separated lists;
It looks like you are trying to use with associations, which it would be nice if there was more support for this out of the box.
I've had a go, and in terms of displaying got it working however saving values will really depend on how you plan to sync values to the server, if you are going to use in built proxies etc. then this will present a whole different challenge. I would like a similar component for my own apps, I will think on this further and may even create a UX for this.
I think you have several issues here, one is getting your associations working properly, then you need to make your tagfield work as expected.
Here is the fiddle
And the key parts are:
An extended tagfield:
Ext.define('RelatedTagField', {
extend: 'Ext.form.field.Tag',
xtype: 'rtagfield',
config: {
relatedStore: null
},
setValue: function (val) {
this.setRelatedStore(val);
var value;
if (val && val.isStore) {
value = val.collect('id');
} else {
value = '';
}
this.callParent([value]);
},
getValue: function () {
return this.relatedStore;
},
onBindStore: function () {
this.callParent(arguments);
this.on('select', function (tagfield, selection) {
var selectedIds = [];
//add any new selections
Ext.each(selection, function (rec) {
var rrec = this.relatedStore.getById(rec.id);
if (!rrec) {
this.relatedStore.add(rec.data)
}
selectedIds.push(rec.id);
}, this);
//remove any not selected anymore
this.relatedStore.each(function (rrec) {
if (selectedIds.indexOf(rrec.id) == -1) {
this.relatedStore.remove(rrec);
}
}, this);
}, this);
},
})
Binding the value:
{
xtype: 'rtagfield',
fieldLabel: 'Sales Department',
name: 'id',
displayField: 'name',
valueField: 'id',
bind: {
store: '{salesDepartment}',
value: '{record.salesDepartment}'
}
},
And adding a definition for the association:
Ext.define('MyApp.model.User', {
extend: 'Ext.data.Model',
alias: 'model.user',
hasMany: [{
model: 'MyApp.model.SalesDepartmentModel',
associationKey: 'salesDepartment',
role: 'salesDepartment'
}],
requires: [
'Ext.data.field.String'
],
fields: [{
type: 'string',
name: 'userName'
}, {
type: 'string',
name: 'firstName'
}, {
type: 'string',
name: 'lastName'
}, {
name: 'salesDepartment'
}, {
name: 'roles'
}, {
type: 'string',
name: 'email'
}, {
name: 'notificationFrequencyId'
}]
});
Further reading
I suggest you read more on associations and the tagfield source code
In terms of saving records back to the server, I would recommend looking at sessions

Placing a filename in a filefield in extjs

In my store I have a field called CreditName. In my view I am trying to check if CreditName is not null and if it is not enter it into my filefield. I have added a listener to my filefield that will enter text into the filefield. What I am having trouble with is getting CreditName into the filefield. I know that it is reading from my store because other fields are appearing properly.
Here is my code for my filefield
xtype: 'filefield',
buttonText: 'Select A File',
fieldLabel: 'File',
name: 'Credit',
labelWidth: 50,
msgTarget: 'under',
return true;
},
listeners: {
render: function (comp) {
comp.setRawValue(CreditName);
}
}
Here is the store code
fields: [ {
name: 'PartyId',
type: 'string'
}, {
name: 'CreditName',
type: 'string',
critical: true
}],
proxy: {
type: 'ajax',
url: 'api/parties',
reader: {
type: 'json'
}
}
PartyId shows up fine, here is the code for that, it is in the same view as filefield
{
xtype: 'displayfield',
name: 'PartyId',
fieldLabel: ' Party ID'
},
In your config of 'filefield', you have to use same name as 'name' property in store. In your case, it should be name: 'CreditName', not 'Credit'.
--edit--
You can get model values in 'render' listener like this:
render: function (comp) {
var model = comp.getModelData(),
value = model.get('CreditName');
comp.setRawValue(value);
}

ExtJS 5.1: Setting default ComboBox value using MVVM store

In my ViewModel, I create an inline data store for a ComboBox that I bind to in the View. The problem that I'm having is setting a default value for the ComboBox, based on one of the values in the store... I might be understanding binding here, so I'd like to hear any feedback.
OrderDetailsStatus model:
Ext.define('UserUI.model.OrderDetailsStatus', {
extend: 'Ext.data.Model',
alias: 'model.OrderDetailsStatus',
fields: [{
type: 'int',
name: 'statusId'
},
{
type: 'string',
name: 'status'
}]
});
ViewModel:
stores: {
/* TODO: This could eventually become an AJAX call, but for right now,
* it's an inline data store... the statusId's are currently unused */
orderDetailsStatusStore: {
model: 'UserUI.model.OrderDetailsStatus',
proxy: {
type: 'memory'
},
data: [
{ status: 'All', statusId: 1 },
{ status: 'Correct', statusId: 2 },
{ status: 'Incorrect', statusId: 3 }
]
}
}
In the View:
{
xtype: 'combo',
fieldLabel: 'Status',
bind: {
store: '{orderDetailsStatusStore}'
},
valueField: 'status',
displayField: 'status',
queryMode: 'local',
value: 'All',
listeners: {
select: 'onSelectComboBoxStatus'
}
}
Using the value: 'All' gives me an error about the model not existing:
TypeError: Model is not a constructor: ext-all...ebug.js (line 122343, col 33)
record = new Model(dataObj);
I'm assuming this is because the bound store hasn't been fully loaded in yet? If I debug the code, at that line, Model is undefined, and the store doesn't have any data. Any help would be appreciated.
Fiddle updated with fix in 5.1.0
<iframe src="https://fiddle.sencha.com/fiddle/m3g"></iframe>
I've created a simple fiddle that replicates yours -
https://fiddle.sencha.com/#fiddle/m3g

Email validation sencha

How to check validation for email field in sencha touch?Here my code in application,Please help me to solve this
{
xtype: 'fieldset',
items:[{
xtype: 'emailfield',
inputType:'email',
labelWidth: '33%',
label: 'Email',
id:'emailId',
name: 'emailId',placeHolder:'emailId'}]
}
The proper way to activate validation directly in the view would be:
{
xtype: 'textfield',
name: 'email',
vtype: 'email'
}
No need for regex.
If you storing fields as model instance, you can do.
Ext.define('User', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'name', type: 'string'},
{name: 'emailId', type: 'string'}
{name: 'phone', type: 'string'}
]
},
validations: [
{type: 'presence', name: 'name',message:"Enter Name"},
{type: 'format', name: 'emailId', matcher: /^\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$/, message:"Wrong Email Format"}
]
});
Or you can just match with regular expression
var ereg = /^\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
var testResult = ereg.test(emailId);
testResult will be true or false based on validation.
For form field validation on user input use the following regex
{
xtype: 'textfield',
allowBlank:false,
regex:/^((([a-zA-Z0-9_\-\.]+)#([a-zA-Z0-9_\-\.]+)\.([a-zA-Z\s?]{2,5}){1,25})*(\s*?;\s*?)*)*$/,
regexText:'This field must contain single or multiple valid email addresses separated by semicolon (;)',
blankText : 'Please enter email address(s)',
}

Resources