Let's assume we'd want to write a component, which displays a string together with an image. This would come in handy, if we need to display the name of a customer (e.g. 'Pfefferminzia') and it's logo. The following picture shows the component in action - in the second row of the dialog.
We can achieve that by combining an normal textfield ('Ext.field.Text') with a label ('Ext.Label') which contains the corresponding image. Thus, we need a conatiner, which surrounds the textfield and the image and keeps them together. Lucky as we are, Sencha Touch already offers such a component, called 'Ext.Container'. Since we want name and image to appear on the same line one after the other, we choose a 'hbox' layout for our container. At this point, out new component looks like this:
Ext.define("myapp.view.CustomerDisplayField", {
extend: 'Ext.Container',
xtype: 'customerdisplayfield',
config: {
layout: 'hbox',
items: [
{
xtype: 'textfield',
label: 'Customer',
labelWidth: '37.4%',
readOnly: true,
flex: 4
},
{
xtype: 'label',
html: '<span style="float:right; margin-right:10px;"><img height="32px" src="resources/images/customer.png"/></span>',
padding: '6 0 0 0',
flex: 1
}
]
}
});
This is all very well, but something is missing: we need the image to change accordingly, whenever the customer changes. In order to achieve this, we add a 'change' listener to the text field. Each time the name of the customer is change (e.g. via a call to 'setvalue()') the image should change as well. But, in the 'change' handler we need to call a function on the label sub-component. How do we get a hold on that? We could, for instance, do something like 'this.up().getComponent(1)' but that would make our component dependent an the structure and on the *order* of the sub-compoenents - which is not good.
Therefore, we add an 'initialize' handler to our component and create all the sub-components in this handler.
Thus, we always have a variable which points directly to our 'image label', which make our life quite easy.
We also add a 'setUrl()' method to our image-label and a 'setValue()' method to our component as a whole. Then we are ready and our source code looks like this:
Ext.define("myapp.view.CustomerDisplayField", {
extend: 'Ext.Container',
xtype: 'customerdisplayfield',
textfield : null,
config: {
layout: 'hbox',
listeners: {
initialize : function() {
//this label displays the icon
var mylabel = Ext.create( 'Ext.Label', {
padding: '6 0 0 0',
flex: 1,
setUrl : function(url) {
this.setHtml('<span style="float:right; margin-right:10px;"><img height="32px" src="'+url+'"/></span>');
}
});
//set a default image
mylabel.setUrl("resources/images/warning.png");
//this textfield displays the customer's name
var mytext = Ext.create('Ext.field.Text',{
label: 'Customer',
labelWidth: '37.4%',
readOnly: true,
flex: 4,
listeners: {
change: function(field,newvalue,oldvalue) {
//get the correct url for my new customer
var url = customernameToUrl(newvalue);
mylabel.setUrl(url);
}
}
});
this.add(mytext);
this.add(mylabel);
this.textfield = mytext;
}
}
},
setValue : function(newvalue) {
this.textfield.setValue(newvalue);
}
});
No comments:
Post a Comment