Help for Slideshow
Push
To get started, you could check out this thread: http://www.zkoss.org/forum/listComment/18466-Wanted-Sliding-container.
Thanks Richard,
first try runs. I will have a look on it.
thanks
Stephan
Hmmmm, it runs locally but not on the web server. On the web server the page where the slideshow is in will not load full. The 'processing' message stays still.
regards
Stephan
I think the endless processing message indicates that the path the .js file is not correct. Have a check on that...
Yeah, thanks Richard. 'easyslider1.7.js' in Windows is not 'easySlider1.7.js' in Linux
Two things are not solved.
1. All Images are showing a little piece of an other image at the left side. (Images are scaled/stored as 400x230px jpg's )
var w = 400;//$("li", obj).width();
var h = 250;//$("li", obj).height();
2. after login and come back to this side the controller generated stuff for the table statistics are not showed in the Chrome Browser.
2.1 In IE the table statistic stuff is not rendered.
http://www.zk-web.de/zksample2/index.zul
any idea
best Stephan
. . . <cell width="50%" style="padding: 0px;" hflex="1"> <include src="/test/slider4.zul"></include> </cell> </hbox> </div> </north> <center id="bl_center" border="none" style="background-color: #EBEBEB" flex="true" ></center> <south id="bl_south" border="none" style="background-color: #EBEBEB" height="32px" ></south> </borderlayout>
slider4.zul
<!-- http://www.zkoss.org/forum/listComment/18466-Wanted-Sliding-container -->
<zk xmlns:c="client">
<script type="text/javascript"
src="js/easyslider1.7/js/easySlider1.7.js">
</script>
<script type="text/javascript">
zk.afterMount(function() { jq("$slider").easySlider({ auto:
true, continuous: true, numeric: true }); });
</script>
<style src="js/easyslider1.7/css/screen.css" ></style>
<div id="slider">
<n:ul xmlns:n="native">
<n:li>
<image
src="/images/slider/zksample2_dashboard_400x230.jpg" ></image>
</n:li>
<n:li>
<image
src="/images/slider/zksample2_loginslog_400x230.jpg" ></image>
</n:li>
<n:li>
<image
src="/images/slider/zksample2_calendar_400x230.jpg" ></image>
</n:li>
<n:li>
<image src="/images/slider/zksampl2_chart_400x230.jpg" ></image>
</n:li>
<n:li>
<image
src="/images/slider/zksample2_many_modal_windows_400x230.jpg" ></image>
</n:li>
</n:ul>
</div>
</zk>
Yes, the little piece of image annoyed me for a while too. In the end, I just hard coded the margin-left to -40, but the images aren't in the same order as in the zul file (that's easily configurable, though, and at least it works and displays properly). If you find a better solution, please let me know. I also added in a mouseover/out functionality to stop and start the slider. Here's the .js file:
(function($) {
$.fn.easySlider = function(options){
// default configuration properties
var defaults = {
prevId: 'prevBtn',
prevText: 'Previous',
nextId: 'nextBtn',
nextText: 'Next',
controlsShow: true,
controlsBefore: '',
controlsAfter: '',
controlsFade: true,
firstId: 'firstBtn',
firstText: 'First',
firstShow: false,
lastId: 'lastBtn',
lastText: 'Last',
lastShow: false,
vertical: false,
speed: 400,
auto: false,
pause: 6000,//6 seconds
continuous: false,
numeric: false,
numericId: 'controls'
};
var options = $.extend(defaults, options);
this.each(function() {
var obj = $(this);
var s = $("li", obj).length;
var w = 500;//$("li", obj).width();
var h = 241;//$("li", obj).height();
var clickable = true;
obj.width(w);
obj.height(h);
obj.css("overflow","hidden");
var ts = s-1;
var t = 0;
$("ul", obj).css('width',s*w);
if(options.continuous){
$("ul", obj).prepend($("ul li:last-child", obj).clone().css("margin-left","-40px"));
$("ul", obj).append($("ul li:nth-child(2)", obj).clone());
$("ul", obj).css('width',(s+1)*w);
};
if(!options.vertical) $("li", obj).css('float','left');
if(options.controlsShow){
var html = options.controlsBefore;
if(options.numeric){
html += '<ol id="'+ options.numericId +'"></ol>';
} else {
if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
html += ' <span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span>';
if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';
};
html += options.controlsAfter;
$(obj).after(html);
};
if(options.numeric){
for(var i=0;i<s;i++){
$(document.createElement("li"))
.attr('id',options.numericId + (i+1))
.html('<a rel='+ i +' href=\"javascript:void(0);\">'+ (i+1) +'</a>')
.appendTo($("#"+ options.numericId))
.click(function(){
animate($("a",$(this)).attr('rel'),true);
});
};
} else {
$("a","#"+options.nextId).click(function(){
animate("next",true);
});
$("a","#"+options.prevId).click(function(){
animate("prev",true);
});
$("a","#"+options.firstId).click(function(){
animate("first",true);
});
$("a","#"+options.lastId).click(function(){
animate("last",true);
});
};
function setCurrent(i){
i = parseInt(i)+1;
$("li", "#" + options.numericId).removeClass("current");
$("li#" + options.numericId + i).addClass("current");
};
function adjust(){
if(t>ts) t=0;
if(t<0) t=ts;
if(!options.vertical) {
$("ul",obj).css("margin-left",(t*w*-1));
} else {
$("ul",obj).css("margin-left",(t*h*-1));
}
clickable = true;
if(options.numeric) setCurrent(t);
};
jq("$slider").mouseenter(function(){
animate("stop",true);
});
jq("$slider").mouseleave(function(){
animate("next",true);
});
function animate(dir,clicked){
if (clickable){
clickable = false;
var ot = t;
switch(dir){
case "next":
t = (ot>=ts) ? (options.continuous ? t+1 : ts) : t+1;
break;
case "prev":
t = (t<=0) ? (options.continuous ? t-1 : 0) : t-1;
break;
case "first":
t = 0;
break;
case "last":
t = ts;
break;
case "stop":
t = t;
break;
default:
t = dir;
break;
};
var diff = Math.abs(ot-t);
var speed = diff*options.speed;
if(!options.vertical) {
p = (t*w*-1);
$("ul",obj).animate(
{
marginLeft: p
},
{
queue:false,
duration:speed,
complete:adjust
}
);
} else {
p = (t*h*-1);
$("ul",obj).animate(
{
marginTop: p
},
{
queue:false,
duration:speed,
complete:adjust
}
);
};
if(!options.continuous && options.controlsFade){
if(t==ts){
$("a","#"+options.nextId).hide();
$("a","#"+options.lastId).hide();
} else {
$("a","#"+options.nextId).show();
$("a","#"+options.lastId).show();
};
if(t==0){
$("a","#"+options.prevId).hide();
$("a","#"+options.firstId).hide();
} else {
$("a","#"+options.prevId).show();
$("a","#"+options.firstId).show();
};
};
if(clicked) clearTimeout(timeout);
if(options.auto && dir=="next" && !clicked){
;
timeout = setTimeout(function(){
animate("next",false);
},diff*options.speed+options.pause);
};
};
};
// init
var timeout;
if(options.auto){
;
timeout = setTimeout(function(){
animate("next",false);
},options.pause);
};
if(options.numeric) setCurrent(0);
if(!options.continuous && options.controlsFade){
$("a","#"+options.prevId).hide();
$("a","#"+options.firstId).hide();
};
});
};
})(jQuery);Yes Richard,
many thanks. In Chrome browser it's now OK with this left side piece of the image.
But now it's in IE browser on the right side the same as before in Chrome :-)
I will have a deep Google search on weekend for an other solution. :-)
thanks
Stephan
Got it! Put this styling in the ul element:
<n:ul style="padding:0;margin:0">
Disregard my last post - replace the .js file with the original keeping the hard-coded width and height:
var w = 500;//$("li", obj).width();
var h = 241;//$("li", obj).height(); And it should work fine in all browsers.
Got it too :-)
Many many thanks Richard. You save my day.
If i put the slider.zul as an Include component in a Panel/PanelChildren combination it renders now correctly after come back to this side.
<panel height="231px"> <panelchildren style="background-color: #EBEBEB"> <include src="/test/slider4.zul" ></include> </panelchildren> </panel>
Tested in Chrome, IE and Firefox.
thanks
Stephan
Hi
This is my implementation, use only three image components
because I do not want to load all images (in baoqiao's case, as many as 600) at once,
use jquery without easyslider because I do not know how to execute a function after each slide with easyslider
TestComposer.java
package j3m116ad$v1;
import java.util.*;import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.*;public class TestComposer extends GenericForwardComposer {
Image imgOne;
Image imgTwo;
Image imgThree;
Intbox interval;
Button start;
Button stop;
List<String> contentList = null;
int length;
int index = 0;public void doAfterCompose (Component comp) throws Exception {
super.doAfterCompose(comp);
// init first part image
imgOne.setSrc(getSrc());
imgTwo.setSrc(getSrc());
imgThree.setSrc(getSrc());
Clients.evalJavaScript("setContent('"+getContentString()+"')");
}
public void onClick$start () {
int delay = interval.getValue();
String command = "startSlideShow(" + delay*1000 + ")";
System.out.println(command);
Clients.evalJavaScript(command);
}
public void onClick$stop () {
String command = "stopSlideShow()";
Clients.evalJavaScript(command);
}
private String getContentString() {
StringBuilder sb = new StringBuilder();
List l = getContentList();
for (int i = 0; i < l.size(); i++) {
if (i > 0)
sb.append(",");
sb.append(l.get(i));
}
return sb.toString();
}
private List<String> getContentList () {
if (contentList == null) {
// modify here for dynamic assign images
contentList = new ArrayList<String>();
for (int i = 0; i < 1000; i++)
contentList.add("img/my_draw_"+i+".png");
}
length = contentList.size();
return contentList;
}
private String getSrc () {
String src = getContentList().get(index);
index = (index+1) % length;
return src;
}
}
index.zul
<zk>
<style>
.the-slider {
width: 420px;
height: 310px;
overflow: hidden;
}
.the-slider div {
width: 1500px;
}
.the-slider div img {
margin: 5px 10px;
width: 400px;
height: 300px;
}
</style>
<script type="text/javascript"><![CDATA[
var contentList = [],
contentLength,
index = 3,
frameWidth = 420,
animateTime = 500,
slideShow;
function setContent (content) {
contentList = content.split(',');
contentLength = contentList.length
}
function startSlideShow (delay) {
var $slider = jq('$slider'),
$container = jq('$container');
slideShow = setInterval (function () {
$slider.animate({'scrollLeft': '+='+frameWidth+'px'}, animateTime, null, function (){
var firstImage = $container.find('img')[0];
// change the src of first image after slide
firstImage.src = contentList[index];
// update index
index = (index+1) % contentLength;// move the first image to the last
$container[0].appendChild(firstImage);
// reset the scrollLeft of slider
$slider[0].scrollLeft = 0;
});
}, delay);
}
function stopSlideShow () {
clearInterval (slideShow);
}
]]></script>
<div apply="j3m116ad$v1.TestComposer">
<div id="slider" class="the-slider">
<div id="container">
<image id="imgOne" />
<image id="imgTwo" />
<image id="imgThree" />
</div>
</div>
delay: <intbox id="interval" /> seconds
<button id="start" label="start" />
<button id="stop" label="stop" />
</div>
</zk>
Regards,
ben
Hi Ben,
Thanks for your example. You said, "I do not know how to execute a function after each slide with easyslider". Actually, all the functionality is already encapsulated in easyslider, so you don't need any extra code. I know there are lots of threads about having a ZK component like this and I think it would be a good candidate to make into a ZK component, i.e.
<slider interval="6000" speed="400">
<image src="images/myimg1.png"/>
<image src="images/myimg1.png"/>
<image src="images/myimg1.png"/>
</slider>Download and demos: http://cssglobe.com/post/5780/easy-slider-17-numeric-navigation-jquery-slider
Hi RichardL,
I need do something after each slide because
I want change the src of the image element which just slide out
so I can load most of the images later in stead of load all images at the begining.
It will like the fragment below:
function afterSlide (slidedImage) {
slidedImage.src = getNewSrc();
}
I think this will save the page loading time and the bandwidth (if users usually do not view all images)
Best Regards,
ben
Oh, I see what you mean about loading on demand if you have a large cache of images. For this case, this is how it can be done with easyslider. With the following in zul (the first image is preloaded from the cache):
<div id="slider">
<n:ul xmlns:n="native" style="padding:0;margin:0;list-style-type: none;">
<n:li>
<n:a href="#">
<n:image class="img1" src="images/slider/01.jpg"></n:image>
</n:a>
</n:li>
<n:li>
<n:a href="#">
<n:image class="img2" src=""></n:image>
</n:a>
</n:li>
</n:ul>
</div>In the .js animate function, put this line (assuming "win is the id of the space owner):
zAu.send(new zk.Event(zk.Widget.$(jq('$win')[0]), 'onSlide', t,{toServer:true})); Then, in your controller:
If you have the following cache (could be from db):
String[] imgs = new String[]{"images/slider/02.jpg","images/slider/03.jpg","images/slider/04.jpg","images/slider/05.jpg"};And index:
int index = 0;
And the following event listener (the data is just the index of the current image - either 0 or 1):
public void onSlide(Event event) throws InterruptedException, Exception {
if(index == imgs.length){
index = 0;
}
String imgClass = "";
if ((Integer)event.getData() % 2 != 0) {//odd
imgClass = "img1";
}else{
imgClass = "img2";
}
Clients.evalJavaScript("jq('."+imgClass+"').attr(\"src\", \""+imgs+"\");");
index++;
}The reason why I chose the class jquery selector is because easyslider adds another image element for each image, so the id selector can't be used.
Hope this helps,
Richard
Oh, I got it,
there is also animate function (and $.animate in it) in easySlider.
Yes. After thinking more, if anyone wants to apply load on demand with next/previous functionality, it would be better to make a seperate AU request in both the "next" (sending "onNextSlide" event) and "previous" (sending "onPreviousSlide" event) switch statement cases in the animate function with corresponding listeners in the composer.
ZK - Open Source Ajax Java Framework
(Please disregard)
I am asking for help in making a slideshow. This slideshow should have start/stop buttons, and better to have an option for setting up playing interval. There will be as many as 600 images to show. These images will be dynamically generated/converted from other engineering files, and generated pictures will remain as cache for replaying, but the server side cache will be cleared when the session is closed.
I really have no idea about this. Maybe you can point me out which way to go. Thanks in advance.