Ok, this is a bit special. We are using UIkit in our XPages application. We also use the tabs and switcher component (http://getuikit.com/docs/tab.html and http://getuikit.com/docs/switcher.html). They work fine until we do a partial refresh of the page. The reason is that those components are initiliazed only once after the pages is loaded. This happens directly in the lib we bind to the page - no own init script etc. After the refresh I must re-init the whole stuff - but I am not familiar with the syntax or even the possibilities. I searched the UIkit lib though and found something like this:
(function(UI) {
"use strict";
UI.component('tab', {
defaults: {
'target' : '>li:not(.uk-tab-responsive, .uk-disabled)',
'connect' : false,
'active' : 0,
'animation' : false,
'duration' : 200
},
boot: function() {
// init code
UI.ready(function(context) {
UI.$("[data-uk-tab]", context).each(function() {
var tab = UI.$(this);
if (!tab.data("tab")) {
var obj = UI.tab(tab, UI.Utils.options(tab.attr("data-uk-tab")));
}
});
});
},
init: function() {
var $this = this;
this.current = false;
this.on("click.uikit.tab", this.options.target, function(e) {
e.preventDefault();
if ($this.switcher && $this.switcher.animating) {
return;
}
var current = $this.find($this.options.target).not(this);
current.removeClass("uk-active").blur();
$this.trigger("change.uk.tab", [UI.$(this).addClass("uk-active"), $this.current]);
$this.current = UI.$(this);
// Update ARIA
if (!$this.options.connect) {
current.attr('aria-expanded', 'false');
UI.$(this).attr('aria-expanded', 'true');
}
});
if (this.options.connect) {
this.connect = UI.$(this.options.connect);
}
// init responsive tab
this.responsivetab = UI.$('<li class="uk-tab-responsive uk-active"><a></a></li>').append('<div class="uk-dropdown uk-dropdown-small"><ul class="uk-nav uk-nav-dropdown"></ul><div>');
this.responsivetab.dropdown = this.responsivetab.find('.uk-dropdown');
this.responsivetab.lst = this.responsivetab.dropdown.find('ul');
this.responsivetab.caption = this.responsivetab.find('a:first');
if (this.element.hasClass("uk-tab-bottom")) this.responsivetab.dropdown.addClass("uk-dropdown-up");
// handle click
this.responsivetab.lst.on('click.uikit.tab', 'a', function(e) {
e.preventDefault();
e.stopPropagation();
var link = UI.$(this);
$this.element.children('li:not(.uk-tab-responsive)').eq(link.data('index')).trigger('click');
});
this.on('show.uk.switcher change.uk.tab', function(e, tab) {
$this.responsivetab.caption.html(tab.text());
});
this.element.append(this.responsivetab);
// init UIkit components
if (this.options.connect) {
this.switcher = UI.switcher(this.element, {
"toggle" : ">li:not(.uk-tab-responsive)",
"connect" : this.options.connect,
"active" : this.options.active,
"animation" : this.options.animation,
"duration" : this.options.duration
});
}
UI.dropdown(this.responsivetab, {"mode": "click"});
// init
$this.trigger("change.uk.tab", [this.element.find(this.options.target).filter('.uk-active')]);
this.check();
UI.$win.on('resize orientationchange', UI.Utils.debounce(function(){
if ($this.element.is(":visible")) $this.check();
}, 100));
this.on('display.uk.check', function(){
if ($this.element.is(":visible")) $this.check();
});
},
check: function() {
var children = this.element.children('li:not(.uk-tab-responsive)').removeClass('uk-hidden');
if (!children.length) return;
var top = (children.eq(0).offset().top + Math.ceil(children.eq(0).height()/2)),
doresponsive = false,
item, link;
this.responsivetab.lst.empty();
children.each(function(){
if (UI.$(this).offset().top > top) {
doresponsive = true;
}
});
if (doresponsive) {
for (var i = 0; i < children.length; i++) {
item = UI.$(children.eq(i));
link = item.find('a');
if (item.css('float') != 'none' && !item.attr('uk-dropdown')) {
item.addClass('uk-hidden');
if (!item.hasClass('uk-disabled')) {
this.responsivetab.lst.append('<li><a href="'+link.attr('href')+'" data-index="'+i+'">'+link.html()+'</a></li>');
}
}
}
}
this.responsivetab[this.responsivetab.lst.children('li').length ? 'removeClass':'addClass']('uk-hidden');
}
});
})(UIkit);
Similar code is created for the connected switcher component.
You can see a demo of my problem here: http://notesx.net/customrenderer.nsf/demo.xsp
Source code here: https://github.com/zeromancer1972/CustomRendererDemo/blob/master/ODP/XPages/demo.xsp
As this is part of the library itself I'd like to find a way to call this from outside the library.
Any ideas are highly appreciated!
Newer versions of uikit have an init method, upgrade and call it from the onComplete event of the combo box.
<xp:comboBox
id="comboBox1">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:return ["value 1", "value 2"];}]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler
event="onchange"
submit="true"
refreshMode="partial"
refreshId="page"
onComplete="$.UIkit.init();">
</xp:eventHandler>
</xp:comboBox>