PDA

View Full Version : Modifying IconCombo example to use image instead of css element



forumuser1080
4 Mar 2011, 11:19 AM
I need to be able to dynamically add different images to my combo box. Because of that I can not define my images in a css element (hence they would not be dynamic). My server gives me back a list of available icons I can use.

I have taken the IconCombo example from: http://www.sencha.com/learn/Tutorial:Extending_Ext2_Class

and modified it for my needs.

It works except for the fact that after I select an item in the combo box I loose the image.
I know that I need to somehow add the image somehow but I am not really sure how.



Ext.ux.IconCombo = Ext.extend(Ext.form.ComboBox, {
initComponent:function() {

Ext.apply(this, {
tpl: '<tpl for=".">'
+ '<div class="x-combo-list-item" >'
+ '<img src="{' + this.iconField + '}" class="ux-icon-combo-item"/>'
+ '{' + this.displayField + '}'
+ '</div></tpl>'
});

// call parent initComponent
Ext.ux.IconCombo.superclass.initComponent.call(this);

}, // end of function initComponent

onRender:function(ct, position) {
// call parent onRender
Ext.ux.IconCombo.superclass.onRender.call(this, ct, position);

// adjust styles
this.wrap.applyStyles({position:'relative'});
this.el.addClass('ux-icon-combo-input');

// add div for icon
this.icon = Ext.DomHelper.append(this.el.up('div.x-form-field-wrap'), {
tag: 'div', style:'position:absolute'
});
}, // end of function onRender

setIconCls:function() {
var rec = this.store.query(this.valueField, this.getValue()).itemAt(0);
if(rec) {
// Comment out the old way
// this.icon.className = 'ux-icon-combo-icon ' + rec.get(this.iconClsField);
//Set css
this.icon.className = 'ux-icon-combo-icon ';
// Now what how do I set my image ('iconField')?????????????????
}
}, // end of function setIconCls

setValue: function(value) {
Ext.ux.IconCombo.superclass.setValue.call(this, value);
this.setIconCls();
} // end of function setValue
});

// register xtype
Ext.reg('iconcombo', Ext.ux.IconCombo);

djones
4 Mar 2011, 3:25 PM
I am no expert with ExtJS but below is what I did and for better or worse it works ;). I don't recall all of the style changes necessary, I think just need something like this CSS snippit:



.ux-icon-combo-icon img
{
position: absolute;
top: 3px;
left: 5px;
}




Ext.ux.IconCombo = Ext.extend(Ext.form.ComboBox, {
iconHeight: 14,
initComponent:function() {

Ext.apply(this, {
tpl: '<tpl for=".">'
+ '<div class="x-combo-list-item ux-icon-combo-item">'
+ '<img height="' + this.iconHeight + '" src="{' + this.iconField + '}" />'
+ '{' + this.displayField + '}'
+ '</div></tpl>'
});

// call parent initComponent
Ext.ux.IconCombo.superclass.initComponent.call(this);

}, // end of function initComponent

onRender:function(ct, position) {
// call parent onRender
Ext.ux.IconCombo.superclass.onRender.call(this, ct, position);

// adjust styles
this.wrap.applyStyles({position:'relative'});
this.el.addClass('ux-icon-combo-input');

// add div for icon
this.iconDiv = Ext.DomHelper.append(this.el.up('div.x-form-field-wrap'), {
tag: 'div', style:'position:absolute'
});


}, // end of function onRender

setIconCls:function() {
var rec = this.store.query(this.valueField, this.getValue()).itemAt(0);
if(rec) {
this.iconDiv.className = 'ux-icon-combo-icon ';
var src = rec.get(this.iconField) || Ext.BLANK_IMAGE_URL;
this.icon = Ext.DomHelper.overwrite(this.iconDiv, {
tag: 'img', src: src, height:this.iconHeight
});
}
}, // end of function setIconCls

setValue: function(value) {
Ext.ux.IconCombo.superclass.setValue.call(this, value);
if(value!=null && value.length > 0 && this.rendered)
this.setIconCls();
} // end of function setValue
});

// register xtype
Ext.reg('iconcombo', Ext.ux.IconCombo);

forumuser1080
4 Mar 2011, 5:10 PM
I can see the icons for each item when i drop down the combo box. My problem is when I select one of the items I don't see the image. Don't you need to override the setValue() function so that the icon appears once you have selected an item?

djones
4 Mar 2011, 5:17 PM
Yup and that's what happens in the code I provided. The onRender override adds the div for the icon to the field wrapper and then each call to setValue calls setIconCls which overwrites the content of the div with an img tag whose src is bound to the value of iconField on the selected record.

Knowing what I know now:
- this.icon should be created in onRender
- setIconCls should be called setIconSrc (tsk tsk, copy&paste)
- setIconSrc should merely set the value of this.icon.src to rec.get(this.iconField)

forumuser1080
4 Mar 2011, 6:46 PM
Ha sorry was viewing the forum on my phone and the bottom part of your past was cut off. That works great thanks.

I am very much a noobie when it comes to all of this even css. What is the 'img' part on the css file. I see you reference that in the javascript:


this.icon = Ext.DomHelper.overwrite(this.iconDiv, {
tag: 'img', src: src, height:this.iconHeight
});


why to tags in the css file
.ux-icon-combo-icon img


again thanks for the help

djones
4 Mar 2011, 7:11 PM
The html tag for an image is <img ... />. The CSS rule I provided merely targets child images of the field wrapper. And the line of code you quoted inserts markup like "<img src='iconFieldValue' />" into the div for the icon.

Incidentally, you could also write this function to instead modify the style of the icon div to use a particular image for the background-image CSS rule but this seems semantically cleaner to me.