Validations in Sencha Touch Architect - validation

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())

Related

Vuetable not registering <vuetable-field-component:account-details> when using __component:account-details

Using Vuetable-2 with laravel but keep getting the error
[Vue warn]: Unknown custom element: <vuetable-field-component:account-details> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
For both the the account-details and account-actions components.
Even though i have already registered the components. Here is the code.
// TableAccounts.vue
<template>
<base-vuetable :api-url="route" :fields="fields" :sort-order="sortOrder">
</base-vuetable>
</template>
<script>
import BaseVuetable from './BaseVuetable.vue';
import AccountActions from './AccountActions.vue';
import AccountDetails from './AccountDetails.vue';
Vue.component('account-actions', require('./AccountActions.vue').default);
Vue.component('account-details', require('./AccountDetails.vue').default);
let fields = [
{
name: '__component:account-details',
title: '',
},
{
name: 'email',
title: 'Email',
sortField: 'email',
callback: (value) => this.email(value)
},
{
name: 'fullname',
title: 'Fullname',
sortField: 'fullname'
},
{
name: 'company',
title: 'Company',
sortField: 'company',
},
{
name: 'role_name',
title: 'Role',
sortField: 'type'
},
{
name: 'active',
title: 'Status',
sortField: 'active',
callback: (value) => this.active(value)
},
{
name: 'signed_in_at',
title: 'Last Login',
sortField: 'signed_in_at',
callback: (value) => this.fromNow(value)
},
{
name: 'updated_at',
title: 'Last update',
sortField: 'updated_at',
callback: (value) => this.fromNow(value)
},
{
titleClass: 'account__actions-button',
name: '__component:account-actions',
title: '',
}
]
export default {
components: {
BaseVuetable,
AccountActions,
AccountDetails
},
props: {
route: {
type: String,
default: ''
}
},
data() {
return {
fields,
sortOrder: [
{
field: 'updated_at',
sortField: 'updated_at',
direction: 'desc'
}
],
}
}
...
}
Any idea why? I have even registred the components globally. If i debug the global components they are there.

Botkit - Slack interactive messages

I am trying to get all the values from all actions. Currently I have two select actions (Pick a game and Pick a day). In the interactive_messages_callback I am getting the selected value only of the currently modified select.
Is there a way to get an array of values from all the actions like currentValues: [ os_type_selection: 'osx', day_selection: '2' ]?
bot.reply(message, {
attachments: [
{
title: 'Question 1',
callback_id: 'question_1',
attachment_type: 'default',
actions: [
{
name: 'os_type_selection',
text: 'Pick a game...',
type: 'select',
options: [
{
text: 'Mac OS X',
value: 'osx',
},
{
text: 'Windows',
value: 'windows',
}
]
}
],
},
{
title: 'Question 2',
callback_id: 'question_2',
attachment_type: 'default',
actions: [
{
name: 'day_selection',
text: 'Pick a day...',
type: 'select',
options: [
{
text: 'Monday',
value: '1',
},
{
text: 'Tuesday',
value: '2',
},
]
},
],
},
],
});
// interactive_messages_callback
{ type: 'interactive_message_callback',
actions:
[ { name: 'day_selection',
type: 'select',
selected_options: [Object] } ],
callback_id: 'question_2',
team: { id: 'T02L9R6LX', domain: 'hellephant' },
channel: 'D9066R5NC',
user: 'U4C2DDM9T',
action_ts: '1517489936.972094',
message_ts: '1517489928.000257',
attachment_id: '2',
token: 'f5LpbwCQ2D97BhNOPgn1Gotb',
is_app_unfurl: false,
original_message:
{ type: 'message',
user: 'U90RBPAE6',
text: '...',
bot_id: 'B90UUGKSR',
attachments: [ [Object], [Object] ],
ts: '1517489928.000257' },
response_url: 'https://hooks.slack.com/actions/T02L9R6LX/309104841078/xsmwspjpdhV1oSW06PQkQZp5',
trigger_id: '308368498005.2689856711.9425688de7f023516061a4e4b2701322',
raw_message:
{ type: 'interactive_message',
actions: [ [Object] ],
callback_id: 'question_2',
team: { id: 'T02L9R6LX', domain: 'hellephant' },
channel: { id: 'D9066R5NC', name: 'directmessage' },
user: { id: 'U4C2DDM9T', name: 'davidnovak' },
action_ts: '1517489936.972094',
message_ts: '1517489928.000257',
attachment_id: '2',
token: 'f5LpbwCQ2D97BhNOPgn1Gotb',
is_app_unfurl: false,
original_message:
{ type: 'message',
user: 'U90RBPAE6',
text: '...',
bot_id: 'B90UUGKSR',
attachments: [Object],
ts: '1517489928.000257' },
response_url: 'https://hooks.slack.com/actions/T02L9R6LX/309104841078/xsmwspjpdhV1oSW06PQkQZp5',
trigger_id: '308368498005.2689856711.9425688de7f023516061a4e4b2701322' },
_pipeline: { stage: 'receive' },
text: '2' }
No. You can not have multiple interactive menus on the same message in Slack. Its technically possible, but once the user selects one menu it will always fire for that menu, making it impossible for the user to select from multiple menus at the same time.
If you want to use multiple menus you need to spread them out over separate messages and let the user select one after the other.
Or check out the dialog function, which allows you to use multiple menus at the same time.

Processing Json data with EXTJS

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()
});
}
});

Extjs proxy just post dirty fields to server, not all filelds

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 }

How to sync combobox and textfield value. i.e how to load different values from store on textfield,while I am changing values on combobox

I am new to EXTjs(and to Stackoverflow as well). I was struggling with this issue and at last decided to ask for help.My question is " How to sync combobox and textfield values. i.e how to load different values from 'store' on textfield,while I am changing values on combobox? " My problem is that while I load values on combobox and I select them my textfield stays empty all the time. I tried "Ext.getCmp().setValue();" it works fine with this ,but I think it is not the best option if I'd have 100 textfields. I want combobox and textfield to be synched with store somehow. Any help is appreciated. Situation in pictures are in links below :
pic one
pic two
And my code :
My app.js :
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'work',
appFolder: 'app',
controllers: ['Work'],
launch: function() {
Ext.create('Ext.container.Viewport', {
//layout: 'fit',
items: [{
xtype: 'rightpanel' // gets it from view class
}
]
});
}
});
My view RightPanel :
Ext.define('work.view.works.RightPanel', {
extend: 'Ext.panel.Panel',
ALIAS: 'widget.rightpanel',
width: 300,
title: 'Building navigation',
animCollapse: true,
collapsible: true,
split: true,
minSize: 400,
maxSize: 400,
margins: '0 5 0 0',
//activeTab:1, tabPosition:'bottom',
initComponent: function() {
this.items = [{
xtype: 'form',
items: [{
xtype: 'combobox',
fieldLabel: 'BuildingID',
queryMode: 'local',
name: 'Bid',
displayField: 'Bid',
valueField: 'Bid',
id: 'Bid',
MODE: 'remote',
store: 'Work'
}, {
xtype: 'textfield',
fieldLabel: 'Address',
name: 'Address',
displayField: 'Address',
valueField: 'Address',
id: 'Address',
store: 'Work'
}]
}];
this.columns = [{
header: 'ID',
dataIndex: 'Bid',
flex: 1
}, {
header: 'Texts',
dataIndex: 'Address',
flex: 1
}];
this.callParent(arguments);
}
});
My store :
Ext.define('work.store.Work', {
extend: 'Ext.data.Store',
model: 'work.model.Work',
storeId: 'workstore',
id: 'workstore',
autoLoad: true,
proxy: {
type: 'ajax',
limitParam: undefined,
startParam: undefined,
paramName: undefined,
pageParam: undefined,
noCache: false,
api: {
read: 'data/showWork.php' // just a .php file that reads values from database and shows them on combobox
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
},
writer: {
type: 'json',
root: 'data',
encode: true
}
}
});
My Model class :
Ext.define('work.model.Work', {
extend: 'Ext.data.Model',
//idProperty: 'WorkID',
fields: [{
name: 'Bid',
type: 'int'
}, 'Address']
});
My Controller :
Ext.define('work.controller.Work', {
extend: 'Ext.app.Controller',
stores: ['Work'],
models: ['Work'],
views: [
'works.RightPanel' // name comes from view class
],
init: function() {
console.log('Done');
this.control({
'viewport > rightpanel': {
render: this.test
},
'rightpanel combobox[id=Bid]': {
select: this.change
}
});
},
change: function(buttons) {
var values = this.getStore('Work').collect('Address', 'Address', false);
var win = buttons.up('rightpanel'); // gets the needed widget
var form = win.down('combobox'); // gets the needed form
var value = form.getValue(); // gets the value
console.log("value " + value);
}
});
You want to watch for a change on the combobox, and then action a change based off its new value.
this.items = [{
xtype: 'form',
items: [{
xtype: 'combobox',
fieldLabel: 'BuildingID',
queryMode: 'local',
name: 'Bid',
displayField: 'Bid',
valueField: 'Bid',
id: 'Bid',
mode: 'remote',
store: 'Work'
listeners::{
change:function(cbx, newVal,oldVal,e){
var record = cbx.getStore().find("Bid",newVal); // theres prolly a better way to find this, such as to find the active record of the cbx
Ext.getCmp('Address').setValue(record.getValue("Address"))
}
}
},{
xtype: 'textfield',
fieldLabel: 'Address',
name: 'Address',
displayField: 'Address',
valueField: 'Address',
id: 'Address',
store: 'Work'
}]

Resources