Submitting a form in Circuit SDK - circuit-sdk

I'm sending a form by bot to conversation using Circuit SDK. That contains a couple of buttons:
client.addTextItem(item.convId, {
content: 'Form test',
form: {
id: 'form123',
title: 'Form test',
controls: [{
type: 'BUTTON',
name: 'fruit',
options: [{
text: 'Apple',
value: '1'
}, {
text: 'Banana asd asd asd asdsa das asd',
value: '2'
}, {
text: "Strawberry",
value: '3'
}]
}]
}});
And I subscribed to formSubmission event to receive user's choice:
client.addEventListener('formSubmission', function (event) {
var formData = event.form;
console.log(event);
console.log(formData);
});
When I click on one of buttons in conversation with bot the event is handled as I want:
{ type: 'formSubmission',
itemId: '44469462-6d79-49ac-8439-3a1a57a9d6d2',
form: { id: 'form123', data: [ [Object] ] },
submitterId: '81cb8c4d-2706-4c03-8d82-20081b9399e4' }
{ id: 'form123', data: [ { name: 'fruit', value: '1' } ] }
But there are a "An error occured submitting the form." notification in top of Circuit UI.
Why user got this message?

This is a bug. We are looking into it. As a workaround you may overwrite the error by defining your own notification after the user clicks the button like this:
client.addTextItem(item.convId, {
content: 'Form test',
form: {
id: 'form123',
title: 'Form test',
controls: [{
type: 'BUTTON',
name: 'fruit',
options: [{
text: 'Apple',
value: '1',
notification: "Form submitted"
}, {
text: 'Banana asd asd asd asdsa das asd',
value: '2',
notification: "Form submitted"
}, {
text: "Strawberry",
value: '3',
notification: "Form submitted"
}]
}]
}});
Each button can have its own notification text.
I will update this stackoverflow question with an estimated date for a fix.

Related

Sencha Touch, setRecord() not working. Fields are blank.

I'm new to Sencha Touch...
I've been searching and asking people for hours, but cannot figure out why my detail view does not get the data (using setRecord).
I have not been able to find an example that uses Ext.NavigationView to push a view that uses the data from setRecord, so I suspect I'm doing something wrong there.
I have a tabbed view. First tab shows a list of items. Click an item disclosure to see details for that item. The detail view appears, but with no any data.
The tabs are setup in the launch function of ViewPortController.
The main view in the first tab is the PeopleListView. All the people appear in the list.
The PeopleListView is added to an Ext.NavigationView. A reference to the Ext.NavigationView is added to the PeopleListView so it can be used later
PeopleListViewController has a function, showDetailView, that is successfully called when a disclosure button is tapped.
The controller's showDetailView function
sets the record (which contains the correct data) on the personDetailView,
retrieves the instance of the Ext.NavigationView and pushes the PersonDetailView.
The record value passed to showDetailView has the correct data.
When personDetailView appears, the fields have no data.
ViewPortController:
launch: function() {
// var personDetailView = {
// xtype: 'persondetailview'
// }
var pplView = Ext.create('PeopleApp.view.PeopleListView');
var pplNavView = Ext.create('Ext.NavigationView', {
title: 'People',
iconCls: 'home',
useTitleForBackButtonText: true,
});
pplView.setNavigationView(pplNavView);
pplNavView.add(pplView);
. . .
var mainViewPort = getMainViewPort();
mainViewPort.setItems([pplNavView, . . .]);
},
PersonModel:
Ext.define('PeopleApp.model.PersonModel', {
extend: 'Ext.data.Model',
requires: ['Ext.data.proxy.Rest'],
config: {
idProperty: 'id',
fields: [
{ name: 'id', type: 'auto' },
{ name: 'name', type: 'string' },
{ name: 'address', type: 'string' },
{ name: 'email', type: 'string' },
{ name: 'age', type: 'int' },
{ name: 'gender', type: 'string' },
{ name: 'note', type: 'string' }
],
proxy: {
type: 'rest',
url: '/app/data/people.json',
reader: {
type: 'json',
rootProperty: 'people'
}
},
}
});
PeopleListViewController:
Ext.define('PeopleApp.controller.PeopleListViewController', {
extend: 'Ext.app.Controller',
xtype: 'peoplelistviewcontroller',
config: {
refs: {
peopleListView: 'peoplelistview',
personDetailView: 'persondetailview',
peopleView: 'peopleview',
},
control: {
peopleListView: {
discloseDetail: 'showDetailView'
}
}
},
showDetailView: function(view, record) {
console.log("record.data.name=" + record.data.name);
var detailView = Ext.create('PeopleApp.view.PersonDetailView');
//var detailView = this.getPersonDetailView();
detailView.setRecord(record);
var navView = view.getNavigationView();
navView.push(detailView);
},
launch: function() { this.callParent(arguments); },
init: function() { this.callParent(arguments); },
});
PersonDetailView:
Ext.define('PeopleApp.view.PersonDetailView', {
extend: 'PeopleApp.view.BaseView',
xtype: 'persondetailview',
requires: [
'Ext.form.FieldSet',
'Ext.form.Text',
'Ext.form.TextArea'
],
config: {
title: "Person Details",
scrollable: true,
items: [{
xtype: 'fieldset',
items: [{
xtype: 'textfield',
name: 'name',
label: 'Name: ',
required: true
}, {
xtype: 'textfield',
name: 'age',
label: 'Age: ',
required: false
}, // etc.
]}
]}
});
Can you tell me why detailView.setRecord(record) does not get the data set in the fields of DetailViewController, and what I need to do differently?
I am not sure but you should use below code in your Person detail view:
items: [
{
xtype:'formpanel',
id:'personDetailViewForm',
items:[{
xtype: 'fieldset',
items: [{
xtype: 'textfield',
name: 'name',
label: 'Name: ',
required: true
}, {
xtype: 'textfield',
name: 'age',
label: 'Age: ',
required: false
}, // etc.
]
}]
}]
and in the personListViewController you can set that form's values instead of setting records to the view like:
var detailView = Ext.create('PeopleApp.view.PersonDetailView');
var personDetailViewForm = detailView.down('#personDetailViewForm ');
personDetailViewForm .setValues(records);
Note that records object property names and form fields names must match and if records doesn't work try with records.data.

Form submit isn't working

I am creating login system with Sencha Touch 2. I am getting an issue while submitting my form. It is not getting response data from server. Below is my code
Controller:
Ext.define("MyMobile.controller.LoginController", {
extend: "Ext.app.Controller",
views: ['LoginView'],
config: {
refs: {
loginForm: "#loginFormPanel"
},
control: {
'button[action=login]': {
tap: "authenticateUser"
}
}
},
authenticateUser: function (button) {
this.getLoginForm().submit({
url: 'login/authenticate',
method: 'POST',
success: function (form, result) {
debugger; //This block of code is not executing even after JSON response
var jsonoutput = Ext.decode(result); // json parsing
Ext.MessageBox.alert('Error', "Success");
},
failure: function (form, result) {//This block of code is not executing even after JSON response
Ext.MessageBox.alert('Error', "Invalid username/password");
}
});
}
});
View
Ext.define("MyMobile.view.LoginView", {
extend: "Ext.form.FormPanel",
alias: "widget.mylogin",
id: 'loginFormPanel',
config: {
margin: '0 auto',
name: 'loginform',
frame: true,
url: 'login/Authenticate',
title: 'Login',
items: [
{
xtype: 'fieldset',
itemId: 'LoginFieldset',
margin: '10 auto 0 auto ',
title: '',
items: [
{
xtype: 'textfield',
label: 'User Name',
name: 'my-username',
required: true,
placeHolder: 'Username'
},
{
xtype: 'emailfield',
label: 'Email',
name: 'Email'
},
{
xtype: 'passwordfield',
label: 'Password',
name: 'my-password',
required: true,
placeHolder: 'Password'
}
]
},
{
xtype: 'button',
id: 'loginButton',
margin: '25 auto 0 auto ',
style: '',
maxWidth: 200,
ui: 'action',
width: '',
iconCls: 'user',
iconMask: true,
text: 'Login',
action: 'login'
}
]
}
});
App.JS
Ext.application({
name: "MyMobile",
appFolder: "myapp",
controllers: ["LoginController"],
views: ['LoginView'],
launch: function () {
var loginPanel= Ext.create('Ext.Panel', {
layout: 'fit',
items: [
{
xtype: 'mylogin'
}
]
});
Ext.Viewport.add(loginPanel);
}
});
Can some one could figure out what should be the problem?
Below was the JSON response i am getting from server.
{"UserName":"Murali","isAdmin":true,"isAuthenticated":true}
Even after getting a JSON and 200 ok result, my code form submit function goes into failure callback. In failure call back function failure:function(form,result) i am getting result param as my JSON. But why it is in failure?
Make your server return a JSON response like below:
If success:
{
"success":true,
"UserName":"Murali",
"isAdmin":true,
"isAuthenticated":true
}
If failure:
{
"success":false
}
Read more here: http://docs.sencha.com/touch/2-0/#!/api/Ext.form.Panel-method-submit

Empty Sencha Touch 2 List

The Git Ropo for full code
I have defined:
/app/model/Todo:
Ext.define('Test.model.Todo', {
extend: 'Ext.data.Model',
config: {
fields: [
{ name: 'title', type: 'string' },
{ name: 'priority', type: 'integer', defaultValue: 0 },
{ name: 'done', type: 'boolean' }
]
}
});
/app/store/TodoStore
Ext.define('Test.store.TodoStore', {
extend: 'Ext.data.Store',
requires: [ 'Test.model.Todo' ],
config: {
model: 'Test.model.Todo',
data: [
{ title: 'Todo Item 1', priority: 0, done: false },
{ title: 'Todo Item 2', priority: 0, done: false },
{ title: 'Todo Item 3', priority: 0, done: false },
{ title: 'Todo Item 4', priority: 0, done: false },
{ title: 'Todo Item 5', priority: 0, done: false },
{ title: 'Todo Item 6', priority: 0, done: false }
]
}
});
Now, if I just use store: 'TodoStore' in a list, I get
[WARN][Ext.dataview.List#applyStore] The specified Store cannot be found
So I added too app.js
Ext.application({
name: 'Test',
...
stores: [ 'TodoStore' ],
The warning goes away, but I still have a blank list. Am I missing something?
Old Post below
Ext.define("SimpleTodo.view.Main", {
extend: 'Ext.Panel',
requires: [ 'Ext.TitleBar', 'Ext.dataview.List' ],
config: {
styleHtmlContent: true,
items: [
...
{
xtype: 'list',
itemTpl: '{name}',
store: {
fields: ['name'],
data: [
{ name: 'Todo 1' },
{ name: 'Todo 2' },
{ name: 'Todo 3' },
{ name: 'Todo 4' },
{ name: 'Todo 5' },
{ name: 'Todo 6' }
]
}
}
]
}
});
Getting:
Expecting a function in instanceof check, but got #<Object>
It's because Sencha Touch does not understand the way you've defined your store.
You should do something like this, which consists of 3 steps:
Defining model
Ext.define('SimpleTodo.model.listitem',{
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'name', type: 'string'},
],
}
})
Defining store:
Ext.define('SimpleTodo.store.listitems', {
extend: 'Ext.data.Store',
config: {
model: 'SimpleTodo.model.listitem',
data: [
{ name: 'Todo 1' },
{ name: 'Todo 2' },
{ name: 'Todo 3' },
{ name: 'Todo 4' },
{ name: 'Todo 5' },
{ name: 'Todo 6' }
],
}
});
finally, in your list:
store: 'listitems'
Hope this helps.
As it turns out, you can't define a list within a panel (however, this view could be part of a tabpanel). So:
Ext.define("SimpleTodo.view.Main", {
extend: 'Ext.dataview.List',
config: {
title: 'Simple Todo',
itemTpl: '{name}',
store: 'myStore'
}
}
UPDATE: Here's an example of a list in a container with a titlebar. Note the layout: 'vbox' on the container and the flex: 1 on the list. Those are both necessary for the list to display properly.
Ext.define("SimpleTodo.view.Main", {
extend: 'Ext.Container',
config: {
layout: 'vbox',
items: [
{
xtype: 'titlebar',
docked: 'top',
title: 'Simple ToDo'
},
{
xtype: 'listcmp',
flex: 1
}
]
}
}
With a separate view containing your list definition. E.g:
Ext.define('SimpleTodo.view.ListCmp', {
extend: 'Ext.List',
xtype: 'listcmp',
config: {
store: 'SimpleToDo',
itemTpl: '{title}'
}
}
try supplying full class path of the store:
store: 'SimpleTodo.store.listitems',
I suppose the framework does not know what class you are referring by just the class/file name.
if still not working i will suspect the list does not what to display, so try configuring the list itemTpl config:
itemTpl: '{name}',

Sencha touche form validation

I am creating my first app with sencha touch.
I have a problem with form validation.
This is the form:
var form = new Ext.form.FormPanel({
title: 'Activity',
items: [{
xtype: 'fieldset',
items: [{
xtype: 'textfield',
name : 'sector',
label: 'Sector',
required: true
},
{
xtype: 'selectfield',
name : 'city',
label: 'City',
options: [
{
text: '*',
value: '*'
},
{
text: 'First Option',
value: 'first'
},
{
text: 'Second Option',
value: 'second'
},
{
text: 'Third Option',
value: 'third'
}]
},
{
xtype: 'textfield',
name : 'nation',
label: 'Nation',
required: true
},
{
xtype: 'toolbar',
docked: 'bottom',
layout: {
pack: 'center'
},
items: [{
xtype: 'button',
text: 'Cerca',
handler: function() {
formSettori.submit({
url: 'book.php',
method: 'GET',
success: function() {
Ext.Msg.alert('OK');
},
failure: function() {
Ext.Msg.alert('NO');
}
});
}
},
{
xtype: 'button',
text: 'Reset',
handler: function() {
form.reset();
}
}]
}]
}]
});
the form has only three fields:
-activities
-city​​
-nation
all fields are required.
activities and the nation must not be empty, while the city should not be equal to *
how do I control the fields?
thank you!
There is not built in way to do form validation. You must do it yourself.
The easiest way is to use the private Ext.form.Panel method getFields to loop through each of the fields and ensure they are not empty.
var fields = form.getFields(),
field, name, isEmpty;
for (name in fields) {
field = fields[name];
isEmpty = (!field.getValue() || field.getValue() == "");
if (isEmpty) {
field.addCls('x-invalid');
} else {
field.removeCls('x-invalid');
}
}
If the field is empty, then we add the x-invalid class (so you can style it).

Sencha Touch 2 FieldSet field values

I have;
{
xtype: 'fieldset',
title: 'Actual Minutes Late',
layout: 'hbox',
name: 'slappy',
items: [
{
xtype: 'numberfield',
name: 'fMinutesLate',
label: 'Minutes Late'
}
]
}
This is sitting within a detailCard.
On the buttons click event, the button is sitting within the the parent fieldset, I want to get the value of the fMinutesLate field.
So far I have tried this within the button;
handler: function (button) {
var form = button.up('slappy');
Ext.data.JsonP.request({
url: 'http://localhost:55427/metrofail.asmx/SubmitFailure',
callbackKey: 'callback',
params: {
LineName : selectedItems[0],
StationName : selectedItems[1],
Hour : '',
Minute : '',
Meridian : '',
Delay : ''
},
success: function () { },
failure: function (a, b) { },
});
}
If the detailCard you speak of extends Ext.data.Form the you can detailCard.getValues() which will return an object of form elements:
{
fMinutesLate: 1234
}
I assume it will go in the "delay" params
delay: detailCard.getValues().fMinutesLate
Should work