I have a code in which I created a component. On click of apply I want to save this forms fields object and make available for getter. So that Parent container can read that.
I also want all field getter/setter, so that can update value runtime. How to achieve this?
Ext.define('MyApp.view.MyForm', {
extend: 'Ext.form.Panel',
height: 463,
width: 227,
bodyPadding: 10,
title: 'My Form',
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'textfield',
fieldLabel: 'Component Name',
anchor: '100%'
},
{
xtype: 'textfield',
fieldLabel: 'Host',
anchor: '100%'
},
{
xtype: 'textfield',
fieldLabel: 'Port',
anchor: '100%'
},
{
xtype: 'textfield',
fieldLabel: 'Path',
anchor: '100%'
},
{
xtype: 'textareafield',
fieldLabel: 'Request Data',
anchor: '100%'
},
{
xtype: 'button',
text: 'Apply',
listeners: {
click: {
fn: me.onButtonClick,
scope: me
}
}
}
]
});
me.callParent(arguments);
},
onButtonClick: function(button, e, options) {
var form = this.getForm(),
values = form.getFieldValues(),
//make this available to public
json = Ext.JSON.encode(values);
console.log(json);
}
});
In order to achieve this need to define all variables inside config:{} extjs will automatically create getter/setter.
You can then reference it using this.getVar(), this.setVar()
I hope this is helpful for beginners.
Refer configuration section at http://docs.sencha.com/ext-js/4-0/#!/guide/class_system for more details
Related
In the record editing window, I need to use the tree selector, for this, the file Ext.ux.TreePicker is included in the app.js file, which is located in the app folder on the same level as the app.js file.
Ext.Loader.setConfig({enabled:true});
Ext.Loader.setPath('Ext.ux', 'app');
Ext.application({
extend: 'Ext.app.Application',
name: 'App',
appFolder: 'app',
requires: ['Ext.ux.TreePicker'],
...
In the record editing window, set the xtype: 'treepicker' field:
Ext.define('App.view.OperationEdit', {
extend: 'Ext.window.Window',
xtype: 'operation-edit',
alias: 'widget.operationedit',
controller: 'operation_controller',
viewModel: {
type: 'operation_model'
},
defaults: {
xtype: 'textfield',
margin: 10,
labelAlign: 'top'
},
closable: true,
items: [{
xtype: 'form',
items: [
{
xtype: 'treepicker',
store: Ext.data.StoreManager.get('StorageStore'),
fieldLabel: "Mesto_hraneniya",
valueField: 'id',
displayField: 'text',
selectChildren: true,
canSelectFolders: true,
name: 'mesto_hraneniya'
},
......
When I open the edit window, I get an error:
TypeError: p is undefined
Example link Fiddle
Why does an error appear? How to display the treepicker field correctly?
thank
The problem in your code, at least in your fiddle is that you defined the "edit form" as fully json, which will be parsed and executed on load time. Since, there is no StorageStore at load time, store parameter of treepicker will be null and that is the reason you get an error. Proper way would be to set form items on object instantiaton as follows, and the working fiddle is here.
Ext.define('App.view.TestEdit', {
extend: 'Ext.window.Window',
xtype: 'test-edit',
alias: 'widget.testedit',
requires: ['App.store.StorageStore'],
controller: 'app_view_testgrid',
defaults: {
xtype: 'textfield',
margin: 10,
labelAlign: 'top'
},
closable: true,
items: [],
initConfig: function(config){
config = config || {};
config.items = [
{
xtype: 'form',
items: [{
xtype: 'combobox',
store: {
type: 'type-store'
},
fieldLabel: 'Type',
displayField: 'name',
valueField: 'id',
name: 'id_type',
reference: 'mycombo',
}, {
xtype: 'textfield',
fieldLabel: 'My field',
name: 'mytextfield'
}, {
xtype: 'treepicker',
store: Ext.data.StoreManager.get("StorageStore"),
fieldLabel: "Mesto_hraneniya",
valueField: 'id',
displayField: 'text',
selectChildren: true,
canSelectFolders: true,
name: 'mesto_hraneniya'
}, {
xtype: 'button',
minWidth: 70,
text: 'Save',
listeners: {
click: 'saveRecord'
}
}]
}
];
this.callParent(arguments);
}
});
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'
}]
});
}
});
Intro:
I need to call the backend controller to see if the user is admin. If the user is NOT admin, hide the toolbar in the application. Currently the var is successfully changing; However, it is changing after the view is already created causing the view to always have the toolbar visable.
Problem:
Need to check backend to see if user is in the admin group.
Need to return true if they are in admin group
MyCode:
var adminBool = false;
function CheckAdmin() {
debugger;
var a;
Direct.Report.IsAdmin(this.results, a);
debugger;
};
function results(result, constructor, c, d, e, f, g, h) {
debugger;
this.adminBool= result.adminUser; //returns bool
}
Ext.define('Ext.View.MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.AdministrationViewModel',
init: this.CheckAdmin(),
data: {
addNew: true,
update: true,
gridData: null,
isAdmin: this.adminBool
}
});
Synopsis:
Call the backend controller for admin status
Return bool
Update viewModel with bool respectively
ViewModel property,'isAdmin', will bind with hidden property to hide unwanted actions for non admins
UPDATE:
Basically I need a way to delay "isAdmin: this.adminBool" check to after the backend call is finished.
As you are using ViewModel.
So you can use set() method to update your viewmodel field.
I have created an sencha fiddle demo using viewmodel. You can check, how it is working in fiddle. In this fiddle I have not used any API, it just example regarding of ViewModel. Hope this will help you to solve your problem or achieve your requirement.
//ViewModel
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.AdministrationViewModel',
data: {
isAdmin: true
}
});
//Panel
Ext.create('Ext.panel.Panel', {
title: 'ViewModel example',
width: '100%',
renderTo: Ext.getBody(),
viewModel: 'AdministrationViewModel',
layout: {
type: 'vbox', // Arrange child items vertically
align: 'stretch', // Each takes up full width
padding: 10
},
defaults: {
margin: 10
},
items: [{
xtype: 'combo',
height: 40,
fieldLabel: 'Choose Admin or user',
emptyText: 'Choose Admin or user',
labelAlign: 'top',
store: {
fields: ['name', 'value'],
data: [{
"value": true,
"name": "Admin"
}, {
"value": false,
"name": "User"
}]
},
queryMode: 'local',
displayField: 'name',
valueField: 'value',
listeners: {
select: function (combo, record) {
var viewModel = combo.up('panel').getViewModel(),
isAdmin = record.get('value');
//If selected value is {Admin} then we will show toolbar otherwise in case of {User} hide
viewModel.set('isAdmin', !isAdmin);
}
}
}, {
xtype: 'toolbar',
width: '100%',
height: 50,
padding: 10,
bind: {
hidden: '{isAdmin}'
},
items: [{
// xtype: 'button', // default for Toolbars
text: 'Admin',
}, {
xtype: 'splitbutton',
text: 'Split Button'
},
// begin using the right-justified button container
'->', // same as { xtype: 'tbfill' }
{
xtype: 'textfield',
name: 'field1',
emptyText: 'enter search term'
},
// add a vertical separator bar between toolbar items
'-', // same as {xtype: 'tbseparator'} to create Ext.toolbar.Separator
'text 1', // same as {xtype: 'tbtext', text: 'text1'} to create Ext.toolbar.TextItem
{
xtype: 'tbspacer'
}, // same as ' ' to create Ext.toolbar.Spacer
'text 2', {
xtype: 'tbspacer',
width: 50
}, // add a 50px space
'text 3'
]
}]
});
I intend to change the state of several fields in a form (hide) according to the value selected in a combobox.
This can be done using methods such as setVisible () or setHidden ().
It will be possible to achieve this goal using binding component state?
SOLVED
Fiddle https://fiddle.sencha.com/#fiddle/1itf
Yes. Using ViewModel formulas. Quoting from the documentation:
Many configs you will want to bind are boolean values, such as visible (or hidden), disabled, checked, and pressed. Bind templates support boolean negation "inline" in the template. Other forms of algebra are relegated to formulas (see below), but boolean inversion is common enough there is special provision for it.
Basically, you can using bindings to control the visible attribute, but the binding needs to be a boolean value. You can see that with your 'isAdmin' check. So what you need to do is create a formula on the ViewModel and bind to that.
Ext.define('My.ViewModel', {
extend: 'Ext.app.ViewModel',
formulas: {
isAlabama: function(get) {
return get('comboboxvalue') === 'AL';
}
}
}
To use this, you'll need to say that you're using this view model in your panel. Also... you see the comboboxvalue bit? Well, it looks like ComboBoxes don't publish their value attribute to the view model automatically - you need to do that explicitly, like so:
{ xtype: 'combobox',
fieldLabel: 'Choose State',
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
reference:'combobox',
bind: {
value: '{comboboxvalue}'
}
}
There may be a more elegant solution but you could add an attribute into your store to determine to hide or not, then bind to that attribute:
Ext.application({
name : 'Fiddle',
launch : function() {
}
});
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama", "hide": 0},
{"abbr":"AK", "name":"Alaska", "hide": 1},
{"abbr":"AZ", "name":"Arizona", "hide": 1}
]
});
Ext.create('Ext.form.Panel', {
title: 'Sign Up Form',
width: 300,
height: 230,
bodyPadding: 10,
margin: 10,
layout: {
type:'anchor',
align: 'stretch'
},
viewModel: true,
items: [{
xtype: 'checkbox',
boxLabel: 'Is Admin',
reference: 'isAdmin'
},{
xtype: 'textfield',
fieldLabel: 'Admin Key',
bind: {
visible: '{!isAdmin.checked}'
}
},{
xtype : 'menuseparator',
width : '100%'
},{
xtype: 'combobox',
fieldLabel: 'Choose State',
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
reference:'combobox'
},{
xtype: 'textfield',
fieldLabel: 'If Alabama, hide',
bind: {
visible: '{combobox.selection.hide}'
}
},{
xtype: 'textfield',
fieldLabel: 'If Alaska, hide',
bind: {
visible: '{}'
}
},{
xtype: 'textfield',
fieldLabel: 'If Arizona, hide',
bind: {
visible: '{}'
}
}],
renderTo: Ext.getBody()
});
So I have the view below. This view is called when an item from a list on a previous view is tapped. The lists on this view are filtered based on the previous selection, but I want to be able to add items to these lists that contain the same filter (store field = "value"). How can I get it so that the value that is filtering the lists is also passed when clicking the button and loading a new view?
My View page.
Ext.define("MyApp.view.ShowAll", {
extend: 'Ext.Container',
requires: ['Ext.NavigationView', 'Ext.dataview.List', 'Ext.layout.HBox', 'Ext.Container'],
xtype: 'myapp-showall',
config: {
layout: 'hbox',
items: [
{
layout: 'fit',
xtype: 'container',
itemId: 'listContainer',
flex: 1,
items: [
{
xtype: 'list',
store: 'leftStore',
itemTpl: '{storeField}',
emptyText: 'No values added yet'
},
{
xtype: 'toolbar',
docked: 'bottom',
padding: '5px',
items: [{ xtype: 'button', itemId: 'addValue', text: 'Add Values', ui: 'confirm', width:'100%' }]
}
]
},
{
style: "background-color: #333;",
width: 10
},
{
layout: 'fit',
xtype: 'container',
itemId: 'listContainerTwo',
flex: 1,
items: [
{
xtype: 'list',
store: 'rightStore',
itemTpl: '{storeField}',
emptyText: 'No values added yet'
},
{
xtype: 'toolbar',
docked: 'bottom',
padding: '5px',
items: [{ xtype: 'button', itemId: 'addValueRight', text: 'Add Values', ui: 'confirm', width:'100%' }]
}
]
}
]
}
});
Here is part of my Controller (which sets the store filters)
showValues: function() {
this.showValueDetails(arguments[3]);
},
showValueDetails: function(record) {
var title = "Value: "+record['data']['name'];
var showValue = Ext.create('MyApp.view.ShowAll', { title: title });
showValue.setRecord(record);
var valueName = record['data']['name'];
var leftStore = Ext.getStore("leftStore");
leftStore.clearFilter();
leftStore.filter('storeField', valueName);
var rightStore = Ext.getStore("rightStore");
rightStore.clearFilter();
rightStore.filter('storeField', valueName);
this.getMain().push(showValue);
},
It sets the page title correctly and filters the store also. I just am unsure how to pass a variable so when the buttons are clicked the valueName (from controller) is passed to the next view.
Since I was able to set the title fine using the code above, once I click the submit button all it takes is the following to get the title.
var titleVariable = Ext.getCmp('ShowAll')['title'];