You guessed it:
PHP Code:
//If no component is defined
if (component == undefined) {
continue;
}
You guessed it:
PHP Code:
//If no component is defined
if (component == undefined) {
continue;
}
JSLint doesn't like that. You should write:
Code:if (!component) { continue; }
Is it possible to insert more than one component, like
var tpl_Template = new Ext.XTemplate(
'<tpl for=".">',
'<h1>{title}</h1>',
'<div class="btnEdit"></div>',
'<div class="more things">',
'<tpl for="comments">',
'<span class="date">{creation_date} {user_name}</span>',
'<p>{content}</p>',
'<div class="btnCommentEdit"></div>',
'</tpl>',
'</div>',
'</tpl>',
);
tpl_Template .compile();
var btnEdit= {
text : 'Edit',
xtype: 'button',
width: '125',
iconCls : 'IconKommentarBearbeiten',
renderTarget: 'div.btnEdit',
handler : function() {
}
}
...
xtype : 'complistview',
...
columns : [
{
xtype: 'lvcolumn',
header: 'Something',
dataIndex: 'temp',
tpl : tpl_Template,
component: [btnEdit, btnCommentEdit, btnSomething]
}
]
If I run this, there will only one textfield. But i.e. "btnCommentEdit" exists more than once.
OK, I tried to find a solution for this:
It is useful. Can it be more smarter?PHP Code:
renderItems : function(startIndex, endIndex){
var ns = this.all.elements;
var args = [startIndex, 0];
for(var i = startIndex; i <= endIndex; i++){
var r = args[args.length] = [];
for(var columns = this.columns, j = 0, len = columns.length, c; j < len; j++){
var component = columns[j].component;
//If no component is defined
if (!component) {
continue;
}
if (component.length > 1) {
var components = component;
for (var k = 0; k < components.length; k++) {
var component = components[k];
c = component.render ?
c = component.cloneConfig() :
Ext.create(component, this.defaultType);
r[j] = c;
var node = ns[i].getElementsByTagName('dt')[j].firstChild;
if(c.renderTarget){
//If no renderTarget was found - prevent errors
if (Ext.DomQuery.selectNode(c.renderTarget, node)) {
c.render(Ext.DomQuery.selectNode(c.renderTarget, node));
}
}else if(c.applyTarget){
c.applyToMarkup(Ext.DomQuery.selectNode(c.applyTarget, node));
}else{
c.render(node);
}
if(c.applyValue === true){
c.applyValue = columns[j].dataIndex;
}
if(Ext.isFunction(c.setValue) && c.applyValue){
c.setValue(this.store.getAt(i).get(c.applyValue));
c.on('blur', function(f){
this.store.getAt(this.index).data[this.dataIndex] = f.getValue();
}, {store: this.store, index: i, dataIndex: c.applyValue});
}
}
} else {
c = component.render ?
c = component.cloneConfig() :
Ext.create(component, this.defaultType);
r[j] = c;
var node = ns[i].getElementsByTagName('dt')[j].firstChild;
if(c.renderTarget){
//If no renderTarget was found - prevent errors
if (Ext.DomQuery.selectNode(c.renderTarget, node)) {
c.render(Ext.DomQuery.selectNode(c.renderTarget, node));
}
}else if(c.applyTarget){
c.applyToMarkup(Ext.DomQuery.selectNode(c.applyTarget, node));
}else{
c.render(node);
}
if(c.applyValue === true){
c.applyValue = columns[j].dataIndex;
}
if(Ext.isFunction(c.setValue) && c.applyValue){
c.setValue(this.store.getAt(i).get(c.applyValue));
c.on('blur', function(f){
this.store.getAt(this.index).data[this.dataIndex] = f.getValue();
}, {store: this.store, index: i, dataIndex: c.applyValue});
}
}
}
}
this.components.splice.apply(this.components, args);
},
I was playing around with your code Condor and couldn't quite get it to do what I needed so I have written this extension which is somewhat similar in nature. This extension lets the user define a template item for a tabpanel and then the template is used to build tabs for the tabpanel out of the store.
CODE WITH EXAMPLE:
Code:Ext.ns('Ext.ux'); Ext.ux.TplTabPanel = Ext.extend(Ext.TabPanel, { initComponent: function () { //Ext.apply(this,{store:this.store}); Ext.ux.TplTabPanel.superclass.initComponent.apply(this, arguments); var tb = this; var itemArr = []; var cnt = tb.store.getCount(); Ext.each(this.tabsTpl, function (j) { for (var i = 0; i < tb.store.getCount(); i++) { var c = j.render ? c = j.cloneConfig() : Ext.ComponentMgr.create(j); function myfn() { Ext.apply(this, tb.store.getAt(i).get(this.applyValues)); } c.cascade(myfn); Ext.ComponentMgr.register(c); tb.items.add(c.id, c); } }); }, }); Ext.reg('tabtpl', Ext.ux.TplTabPanel); Ext.onReady(function () { new Ext.Viewport({ layout: 'hbox', layoutConfig: { align: 'stretch' }, defaults: { flex: 1 }, items: new Ext.ux.TplTabPanel({ id: 'climate_panel', activeTab: 0, store: new Ext.data.JsonStore({ storeId: 'weather', data: [{ id: 'raw', panel: { title: 'Raw', id: 'rawfield' }, fieldset: { title: 'Observed', id: 'observed' }, checks: { items: [{ boxLabel: 'Precipitation', id: 'chk1' }, { boxLabel: 'Temperature', id: 'chk2' }] } }, { id: 'hourly', panel: { title: 'Hourly', id: 'hourfield' }, fieldset: { title: 'Observed Hourly', id: 'observed_hourly' }, checks: { items: [{ boxLabel: 'Altimeter' }, { boxLabel: 'Visibility' }] } }], fields: ['panel', 'title', 'id', 'cn', 'value', 'checks', 'fieldset', 'boxLabel', 'items'], }), tabsTpl: { xtype: 'panel', layout: 'form', applyValues: 'panel', items: { xtype: 'fieldset', applyValues: 'fieldset', items: { xtype: 'checkboxgroup', //items:[], applyValues: 'checks' } } } }) }); });
Last edited by bartonjd; 6 Jul 2010 at 4:56 PM. Reason: removed unnecessary code
Hello,
if someone comes to the point, to add more than one button in the list by using the renderTarget property, here is a solution:
The part:PHP Code:
Ext.ux.ComponentListView = Ext.extend(Ext.ListView, {
defaultType: 'textfield',
initComponent : function(){
Ext.ux.ComponentListView.superclass.initComponent.call(this);
this.components = [];
},
refresh : function(){
Ext.destroy(this.components);
this.components = [];
Ext.ux.ComponentListView.superclass.refresh.apply(this, arguments);
this.renderItems(0, this.store.getCount() - 1);
},
onUpdate : function(ds, record){
var index = ds.indexOf(record);
if(index > -1){
this.destroyItems(index);
}
Ext.ux.ComponentListView.superclass.onUpdate.apply(this, arguments);
if(index > -1){
this.renderItems(index, index);
}
},
onAdd : function(ds, records, index){
var count = this.all.getCount();
Ext.ux.ComponentListView.superclass.onAdd.apply(this, arguments);
if(count !== 0){
this.renderItems(index, index + records.length - 1);
}
},
onRemove : function(ds, record, index){
this.destroyItems(index);
Ext.ux.ComponentListView.superclass.onRemove.apply(this, arguments);
},
/**
* Workarround, um einen Destroy Fehler zu vermeiden
* Quelle: http://www.sencha.com/forum/showthread.php?79210-ComponentDataView-Ext-components-inside-a-dataview-or-listview
*/
onDestroy : function(){
Ext.ux.ComponentListView.superclass.onDestroy.call(this);
Ext.destroy(this.components);
this.components = [];
},
renderItems : function(startIndex, endIndex){
var ns = this.all.elements;
var args = [startIndex, 0];
for(var i = startIndex; i <= endIndex; i++){
var r = args[args.length] = [];
for(var columns = this.columns, j = 0, len = columns.length, c; j < len; j++){
var component = columns[j].component;
//If no component is defined
if (!component) {
continue;
}
if (component.length > 1) {
var components = component;
for (var k = 0; k < components.length; k++) {
var component = components[k];
c = component.render ?
c = component.cloneConfig() :
Ext.create(component, this.defaultType);
r[j] = c;
var node = ns[i].getElementsByTagName('dt')[j].firstChild;
if(c.renderTarget){
//If no renderTarget was found - prevent errors
if (Ext.DomQuery.jsSelect(c.renderTarget, node)) {
//c.render(Ext.DomQuery.selectNode(c.renderTarget, node));
var elm = Ext.DomQuery.jsSelect(c.renderTarget, node);
Ext.each(elm, function(item) {
var nextEl = c.cloneConfig();
nextEl.render(item);
})
}
/*if (Ext.DomQuery.selectNode(c.renderTarget, node)) {
c.render(Ext.DomQuery.selectNode(c.renderTarget, node));
}*/
}else if(c.applyTarget){
c.applyToMarkup(Ext.DomQuery.selectNode(c.applyTarget, node));
}else{
c.render(node);
}
if(c.applyValue === true){
c.applyValue = columns[j].dataIndex;
}
if(Ext.isFunction(c.setValue) && c.applyValue){
c.setValue(this.store.getAt(i).get(c.applyValue));
c.on('blur', function(f){
this.store.getAt(this.index).data[this.dataIndex] = f.getValue();
}, {store: this.store, index: i, dataIndex: c.applyValue});
}
}
} else {
c = component.render ?
c = component.cloneConfig() :
Ext.create(component, this.defaultType);
r[j] = c;
var node = ns[i].getElementsByTagName('dt')[j].firstChild;
if(c.renderTarget){
//If no renderTarget was found - prevent errors
if (Ext.DomQuery.selectNode(c.renderTarget, node)) {
c.render(Ext.DomQuery.selectNode(c.renderTarget, node));
}
}else if(c.applyTarget){
c.applyToMarkup(Ext.DomQuery.selectNode(c.applyTarget, node));
}else{
c.render(node);
}
if(c.applyValue === true){
c.applyValue = columns[j].dataIndex;
}
if(Ext.isFunction(c.setValue) && c.applyValue){
c.setValue(this.store.getAt(i).get(c.applyValue));
c.on('blur', function(f){
this.store.getAt(this.index).data[this.dataIndex] = f.getValue();
}, {store: this.store, index: i, dataIndex: c.applyValue});
}
}
}
}
this.components.splice.apply(this.components, args);
},
destroyItems : function(index){
Ext.destroy(this.components[index]);
this.components.splice(index, 1);
}
});
Ext.reg('complistview', Ext.ux.ComponentListView);
Clones the button, so you can use it more than one time.PHP Code:
//If no renderTarget was found - prevent errors
if (Ext.DomQuery.jsSelect(c.renderTarget, node)) {
var elm = Ext.DomQuery.jsSelect(c.renderTarget, node);
Ext.each(elm, function(item) {
var nextEl = c.cloneConfig();
nextEl.render(item);
})
}
Thanks for this Condor. For anyone wanting to add Ext.ux.RowActions type functionality to a ListView here is an example:
This needs the renderItems change from earlier in this threadPHP Code:
new Ext.ux.ComponentListView({
store : lbStore,
autoHeight : true,
emptyText : 'No VIP\'s to display',
columns : [{
header : 'VIP',
dataIndex : 'lb'
}, {
header : 'VIP Port',
dataIndex : 'lb_port'
}, {
header : ' ',
component : {
xtype : 'box',
autoEl: {
tag: 'img',
src: '/images/del-icon.png',
cls: 'row-action-del'
}
}
}],
listeners: {
click : {
fn: function(view, index, node, e) {
var el = Ext.get(e.target);
if(el.hasClass('row-action-del'))
{
var record = view.getRecord(node);
view.getStore().remove(record);
}
}
}
}
});
PHP Code:
// If no component is defined
if (!component) {
continue;
}
I have a control that extends CustomDataView. The data in the control is about 200 records. It consists of a checkbox and a label. The control takes around 900 milliseconds for the renderItems function to load. It would be very nice if I could get that down to a more acceptable level.
Thanks,
Justin
I meant ComponenetDataView.
Do you actually need Ext components, or could you just render HTML <label> and <input> elements in a normal DataView?