Пример создания универсального popup виджета (тултипа) на примере раскрытия текста в dojox.grid.
В предыдущем примере был создан виджет для скрытия излишнего текста в гриде.
Но, при его использовании высота строк в таблице не менялась, это не удобно и не всегда работает корректно в данном случае, возможен второй способ реализации, в тултипе показываемом поверх текста.
Реализация универсального попапа:
dojo.provide("dojoi.tools.popupSlicer");
dojo.require('dijit._base.popup');
dojo.require('dijit.layout.ContentPane');
dojo.declare("dojoi.tools.popupSlicer", [dijit._Widget,dijit._Templated] ,{
originalValue: '',
slicedValue: '',
tuggle: false,
parent: null,
id: null,
templateString: ""+
"[+]"+
""
+"",
indicatorCont: function(e){
dojo.stopEvent(e);
if (!this.tuggle){
this.tuggle = true;
// временный div с оригинальным текстом
var tempNode = dojo.create('div',{innerHTML:this.originalValue,style:{}},dojo.body(),'last');
// вручную генерируем уникальный ID для виджета
var tempWidgetId = dijit.getUniqueId('dijit.layout.ContentPane');
// временный простейший виджет, необходим для popup
var tempWidget = dojo.parser.instantiate([tempNode], {
dojoType: "dijit.layout.ContentPane",
id: tempWidgetId
});
tempWidget = tempWidget[0];
this.id = tempWidgetId;
// оформляем внешний вид виджета
dojo.style(tempNode, {
// ширина попапа вычисляется исходя из размеров
// parentNode + 20px
'width': dojo.style(this.wrapper.parentNode,'width')+20+'px',
'backgroundColor': 'white',
'border': '1px solid grey',
'padding': '4px'
});
var id = this.id;
// открываем попап
var popup = dijit.popup.open({
// для его создания необходимо передавать сущность виджета
// который мы предварительно создали
'popup': tempWidget,
around: this.wrapper.parentNode,
orient: {TL:'TL', BL:'TL'},
onClose: function(){
// при закрытии попапа уничтожаем временный виджет с его
// html представлением
dijit.byId(id).destroy();
}
});
// соединяем события потери фокуса с закрытием
dojo.connect(tempWidget, 'onBlur', this, 'close');
dijit.focus(tempWidget.domNode);
} else {
this.close();
}
},
constructor: function(v){
this.originalValue = v.value;
this.parent = v.parent;
this.slicedValue = v.value.slice(0,100);
},
close: function(){
// при закрытии необходимо вернуть индикатор в исходное положение
this.indicator.innerHTML = '[+]';
this.tuggle = false;
dijit.popup.close(dijit.byId(this.id));
},
postCreate: function(){
this.pain.innerHTML = this.slicedValue+'[...]';
}
});
Использование вместе с dojox.grid описано тут.
Давайте разберем, что вышло.
Идея виджета та же, при инициализации, в constructor’е сохраняем оригинальное значение и создаем короткое.
Но на этот раз, алгоритм события при клике на «+» другой.
Для открытия dijit.popup одним из аргументов необходимо передать виджет, который будет его телом, для этого в tempNode сохраняем временный, созданный div, который содержит оригинальный текст.
Генерируем уникальный widgetId – tempWidgetId.
Создаем временный виджет – tempWidget с ID tempWidgetId.
Открываем с помощью dijit.popup тултип.
Достаточно важным момент является закрытие виджета. В предыдущем примере мы это делали нажатием на «-», теперь это невозможно. Связываем события потери фокуса виджета с функцией его закрытия и устанавливаем фокус на временный виджет.
dojo.connect(tempWidget, 'onBlur', this, 'close'); dijit.focus(tempWidget.domNode);
Этот виджет вышел довольно универсальным.
Единственным его «тонким» местом является динамическая ширина, предполагаю, что иногда нужно будет ее задавать вручную.
Планирую в ближайшее время сделать открытый репозиторий описанных в статьях виджетов.

