move a div from one li to another - javascript

I am trying to sort from two li. If i will delete any div it will be sort by asc.
The fiddle is
i am using jquery append to to move div.
please take a look in my delete function
function del_slide(no,sdiv)
{
$('.s'+no).remove();
if(sdiv==1)
{
alert("first");
$($('.bxslider .btm-slides').last()).appendTo(".bs1");
}
else if($('.bxslider .btm-slides').last())
{
alert("last");
$($('.bxslider .btm-slides').last()).appendTo(".bs1");
}
}
If i am deleting any item !. Then divs are not in order.
How to do all the items in ascending order? I can't do this sort. Please help me.
I need to put first li full. If i will delete any div from first li then one of 2nd li's div should move to the first div. If i will delete from last li the div will be on the same position.
If i will delete any div then last li will blank. But first li will contain 3 div.If I will delete a div from first li then one div from second li will come to first one.

Did you want something that works like this?
JSFiddle: http://jsfiddle.net/TrueBlueAussie/H6PY6/3/
I removed all the unnecessary classes and links and inline javascript as you can connect it all with jQuery and work out the positions via jQuery DOM traversing.
$(function () {
$(".bxslider").on('click', '.editText', function (e) {
// Stop click of link
event.preventDefault();
// Edit code goes here
}).on('click', '.delSlide', function (e) {
// Stop click of link
event.preventDefault();
var $this = $(this);
// Find current slide we clicked
var $slide = $this.closest('.btm-slides');
// Get parent of slide
var $parent = $slide.closest(".bottom-slides");
// if parent li is the first li
if ($parent.closest('li').index() == 0)
{
// Move up one slide from the last li
var $from = $parent.closest(".bxslider").children().last();
// Move up one item from second section
$parent.append($from.find('.btm-slides:first'));
}
// Empty the contents of the deleted slide
$slide.html('');
});
});

Related

jQuery hiding child element opens its child

Im using a table and rows can have child rows and it can go down a few levels,
what is happening now is that when hiding a child element it then opens that childs child element.
Heres my jQuery:
$(document).ready(function() {
function getChildren($row) {
var children = [], level = $row.attr('data-level');
while($row.next().attr('data-level') > level) {
children.push($row.next());
$row = $row.next();
}
return children;
}
$('.parent').on('click', function() {
var children = getChildren($(this));
$.each(children, function() {
$(this).toggle();
})
});
$(".parent a").click(function(e) {
e.stopPropagation();
})
})
I have set up a jsfiddle so you can see whats happening
https://jsfiddle.net/rhvye8k0/4/
If you click the first "+" you will see what im trying to describe.
Cant think how to sort it out
Update,
have sorted it and updated jsfiddle https://jsfiddle.net/rhvye8k0/5/
There may be a way to reduce the jQuery but it works for now
Your problem is the $(this).toggle(); in .parent's onclick handler. The tr at level 3 has style="display:none", the others don't. toggle() will toggle the receiving element(s) visibility so the others are show (their display is implicitly block) and level 3's is hidden.

jQuery Accordion | Open first element on pageload & active state confusion

I am using the Javascript below to animate an accordion (it's a slightly modified variant of the one explained here: http://tympanus.net/codrops/2010/04/26/elegant-accordion-with-jquery-and-css3/.
Now I wanted to have the first element to be open on pageload, so I figured I just give it some sort of extra-class via Javascript (and define that .active state via CSS) to have it open up.
This worked, however if I hover over any but the first-element with said .active class, the first element keeps its state, and stays open until I hover over it at least once.
So, what I want is: the first element of my accordion is open and collapses if the user hovers over any of the elements that are not the first. I think I need to add a line in the hover function to either take the class away of the first element or to give the new element the active state, but I don't know how to do it and keep breaking the thing.
<script type="text/javascript">
jQuery(function() {
activeItem = jQuery("#accordion li:first");
jQuery(activeItem).addClass('active');
jQuery('#accordion > li, #accordion > li.heading').hover(
function () {
var jQuerythis = jQuery(this);
jQuerythis.stop().animate({'height':'280px'},500);
jQuery('.heading',jQuerythis).stop(true,true).fadeOut();
jQuery('.bgDescription',jQuerythis).stop(true,true).slideDown(500);
jQuery('.description',jQuerythis).stop(true,true).fadeIn();
},
function () {
var jQuerythis = jQuery(this);
jQuerythis.stop().animate({'height':'40px'},1000);
jQuery('.heading',jQuerythis).stop(true,true).fadeIn();
jQuery('.description',jQuerythis).stop(true,true).fadeOut(500);
jQuery('.bgDescription',jQuerythis).stop(true,true).slideUp(700);
}
);
});
</script>
Looks like this is happening because each accordion item has its own hover event that takes care of its own animation. You can refactor the code slightly to make this easier to understand and reuse:
var activeItem = jQuery("#accordion li:first");
jQuery('#accordion > li, #accordion > li.heading').hover(
function () { hoverMe(jQuery(this)); },
function () { unhoverMe(jQuery(this)); }
);
//This gets called when cursor hovers over any accordion item
var hoverMe = function(jQuerythis) {
//If the first item is still active
if (activeItem) {
contract(activeItem); //...Shrink it!
activeItem = false;
}
//Expand the accordion item
expand(jQuerythis);
};
//This gets called when cursor moves out of accordion item
var unhoverMe = function(jQuerythis) {
contract(jQuerythis);
};
//I have moved the hover animation out into a separate function, so we can call it on page load
var expand = function(jQuerythis) {
jQuerythis.stop().animate({'height':'280px'},500);
jQuery('.heading',jQuerythis).stop(true,true).fadeOut();
jQuery('.bgDescription',jQuerythis).stop(true,true).slideDown(500);
jQuery('.description',jQuerythis).stop(true,true).fadeIn();
};
//I have moved the unhover animation out into a separate function, so we can contract the first active item from hoverMe()
var contract = function() {
jQuerythis.stop().animate({'height':'40px'},1000);
jQuery('.heading',jQuerythis).stop(true,true).fadeIn();
jQuery('.description',jQuerythis).stop(true,true).fadeOut(500);
jQuery('.bgDescription',jQuerythis).stop(true,true).slideUp(700);
};
//Now expand the first item
expand(activeItem);
I have put together a simplified version demonstrating the logic. Please let me know how you get on.

Checking if Element hasClass then prepend and Element

What I am trying to achieve here is when a user clicks an element it becomes hidden, once this happens I want to prepend inside the containing element another Element to make all these items visible again.
var checkIfleft = $('#left .module'),checkIfright = $('#right .module');
if(checkIfleft.hasClass('hidden')) {
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if(checkIfright.hasClass('hidden')) {
right.prepend('<span class="resetRight">Reset Right</span>');
}
I tried multiple ways, and honestly I believe .length ==1 would be my best bet, because I only want one element to be prepended. I believe the above JS I have will prepend a new element each time a new item is hidden if it worked.
Other Try:
var checkIfleft = $('#left .module').hasClass('hidden'),
checkIfright = $('#right .module').hasClass('hidden');
if(checkIfleft.length== 1) {
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if(checkIfright.length== 1) {
right.prepend('<span class="resetRight">Reset Right</span>');
}
else if(checkIfleft.length==0){
$('.resetLeft').remove()
} else if (checkIfright.length==0){
$('.resetRight').remove()
}
Basically if one element inside the container is hidden I want a reset button to appear, if not remove that reset button...
hasClass() only works on the first item in the collection so it isn't doing what you want. It won't tell you if any item has that class.
You can do something like this instead where you count how many hidden items there are and if there are 1 or more and there isn't already a reset button, then you add the reset button. If there are no hidden items and there is a reset button, you remove it:
function checkResetButtons() {
var resetLeft = $('#left .resetLeft').length === 0;
var resetRight = $('#left .resetRight').length === 0;
var leftHidden = $('#left .module .hidden').length !== 0;
var rightHidden = $('#right .module .hidden').length !== 0;
if (leftHidden && !resetLeft) {
// make sure a button is added if needed and not already present
$('#left').prepend('<span class="resetLeft">Reset Left</span>');
} else if (!leftHidden) {
// make sure button is removed if no hidden items
// if no button exists, this just does nothing
$('#left .resetLeft').remove();
}
if (rightHidden && !resetRight) {
$('#right').prepend('<span class="resetRight">Reset Right</span>');
} else if (!rightHidden) {
$('#right .resetRight').remove();
}
}
// event handlers for the reset buttons
// uses delegated event handling so it will work even though the reset buttons
// are deleted and recreated
$("#left").on("click", ".resetLeft", function() {
$("#left .hidden").removeClass("hidden");
$("#left .resetLeft").remove();
});
$("#right").on("click", ".resetRight", function() {
$("#right .hidden").removeClass("hidden");
$("#right .resetRight").remove();
});
FYI, if we could change the HTML to use more common classes, the separate code for left and right could be combined into one piece of common code.
Add the reset button when hiding the .module, if it's not already there :
$('#left .module').on('click', function() {
$(this).addClass('hidden');
var parent = $(this).closest('#left');
if ( ! parent.find('.resetLeft') ) {
var res = $('<span />', {'class': 'resetLeft', text : 'Reset Left'});
parent.append(res);
res.one('click', function() {
$(this).closest('#left').find('.module').show();
$(this).remove();
});
}
});
repeat for right side !
I've recently experimented with using CSS to do some of this stuff and I feel that it works quite well if you're not trying to animate it. Here is a jsfiddle where I can hide a module and show the reset button in one go by adding/removing a 'hideLeft' or 'hideRight' class to the common parent of the two modules.
It works by hiding both reset button divs at first. Then it uses .hideLeft #left { display:none;} and .hideLeft #right .resetLeft { display: block; } to hide the left module and display the reset button when .hideLeft has been added to whichever element both elements descend from. I was inspired by modernizr a while back and thought it was a neat alternative way to do things. Let me know what you think, if you find it helpful, and if you have any questions :)

Collapsible menu javascript problem

I am struggling with a collapsible vertical menu. The first part of the script below works, so that the upper UL display its sibling LIs, while the other ULs keep their sibling LIs hidden.
My difficult task (to me at least) is to make the parent UL to the active link keep its sibling LIs visible. This is what I tried in the lower part of the script.
My a-links some times get a trailing hash (#) which I want to remove in order to compare i to the active URL. This is done through the trimHash(string)-function--which works when tested on a simple string, but not in this script.
Any good advice out there?
$(document).ready(function() {
// Collapse everything but the first menu:
$(".mainmenu > li > a").not(":first").find("+ ul").slideUp(1);
// Expand or collapse:
$(".mainmenu > li > a").click(function() {
$(this).find("+ ul").slideToggle("fast");
});
$(".mainmenu li").each(function () {
var li = $(this);
var a = rtrimHash(li[0].firstChild);
if (a.href == location.href) {
$(this).find("+ ul").slideDown(1);
}
});
I ended up with this solution. As it is a Wordpress site, while stepping through the menu items in the menu I could check if each link is active by comparing the link to the active post, and insert the class "current" to these menu items:
echo '<li class="child';
if ( $menuPost->ID == $post->ID ) { echo ' current'; }
And then use jQuery to find all instances of the li "current" class, and trigger the parent ul's to slideDown:
$(document).ready(function() {
// Collapse everything:
$("li.cat").find("+ ul").slideUp(1);
// Collapse everything but the first menu:
//$("li.cat").not(":first").find("+ ul").slideUp(1);
// Expand or collapse:
$("li.cat").click(function() {
$(this).find("+ ul").slideToggle("fast");
});
$("li.current").parent().slideDown(1);
});
Sorry I didn't solve this through javascript as I intended, but I achieved what I wanted.

javascript set element background color

i have a little javascript function that does something when one clicks on the element having onclick that function.
my problem is:
i want that, into this function, to set a font color fot the html element having this function onclick. but i don't suceed. my code:
<script type="text/javascript">
function selecteazaElement(id,stock){
document.addtobasket.idOfSelectedItem.value=id;
var number23=document.addtobasket.number;
number23.options.length=0;
if (stock>=6) stock=6;
for (i=1;i<=stock;i++){
//alert ('id: '+id+'; stock: '+stock);
number23.options[number23.options.length]=new Option(i, i);
}
}
</script>
and how i use it:
<li id = "product_types">
<a href="#" onclick='selecteazaElement(<?= $type->id; ?>,<?= $type->stock_2; ?>);'><?= $type->label; ?></a>
</li>
any suggestions? thanks!
i have added another function (jquery one) that does partially what i need. the new problem is: i want that background color to be set only on the last clicked item, not on all items that i click. code above:
$(document).ready(function() {
$('.product_types > li').click(function() {
$(this)
.css('background-color','#EE178C')
.siblings()
.css('background-color','#ffffff');
});
});
any ideas why?
thanks!
I would suggest
$(document).ready(function() {
$('.product_types > li').click(function() {
$('.product_types > li').css('background-color','#FFFFFF');
$(this).css('background-color','#EE178C');
});
});
Your element could have this code:
<li id = "product_types" onclick="selecteazaElement(this);" <...> </li>
To change the foreground color of that element:
function selecteazaElement(element)
{
element.style.foregroundColor="#SOMECOLOR";
}
If you want to change the background color on only the last element clicked, each element must have a different id. I'd suggest naming each one something like product_types1, product_types2, ..., product_typesN, and so on. Then have a reset function:
function Reset()
{
for (var i = 1; i <= N; i = i + 1)
{
document.getElementById('product_types'+i).style.backgroundColor="#RESETCOLOR";
}
}
When you call your selecteazaElement(this) function, first call the Reset function, then set the new element:
function selecteazaElement(element)
{
Reset();
element.style.backgroundColor="#SOMECOLOR";
}
This way all of the elements that start with product_types followed by a number will be reset to one particular color, and only the element clicked on will have the background changed.
The 'scope' of the function when invoked is the element clicked, so you should be able to just do:
function selecteazaElement(id,stock){
document.addtobasket.idOfSelectedItem.value=id;
var number23 = document.addtobasket.number;
number23.options.length=0;
if (stock>=6){
stock=6;
}
for (var i=1;i<=stock;i++){
//alert ('id: '+id+'; stock: '+stock);
number23.options[number23.options.length]=new Option(i, i);
}
// Alter 'this', which is the clicked element in this case
this.style.backgroundColor = '#000';
}
$(function() {
/*if product_types is a class of element ul the code below
will work otherwise use $('li.product_types') if it's a
class of li elements */
$('.product_types li').click(function() {
//remove this class that causes background change from any other sibling
$('.altBackground').removeClass('altBackground');
//add this class to the clicked element to change background, color etc...
$(this).addClass('altBackground');
});
});
Have your css something like this:
<style type='text/css'>
.altBackground {
background-color:#EE178C;
/* color: your color ;
foo: bar */
}
</style>
Attach a jQuery click event to '#product_types a' that removes a class from the parent of all elements that match that selector; then, add the class that contains the styles you want back to the parent of the element that was just clicked. It's a little heavy handed and can be made more efficient but it works.
I've made an example in jsFiddle: http://jsfiddle.net/jszpila/f6FDF/
try this instead:
//ON PAGE LOAD
$(document).ready(function() {
//SELECT ALL OF THE LIST ITEMS
$('.product_types > li').each(function () {
//FOR EACH OF THE LIST ITEMS BIND A CLICK EVENT
$(this).click(function() {
//GRAB THE CURRENT LIST ITEM, CHANGE IT BG, RESET THE REST
$(this)
.css('background-color','#EE178C')
.siblings()
.css('background-color','transparent');
});
});
});
If I am correct, the problem is that the click event is being binded to all of the list items (li). when one list item is clicked the event is fired on all of the list items.
I added a simple .each() to your code. It will loop through each of the list items and bind a event to each separately.
Cheers,
-Robert Hurst

Categories

Resources