Is it possible to add a Sencha button into a template?
Printable View
Is it possible to add a Sencha button into a template?
Will renderTpl work somehow?
This may come handy for rendering button in Templates.Code:xtype:'dataview',
scroll:false,
singleSelect: true,
itemSelector: 'div.testbutton',
store: teststore,
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<div class="testbutton" id="renderbutton"></div>',
'</tpl>'),
listeners:{
afterrender:function(){
new Ext.Button({
text:'Button',
ui:'action',
renderTo:'renderbutton'
});
}
}
Thank you, I think thats what I'm looking for.
Hello, I had a similar need for inserting a component inside a template. I can't use the proposed solution though since my templates are in separate files and I don't like much the idea of having parts of the template in a file and other parts (the components) somewhere else.
I came up with an override of XTemplate that allows me to do the following:
Here's the code for the override.Code:<tpl for=".">
Click here: {[ this.addCmp({xtype:"button", text:"OK"}) ]}
</tpl>
You can insert any component but be aware of a few restrictions:Code:(function () {
var originalOverwrite = Ext.XTemplate.prototype.overwrite;
Ext.override(Ext.XTemplate, {
overwrite: function () {
//execute the base overwrite method
originalOverwrite.apply(this, arguments);
//then, render any components that addCmp might have added
while (this.templateComponents.length > 0) {
var el = this.templateComponents.shift();
if (Ext.get(el.renderTo) != null) {
var newel = new Ext.create(el);
}
}
},
//an array to store the initialconfigs of the components-to-be
templateComponents:[],
//Pushes an initialConfig to the array so that
//a component can be later created and rendered.
//It also generates a div container for the component
//with a random id if no id was provided
addCmp: function (initConfig) {
var wrapperId = "ext-comp-wrapper-";
if (initConfig.id != void (0)) {
wrapperId += initialConfig.id;
} else {
wrapperId += Math.random().toString().replace(".", "");
}
initConfig.renderTo = wrapperId;
this.templateComponents.push(initConfig);
return '<div id="' + wrapperId + '"></div>';
}
});
})();
- Lazy instantiation must be used and an xtype must be provided;
- Always use double quotes (e.g xtype:"button"), cause single quotes don't work and Sencha 0.98 will throw an "Unexpected identifier" error;
- The whole instruction must be on a single line, you'll get an error otherwise;
- Watch out when you mix square and curly brackets, the template parser might get confused (eg. {xtype:"tabpanel", items:[{title:"Tab1"}]} ). Just add a space to avoid confusion. (eg. {xtype:"tabpanel", items:[{title:"Tab1"}]<spaceHere>} )
May I suggest something similar to be added in a future version of Sencha? Or is there already a simpler way to do this?
@Brightsoul, well i implanted it and the button is rendered, i did not find another way to handle this untill now.
But there is a slight problem for me, i would like to know an item id, but cant pass the data to an handler.
I am using it in an dataview, and i want 2 buttons, one for showing details, one to add the item to an store.
The alert("okay") is working just fine, if i put an +id alert("okay "+id) to it, it will pass me the ext-gen id, if i put anCode:var dataview = new Ext.DataView({
store: itemStore,
tpl : new Ext.XTemplate(
'<ul>',
'<tpl for=".">',
'<li class="phone" id="itemID{id}" >',
'<div class="itemPic" id="boxPic{id}" onclick="onPic({id})">',
'<img width="64" height="64" src="images/phones/{code}.png" />',
'</div>',
'<div class="itemText">',
'<strong>{name}</strong>',
'</div>',
'<div class="itemPrice">',
'<span>{price} €</span>',
'</div>',
'{[ this.addCmp({xtype:"button", text:"OK", handler:function fn(){ alert("okay") } }) ]}',
'</li>',
'</tpl>',
'</ul>'
)
this.id i will see the id of the template.
So now i would like to pass the id of the item, passed by the store.
And i cant find a way to get this. If i try an alert("okay "+{id}) it throws an error:
missing ) after argument list
So now i am stucked, has anyone an solution???
Regards
Sosy
Well, after i could not manage to get the above code working, i created an alternative:
Which will make it look (with correct css) like thisCode:var dataview = new Ext.DataView({
store: itemStore,
tpl : new Ext.XTemplate(
'<ul>',
'<tpl for=".">',
'<li class="item" id="itemID{id}" >',
'<div class="itemPic" id="boxPic{id}">',
'<img width="64" height="64" src="images/phones/{code}.png" />',
'</div>',
'<div class="itemText">',
'<strong>{name}</strong>',
'</div>',
'<div class="itemPrice">',
'<span>{price} €</span>',
'</div><br /><br />'
+ '<img id="nodeInfo_{id}" class="infoButt" style="width:32px;height:32px;" src="images/det32.png" '
+ 'ONMOUSEOVER="this.src=\'images/det32o.png\'" '
+ 'ONMOUSEOUT="this.src=\'images/det32.png\'" /><img src="images/s.png" style="width:19px; height:1px;" /><span><img src="images/s.png" style="width:19px; height:19px;" /></span>'
+ '<img id="nodeAdd_{id}" class="infoButt" style="width:135px;height:32px;" src="images/addcart1.png" '
+ 'ONMOUSEOVER="this.src=\'images/addcart2.png\'" '
+ 'ONMOUSEOUT="this.src=\'images/addcart1.png\'" /><img src="images/s.png" style="width:19px; height:1px;" /><br />',
'</li>',
'</tpl>',
'</ul>'
)
,id : 'items',
itemSelector : 'li.item',
overClass : 'item-hover',
singleSelect : true,
height : '100%',
autoScroll : true,
autoWidth : true,
listeners :
{
scope : this
,click :
{
fn: function(dataView, index, element, e)
{
var selNode = dataview.getSelectedRecords();
var id = selNode[0].data.id;
var itemID = "itemID"+id;
var em = dataView.isSelected(element);
var pc = Ext.get('nodeInfo_' + id).dom.src.indexOf('images/det32o.png');
var cc = Ext.get('nodeAdd_' + id).dom.src.indexOf('images/addcart2.png');
if (pc==38)
{
showInfo(id)
}
if (cc==38)
{
var name = selNode[0].data.name;
var price = selNode[0].data.price;
var code = selNode[0].data.code;
var add2Cart =
{
url : 'modules/h!s_cart.php',
method : 'post',
params :
{
cmd : 'add'
,id : id
,name : name
,price : price
,code : code
},
success : function(response, options)
{
done = Ext.decode(response.responseText).done;
aant = Ext.decode(response.responseText).aant;
if (done=='1')
{
var myFieldset2 = Ext.getCmp('loginPanel');
//myFieldset2.collapse(true);
Ext.fly('isCart').update(+aant+' Artikel im Einkaufswagen');
miniCartStore.reload();
}
else
{
alert("er is iets niet goed");
}
},
failure: function(response)
{
var result=response.responseText;
Ext.MessageBox.alert('error','could not connect to the language file. retry later');
}
};
Ext.Ajax.request(add2Cart);
}
Ext.get(itemID).stopFx();
Ext.get(itemID).fadeIn
({
endOpacity : 0, //can be any value between 0 and 1 (e.g. .5)
easing : 'elasticBoth',
duration : 2,
remove : false,
useDisplay : false
});
}
}
}
});
Attachment 23445
Now i have the possibility to 1) show details on the item, and 2) add it to an database (cart)..
Hope it helps someone!?
Regards
Sosy
Hello there, try using values.id, like this:
{[ this.addCmp({xtype:"button", text:"OK", handler:function fn(){ alert("okay" + values.id); } }) ]}
This was also a problem I had.
This is an awesome extension. I wish it was part of the toolkit proper.
The only issue I am running into is that it would be much more powerful if there was a way to get a scope into the template so I could add handlers that point at specific callbacks on other objects. Does anyone know a good way to get a scope into the template evaluation. (in particular when used with an Ext.List).
Once again, great extension.
Guys,
This can be a great help to me.
I have a situation like:
console.log('override');
(function () {
var originalOverwrite = Ext.XTemplate.prototype.overwrite;
Ext.override(Ext.XTemplate, {
overwrite: function () {
//execute the base overwrite method
originalOverwrite.apply(this, arguments);
//then, render any components that addCmp might have added
while (this.templateComponents.length > 0) {
var el = this.templateComponents.shift();
if (Ext.get(el.renderTo) != null) {
var newel = new Ext.create(el);
}
}
},
//an array to store the initialconfigs of the components-to-be
templateComponents:[],
//Pushes an initialConfig to the array so that
//a component can be later created and rendered.
//It also generates a div container for the component
//with a random id if no id was provided
addCmp: function (initConfig) {
var wrapperId = "ext-comp-wrapper-";
if (initConfig.id != void (0)) {
wrapperId += initialConfig.id;
} else {
wrapperId += Math.random().toString().replace(".", "");
}
initConfig.renderTo = wrapperId;
this.templateComponents.push(initConfig);
return '<div id="' + wrapperId + '"></div>';
}
});
})();
console.log('template');
var xtemp = new Ext.XTemplate(
'<tpl for=".">',
'<div id="topo"/>',
'<span id="tituloTxt">{txt}</span>',
'{[ this.addCmp({xtype:"panel", id:"conteudop", html:"OK", fullscreen: false }) ]}',
'<div id="base"/>',
'</tpl>'
);
Ext.setup({
tabletStartupScreen: 'tablet_startup.png',
phoneStartupScreen: 'phone_startup.png',
icon: 'icon.png',
glossOnIcon: false,
onReady: function() {
var teste = new Ext.Component({
fullscreen: true,
defaults: {
flex: 1
},
tpl: xtemp
});
teste.update({txt:'aaa'});
}
});
where I want to insert a panel in a component. The template is working, APART from the insertion of the panel. If I remove the addCmp call, it works as needed. What is the deal here, is it a limitation of the idea? I feel it is not, and I'm missing something on the usage of override.
Thanks for any input!
Cheers,