PDA

View Full Version : Tooltip for fieldLabel



spor
28 Jun 2010, 5:51 AM
Was wondering if its possible to make a tooltip for a fieldLabel of a TextField/NumberField.

Condor
28 Jun 2010, 6:03 AM
The easiest method is:

fieldLabel: '<span ext:qtip="Tooltip">Label</span>'

spor
28 Jun 2010, 6:14 AM
Thanks a lot, Condor! Great help as usual!

Animal
28 Jun 2010, 6:51 AM
Or, if you need a bit richer content, automatically applied, to every field in a FormPanel, use a DataTip modified to use the label tag as its delegate:



/**
* @class Ext.ux.DataTip
* @extends Ext.ToolTip.
* <p>This plugin implements automatic tooltip generation for an arbitrary number of child nodes <i>within</i> a Component.</p>
* <p>This plugin is applied to a high level Component, which contains repeating elements, and depending on the host Component type,
* it automatically selects a {@link Ext.ToolTip#delegate delegate} so that it appears when the mouse enters a sub-element.</p>
* <p>When applied to a GridPanel, this ToolTip appears when over a row, and the Record's data is applied
* using this object's {@link Ext.Component#tpl tpl} template.</p>
* <p>When applied to a DataView, this ToolTip appears when over a view node, and the Record's data is applied
* using this object's {@link Ext.Component#tpl tpl} template.</p>
* <p>When applied to a TreePanel, this ToolTip appears when over a tree node, and the Node's {@link Ext.tree.TreeNode#attributes attributes} are applied
* using this object's {@link Ext.Component#tpl tpl} template.</p>
* <p>When applied to a FormPanel, this ToolTip appears when over a Field, and the Field's <code>tooltip</code> property is used is applied
* using this object's {@link Ext.Component#tpl tpl} template, or if it is a string, used as HTML content.</p>
* <p>If more complex logic is needed to determine content, then the {@link Ext.Component#beforeshow beforeshow} event may be used.<p>
* <p>This class also publishes a <b><code>beforeshowtip</code></b> event through its host Component. The <i>host Component</i> fires the
* <b><code>beforeshowtip</code></b> event.
*/
Ext.ux.DataTip = Ext.extend(Ext.ToolTip, (function() {

// Target the body (if the host is a Panel), or, if there is no body, the main Element.
function onHostRender() {
this.dataTip.initTarget(this.body || this.el);
}

function updateTip(tip, data) {
if (tip.rendered) {
tip.update(data);
} else {
if (Ext.isString(data)) {
tip.html = data;
} else {
tip.data = data;
}
}
}

function beforeTreeTipShow(tip) {
var id = Ext.fly(tip.triggerElement).getAttribute('tree-node-id', 'ext'),
node = tip.host.getNodeById(id);
if(node){
updateTip(tip, node.attributes);
}
}

function beforeGridTipShow(tip) {
var rec = this.host.getStore().getAt(this.host.getView().findRowIndex(tip.triggerElement));
if (rec){
updateTip(tip, rec.data);
}
}

function beforeViewTipShow(tip) {
var rec = this.host.getRecord(tip.triggerElement);
if (rec){
updateTip(tip, rec.data);
}
}

function beforeFormTipShow(tip) {
var el = Ext.fly(tip.triggerElement.nextSibling).child('input,textarea'),
field = el ? this.host.getForm().findField(el.id) : null;
if (field && (field.tooltip || tip.tpl)){
updateTip(tip, field.tooltip || field);
} else {
return false;
}
}

return {
constrainPosition: true,

autoRender: true,

init: function(host) {
host.dataTip = this;
this.host = host;
if (host instanceof Ext.tree.TreePanel) {
this.delegate = 'div.x-tree-node-el';
this.on('beforeshow', beforeTreeTipShow);
} else if (host instanceof Ext.grid.GridPanel) {
this.delegate = host.getView().rowSelector;
this.on('beforeshow', beforeGridTipShow);
} else if (host instanceof Ext.DataView) {
this.delegate = host.itemSelector;
this.on('beforeshow', beforeViewTipShow);
} else if (host instanceof Ext.FormPanel) {
this.delegate = 'label.x-form-item-label';
this.on('beforeshow', beforeFormTipShow);
}
host.onRender = host.onRender.createSequence(onHostRender);
},

fireEvent: function(ename) {
var result = Ext.util.Observable.prototype.fireEvent.apply(this, arguments);
if (result !== false) {
arguments[0] = ename + 'tip';
result = Ext.util.Observable.prototype.fireEvent.apply(this.host, arguments);
}
return result;
}
};
})());

spor
29 Jun 2010, 1:18 AM
Thanks for the tip, Animal. Maybe I will try that later. I haven't managed to find example code using that extension yet.

Condor, your example worked well on FF 3.6.6. On IE 8, however, the fieldLabels are misaligned with the textFields. The textFields are shifted 1 line down compared to the fieldLabels. Do you know about this issue?

Condor
29 Jun 2010, 1:29 AM
You could also build it into the form layout itself, e.g.

Ext.override(Ext.layout.FormLayout, {
fieldTpl: (function() {
var t = new Ext.Template(
'<div class="x-form-item {itemCls}" tabIndex="-1">',
'<label for="{id}" style="{labelStyle}" class="x-form-item-label" {labelAttrs}>{label}{labelSeparator}</label>',
'<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
'</div><div class="{clearCls}"></div>',
'</div>'
);
t.disableFormats = true;
return t.compile();
})(),
getTemplateArgs: function(field) {
var noLabelSep = !field.fieldLabel || field.hideLabel;
return {
id : field.id,
label : field.fieldLabel,
labelAttrs : field.fieldLabelTip ? 'ext:qtip=' + Ext.util.Format.htmlEncode(field.fieldLabelTip) + '"' : '',
itemCls : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''),
clearCls : field.clearCls || 'x-form-clear-left',
labelStyle : this.getLabelStyle(field.labelStyle),
elementStyle : this.elementStyle || '',
labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
};
}
});
(and configure your field with a fieldLabelTip)

spor
29 Jun 2010, 2:50 AM
So if I put this code of yours inside my FormPanel extended class, where exactly should those 2 methods be called?

Here is my existing code:


Ext.ns('Arkiv.forms')

Arkiv.forms.Saksform = Ext.extend(Arkiv.forms.Form, {
initComponent: function() {
Ext.apply(this, {

items: [{
id: '1',
xtype: 'fieldset',
layout: 'hbox',
padding: 3,
hideBorders: true,
items: [{
id: '1.1',
xtype: 'fieldset',
layout: 'form',
hideBorders: true,
padding: 2,
flex: 1,
items: [{
id: '1.1.1',
xtype: 'numberfield',
fieldLabel: '<span ext:qtip="Case number">Case no</span>',
name: 'casenumber',
anchor: '100%'

},
...................................

spor
29 Jun 2010, 4:21 AM
Obviously those two methods are called automatically in the initialization of the FormPanel, so just look past my previous post, please...

I tried this in my code:

items: [{
id: '1.1.1',
xtype: 'numberfield',
fieldLabel: 'caseno',
fieldLabelTip: 'Type in your case number',
name: 'casenumber',
anchor: '100%'

}
.............

Is that the correct approach? It didn't work... Do I have to do anything with labelAttrs?

spor
29 Jun 2010, 6:31 AM
I found out why it didn't work... I had deleted the line Ext.QuickTips.init(); from my code.

Now the tooltip works... well, not 100 percent. The fieldLabelTip string gets trimmed to only one word even though there are multipe words. E.g. "case number" will only show up as "case".

spor
29 Jun 2010, 7:05 AM
Now it works perfectly. Found out that you had forgotten a quote character in your code, Condor :)

It should have been
labelAttrs : field.fieldLabelTip ? 'ext:qtip=' + '"' + Ext.util.Format.htmlEncode(field.fieldLabelTip) + '"' : '',

Thanks for the help again.

NoahK17
9 Jun 2011, 11:35 AM
Is this method still valid in 4.x?

mysticav
26 Jan 2012, 12:26 AM
I'm asking the same thing. Can somebody give us a help for Ext 4 ?

rlovelett
9 Oct 2012, 8:58 AM
I'm asking the same thing. Can somebody give us a help for Ext 4 ?

Should work for ExtJS 4.1.x: https://gist.github.com/3860030