Want to display 3 items from ul at a time. And when user clicks to the next arrow each element is traversed and when control reaches to last item i.e 3rd item , next three items should be shown in place of first three items.
The list should not be circular, means after last item in the list there must not be first item.
Have created fiddle but it traversing in circular fashion.
I am traversing list using this,
$("#rightArrow").click(function (e) {
var curr = $("#itemsListBox ul li:last");
curr.parent().prepend(curr);
});
$("#leftArrow").click(function (e) {
var curr = $("#itemsListBox ul li:first");
curr.parent().append(curr);
});
http://jsfiddle.net/N6XrL/
You could simply hide and show the appropriate element instead of appending/prepending:
http://jsfiddle.net/N6XrL/2/
var $elements = $("#itemsListBox ul li");
var count = $elements.length;
var showNum = 3;
var counter = 0;
$("#rightArrow").click(function (e) {
if (counter + showNum < count) {
counter++;
}
display();
});
$("#leftArrow").click(function (e) {
if (counter > 0) {
counter--;
}
display();
});
function display() {
$elements.hide();
$elements.slice(counter, counter + showNum).show();
}
display();
You should keep track of you current picture. like in following code.
var items_count = $("#itemsListBox ul li").length, current_item_counter=0;
$("#rightArrow").click(function(e) {
if(current_item_counter<items_count)
{
var curr = $("#itemsListBox ul li:last");
curr.parent().prepend(curr);
current_item_counter++;
}
});
$("#leftArrow").click(function(e) {
if(current_item_counter> 0)
{
var curr = $("#itemsListBox ul li:first");
curr.parent().append(curr);
current_item_counter--;
}
});
here is jsFiddle.
Related
// .items direct child
var itemsContainer = $('.blog-ticker').children();
// each item in .items
var items = $('.blog-ticker').children().children();
setInterval(function(){
var i = 0;
itemsContainer.css({
'top': -(items[i].clientHeight)+'px'
});
if(i <= items.length) {
i++;
}
}, 2000);
it stops after the first round... confusion sets in. What Should I do?
No it probably doesn't stop after the first round.
The problem is that you are declaring i to 0 each time the function runs, so you are just setting the first item to the same position and it appears to be doing nothing.
You just need to declare i outside of the function and it should work fine:
// .items direct child
var itemsContainer = $('.blog-ticker').children();
// each item in .items
var items = $('.blog-ticker').children().children();
// counter
var i = 0;
setInterval(function(){
itemsContainer.css({
'top': -(items[i].clientHeight)+'px'
});
if(i <= items.length) {
i++;
}
}, 2000);
I have a class which creates mousedown listeners for each LI. However, a click to the LI of the first instance results in events firing for every LI instance which was created after it. If you create a 3rd instance, the click on the 1st instance will result in all 3 firing and a click on the 2nd results in the 2nd and 3rd firing, etc.
To duplicate, run the jsfiddle and click on the two links (one after the other) which will create two UL elements each containing an LI element. Alerts() are set up to show each event firing. If you continue to click on the links, you will see how the events continue to stack.
I'm new to creating classes in javascript, so I've obviously missed something, but can't see why the events for the multiple instances are not separate. In case you're wondering, I've created my class the way I did to allow for static variables and methods. I am not using jQuery.
I've posted a jsfiddle of the below code
UPDATE
Fixed errors due to paring complicated code down for SO. I've updated to reflect multiple LI elements being created in each UL (the number is dynamic and db driven) and the ID's being unique.
<div id="outer">
Click here first id=g123
<br>
Click here second id=g234
</div>
<script>
listbox = (function (id) {
var currentul = "";
var counter = 0;
function listbox(id) {
this.id = id;
};
// show or hide once all the properties are set
listbox.prototype.go = function () {
this.initlistbox();
this.addlisteners();
}
// create the elements for drag and drop between two list boxes
listbox.prototype.initlistbox = function () {
var _this = this;
var divlist = document.createElement('div');
divlist.style.minHeight = '100px';
divlist.style.width = '300px'
divlist.style.outline = '1px solid blue'
// the UL
var ul = document.createElement('ul');
ul.setAttribute('id', 'ulchosen-' + this.id);
// track which UL is active for keystrokes
ul.addEventListener('click', function (e) {
if (e.stopPropagation) e.stopPropagation();
currentul = this.id;
}, false);
// add the ul to the div
divlist.appendChild(ul);
divouter = document.getElementById("outer");
// add the div to the body
divouter.appendChild(divlist);
// The LI
// create LI elements
for (i=0; i < 4; i++){
var li = document.createElement('li');
counter++;
li.setAttribute('id', 'lb-li-chosen-' + counter);
li.innerHTML = "Hello " + counter + " " + this.id;
ul.appendChild(li);
}
};
listbox.prototype.addlisteners = function () {
var _this = this;
var lis = document.querySelectorAll("[id^='lb-li-']");
for (var i = 0; i < lis.length; i++) {
this.setlilisteners(lis[i]);
}
};
listbox.prototype.setlilisteners = function (el) {
var _this = this;
// click is for non drag, non shift / ctrl
el.addEventListener('click', function (e) {
alert("A: " + _this.id);
e.preventDefault();
return false;
}, false);
// mousedown is to select LI elements
el.addEventListener('mousedown', function (e) {
e.stopPropagation();
e.preventDefault();
alert("B: " + _this.id);
return false;
}, false);
};
return listbox;
})();
function edit(id) {
var a = new listbox(id);
a.go();
}
</script>
Each time you use addEventListener a new function is stacked for execution. addEventListener does not removes the older function. So you have to call it just once per element.
The code below will work.
listbox = (function (id) {
var currentul = "";
function listbox(id) {
this.id = id;
};
// show or hide once all the properties are set
listbox.prototype.go = function () {
this.initlistbox();
}
// create the elements for drag and drop between two list boxes
listbox.prototype.initlistbox = function () {
var _this = this;
var divlist = document.createElement('div');
divlist.style.minHeight = '100px';
divlist.style.width = '300px'
divlist.style.outline = '1px solid blue'
// the UL
var ul = document.createElement('ul');
ul.setAttribute('id', 'ulchosen-' + this.id);
// track which UL is active for keystrokes
ul.addEventListener('click', function (e) {
if (e.stopPropagation) e.stopPropagation();
currentul = this.id;
}, false);
// add the ul to the div
divlist.appendChild(ul);
divouter = document.getElementById("outer");
// add the div to the body
divouter.appendChild(divlist);
// The LI
// create LI elements
var li = document.createElement('li');
li.setAttribute('id', 'lb-li-chosen-1');
li.innerHTML = "Hello " + this.id;
ul.appendChild(li);
this.setlilisteners(li);
};
listbox.prototype.setlilisteners = function (el) {
var _this = this;
// click is for non drag, non shift / ctrl
el.addEventListener('click', function (e) {
alert("A: " + _this.id);
e.preventDefault();
return false;
}, false);
// mousedown is to select LI elements
el.addEventListener('mousedown', function (e) {
e.stopPropagation();
e.preventDefault();
alert("B: " + _this.id);
return false;
}, false);
};
return listbox;
})();
function edit(id) {
var a = new listbox(id);
a.go();
}
Gustavo's answer helped me locate the bug. I wasn't filtering the LI elements to only include the current UL, so with each additional instance, a listener for ALL the LI elements were being set again. He was trying to tell me this... So here it is:
listbox.prototype.addlisteners = function () {
var _this = this;
var lis = document.querySelectorAll("[id^='lb-li-']");
for (var i = 0; i < lis.length; i++) {
// THIS IF STATEMENT WAS MISSING
if (lis[i].parentNode.id.indexOf("-" + this.id) !== -1){
this.setlilisteners(lis[i]);
}
}
};
The fiddle is creating multiple LI elements with the same id lb-li-chosen-1 which is invalid HTML. In some browsers I believe it may result in the query selector returning an array of multiple LI elements with result that each time .addListeners is called a new event listener function is added to each LI element defined so far.
Here i have created a image slider kind of thing with 3 images initially, where clicking on pre/next button will replace the prev next image.
I want clicking on prev/next button should completely replace the images with prev/next 3 images(not just one).
var stPt = 0, elToShow = 10; //showing 10 elements
var $ul = $('ul.ice-navigator');
var $li = $('ul.ice-navigator li'); //get the list of li's
var $copy_li = [];
var copy_lgt = $li.length - elToShow;
//call to set thumbnails based on what is set
initNav();
function initNav() {
var tmp;
for (var i = elToShow; i < $li.length; i++) {
tmp = $li.eq(i);
$copy_li.push(tmp.clone());
tmp.remove();
}
}
$('.ice-next').click (function () {
$li = $('ul.ice-navigator li'); //get the list of li's
//move the 1st element clone to the last position in copy_li
$copy_li.splice(copy_lgt, 0, $li.eq(0).clone() ); //array.splice(index,howmany,element1,.....,elementX)
//kill the 1st element in the UL
$li.eq(0).remove();
//add to the last
$ul.append($copy_li.shift());
});
$('.ice-previous').click (function () {
$li = $('ul.ice-navigator li'); //get the list of li's
//move the 1st element clone to the last position in copy_li
$copy_li.splice(0, 0, $li.eq(elToShow-1).clone()); //array.splice(index,howmany,element1,.....,elementX)
//kill the 1st element in the UL
$li.eq(elToShow-1).remove();
//add to the last
$ul.prepend($copy_li.pop());
});
http://jsfiddle.net/devsvits/hV5DA/
How can i do this?
Here is one way of doing it...
You stick your advance code in a function and call it as many times as images you want to advance.
http://jsfiddle.net/hV5DA/1/
$('.ice-next').click (function () {
function nextItem(){
$li = $('ul.ice-navigator li'); //get the list of li's
//move the 1st element clone to the last position in copy_li
$copy_li.splice(copy_lgt, 0, $li.eq(0).clone() ); //array.splice(index,howmany,element1,.....,elementX)
//kill the 1st element in the UL
$li.eq(0).remove();
//add to the last
$ul.append($copy_li.shift());
}
//number of items to replace
var numItemsToAdvance = 3;
//call function n times
while(numItemsToAdvance--){
nextItem();
}
});
I am researching and testing with forms. So far, I succeeded in moving items in select box list up and down one by one with following fiddle.
Instance of code (to move up):
function moveUp() {
$("#list-box option:selected").each(function () {
var listItem = $(this);
var listItemPosition = $("#list-box option").index(listItem) + 1;
if (listItemPosition == 1) return false;
listItem.insertBefore(listItem.prev());
});
}
But now I need to move a selected value, either to be at extreme top in the list or at very bottom. Please try to experiment up with this fiddle and suggest me possible jQuery tree traversal method if it applies.
Thanks in advance!
Use prependTo and appendTo
function moveTop(){
$('#list-box option:selected').prependTo('#list-box');
}
function moveBottom(){
$('#list-box option:selected').appendTo('#list-box');
}
FIDDLE
To move it to the very top:
var listItem = $(this);
listItem.insertBefore(listItem.siblings().first());
To move it to the very bottom:
var listItem = $(this);
listItem.insertBefore(listItem.siblings().last());
http://jsfiddle.net/mblase75/cYw6R/
http://jsfiddle.net/b7Yct/7/
You need to change your insertBefore and insertAfter statement to insert before the first option and after the last option.
function moveUp() {
$("#list-box option:selected").each(function () {
var listItem = $(this);
var listItemPosition = $("#list-box option").index(listItem) + 1;
if (listItemPosition == 1) return false;
listItem.insertBefore($("#list-box option:first"));
});
}
function moveDown() {
var itemsCount = $("#list-box option").length;
$($("#list-box option:selected").get().reverse()).each(function () {
var listItem = $(this);
var listItemPosition = $("#list-box option").index(listItem) + 1;
if (listItemPosition == itemsCount) return false;
listItem.insertAfter($("#list-box option:last"));
});
}
I have a big ul list. With a lot of li items. I want split this big list in parts of 10. I make a script, but the script is not working. What do i wrong:
var maxItems = 10;
var ul = $('.list-thumbnails');
var current;
ul.find('li').each(function(i, el) {
if (i < maxItems) {
// leave first 10 in the original list
return;
}
if (i % maxItems == 0) {
current =
$(el)
.closest('ul')
.clone()
.after($(el).closest('ul'));
}
.append(current);
});
I have modified the code block as below. Please check it
Since your looping the $.each though you use append method it won't get reflected in the ul and so we need to remove the element.
var maxItems = 10;
var ul = $('.list-thumbnails');
var currentul;
var elements = ul.find('li');
elements.each(function (i, el) {
if (i < maxItems) {
// leave first 10 in the original list
return;
}
if (i % maxItems == 0) {
currentul = $("<ul></ul>").addClass("new");
$(el).closest('ul').parent().append((currentul.append(el)));
}
else {
currentul.append(el)
}
});
$('.list-thumbnails').find("li:gt(9)").remove();
Please check the below jsfiddle
http://jsfiddle.net/aQ5K8/13/
Thanks
Sridhar