divide ExtJS form between two windows - extjs

I need to make an app that shows a form in a window on one screen and the main window with part of the same form - or is this is'n possible another form - on the other screen. Is this possible with ExtJs ? How ? Has anyone seen an example or perhaps an extension that does such ?

You can use a 'card' layout inside your form.
In the following example, the user sees three different pages, the first two pages have fields and the last one a button.
Clicking on the button retrieves the values from the fields. It doesn't matter that the fields are in different containers, as long as these containers are 'descendants' of the form.
Ext.application({
name : 'MyApp',
launch : function() {
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
layout:'card',
activeItem: 0,
bbar: [{
text: '« Previous',
handler: function(button) {
var cardlayout = button.up('form').getLayout();
var prev = cardlayout.getPrev();
if (prev) {
cardlayout.setActiveItem(prev);
}
}
},{
text: 'Next »',
handler: function(button) {
var cardlayout = button.up('form').getLayout();
var next = cardlayout.getNext();
if (next) {
cardlayout.setActiveItem(next);
}
}
}],
items: [{
xtype: 'container',
items: [{
xtype: 'textfield',
fieldLabel: 'First name',
name: 'firstName'
}]
},{
xtype: 'container',
items: [{
xtype: 'textfield',
fieldLabel: 'Last name',
name: 'lastName'
}]
},{
xtype: 'container',
items: [{
xtype: 'button',
text: 'Submit',
handler: function(button) {
var formValues = button.up('form').getValues();
alert('Name: ' + formValues.firstName
+ ' ' + formValues.lastName);
}
}]
}]
});
}
});

Related

ExtJs: How to get parent tab of control

I am currently working on ExtJs and I am stuck at a place where I want to iterate through all components and find the parent tab of each component.
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.tab.Panel', {
width: 300,
height: 200,
activeTab: 0,
items: [
{
title: 'Tab 1',
bodyPadding: 10,
items : [{
xtype: 'fieldset',
itemId: 'fieldsetId',
items: [{
xtype: 'checkbox',
fieldLabel: 'Check 1'
},{
xtype: 'checkbox',
fieldLabel: 'Check 2'
},{
fieldLabel: 'Combo 1',
xtype: 'combobox',
store: ['value1','value2','value3']
}]
},
{
xtype: 'button',
text: 'Reset',
}]
},
{
title: 'Tab 2',
html : 'Another one',
items: [{
xtype: 'button',
text: 'Test',
}]
}
],
renderTo : Ext.getBody()
});
}
});
In above code, when I iterate through all components and log name of the parent tab whether it is Tab 1 or Tab 2
Whenever you are iterating through all the components, just do
field.up().up()
where field is the component of your tab and above statement will return you the parent tabpanel and so with
field.up().up().title
will return you "Tab 1"
In the same way for tab 2 components it will be
field.up() only.
If you have only one loop or something to go through all components then you can put a condition that
if(field.up()) returns you the panel then read it\'s title
else do field.up().up() and then read the title.
I hope this solves you issue.
You can use , field.up('tabPanel') to get the reference of the tabPanel, and then from the reference you can get name,title for the tabPanel

ExtJs: how to disable fieldset on button click event

I have a fieldset defined on my page. Now I want to enable or disable this field set on button click event. But it is not working properly. Below is the code I have written:
To Disable:
this.mySettings.query('[name="fieldsetName"]').forEach(function (field) {
field.disable();
});
To Enable:
this.mySettings.query('[name="fieldsetName"]').forEach(function (field) {
field.enable();
});
Issue-1 : When I disable fieldset, it seems to be disabled visually. But still I can access controls inside it.
Issue-2 : Once it is disabled, I cannot re-enable it.
I need a working sample with these two issues resolved.
Currently I am using version 4.2 of ExtJs
You should call the setDisabled function on the fieldset. It will disable all containing components.
fieldset.setDisabled(true);
// the fieldset and all inner components are disabled
fieldset.setDisabled(false);
// the fieldset and all inner components are enabled
See the Sencha ExtJs 4.2.0 documentation and
the following minimal working example can be found on Sencha Fiddle.
Ext.create('Ext.panel.Panel',{
items: [{
xtype: 'fieldset',
itemId: 'fieldsetId',
items: [{
xtype: 'checkbox',
fieldLabel: 'Check 1'
},{
xtype: 'checkbox',
fieldLabel: 'Check 2'
},{
fieldLabel: 'Combo 1',
xtype: 'combobox',
store: ['value1','value2','value3']
}]
}, {
xtype: 'button',
text: 'Disable fieldset',
handler: function (button) {
var fieldset = Ext.ComponentQuery.query('panel > #fieldsetId')[0];
var toggle = !fieldset.isDisabled();
var text = (toggle ? 'Enable' : 'Disable') + ' fieldset';
fieldset.setDisabled(toggle);
button.setText(text);
}
}],
renderTo: Ext.getBody()
});
Paste this into a Sencha fiddle and hit Run:
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.Msg.alert('Fiddle', 'Welcome to Sencha Fiddle!');
Ext.create('Ext.window.Window', {
height: '100%',
width: '100%',
autoShow:true,
bodyPadding: 25,
title:'win',
items: [{
xtype: 'fieldset',
items: [{
xtype: 'checkbox',
fieldLabel: 'field1'
},{
xtype: 'checkbox',
fieldLabel: 'field2'
},{
fieldLabel: 'field3',
xtype: 'combo',
store: ['asdf','zzasdf','dfdf']
}]
}, {
xtype: 'button',
text: 'Enable/Disable entire fieldset',
handler: function(btn){
var fset = btn.up('window').down('fieldset');
fset.setDisabled(!fset.disabled);
}
}, {
margin: '0 0 0 10',
xtype: 'button',
text: 'Enable/Disable each field in fieldset individually',
handler: function(btn){
var fset = btn.up('window').down('fieldset');
fset.items.each(function(i){
i.setDisabled(!i.disabled);
});
}
}]
});
}
});

How to make nested re-usable fieldsets and use updateRecord to retrieve input and setRecord to load entered data?

My app requires a lot of data-input from the user. And there's repetition, so for example the person fields must be filled in three times (all possibly different).
Person fieldset that I want to reuse
Ext.define('MyApp.form.PersonForm',
{
extend: 'Ext.form.FieldSet',
xtype: 'personform',
config:
{
items:
[
{
xtype: 'textfield',
name: 'surname',
label: 'Naam:',
placeHolder: ''
},
{
xtype: 'textfield',
name: 'adres',
label: 'Adres:',
placeHolder: 'Straat en huisnummer'
},
{
xtype: 'textfield',
name: 'zipCode',
label: 'Postcode:',
placeHolder: '1234AB'
},
{
xtype: 'textfield',
name: 'city',
label: 'Plaats:',
placeHolder: 'Of stad'
},
{
xtype: 'textfield',
name: 'country',
label: 'Land:',
placeHolder: ''
},
{
xtype: 'textfield',
name: 'phone',
label: 'Telefoon:',
placeHolder: ''
},
{
xtype: 'textfield',
name: 'email',
label: 'e-mail:',
placeHolder: ''
}
]
}
});
So I've made small fieldset and am trying to reuse them several times in the form. But when I try to load the saved data it concats all fields with the same name into an array of fields, so they don't get updated.
So instead of having one fieldset with others in it, each fieldset now only contains the fields directly in it. And the must all be placed in their own container so I can access them in the controller and update\load their respective data.
Ext.define('MyApp.form.UserDataForm',
{
extend: 'Ext.Container',
requires:
[
'Ext.form.FieldSet',
'Ext.form.Panel',
'Ext.field.Hidden',
'MyApp.form.PersonForm'
],
xtype: 'userdataform',
config:
{
items:
[
{
xtype: 'formpanel',
itemId: 'userDataForm',
flex: 1,
items:
{
xtype: 'fieldset',
items:
[
{
xtype: 'hiddenfield',
name: 'id'
},
{
xtype: 'textfield',
name: 'reportCode',
label: 'Meld code:',
itemId: 'txtReportCode'
},
{
xtype: 'textfield',
name: 'firstName',
label: 'Voornaam:',
itemId: 'txtFirstName'
}
]
}
},
{
xtype: 'personform',
name: 'person'
}
]
}
});
The problem is that the fieldset directly in the panel is invisible (unlike when all fieldsets where nested in each other). So this only shows the personform. However the first fieldset is shown when I force the height to a set value.
Code for loading saved data and saving input:
onLoadUserData: function ()
{
var userDataStore = Ext.getStore('userDataStore');
var userDataRecord = userDataStore.getFirst();
var userDataView = this.getUserDataView();
var userDataForm = this.getUserDataForm();
userDataForm.setRecord(userDataRecord);
userDataForm.down('personform[name=insured]').setRecord(userDataRecord.data.person);
},
onTapBtnSave: function ()
{
var userDataView = this.getUserDataView();
var userDataStore = Ext.getStore('userDataStore');
var isNew = userDataStore.getCount() == 0;
var userDataRecord = userDataStore.getFirst();
userDataView.updateRecord(userDataRecord);
userDataRecord.data.person = userDataRecord.data.person|| Ext.create('MyApp.model.PersonModel');
userDataView.updateRecord(userDataRecord.data.person);
if (isNew)
{
userDataStore.add(userDataRecord);
}
else
{
userDataRecord.setDirty();
}
userDataStore.sync();
}
I tried using layout: 'vbox' and layout: 'flex' and or not using the flex: 1 on the containing panel.
So how do I get Sencha to show those fields when they are there, without forcing a specific height?
Edit: the problem seems to lie in using a form.Panel instead of a container. While the container will simply take the space it needs the Panel won't. But I need it to be a panel to get the loading and saving of user input working.

ExtJS Use same window for editing and adding a record

I have my ExtJS 4.2.1 MVC Application.
Inside my app, I have a grid with a toolbar. The toolbar has 2 buttons, "Add New" and "Edit Record".
Inside my Controller.js I listen for my toolbar buttons click events.
this.control({
'toolbar #newRecord': {
click: this.addRecord
},
'toolbar #editRecord': {
click: this.editRecord
},
'[xtype=editshiftcode] button[action=commit]': {
click: this.saveRecord // here I have to add or edit
}
}
Then I have Window that I want to use for editing and adding records:
Ext.define('App.view.EditShiftCode', {
extend: 'Ext.window.Window',
alias: 'widget.editshiftcode',
height: 250,
width: 550,
title: 'Add / Edit Shift',
modal: true,
resizable: false,
layout: 'fit',
glyph: Glyphs.PENCIL,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'container',
//height: 175,
layout: {
type: 'hbox',
align: 'strech'
},
items: [{
xtype: 'form',
bodyPadding: 10,
autoScroll: false,
itemId: 'editForm',
defaults: { // defaults are applied to items, not the container
allowBlank: false,
allowOnlyWhitespace: false,
msgTarget: 'side',
xtype: 'textfield'
},
items: [
{
xtype: 'textfield',
name: 'ShiftCode',
fieldLabel: 'Code'
},
{
xtype: 'textfield',
name: 'Description',
fieldLabel: 'Description'
},
{
xtype: 'hiddenfield',
name: 'ShiftType'
},
{
xtype: 'hiddenfield',
name: 'ShiftTypeId'
},
{
xtype: 'textfield',
name: 'Hours',
fieldLabel: 'Hours per Day'
},
{
xtype: 'colorcombo',
name: 'ColorHex',
fieldLabel: 'Color'
},
{
xtype: 'checkbox',
fieldLabel: 'Active',
name: 'IsActive',
}
],
}]
}],
buttons: [
{
text: 'OK',
action: 'commit',
glyph: Glyphs.SAVE
},
{
text: 'Cancel',
action: 'reject',
glyph: Glyphs.CANCEL
}]
});
me.callParent(arguments);
},
});
My editRecord function is:
editRecord: function (button, e, options) {
var me = this;
var window = Ext.create('App.view.EditShiftCode');
window.show();
},
My addRecord function is:
addRecord: function (button, e, options) {
var me = this;
var window = Ext.create('App.view.EditShiftCode');
window.show();
},
My saveRecord function is:
saveRecord: function (button, e, options) {
// here i need to know what operation im going to perform.
// if Im going to edit then I have to update my form record to my store record
// if im going to add then I need to add a new item to my store.
}
Is this correct? To use the same function to perform 2 different actions? And if so, how can I know what action am I going to perform and how to do it?
Thanks
This way always worked for me:
User selects a record in the grid
User clicks "Edit record"
I use loadRecord to load the selected record in the form
When he clicks OK I call updateRecord
If user clicks "Add record" I create a new blank record and go to step 3
If he clicks OK after adding record, I just add the new record to the grid - you can easily know if the record is new or existing by checking phantom flag. So if record.phantom === true then it is new.

Form panel not showing by set active item

Am new to sencha touch, my problem is i have a separate view to show a form panel by clicking on control event the form panel view will load, but when i click on the event nothing display on my screen. Just a blank screen to show..I dont know what am doing. The form panel is taken from sencha form panel tutorial
The following are my form panel view
Ext.define('WinReo.view.AddContact', {
extend: 'Ext.Container',
xtype: 'addcontact',
requires: [
'Ext.TitleBar'
//'Ext.Video'
],
config: {
layout:'fit'
},
initialize:function(){
console.log('inside initialize');
var formPanel = Ext.create('Ext.form.Panel', {
//xytpe:'formpanel',
fullscreen: true,
layout:'fit',
items: [{
xtype: 'fieldset',
items: [
{
xtype: 'textfield',
name : 'name',
label: 'Name'
},
{
xtype: 'emailfield',
name : 'email',
label: 'Email'
},
{
xtype: 'passwordfield',
name : 'password',
label: 'Password'
}
]
}]
});
formPanel.add({
xtype: 'toolbar',
docked: 'bottom',
layout: { pack: 'center' },
items: [
{
xtype: 'button',
text: 'Set Data',
handler: function() {
formPanel.setValues({
name: 'Ed',
email: 'ed#sencha.com',
password: 'secret'
})
}
},
{
xtype: 'button',
text: 'Get Data',
handler: function() {
Ext.Msg.alert('Form Values', JSON.stringify(formPanel.getValues(), null, 2));
}
},
{
xtype: 'button',
text: 'Clear Data',
handler: function() {
formPanel.reset();
}
}
]
});
}
});
This is the controller event to show form panel view
onItemSwiped: function(list,index,target,record,e)
{
var addcontact= Ext.create('WinReo.view.AddContact');
Ext.Viewport.add(addcontact);
Ext.Viewport.setActiveItem(addcontact);
},
Just a simple task but am spending too much time to fix this one..please help me to solve this issue. Thanks in advance..
Your right about setActiveItem and you need to use it. because Ext.Viewport.add() only adds to viewPort not shows the view.
So only problem in your code is you created formPanel, but not added it in the AddContact View.
...........
// same code
{
xtype: 'button',
text: 'Get Data',
handler: function() {
Ext.Msg.alert('Form Values', JSON.stringify(formPanel.getValues(), null, 2));
}
},
{
xtype: 'button',
text: 'Clear Data',
handler: function() {
formPanel.reset();
}
}
]
});
this.add(formPanel); // add this line
}
});
See this fiddle

Resources