I need to change xtype from textfield to textareafield basing on a condition.
I need to do something like this, but I cant update xtype
Ext.define('app',{
launch: function(){
var i = 1;
if (i == 1) {
Ext.getCmp('myID').updateXtype('textareafield')
}
},
items:[{
xtype: 'fieldset',
title: 'title'
},
items: [{
xtype: 'textfield',
label: 'label'
}]]
})
or i can use the viewmodel, but xtype is not bindable
Ext.define('app',{
launch: function(){
var i = 1;
if (i == 1) {
this.getViewModel().set('newXtype', 'textareafield');
}
},
items:[{
xtype: 'fieldset',
title: 'title'
},
items: [{
xtype: 'textfield',
label: 'label',
bind: {
xtype: '{newXtype}'
}
}]]
})
Exactly: you cannot bind xtype in this way. In the situation I would use a hidden binding . You will build the form with textfield and textareafield. Then switch the hidden binding depending on your use case (condition).
https://fiddle.sencha.com/#view/editor&fiddle/2trf
Ext.create('Ext.form.Panel', {
title: 'Switch between textfield and textareafield',
width: 360,
bodyPadding: 10,
renderTo: Ext.getBody(),
viewModel: {
data: {
showTextfield: true
}
},
defaults: {labelWidth: 120},
tbar: [{
text: 'Switch',
handler: function(button) {
let vm = this.up('panel').getViewModel();
let showTextfield = vm.get('showTextfield');
vm.set('showTextfield', !showTextfield)
}
}],
items: [{
xtype: 'textfield',
fieldLabel: 'TEXTFIELD',
bind: { hidden: '{showTextfield}'}
},{
xtype: 'textareafield',
fieldLabel: 'TEXTAREAFIELD',
bind: { hidden: '{!showTextfield}'}
}]
});
Related
I have a field which is by default set as disabled. But I want to change this attribute (enable it) on button click.
{
margin: '10 50 10 50',
padding: '10 20 10 20',
xtype: 'textfield',
name: 'name',
fieldLabel: 'Survey Name',
allowBlank: false,
disabled: true,
id: 'name'
},
This is the button:
{
margin: '0 50 0 50',
padding: '10 20 10 20',
xtype: 'button',
text: "Create",
listeners: {
click: function() {
Ext.get('name').disabled = false;
}
}
}
When I click this nothing is happening. What is wrong here?
As you have provided id to your component so instead of getting by Ext.get() use Ext.getCmp().
Example
Ext.getCmp('name').setDisabled(false)
In this Fiddle, I have created a demo using same code.
Code snippet:
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create({
xtype: 'panel',
title: 'Demo',
renderTo: Ext.getBody(),
layout: 'hbox',
bodyPadding: 10,
items: [{
xtype: 'textfield',
name: 'name',
fieldLabel: 'Survey Name',
allowBlank: false,
disabled: true,
id: 'name'
}, {
xtype: 'button',
text: "Create",
listeners: {
click: function () {
Ext.getCmp('name').setDisabled(false);
}
}
}]
})
}
});
Note: Instead of using id use the itemId or any other config of extjs component because id can't be duplicate. So you can also do like this
Code snippet:
Ext.create({
xtype: 'panel',
title: 'Enable component using ITEM ID',
renderTo: Ext.getBody(),
layout: 'hbox',
bodyPadding: 10,
items: [{
xtype: 'textfield',
name: 'name',
fieldLabel: 'Survey Name',
allowBlank: false,
disabled: true,
itemId: 'name'
}, {
xtype: 'button',
text: "Create",
handler: function() {
this.up('panel').down('#name').setDisabled(false);
}
}]
})
I have the following code in ExtJS
var formPanel = Ext.create('Ext.form.Panel', {
title: 'Panel title',
renderTo: Ext.getBody(),
items: [{
xtype: 'container',
layout: 'hbox',
items: [{
xtype: 'textfield',
fieldLabel: 'First Name',
name: 'FirstName',
}, {
xtype: 'textfield',
fieldLabel: 'Last Name',
name: 'LastName',
},{
xtype:'fieldset',
title: 'Phone Number',
defaultType: 'textfield',
items :[{
fieldLabel: 'Home',
name: 'home',
value: '(888) 555-1212'
},{
fieldLabel: 'Business',
name: 'business',
toBeRendered: IS_BUSINESS_FIELD_SUPPORTED_IN_CURRENT_RELEASE // custom property that must restrict rendering
rendered: IS_BUSINESS_FIELD_SUPPORTED_IN_CURRENT_RELEASE //doesn't work
}]
}]
}]
});
I want to create an application, that will have properties file where I can set up flags for SUPPORTED fields e.g IS_BUSINESS_FIELD_SUPPORTED_IN_CURRENT_RELEASE = false. If it's false than text input fieldLabel: 'Business' will not be rendered at all - no hidden/disabled text input Business in html.
I've tried rendered property - but it doesn't work, the only solution so far is to use items = Ext.Array.filter(items,filterFunction) in onRender;
Are there any other solutions how can I restrict rendering input elements?
Thanks in advance.
Instead of the constructor, use the initItems method:
Ext.define('MyComponent', {
extend: 'Ext.panel.Panel',
xtype: 'mycomponent',
bodyPadding: 10,
border: true,
title: 'My component',
items : [
{
xtype: 'button',
text: 'My allowed button'
}
],
initItems : function() {
var items = this.items;
// Your conditions
if (false) {
items.push({
xtype: 'button',
text: 'My denied button'
});
}
this.callParent();
}
});
https://fiddle.sencha.com/#fiddle/17qi
I think that best approach is to define custom components for your application parts and add required components within its constructor, like this:
constructor: function () {
var myComponentItems = [
{
xtype: 'button',
text: 'My allowed button'
}
];
// Your conditions
if(false) {
myComponentItems.push({
xtype: 'button',
text: 'My denied button'
});
}
Ext.apply(this, {
items: myComponentItems
});
this.callParent(arguments);
}
Working fiddle
I have a form panel with a radiogroup, and depending on the radiogroup selection, it will show some other components. If a radiofield is not selected, then its items will be hidden, as they're not part of the active card.
Now, if I have allowblank: false set on a field (and it's empty) within the hidden card, my form is still considered invalid. Being hidden means the user would not like to use it, so it should not be considered as part of the form. Here's an example.
In the example, I have 2 forms... the top form is the one that I'm curious about... is there a way to get this working without having to bind to disabled? I tried looking at hideMode, but that wasn't what I was looking for.
Ideally, I wouldn't have to create a formula for each card that I add... that seems silly. I realize I could create a generic formula, but once again, that just seems extraneous. Another option could be ditching the card layout, and binding each card to hidden and disabled, but I'm creating more formulas. Is there some sort of property I'm missing?
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('MyController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myview',
onValidityChange: function(form, isValid, eOpts) {
this.getViewModel().set('isFormValid', isValid);
}
});
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myview',
data: {
activeItem: {
myInput: 0
}
},
formulas: {
activeCardLayout: function(getter) {
var myInput = getter('activeItem.myInput');
console.log(myInput);
return parseInt(myInput);
}
}
});
Ext.define('MyForm', {
extend: 'Ext.form.Panel',
title: 'My Form',
controller: 'myview',
viewModel: {
type: 'myview'
},
layout: {
type: 'hbox'
},
listeners: {
validitychange: 'onValidityChange'
},
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
layout: {
type: 'hbox'
},
items: [{
xtype: 'button',
text: 'Save',
reference: 'saveButton',
disabled: true,
bind: {
disabled: '{!isFormValid}'
}
}]
}],
items: [{
xtype: 'radiogroup',
vertical: true,
columns: 1,
bind: {
value: '{activeItem}'
},
defaults: {
name: 'myInput'
},
items: [{
boxLabel: 'None',
inputValue: '0'
}, {
boxLabel: 'Something',
inputValue: '1'
}]
}, {
xtype: 'container',
layout: 'card',
flex: 1,
bind: {
activeItem: '{activeCardLayout}'
},
items: [{
xtype: 'container',
layout: 'fit'
}, {
xtype: 'container',
layout: 'fit',
items: [{
xtype: 'textfield',
fieldLabel: 'hello',
allowBlank: false
}]
}]
}]
});
Ext.define('MyViewModel2', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myview2',
data: {
activeItem: {
myInput: 0
}
},
formulas: {
disableSomethingCard: function(getter) {
return getter('activeItem.myInput') !== '1';
},
activeCardLayout: function(getter) {
var myInput = getter('activeItem.myInput');
console.log(myInput, 'here');
return parseInt(myInput);
}
}
});
Ext.define('MyForm2', {
extend: 'MyForm',
title: 'My Form 2 (works)',
viewModel: {
type: 'myview2'
},
items: [{
xtype: 'radiogroup',
vertical: true,
columns: 1,
bind: {
value: '{activeItem}'
},
defaults: {
name: 'myInput'
},
items: [{
boxLabel: 'None',
inputValue: '0'
}, {
boxLabel: 'Something',
inputValue: '1'
}]
}, {
xtype: 'container',
layout: 'card',
flex: 1,
bind: {
activeItem: '{activeCardLayout}'
},
items: [{
xtype: 'container',
layout: 'fit'
}, {
xtype: 'container',
layout: 'fit',
bind: {
disabled: '{disableSomethingCard}'
},
items: [{
xtype: 'textfield',
fieldLabel: 'hello',
allowBlank: false
}]
}]
}]
});
Ext.create('MyForm', {
renderTo: Ext.getBody()
});
Ext.create('MyForm2', {
renderTo: Ext.getBody()
});
}
});
I have a grid panel and when the user selects the row and clicks the edit button or dbl clicks the row, I want to send the selected row to the new window. But I am having trouble in sending the data.
Here is my grid panel. (List.js)
Ext.define('MyApp.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'mainlist',
require: [ 'MyApp.view.student.StudentForm' ],
title: 'Student Records',
scrollable: true,
margin: 20,
layout: {
type: 'vbox',
align: 'stretch'
},
reference: 'studentGrid',
frame: true,
collapsible: true,
store: 'StudentStore',
collapsible: true,
columns: [
{
text: 'Name',
dataIndex: 'name',
flex: 1
},
{
text: 'Address',
dataIndex: 'address',
flex: 1
},
{
text: 'Phone',
dataIndex: 'phone',
flex: 1
},
{
text: 'Email',
dataIndex: 'email',
flex: 1
},
{
text: 'Faculty',
dataIndex:'faculty',
flex: 1
}
],
dockedItems: [
{
xtype: 'toolbar',
dock: 'top',
items: [
{
xtype: 'button',
text: 'Add',
iconCls: 'fa fa-plus',
listeners: {
click: 'onAdd'
}
},
{
xtype: 'button',
text: 'Edit',
iconCls: 'fa fa-edit',
id: 'editButton',
listeners: {
click: 'onEdit'
}
},
{
xtype: 'button',
text: 'Delete',
iconCls: 'fa fa-trash-o',
bind: {
disabled: '{ !mainlist.selection }'
},
listeners: {
click: 'onDelete'
}
}]
}
],
// toolbar for our store filter field
tbar: [{
xtype: 'textfield',
fieldLabel: 'Search Student',
emptyText: '...type to filter',
width: 300,
listeners: {
change: 'onSearch'
},
triggers: {
clear: {
cls: 'x-form-clear-trigger',
handler: function(){
this.reset();
}
}
}
}]
});
And this my Controller (MainController.js)
createDialog: function(record)
{
if (record)
{
var form = Ext.create('MyApp.view.student.StudentForm');
form.loadRecord(record);
form.show();
}
Ext.create('MyApp.view.student.StudentForm').show();
},
onEdit: function(button, e, options){
var row = button.up('mainlist').getSelection();
debugger;
this.createDialog(row[0]);
},
And here is the pop up window where the data has to be loaded(StudentForm.js)
Ext.define('MyApp.view.student.StudentForm', {
extend: 'Ext.window.Window',
xtype: 'student-form',
height: 400,
width: 500,
layout: {
type: 'fit'
},
reference: 'form',
title: 'Add Student',
closable: true,
modal: true,
items: [{
xtype: 'form',
id : 'formId',
bodyPadding: 5,
modelValidation : true,
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'fieldset',
flex: 1,
title: 'Student Information',
layout: 'anchor',
defaultType: 'textfield',
defaults: {
anchor: '100%',
msgTarget: 'side'
},
items: [
{
xtype: 'hiddenfield',
name: 'id',
fieldLabel: 'Label'
},
{
fieldLabel: 'Name',
name: 'name'
},
{
fieldLabel: 'Address',
name: 'address'
},
{
fieldLabel: 'Phone',
name: 'phone'
},
{
fieldLabel: 'Email',
name: 'email'
},
{
xtype: 'combo',
fieldLabel: 'Faculty',
name: 'facultyName',
queryMode: 'local',
displayField: 'facultyName',
valueField: 'facultyName',
store: {
fields: ['facultyName'],
data: [{
facultyName: 'computing'
}, {
facultyName: 'multimedia'
}, {
facultyName: 'networking'
}]
}
}
]
}],
dockedItems: [
{
xtype: 'toolbar',
dock: 'bottom',
layout: {
pack: 'end',
type: 'hbox'
},
items: [
{
xtype: 'button',
text: 'Save',
iconCls: 'fa fa-check',
listeners: {
click: 'onSave'
}
},
{
xtype: 'button',
text: 'Cancel',
iconCls: 'fa fa-times',
listeners: {
click: 'onCancel'
}
}
]
}]
}]
});
What am I missing here?Any suggestions?
It says loadRecord() is not a function
Your MyApp.view.student.StudentForm is not actually a form. It is a window, hence there is no loadRecord method.
Instead of form.loadRecord(record); call form.down('form').loadRecord(record).
Remember, it is worth naming things what they are.
I would like to place a comboBox underneath a datePicker however I manage to overwrite the datePicker with my comboBox when I place it inside a container. The datePicker is set to a panel and in Hbox layout, I've tried to change this to a vBox layout but this hasn't helped. Is there a way around this.
Here is my code:
..........................
items: [{
xtype: 'container',
items: [{
xtype: 'comboBox',
fieldLabel: 'Choose Calendar',
reference: 'chooseCalendar',
editable: false,
displayField: 'title',
valueField: 'title',
queryMode: 'local'
}]
}],
datePickerCfg: {
reference: 'datePicker',
flex: 3,
},
........................
datePicker is inside a constructor function in another file
........................
layout: {
type: 'hbox',
pack: 'start',
align: 'stretch'
},
constructor: function(config) {
var newConfig = {
items: config.items || []
},
datePicker = {
xtype: 'datepicker'
},
checkBoxes = {
xtype: 'checkboxgroup'
};
if (config.datePickerCfg) {
datePicker = Ext.apply(datePicker, config.datePickerCfg);
newConfig.items.push(datePicker);
}
checkBoxes = Ext.apply(checkBoxes, config.checkBoxes);
newConfig.items.push(checkBoxes);
this.callParent([Ext.apply(newConfig, config)]);
A friend of mine found a way to do this before I could, grrr. But here it is...
datePickerPanelCfg: {
xtype: 'container',
reference: 'datePickerPanelRef',
items: [{
xtype: 'datepicker'
}, {
xtype: 'combobox',
fieldLabel: 'Choose Calendar',
reference: 'chooseCalendar',
editable: false,
bind: {
store: '{calendars}'
},
displayField: 'title',
valueField: 'title',
queryMode: 'local'
}, {
xtype: 'colorpicker',
valueField: 'value',
reference: 'colorPickerRef',
listeners: {
'select': 'colorPicker'
}
}]
}]
the file with the constructor has the following code added to it
layout: {
type: 'hbox',
pack: 'start',
align: 'stretch'
},
constructor: function(config) {
var newConfig = {
items: config.items || []
},
calendarPanel = {
xtype: 'calendarpanel'
},
datePickerPanel = {
xtype: 'container',
layout: {
type: 'vbox'
},
renderTo: Ext.getBody(),
border: 1,
style: {
borderColor: '#000000',
borderStyle: 'solid',
borderWidth: '1px'
},
items: [{
xtype: 'datepicker'
}, {
xtype: 'checkboxgroup'
}, {
xtype: 'container'
}]
};
if (config.datePickerCfg) {
datePicker = Ext.apply(datePicker, config.datePickerCfg);
newConfig.items.push(datePicker);
}
datePickerPanel = Ext.apply(datePickerPanel, config.datePickerPanelCfg);
newConfig.items.push(datePickerPanel);
calendarPanel = Ext.apply(calendarPanel, config.calendarPanelCfg);
newConfig.items.push(calendarPanel);
this.callParent([Ext.apply(newConfig, config)]);