My problem is when I click Add button it needs to add a fieldset ("rulepanel") after the previous fieldset, but in my code if I execute it the new fieldset is added on top of the previous (I can be able to notice it as the letters are getting bold when click on Add button).
This is my code:
var rulepanel = {
xtype: 'fieldset',
border: false,
itemId: 'rule',
items: [{
xtype: 'container',
items: [{
xtype: 'textfield',
fieldLabel: 'value',
name: 'value',
allowBlank: false,
placeholder: 'value'
}, {
xtype: 'button',
id: 'add',
text: 'Add',
handler: function (button, event) {
me.insert(rulepanel);
}
}, {
xtype: 'button',
id: 'branch',
text: 'Branch'
}]
}]
};
Ext.apply(me, {
items: [rulepanel]
});
Your code should be like below:-
{
xtype: 'button',
text: 'Add',
handler: function (button, event) {
button.up('fieldset').insert(rulepanel);
}
}
You can find running example here.
Hope this will help you.
Related
The ExtJS docs describe a method focus for textfields that will either focus a textfield or return false: https://docs.sencha.com/extjs/6.7.0/modern/Ext.field.Text.html#method-focus
Generally this seems to work just fine, but once the textfield that should be focused is inside a list (part of the listitem) the focus is immediately removed and set to the parent listitem container. Focus however returns true (the focus is actually on the field for a few ms).
https://fiddle.sencha.com/#view/editor&fiddle/315h shows this by example. The first button tries to focus the first textfield inside the list (which fails) and the second one focuses the field below the list.
Is there any way to prevent the listitem from becoming focused?
Code from the fiddle:
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create({
fullscreen: true,
xtype: 'container',
items: [{
xtype: 'list',
itemConfig: {
xtype: 'container',
items: [{
xtype: 'component',
html: 'Row'
}, {
xtype: 'textfield',
value: 'Focus Me'
}],
margin: '15px 0'
},
data: [{
title: 'Item 1'
}, {
title: 'Item 2'
}, {
title: 'Item 3'
}, {
title: 'Item 4'
}]
}, {
xtype: 'button',
text: 'Try to focus',
handler: function () {
this.up('container').down('list').down('textfield').focus();
Ext.toast(this.up('container').down('list').down('textfield').hasFocus + '');
}
}, {
xtype: 'textfield',
itemId: 'focusable',
value: 'Focusable'
}, {
xtype: 'button',
text: 'Try to focus',
handler: function () {
this.up('container').down('#focusable').focus();
Ext.toast(this.up('container').down('#focusable').hasFocus + '');
}
}]
});
}
});
On ExtJS 6.7 the first click on a textfield in a list does not even work but this seems to be fixed in 7.0.
Set defaultFocus for listitem container. Its work for me (fiddle).
P.S. thank you for your fiddle example. few do it.
When I click a add button it needs to add a same container again. The below I have given my code segment
var rulepanel = Ext.apply(me, {
items: [{
xtype: 'uxform',
id: 'rule',
bodyPadding: 10,
items: [{
xtype: 'container',
items: [{
xtype: 'combobox',
fieldLabel: 'match',
name: 'name',
allowBlank: false,
placeholder: 'match'
}]
}, {
xtype: 'container',
layout: {
type: 'hbox',
align: 'stretch'
},
items: [{
xtype: 'combobox',
fieldLabel: 'Product/KPI',
name: 'name',
}, {
xtype: 'button',
id: 'add',
text: 'Add',
handler: function(button, event) {
//rulepanel.insert(0, Ext.create(rulepanel.model));
// so here how can I add it
}
}],
}]
}]
});
So when click the add button what I need is I need to clone the "match,product/kpi and add button" fields. How can I achieve this task. I have tried with cloneconfig(). But couldn't achieve it. Thanks in advance.
In ExtJs, You create your own component as common and you can reuse whenever you required in application. You need to use Ext.define
Defines a class or override. A basic class is defined like this:
Ext.define('My.awesome.Class', {
someProperty: 'something',
someMethod: function() {
alert(s + this.someProperty);
}
...
});
var obj = new My.awesome.Class();
obj.someMethod('Say '); // alerts 'Say something'
In this FIDDLE, I have created a demo using your code as reference. Hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.define('ProductKpi', {
extend: 'Ext.container.Container',
xtype: 'productkpi',
layout: {
type: 'hbox',
align: 'stretch'
},
margin:5,
items: [{
xtype: 'combobox',
flex:1,
fieldLabel: 'Product/KPI',
name: 'name',
}, {
xtype: 'button',
margin:'0 5',
text: 'Add',
handler: function (button, event) {
button.up('#rule').add({
xtype: 'productkpi'
})
}
}],
});
Ext.create('Ext.form.Panel', {
title: 'Demo',
renderTo: Ext.getBody(),
id: 'rule',
bodyPadding: 10,
items: [{
xtype: 'container',
items: [{
xtype: 'combobox',
fieldLabel: 'match',
name: 'name',
allowBlank: false,
placeholder: 'match'
}]
}, {
xtype: 'productkpi'
}]
});
}
});
var radioGroup = {
xtype: 'radiogroup',
itemId: 'radioButton',
layout: 'hbox',
width: 700,
defaults: {
flex: 1
},
items: [{
boxLabel: option1
name: 'timeInterval',
inputValue:0
checked: true
}, {
boxLabel: option2
name: 'timeInterval',
inputValue:1,
checked: false
}, {
boxLabel: option1
name: 'timeInterval',
inputValue:2,
checked: false
}],
listeners: {
change: function (radio, newValue, oldValue) {
if (radio.getValue().timeInterval == 2) {
cardPanel.layout.setActiveItem(0);
//getting error cardPanel.layout.setActiveItem is not a function
} else if (radio.getValue().timeInterval == 0) {
cardPanel.layout.setActiveItem(1);
} else if (radio.getValue().timeInterval == O1) {
cardPanel.layout.setActiveItem(2);
}
}
}
};
var cardPanel = {
layout: 'card',
itemId: 'PanelID',
activeItem: 0,
items: [{
itemId: 'timeIntervalPanel',
name: 'timeInterval',
xtype: 'timeintervalpanel',
selection: this.defaultData,
dateFormat: this.dateFormat,
timeFormat: this.timeFormat
}, {
id: 'specificIntervalPanel',
name: 'timeInterval',
xtype: 'specificinterval',
selection: this.defaultData
}, {
itemId: 'emptyPanel',
name: 'emptyCard',
xtype: 'panel'
}]
};
You need to use following steps :-
First you need to get component which you have provided layout:"card" in change event of RadioGroup.
Now, you need to get getLayout() of your component.
Now need to use setActiveItem(newItem) method of card layout component.
In this FIDDLE, I have created a demo using your code and put some modification. I hope this will help you.
Code Snippet
//Timeinterval panel
Ext.define('Timeintervalpanel', {
extend: 'Ext.panel.Panel',
xtype: 'timeintervalpanel',
html: 'This is timeintervalpanel'
});
//Specific Interval panel
Ext.define('SpecificInterval', {
extend: 'Ext.panel.Panel',
xtype: 'specificinterval',
html: 'This is specificinterval'
});
//Empty Panel
Ext.define('EmptyPanel', {
extend: 'Ext.panel.Panel',
xtype: 'emptyPanel',
html: 'This is emptyPanel'
});
//Panel with radio button and card item.
Ext.create('Ext.panel.Panel', {
title: 'Card Layout Example with radio buttons',
renderTo: Ext.getBody(),
height: window.innerHeight,
layout: 'vbox',
tbar: [{
xtype: 'radiogroup',
itemId: 'radioButton',
layout: 'hbox',
defaults: {
flex: 1,
margin: 5,
name: 'timeInterval'
},
items: [{
boxLabel: 'Timeinterval panel',
inputValue: 0,
checked: true
}, {
boxLabel: 'Specific Interval',
inputValue: 1
}, {
boxLabel: 'Empty Panel',
inputValue: 2
}],
listeners: {
change: function (radio, newValue, oldValue) {
var cardPanel = radio.up('panel').down('#PanelID').getLayout();
cardPanel.setActiveItem(newValue.timeInterval);
//Only just for animation
//activeItem.getEl().slideIn('r');
}
}
}],
items: [{
//This panel have provided card layout.
xtype: 'panel',
flex: 1,
width: '100%',
layout: 'card',
itemId: 'PanelID',
defaults: {
bodyPadding: 20
},
items: [{
xtype: 'timeintervalpanel'
}, {
xtype: 'specificinterval'
}, {
xtype: 'emptyPanel'
}]
}]
});
I have a toolbar with 4 buttons. 'Approval', 'New Request Patient', 'View Request Details', and 'Close' buttons. By default when the page loads, all of these buttons are visible EXCEPT for the 'Approval' button. I want the 'Approval' button to be visible when the user clicked on the 'New Request Patient' which will take the user to that page. And the button will be hidden again when the user clicked on the 'View Request Details' button. So that is my first problem.
My second problem is when the user clicked on the 'New Request Patient' button, the 'View Request Details' button will change its text to 'View Request List'. For some reason I can't figure this out. Here is my code: -
{
xtype: 'toolbar',
docked: 'bottom',
layout: {
pack: 'left',
size: '20px'
},
defaults: {
margin: '10 10'
},
items: [
{
xtype: 'button',
text: 'Approval',
hidden: true
},
{
xtype: 'button',
text: 'New Request Patient',
handler: function () {
Ext.getCmp('requestpatient').setActiveItem(1);
},
//listeners: {
// tap: function()
// {
// myButton.setText('View Request List');
// }
//}
},
{
xtype: 'button',
id: 'myButton',
text: 'View Request Details',
handler: function () {
Ext.getCmp('requestpatient').setActiveItem(0);
}
},
{
xtype: 'button',
text: 'Close'
},
]
},
You can do something like this (see below), but Im not sure I understand what you mean by your button text gets changed? I see a commented code there, to do exactly that.
items: [{
xtype: 'button',
text: 'Approval',
hidden: true
},{
xtype: 'button',
text: 'New Request Patient',
handler: function (b) {
Ext.getCmp('requestpatient').setActiveItem(1);
b.up().down('button[text=Approval]').setHidden(false);
},
},{
xtype: 'button',
itemId: 'myButton',
text: 'View Request Details',
handler: function (b) {
Ext.getCmp('requestpatient').setActiveItem(0);
b.up().down('button[text=Approval]').setHidden(true);
}
},{
xtype: 'button',
text: 'Close'
}]
I am having a bit of trouble adding/removing fields to/from an ExtJS form. My use case is as follows:
Provide a set of radio buttons on the form. Depending on which radio button is selected, show a different set of form fields.
I am not all that familiar with ExtJS, but what I am doing is caching the fields that are to be added/removed and adding/removing them from the form when the radio button change event is fired. Here is a simplified version of my code:
var textFieldA = new Ext.form.TextField({
fieldLabel: 'Text Field A',
name: 'text_field_a',
allowBlank: false
});
var textFieldB = new Ext.form.TextField({
fieldLabel: 'Text Field B',
name: 'text_field_b',
allowBlank: false
});
var form = new Ext.FormPanel({
autoScroll: true,
bodyStyle: 'padding: 5px 5px 0',
border: false,
frame: true,
layout: 'form',
items: [{
xtype: 'fieldset',
fieldLabel: 'Fieldset',
autoHeight: true,
items: [{
xtype: 'radiogroup',
fieldLabel: 'Show text field',
columns: 1,
vertical: true,
items: [
{
xtype: 'radio',
boxLabel: 'Show field a',
name: 'field_to_show',
inputValue: 'a'
},
{
xtype: 'radio',
boxLabel: 'Show field b',
name: 'field_to_show',
inputValue: 'b'
}
],
listeners: {
'change': {
fn: function(radioGroup, selectedRadio) {
switch (selectedRadio.getGroupValue())
{
case 'a':
radioGroup.findParentByType('fieldset').remove(textFieldB);
radioGroup.findParentByType('fieldset').add(textFieldA);
break;
case 'b':
radioGroup.findParentByType('fieldset').remove(textFieldA);
radioGroup.findParentByType('fieldset').add(textFieldB);
break;
}
radioGroup.findParentByType('fieldset').doLayout();
}
}
}
}]
}]
});
form.render('container');
This works the first time each radio is selected, but subsequent selections do not work as I would expect. In Firefox, a JavaScript error is raised:
Operation is not supported" code: "9
[Break on this error] return !!(p.compareDocumentPosition(c) & 16); in ext-base-debug-w-comments.js
In Chrome, only the labels will be added to the form.
Is the way I am expecting this to work incorrect?
I wouldnt necessarily take the approach of adding/removing the fileds- why not give each field an id (also good practice for form fields) using:
id:'fieldname'
Then either hide/show the field as appropriate using:
Ext.getCmp('fieldname').hide()
Ext.getCmp('fieldname').show()
I've written a very similar form. If the only common element is the radio group, here's what I suggest:
Create an outer Container that contains the RadioGroup, then a subcontainer with a CardLayout. Each child of that card layout contains a form with the fields for the different states of the RadioGroup. Add listeners to the RadioGroup so when the selection changes, you change the active item in the card container.
Basic code to get you started from when I did this:
OuterForm = Ext.extend(Ext.Container, {
initComponent: function() {
Ext.apply(this, {
layout: "vbox",
layoutConfig: { align: "stretch" }
});
this.items = [{
xtype: "container",
layout: "form",
items: [{
xtype: "radiogroup",
fieldLabel: "Form to fill out",
ref: "../../formSelector",
items: [{
name: "type",
inputValue: "1",
boxLabel: "Form 1"
}, {
name: "type",
inputValue: "2",
boxLabel: "Form 2"
}],
listeners: {
scope: this,
change: function(rg, checkedItem) {
this.formContainer.layout.setActiveItem(parseInt(checkedItem.inputValue));
}
}
}]
}, {
xtype: "container",
layout: "card",
flex: 1,
ref: "formContainer",
items: [{
xtype: "form1"
}, {
xtype: "form2"
}]
}];
OuterForm.superclass.initComponent.call(this);
}
});
Not tested for typos/bugs, but just set a height for the outer form, create your form1 and form2 xtypes and it should work.
If you need all fields part of the same form, make OuterForm extend FormPanel instead of defining form1 and form2 as independent FormPanels.