getting error at that button.up('form').getForm().reset(); is undefined....
functions of Submit - is send user details to server
cancel button - it sgould reset form.
// this is code of controller for login form..which consist of two event s for submit button & for cancel
Ext.define('Packt.controller.Login',
{
extend: 'Ext.app.Controller',
views: [
'Login'
],
init: function(application)
{
this.control({
"button#submit": {
click: this.onButtonClickSubmit
},
"button#cancel": {
click: this.onButtonClickCancel
}
});
},
// implementation of action to be executed when events happnes
onButtonClickSubmit: function(button, e, options)
{
get login form referance
var formPanel = button.up('form'),
login = button.up('login'),
user = formPanel.down('textfield[name=user]').getValue(),
pass = formPanel.down('textfield[name=password]').getValue(),
if (formPanel.getForm().isValid())
{
encryptting password
pass = Packt.util.MD5.encode(pass);
sending user details to server
Ext.Ajax.request({
url: 'php/login.php',
params: {
user: user,
password: pass
}
});
}
},
onButtonClickCancel: function(button, e, options)
{
button.up('form').getForm().reset();
}
});
code of view for form :
Ext.define('Packt.view.Login', {
extend: 'Ext.window.Window',
alias: 'widget.login',
autoShow: true,
height: 170,
width: 360,
layout: {
type: 'fit'
},
iconCls: '.key',
title: 'Login',
closeAction: 'hide',
closable: false ,
items: [
{
type: 'form',
frame: false,
bodyPadding: 15,
defaults: {
xtype: 'textfield',
anchor: '100%',
labelWidth: 60 ,
allowBlank: false,
vtype: 'alphanum',
minLength: 3,
msgTarget: 'side'
},
items: [
{
name: 'user',
fieldLabel: 'user',
maxLength :25
},
{
inputType: 'password',
name: 'password',
fieldLabel: 'Password',
maxLength :15,
enableKeyEvents: true,
id: 'password'
}
]
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
xtype: 'tbfill'
},
{
xtype: 'button',
itemId: 'cancel',
iconCls: 'cancel',
text: 'Cancel'
},
{
xtype: 'button',
itemId: 'submit',
formBind: true,
iconCls: 'key-go',
text: 'Submit'
}
]
}
]
});
this is code of app.js that is main
Ext.application({
// namespace fr project
name: 'Packt',
/*requires: [
'Packt.view.Login'
],
views: [
'Login'
],
*/
controllers: [
'Login'
],
init: function()
{
splashscreen = Ext.getBody().mask('Loading application','splashscreen');
splashscreen.addCls('splashscreen');
Ext.DomHelper.insertFirst(Ext.query('.x-mask-msg')[0], {cls: 'x-splash-icon' });
splashscreen.next().fadeOut({
duration: 1000,
remove:true,
listeners: {
afteranimate: function(el, startTime, eOpts )
{
Ext.widget('login');
}
}
});
}
});
Related
I have a handler function that creates a Ext.window.Window, with fields to enter data, I need o move this part of the code to a controller function, and separate it from the main ajax request, this is for code reuse purposes.
var win = Ext.create('Ext.window.Window', {
title: 'New Client',
id: 'addClientWindow',
width: 500,
height: 300,
items: [{
xtype: 'form',
bodyPadding: 10,
items: [{
xtype: 'fieldset',
title: 'My Fields',
items: [{
xtype: 'textfield',
anchor: '100%',
id: 'nameTextField',
fieldLabel: 'Name',
labelWidth: 140
}, {
xtype: 'textfield',
anchor: '100%',
id: 'physicalTextField',
fieldLabel: 'Physical Address',
labelWidth: 140
}, {
xtype: 'textfield',
anchor: '100%',
id: 'postalTextField',
fieldLabel: 'Postal Address',
labelWidth: 140
}]
}],
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
xtype: 'button',
id: 'cancelClientBtn',
text: 'Cancel',
listeners: {
click: function(c) {
Ext.getCmp('addClientWindow').close();
}
}
}, {
xtype: 'tbspacer',
flex: 1
}, {
xtype: 'button',
id: 'saveClientBtn',
text: 'Save',
listeners: {
click: function(c) {
Ext.Ajax.request({
url: 'system/index.php',
method: 'POST',
params: {
class: 'Company',
method: 'add',
data: Ext.encode({
name: Ext.getCmp('nameTextField').getValue(),
physical: Ext.getCmp('physicalTextField').getValue(),
postal: Ext.getCmp('postalTextField').getValue()
})
},
success: function(response) {
Ext.MessageBox.alert('Status', 'Record has been updated.');
Ext.getStore('CompanyStore').reload();
Ext.getCmp('addClientWindow').close();
},
failure: function() {
Ext.MessageBox.alert('Status', 'Failed to update record.');
}
});
}
}
}]
}]
}]
});
win.show();
The button opens this window and performs this ajax request, I just need the two separated from one another. Any help appreciated.
You can define your window in a separated file and give it an alias:
Ext.define('MyApp.view.MyWindow', {
extend: 'Ext.window.Window',
alias: 'widget.addclient',
...
click: function(){
var data = Ext.encode({
name: Ext.getCmp('nameTextField').getValue(),
physical: Ext.getCmp('physicalTextField').getValue(),
postal: Ext.getCmp('postalTextField').getValue()
});
// I assume here "this" links to the window component,
// if not, adjust accordingly
if(this.mycallback){
this.mycallback(data);
}
}
});
Then you can call it from other controllers and provide a callback:
Ext.define('MyApp.view.MyController', {
extend: 'Ext.app.ViewController',
requires: 'MyApp.view.MyWindow',
openWindow: function(){
var win = Ext.widget('addclient');
win.mycallback = this.onAddClientCallback.bind(this);
win.show();
},
onAddClientCallback: function(data){
console.log("data from window", data);
}
});
I have a form that has comboboxes, tagfields, date pickers, etc., and a grid. Each of these elements has a different store. The user is going to make selections from the comboboxes, etc,. and enter values into the grid. Then the values from the grid and other form elements are all sent on a POST to the server. I know how to POST the data from the comboboxes, tagfields, and date pickers. However, I don't know how to send the data in the grid with the form. Here is the form view:
Ext.define('ExtTestApp.view.main.List', {
extend: 'Ext.form.Panel',
xtype: 'cell-editing',
frame: true,
autoScroll: true,
title: 'Record Event',
bodyPadding: 5,
requires: [
'Ext.selection.CellModel',
'ExtTestApp.store.Personnel'
],
layout: 'column',
initComponent: function(){
this.cellEditing = new Ext.grid.plugin.CellEditing({
clicksToEdit: 1
});
Ext.apply(this, {
//width: 550,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 90,
anchor: '100%',
msgTarget: 'side'
},
items: [{
xtype: 'fieldset',
//width: 400,
title: 'Event Information',
//height: 460,
//defaultType: 'textfield',
layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [{
xtype: 'fieldcontainer',
fieldLabel: 'Event',
layout: 'hbox',
defaults: {
hideLabel: 'true'
},
items: [{
xtype: 'combobox',
name: 'eventTypeId',
width: 300,
//flex: 1,
store: {
type: 'events'
},
valueField: 'eventTypeId',
// Template for the dropdown menu.
// Note the use of the "x-list-plain" and "x-boundlist-item" class,
// this is required to make the items selectable.
allowBlank: false
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'datefield',
fieldLabel: 'Date',
format: 'Y-m-d',
name: 'startDate',
//msgTarget: 'under', //location of error message, default is tooltip
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
//flex: 1,
emptyText: 'Start',
allowBlank: false
},
{
xtype: 'datefield',
format: 'Y-m-d',
name: 'endDate',
//msgTarget: 'under', //location of error message
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
//flex: 1,
margin: '0 0 0 6',
emptyText: 'End',
allowBlank: false
}
]
}]
},
{
xtype: 'fieldset',
//height: 460,
title: 'Platform Information',
//defaultType: 'textfield',
layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [
{
xtype: 'fieldcontainer',
layout: 'hbox',
fieldLabel: 'Platform',
//combineErrors: true,
defaults: {
hideLabel: 'true'
},
items: [
{
xtype: 'combobox',
name: 'platformId',
store: {
type: 'platforms'
},
valueField: 'platformId',
allowBlank: false
}
]
}
]
},
{
xtype: 'fieldcontainer',
layout: 'hbox',
fieldLabel: 'Software Type(s)',
//combineErrors: true,
defaults: {
hideLabel: 'true'
},
items: [
{
xtype: 'tagfield',
width: 400,
//height: 50,
fieldLabel: 'Software Type(s)',
name: 'softwareTypeIds',
store: {
type: 'softwareTypes'
},
labelTpl: '{softwareName} - {manufacturer}',
valueField: 'softwareTypeId',
allowBlank: false
}
]
},
{
xtype: 'gridpanel',
layout: 'anchor',
defaults: {
anchor: '100%'
},
width: 1300,
//columnWidth: 0.78,
//title: 'Metrics',
plugins: [this.cellEditing],
title: 'Personnel',
store: {
type: 'personnel'
},
columns: [
{ text: 'Name', dataIndex: 'name', editor: 'textfield' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone', flex: 1 }
]
}
],
buttons: [
{
text: 'Save Event',
handler: function() {
var form = this.up('form'); // get the form panel
// if (form.isValid()) { // make sure the form contains valid data before submitting
Ext.Ajax.request({
url: 'api/events/create',
method:'POST',
headers: { 'Content-Type': 'application/json' },
params : Ext.JSON.encode(form.getValues()),
success: function(form, action) {
Ext.Msg.alert('Success', action.result);
},
failure: function(form, action) {
//console.log(form.getForm().getValues());
Ext.Msg.alert('Submission failed', 'Please make sure you selected an item for each required field.', action.result);
}
});
// } else { // display error alert if the data is invalid
// Ext.Msg.alert('Submit Failed', 'Please make sure you have made selections for each required field.')
// }
}
}
]
});
this.callParent();
}
});
var grid = Ext.ComponentQuery.query('grid')[0];
Here is the store for the grid:
Ext.define('ExtTestApp.store.Personnel', {
extend: 'Ext.data.Store',
alias: 'store.personnel',
fields: [
'name', 'email', 'phone'
],
data: { items: [
{ name: 'Jean Luc', email: "jeanluc.picard#enterprise.com", phone: "555-111-1111" },
{ name: 'Worf', email: "worf.moghsson#enterprise.com", phone: "555-222-2222" },
{ name: 'Deanna', email: "deanna.troi#enterprise.com", phone: "555-333-3333" },
{ name: 'Data', email: "mr.data#enterprise.com", phone: "555-444-4444" }
]},
autoLoad: true,
proxy: {
type: 'memory',
api: {
update: 'api/update'
},
reader: {
type: 'json',
rootProperty: 'items'
},
writer: {
type: 'json',
writeAllFields: true,
rootProperty: 'items'
}
}
});
Ideally, you would need to create a custom "grid field" so that the grid data is picked up on form submit like any other field.
You can also use this workaround: in the "Save Event" button handler, dig out the grid store and fish data out of it:
var gridData = [];
form.down('gridpanel').store.each(function(r) {
gridData.push(r.getData());
});
Then get the rest of the form data and put the grid data into it:
var formData = form.getValues();
formData.gridData = gridData;
Finally, include it all in your AJAX call:
params: Ext.JSON.encode(formData)
I've got code:
win = desktop.createWindow({
id: 'admin-win',
title: 'Add administration users',
width: 740,
height: 480,
iconCls: 'icon-grid',
animCollapse: false,
constrainHeader: true,
xtype: 'form',
bodyPadding: 15,
url: 'save-form.php',
items: [{
xtype: 'textfield',
fieldLabel: 'Field',
name: 'theField'
}],
buttons: [{
text: 'Submit',
handler: function () {
var form = this.up('form').getForm();
if (form.isValid()) {
form.submit({
success: function (form, action) {
Ext.Msg.alert('Success', action.result.message);
},
failure: function (form, action) {
Ext.Msg.alert('Failed', action.result ? action.result.message : 'No response');
}
});
}
}
}]
});
And buttons doesn't work. It creates error - this.up('form') is undefined. How can I call getForm() in such code like that?
UPDATE:
Thanks for really quick reply!
I modified your code for my needs, this is it, and it works with Desktop Example:
win = desktop.createWindow({
id: 'admin-win',
title: 'Add administration users',
width: 740,
iconCls: 'icon-grid',
animCollapse: false,
constrainHeader: true,
items: [{
xtype: 'form',
bodyPadding: 15,
url: 'save-form.php',
items: [{
xtype: 'textfield',
fieldLabel: 'Field',
name: 'theField'
}],
buttons: [{
text: 'Submit',
handler: function () {
var form = this.up('form').getForm();
if (form.isValid()) {
this.up().up().submit({
success: function (form, action) {
Ext.Msg.alert('Success', action.result.message);
},
failure: function (form, action) {
Ext.Msg.alert('Failed', action.result ? action.result.message : 'No response');
}
});
}
}
}]
}]
});
As I already said, it seems that you have problems with your code. You are passing Ext.form.Panel options to a Ext.window.Window (I assuming this because the name of the method that you are calling). I'm writing an example with a window for you. Just a moment.
It is ready. Take a look:
Ext.create('Ext.window.Window', {
title: 'This is a Window with a Form',
height: 200,
width: 400,
layout: 'fit',
items: [{ // the form is an item of the window
id: 'admin-win',
title: 'Add administration users',
width: 740,
height: 480,
iconCls: 'icon-grid',
animCollapse: false,
constrainHeader: true,
xtype: 'form',
bodyPadding: 15,
url: 'save-form.php',
items: [{
xtype: 'textfield',
fieldLabel: 'Field',
name: 'theField',
allowBlank: false
}],
buttons: [{
text: 'Submit',
handler: function() {
var form = this.up('form').getForm();
if (form.isValid()) {
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.message);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result ? action.result.message : 'No response');
}
});
} else {
Ext.Msg.alert( "Error!", "Your form is invalid!" );
}
}
}]
}]
}).show();
jsFiddle: http://jsfiddle.net/davidbuzatto/vWmmD/
I have tabpanel, which contains a few tabs. I will be concentrating on the 6th tab here - navigatingPanels.js file. In this file, I have a card layout, so that the user can fill form1 & move to form2 on submission (slide to form2). I also have a docked toolbar, with a back button, so that the user can move back to form1 (if needed). It gives an error -
Uncaught Error: [ERROR][Ext.Base#callParent] Invalid item given: undefined, must be either the config object to factory a new item, or an existing component instance.
The app can be seen here - http://maalguru.in/touch/Raxa-70/MyApp/
Update - If I add one extra card to the concerned panel, & remove the form1 & form2 (required panels/cards), then it works fine. In this case I have to setActiveItem to the desired cards (form1 & form2). Changed Viewport - http://pastebin.com/P4k04dBQ
Is there any solution to achieve with only 2 panels/cards ?
Viewport.js
Ext.define('MyApp.view.Viewport', {
extend: 'Ext.TabPanel',
xtype: 'my-viewport',
config: {
fullscreen: true,
tabBarPosition: 'bottom',
items: [{
xclass: 'MyApp.view.navigatingPanels'
}]
}
});
NavigatingPanels.js
Ext.define('MyApp.view.navigatingPanels', {
extend: 'Ext.Panel',
id: 'navigatingPanels',
xtype: 'navigatingPanels',
config: {
iconCls: 'user',
title: 'Navigating Panels',
layout: 'card',
animation: {
type: 'slide',
direction: 'left'
},
defaults: {
styleHtmlContent: 'true'
},
items: [{
docked: 'top',
xtype: 'toolbar',
title: 'Registeration Form',
items: [{
text: 'Back',
ui: 'back',
align: 'centre',
//back button to take the user back from form2 to form1
handler: function() {
Ext.getCmp('navigatingPanels').setActiveItem(form1);
}
}]
},
form1,
form2
]
}
});
var form1 = new Ext.Panel({
scrollable: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Form 1',
items: [{
xtype: 'textfield',
label: 'Name',
name: 'name',
},
{
xtype: 'button',
text: 'Save Data & move to form2',
ui: 'confirm',
//TODO add some action: to store data
//save data & move to form2
handler: function() {
Ext.getCmp('navigatingPanels').setActiveItem(form2, {
type: 'slide',
direction: 'right'
});
console.log("Form1");
}
}
]
}]
});
var form2 = new Ext.Panel({
scrollable: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Form 2',
items: [{
xtype: 'textareafield',
label: 'Message',
name: 'message'
},
{
xtype: 'button',
text: 'Submit Data',
ui: 'confirm',
//TODO add some action: to store data
//action: 'Submit Data'
}
]
}]
});
App.js
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'MyApp',
controllers: ['Main'],
launch: function() {
Ext.create('MyApp.view.Viewport', {
fullscreen: true
});
}
});
Finally I got the answer. The component instances should not be given as items in Ext.define, instead their config should be given. The setActiveItem can be called the the normal way -
Ext.getCmp('navigatingPanels').setActiveItem(0);
CODE SNIPPET
Ext.define('MyApp.view.navigatingPanels', {
extend: 'Ext.Panel',
id: 'navigatingPanels',
xtype: 'navigatingPanels',
config: {
iconCls: 'user',
title: 'Navigating Panels',
layout: 'card',
animation: {
type: 'slide',
direction: 'left',
duration: 300
},
defaults: {
styleHtmlContent: 'true'
},
items: [{
docked: 'top',
xtype: 'toolbar',
title: 'Registeration Form',
items: [{
text: 'Back',
ui: 'back',
align: 'centre',
//back button to take the user back from form2 to form1
handler: function() {
Ext.getCmp('navigatingPanels').setActiveItem(0, {
type: 'slide',
reverse: 'true',
duration: '300'
});
console.log(Ext.getCmp('navigatingPanels'));
}
}]
},
{
xtype: 'fieldset',
title: 'Form 1',
scrollable: 'vertical',
items: [{
xtype: 'textfield',
label: 'Name',
name: 'name',
},
{
xtype: 'button',
text: 'Save Data & move to form2',
ui: 'confirm',
//TODO add some action: to store data
//save data & move to form2
handler: function() {
Ext.getCmp('navigatingPanels').setActiveItem(1, {
type: 'slide',
direction: 'right'
});
console.log("Form1");
}
}
]
},
{
scrollable: 'vertical',
items: [{
xtype: 'fieldset',
title: 'Form 2',
items: [{
xtype: 'textareafield',
label: 'Message',
name: 'message'
},
{
xtype: 'button',
text: 'Submit Data',
ui: 'confirm',
//TODO add some action: to store data
//action: 'Submit Data'
}
]
}]
}
]
}
});
Try this...
myNavigationPanel = Ext.create('MyApp.view.navigatingPanels');
myNavigationPanel.setActiveItem(0);
Ext.define('MyApp.view.Viewport', {
extend: 'Ext.TabPanel',
xtype: 'my-viewport',
config: {
fullscreen: true,
tabBarPosition: 'bottom',
items: [{
xclass: 'MyApp.view.Home'
},
{
xclass: 'MyApp.view.Contact'
},
{
xclass: 'MyApp.view.Products'
},
{
xclass: 'MyApp.view.Forms'
},
{
xclass: 'MyApp.view.NestedTabPanels'
},
myNavigationPanel
]
}
});
I have a sample login form. In that there is a controller, view and a model.I would like to validate the form. my Form panel id is 'formPanelLogin' and have to update the form record in the controller. but this code "formPanelLogin.updateRecord (teamModel);" can't work and error message like "updateRecord is not define".
Please give me an answer for this problem. my code will following..
//Controller
Ext.define('MyApp.controller.mvcController', {
extend: 'Ext.app.Controller',
config: {
refs: {
BtnSubmit: "#btnSubmit",
BtnCancel:"#btnCancel",
BtnPromoHome:"#PromotionsBtnHome",
BtnThirdBack:"#thirdBtnBack",
BtnSecondBack:"#btnUnderHoodService",
},
control: {
BtnSubmit:
{
tap: "onBtnSubmitTap"
},
BtnCancel:
{
tap: "onBtnCancelTap"
},
BtnPromoHome:
{
tap: "onBtnPromoHomeTap"
},
BtnSecondBack:
{
tap: "onBtnSecondBackTap"
},
BtnThirdBack:
{
tap: "onBtnThirdBackTap"
}
}
},
onBtnCancelTap: function (options)
{
//formPanelLogin.reset();
var teamModel = Ext.create('MyApp.model.MyModel'),
errors, errorMessage = '';
formPanelLogin.updateRecord (teamModel);
errors = teamModel.validate();
if (!errors.isValid()) {
errors.each(function (err) {
errorMessage += err.getMessage() + '<br/>';
}); // each()
Ext.Msg.alert('Form is invalid!', errorMessage);
} else {
Ext.Msg.alert('Form is valid!', '');
} // if
console.log("Cancel");
},
});
//view
Ext.define('MyApp.view.MyContainer', {
extend: 'Ext.Container',
config: {
layout:
{
type: 'card'
},
items: [
{
xtype: 'panel',
id: 'panelOuter',
layout:
{
type: 'card',
animation:
{
type: 'slide'
}
},
items: [
{
xtype: 'panel',
items: [
{
xtype: 'toolbar',
docked: 'top',
title: 'MVC',
items: [
{
xtype: 'button',
docked: 'left',
id: 'btnBack'
},
{
xtype: 'button',
docked: 'right',
id: 'btnHome'
}
]
},
{
xtype: 'formpanel',
docked: 'top',
height: 117,
id: 'formPanelLogin',
scrollable: true,
items: [
{
xtype: 'fieldset',
id: 'loginform',
items: [
{
xtype: 'textfield',
label: 'UserName',
name: 'userName',
labelWidth: '40%',
name: 'usernameField',
placeHolder: '...... Type here .......',
required: true
},
{
xtype: 'passwordfield',
label: 'Password',
labelWidth: '40%',
required: true
}
]
}
]
},
{
xtype: 'panel',
height: 45,
id: 'btnPanel',
items: [
{
xtype: 'button',
docked: 'right',
id: 'btnSubmit',
ui: 'action-small',
width: 85,
text: 'Submit'
},
{
xtype: 'button',
docked: 'right',
id: 'btnCancel',
ui: 'decline-small',
width: 85,
text: 'Cancel'
}
]
}
]}
]
},
});
//model
Ext.define('MyApp.model.MyModel', {
extend: 'Ext.data.Model',
config: {
fields : [
{
name: 'userName',
type: 'string'
},
{
name: 'password',
type: 'string'
}
],
validations: [
{
field: 'userName',
type: 'presence',
message: 'User Name is required.'
}
]
}
});