Ext JS: tpl config is ignoring html in Panel - javascript

I need to use both of configs tpl and html within panel class but it's not let to render both configs.
How can be able to use both?
Ext.define('InfoCard.Main', {
extend: 'Ext.panel.Panel',
viewModel: {
type: 'infocardvm'
},
layout: {
type: 'table'
},
items: [{
xtype: 'infocard',
userCls: 'totalReCls',
bind: {
html: '{totalReBar}'
}, //Can't use 'tpl' here because it doesn't have setTpl()
glyph: 'xf015#FontAwesome',
// tpl: 'TotalReBar' //When I'm uncomment the config, then ignores 'bind: html'
}]
});
Here is full sample FIDDLE.
Question is related with this post at Software Engineering site.

You can use displayfield inside of items of panel. In display field have methods for setValue() and setFieldLabel(). So you can change on basis of requirement.
In this FIDDLE, I have created a demo using your code and put modification. Hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.define('InfoCard.Main', {
extend: 'Ext.panel.Panel',
tbar: [{
text: 'Refresh data',
handler: function () {
var vm = this.up('panel').getViewModel(),
store = vm.getStore('firstStore');
store.getProxy().setUrl('stat1.json');
store.load();
}
}],
viewModel: {
type: 'infocardvm'
},
layout: {
type: 'table'
},
defaults: {
xtype: 'infocard',
},
items: [{
items: {
xtype: 'displayfield',
fieldLabel: 'Total ReBar',
bind: '{totalReBar}'
},
glyph: 'xf015#FontAwesome'
}, {
items: {
xtype: 'displayfield',
fieldLabel: 'Total RoBar',
bind: '{totalRoBar}'
},
bodyStyle: {
"background-color": "#DFE684"
},
glyph: 'xf015#FontAwesome'
}, {
items: {
xtype: 'displayfield',
fieldLabel: 'Total PaBar',
bind: '{totalPaBar}'
},
bodyStyle: {
"background-color": "#fbe3ab"
},
glyph: 'xf015#FontAwesome'
}]
});

When I understand you correctly you want to render a static string with a variable value.
{
xtype: 'infocard',
bind: { data: '{totalReBar}' }, // bind the data for the tpl
tpl: 'TotalReBar {totalCount}' // use the data provided via binding in the tpl
}
The formula now has to return an object for the tpl data binding.
You can access the values in the tpl via the key's.
formulas: {
totalReBar: {
bind: {bindTo: '{firstStore}', deep: true},
get: function (store) {
var record = store.findRecord("code", "TOTALRE");
return {
totalCount: record ? record.get("totalcount") : "-1" // totalCount is now available in the tpl as a variable
};
}
},
See the modified fiddle.

I believe that what you want is this:
{
xtype: 'infocard',
userCls: 'totalReCls',
bind: {data: {'myVal': '{totalReBar}'}},
glyph: 'xf015#FontAwesome',
tpl: '{myVal}'
}
hope that helps

Related

ExtJS 5 Uncaught TypeError: cannot read property 'parentNode' of null in Tab Panel

I am using ExtJS version 5.1.0.
Problem: I have a Ext.panel.Panel in my view. In this panel's beforeRender, I am trying to add an xtype:'form' whose items contain a tabpanel with multiple tabs.
When I switch the tab after some seconds of waiting on other tab, I get this exception
Uncaught TypeError: cannot read property 'parentNode' of null
And as a result of this, entire view of the switched tab is lost(its blank).
I have been trying this for a time now, but unable to find a solution.
Any suggestions on this would be a great help.
Here is my code snippet:
Ext.define({
'myClass',
extend: 'Ext.panel.Panel',
layout: 'fit',
viewModel: {
type: 'abc'
},
beforeRender: function() {
var me = this;
me.add({
xtype: 'form',
trackResetOnLoad: 'true',
layout: {
type: 'vbox',
align: 'stretch'
},
items: [
me.getContainer()
]
});
},
getContainer: function() {
var me = this;
var tabpanel = Ext.create({
'Ext.TabPanel',
allowDestroy: false,
reference: 'abc', //being used in application somewhere
layout: 'fit',
border: 0,
activeTab: 0,
items: [{
xtype: 'container',
bind: {
data: {
abcd
}
},
title: 'tab1',
layout: 'fit',
items: [
me.createContainer1() // contains form fields
]
},
{
xtype: 'container',
title: 'tab2',
layout: 'fit',
bind: {
data: {
abcf
}
},
items: [
me.createContainer2() // contains form fields
]
}
]
});
}
});
This is not a duplicate, it is a issue related to tabpanel and not simple HTML. It uses framework related knowledge. If anyone has idea about this, then please explain.
Firstly you need to use beforerender event instead of beforeRender and beforerender will be inside of listeners.
And also you can return directly xtype instead of creating like below example
createField: function() {
return [{
xtype: 'textfield',
emptyText: 'Enter the value',
fieldLabel: 'Test'
}];//You here return Object or Array of items
}
In this FIDDLE, I have created a demo using your code and make some modification. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
//Define the viewmodel
Ext.define('ABC', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.abc',
data: {
tab1: 'Tab 1',
tab2: 'Tab 2',
tab3: 'Tab 3',
tab4: 'Tab 4',
title: 'Basic Example'
}
});
//Define the panel
Ext.define('MyPanel', {
extend: 'Ext.panel.Panel',
xtype: 'mypanel',
layout: 'fit',
//This function will return field items for container or panel
createContainer: function (fieldLabel) {
return {
xtype: 'textfield',
emptyText: 'Enter the value',
fieldLabel: fieldLabel
};
},
//This function will return tabpanel for form items.
getContainer: function () {
var me = this;
return {
xtype: 'tabpanel',
allowDestroy: false,
//reference: 'abc', //being used in application somewhere
layout: 'fit',
border: 0,
activeTab: 0,
items: [{
bind: '{tab1}',
bodyPadding: 10,
layout: 'fit',
items: me.createContainer('Tab1 field') // contains form fields
}, {
bind: '{tab2}',
bodyPadding: 10,
layout: 'fit',
items: me.createContainer('Tab2 field') // contains form fields
}, {
bind: '{tab3}',
bodyPadding: 10,
layout: 'fit',
items: me.createContainer('Tab3 field') // contains form fields
}, {
bind: '{tab4}',
bodyPadding: 10,
layout: 'fit',
items: me.createContainer('Tab4 field') // contains form fields
}]
};
},
listeners: {
beforerender: function (cmp) {
var me = this;
//Add form inside of panel
me.add({
xtype: 'form',
trackResetOnLoad: true,
layout: {
type: 'vbox',
align: 'stretch'
},
items: me.getContainer()
});
}
}
});
//Create the mypanel
Ext.create({
xtype: 'mypanel',
viewModel: {
type: 'abc'
},
bind: '{title}',
renderTo: Ext.getBody()
});
}
});

ExtJS 6.2 Can't add plugin to inner grid - TypeError: view is undefined

I have a grid with drag'n'drop and row editing plugins. It worked fined when it was an outer class. However, since I striped the grid from having a class and put as an inner component, it started giving me errors. If I comment out code concerning plugins, it works fine.
Ext.define('Dashboards.view.widgets.barChartAndLine.BarChartAndLineWidgetForm', {
extend: 'Dashboards.view.widgets.WidgetBaseForm',
xtype: 'barChartAndLineWidgetForm',
items : [{
xtype: 'grid',
rowEditing: null,
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop'
}
},
listeners: {
drop: function() {
this.updateData();
}
},
initComponent: function() {
var me = this;
this.rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 1,
autoCancel: false,
listeners: {
edit: function() {
me.updateData();
}
}
});
this.plugins = [this.rowEditing];
this.callParent(arguments);
},
store: {
fields : ['label', 'linevalue', 'barvalue'],
bind : {
data : '{widget.data.data.items}'
}
},
columns: [{
header: 'Pavadinimas',
dataIndex: 'label',
flex: 3,
editor: {
allowBlank: false
}
}, {
xtype: 'numbercolumn',
header: 'Stulpelio reikšmė',
dataIndex: 'barvalue',
flex: 1,
editor: {
xtype: 'numberfield',
allowBlank: false
}
}, {
xtype: 'numbercolumn',
header: 'Linijos reikšmė',
dataIndex: 'linevalue',
flex: 1,
editor: {
xtype: 'numberfield',
allowBlank: false
}
}, {
xtype: 'actioncolumn',
width: 30,
items: [{
iconCls: 'x-fa fa-trash',
tooltip: 'Pašalinti',
handler: function(g, ri, ci) {
var grid = this.up().up();
grid.getStore().removeAt(ri);
grid.getStore().sync();
}
}]
}],
tbar: [{
xtype: 'button',
text: 'Pridėti',
handler: function() {
var grid = this.up().up();
var r = {
label: 'label',
linevalue: '0',
barvalue: '0'
};
var modelResult = grid.getStore().insert(0, r);
}
}]
}]
});
Instead of adding the rowediting plugin inside the initComponent function, you can set the plugin with grid's configs.
Based on your code have remote data, I created a fiddle to test the view, you can apply the view structure with your data.
If you have any question, let me know.

Extjs add item to extended class

Using Extjs 5 I am defining my custom toolbar:
Ext.define('Core.toolbar.view.ToolbarView',
{
extend: 'Ext.toolbar.Toolbar',
dock: 'top',
items: [
{
xtype: 'button',
text: 'add'
},
{
xtype: 'button',
text: 'remove'
}]
});
Now I want to use it:
Ext.define('MyApp.view.ToolbarView',
{
extend: 'Core.toolbar.view.ToolbarView',
items: [
{
xtype: 'button',
text: 'ADDING AN OTHER BUTTON'
}]
});
Ext.create('MyApp.view.ToolbarView');
Using items property I am overriding the old items with the new item, but I do not want to do it. I want to add third button.
Is possible?
I'd make use of initComponent, like this (example):
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.define('Core.toolbar.view.ToolbarView', {
extend: 'Ext.toolbar.Toolbar',
dock: 'top',
items: [{
xtype: 'button',
text: 'add'
}, {
xtype: 'button',
text: 'remove'
}]
});
Ext.define('MyApp.view.ToolbarView', {
extend: 'Core.toolbar.view.ToolbarView',
initComponent: function() {
this.callParent();
this.add({
xtype: 'button',
text: 'ADDING AN OTHER BUTTON'
});
}
});
Ext.create('MyApp.view.ToolbarView', {
renderTo: Ext.getBody()
});
Ext.create('MyApp.view.ToolbarView', {
renderTo: Ext.getBody()
});
}
});
You can use onClassExtended on your core toolbar and set a onBeforeCreated hook, for example:
onClassExtended: function (cls, data, hooks) {
var onBeforeClassCreated = hooks.onBeforeCreated,
Cls = this,
xArray = Ext.Array;
hooks.onBeforeCreated = function (clss, dataa) {
dataa.items = xArray.from(Cls.prototype.items).concat(xArray.from(dataa.items));
onBeforeClassCreated.call(this, clss, dataa, hooks);
};
}
Working example: https://fiddle.sencha.com/#fiddle/t3i
When you provide items on extending an Ext.container.Container (or creating an instance of it), by default, any previously specified items will be overridden, indeed. There is no out-of-the-box logic in place to merge them — simply because Ext JS does not know how you want them merged: whether you want the latter items to go after the former ones, or before, or somehow in the middle, or you want overriding. You need to tell Ext JS what you want explicitly.
So, here is yet another approach:
Ext.define('Core.toolbar.view.ToolbarView', {
extend: 'Ext.toolbar.Toolbar',
dock: 'top',
buildItems: function() {
return [
{
xtype: 'button',
text: 'add'
},
{
xtype: 'button',
text: 'remove'
}
];
},
initComponent: function() {
this.items = this.buildItems();
this.callParent();
}
});
Ext.define('MyApp.view.ToolbarView', {
extend: 'Core.toolbar.view.ToolbarView',
buildItems: function() {
return this.callParent().concat([
{
xtype: 'button',
text: 'ADDING AN OTHER BUTTON'
}
]);
}
});
Ext.create('MyApp.view.ToolbarView');
Example: https://fiddle.sencha.com/#fiddle/t48

extjs5 widgetcolumn multiple widgets in a single cell

I create a widgetcolumn as the panel in which several components. How can i link record parameters with these components?
For example:
{
xtype: 'widgetcolumn',
dataIndex: 'data',
widget: {
xtype: 'panel',
height: 77,
width: 642,
layout: {
type: 'vbox',
align: 'stretch'
},
items: [
{
xtype: 'button',
text: record.get('name') //<<-- how can i link this record from the grid with this component?
},
{
xtype: 'button',
text: record.get('type') //<<-- how can i link this record from the grid with this component?
},
{
xtype: 'button',
text: record.get('location') //<<-- how can i link this record from the grid with this component?
}
]
}
}
I have a following store:
var store = Ext.create('Ext.data.Store', {
fields:['name', 'type', 'location'],
data:[
{name: 'name1', type: 'type1', location: 'loc1'},
{name: 'name2', type: 'type2', location: 'loc2'}
]
});
Maybe, I can get access to the record via renderer function? Something like this:
renderer: function(value, meta, record) {
//How can I get access to widget instance?
}
I solved this problem. We need to get access to the parent element - widgetcolumn, and then call the function - getWidgetRecord.
{
xtype: 'label',
text: 'Some text...',
cls: 'gridcall-label-asgmt',
listeners: {
resize: function(label) {
var parent = label.up();
while(typeof parent.up() !== 'undefined') {
parent = parent.up();
} // --- while
var record = parent.getWidgetRecord();
if (typeof record === 'undefined') return;
label.setText(record.data.asgmt, false);
} // --- resize
} // --- listeners
}

Sencha Touch 2: Passing data from controller to a view

I am attempting to load a detail view for an item disclosure from a list but without using NavigationView and the "push()" command.
CONTROLLER:
Ext.define('App.controller.MyPlans', {
extend: 'Ext.app.Controller',
requires: ['App.view.EventDetail',
'App.view.PlansContainer'],
config: {
refs: {
},
control: {
'MyPlansList': {
disclose: 'onDisclose'
}
}
},
onDisclose: function (view, record) {
console.log("My Plans list disclosure " + record.get('id'));
var eventDetailView = Ext.create('App.view.EventDetail');
eventDetailView.setRecord(record);
Ext.Viewport.setActiveItem(eventDetailView);
}
});
VIEW:
Ext.define('App.view.EventDetail', {
extend: 'Ext.Panel',
xtype: 'EventDetail',
config: {
items: [{
xtype: 'toolbar',
docked: 'top',
title: 'Event Name',
items: [{
xtype: 'button',
id: 'addRunBackBtn',
ui: 'back',
text: 'Back'
}]
}, {
xtype: 'panel',
styleHtmlContent: true,
itemTpl: [
'<h1>{name}</h1>',
'<h2>{location}</h2>',
'<h2>{date}</h2>']
}],
}
});
I am basically trying to pass the data to the view using the "setRecord()" command but nothing seems to be loading in the view. Any thoughts??
Thanks
Instead of ItemTpl just write Tpl. I doubt that itemTpl exists without list xtype.
Other thing is put Tpl inside config:
{tpl:['<div class="ListItemContent">{descriptionddata}</div>']}
The answer before/above me is good but if you intend of keeping your formatting inside view and not in controller then , it works by using setData instead of setRecord
detailview.setData({title:record.get('title'), description:record.get('descriptiondata')});
Instead of panel try list as below
Ext.define('App.view.EventDetail', {
extend: 'Ext.TabPanel',
xtype: 'EventDetail',
config: {
items: [{
xtype: 'toolbar',
docked: 'top',
title: 'Event Name',
items: [{
xtype: 'button',
id: 'addRunBackBtn',
ui: 'back',
text: 'Back'
}]
}, {
xtype: 'list',
styleHtmlContent: true,
itemTpl: [
'<h1>{name}</h1>',
'<h2>{location}</h2>',
'<h2>{date}</h2>']
}],
}
});
I found the issue here:
A panel doesn't have a itemTpl
{
xtype: 'panel',
styleHtmlContent: true,
itemTpl : [
'<h1>{name}</h1>',
'<h2>{location}</h2>',
'<h2>{date}</h2>'
]
}
The one of the possible way to do it could be:
Change the VIEW:
{
xtype: 'panel',
id: 'thePanel',
styleHtmlContent: true
}
Change the Controller:
onDisclose: function(me, record, target, index, e, eOpts) {
...
Ext.getCmp('thePanel').setHtml('<h1>'+record.get('name')+'</h1><h2>'+record.get('location')+'</h2><h2>'+record.get('date')'</h2>'); //For setting the Data
...
}
Hope this could help!

Categories