Add new item to bottom of scrollabe div - javascript

I'm trying to append a div to the bottom of a another div, by clicking a button in javascript, but once the height of the outer container is reached, it no longer scrolls the list to the bottom, after an insert.
Please see the fiddle here
If you click the red add button until you get to about 13 items in the list, it seems something goes wrong with the scrollTop function, and it it no longer functions correctly (hovers around the same spot in).
I'm pretty lost on this, and have tried a bunch of different combinations of css settings for both the container and side div. Please help me.

I've reformatted your code to be more jQuery-esque. The main change, however, was to change the list.scrollTop() function so that it just scrolls to the bottom of list:
$(document).ready(function() {
var list = $("#q-d-list");
$(document).on('click', '#add', function() {
$('.active', list).removeClass("active");
var count = list.children().length + 1;
var active = $('<div />', {
'data-qid': count,
'class': 'mli active'
}).text('q' + count).appendTo(list);
list.scrollTop(list[0].scrollHeight);
});
});​
Demo: http://jsfiddle.net/MrvcB/19/

Use
list.scrollTop(list.get(0).scrollHeight);
rather than
list.scrollTop($(".active").offset().top);

Try:
$(document).ready(function () {
var count = 2;
$("#add").live("click", function () {
var list= $("#q-d-list");
// remove the active class from the old item
var $clone = $(list.find("div:last-child").removeClass("active").clone());
count+=1;
var str_count = "q"+count.toString();
$clone.addClass("active").attr("data-qid",str_count).text(str_count);
list.append($clone);
list.scrollTop(list.get(0).scrollHeight);
});
});
http://jsfiddle.net/H4Kb3/

Related

Remove an active class by clicking on a parent's brother item in JavaScript

I am working on a get a card script, that consists of 2 phases.
Selecting a card > opens a relevant window on the right
Pressing an Apply now button on that opened window > opens a relevant window on the bottom.
Right now everything works as intended, except:
I want to make so that if a person removes a card selection (.gacca1 / .gacca2), it also removes the "activated" class from the "Get card" div (.gaccaiGET), thus removing the bottom div (.gara). Right now, it keeps the "Get a card" activated, even if you deactivate the card selector.
No matter how I try (with my beginner js skills), i can't make it work.
Also, if you look at the html and css, you will see that most of the elements are positioned absolute, which is a very bad way of making this work. Unfortunately, I could not figure a way to make the positions relative, because the
.divclass.active + .otherdivclass { css }
works only for brother elements, and, even, only for the brother elements that are next to each other. Which resulted in writing poor html and css, to make it look and work the way I want it to. If you have any tips on this matter, please let me know!
Thanks
http://jsfiddle.net/4XM9A/10/
(function () {
var links = Array.prototype.slice.call(document.querySelectorAll('.gacca1'));
var links2 = Array.prototype.slice.call(document.querySelectorAll('.gacca2'));
var links3 = Array.prototype.slice.call(document.querySelectorAll('.gaccaiGET'));
var toggleClass = function (className, element) {
element.classList.toggle(className);
};
var clickHandler = function (linksToDisable) {
return function () {
toggleClass('active', this);
linksToDisable.filter(function (link) {
return link.classList.contains('active');
})
.forEach(function (link) {
toggleClass('active', link);
});
};
};
links.forEach(function (link) {
link.addEventListener('click', clickHandler(links2));
});
links2.forEach(function (link) {
link.addEventListener('click', clickHandler(links));
});
links3.forEach(function (link) {
link.addEventListener('click', function () {
toggleClass('active', this);
});
});
}());
As far as I understand you should firstly toggle '.active' of all divs of the '.gaccai' that goes after the ".active" parent. Try changing function toggleClass a bit:
var toggleClass = function (className, element) {
var array = document.querySelectorAll('.' + element.classList + ' + .gaccai .active');
for (var i = 0; i < array.length; i++) {
array[i].classList.toggle(className);
}
element.classList.toggle(className);
};

scrollTop to active element in a overflow scroll div

I have a specific question about .scrollTop. I have a div with a specific height and a lot of p tags inside:
<div id="scroll">
<p>name1</p>
<p>name2</p>
<!-- till name50 -->
</div>
depending on the name you click it gets a class .active. What I then want to do is scroll the div so, that the name is at the top. So what I get is that I can use scrollTop in an animate function like this:
$('#scroll').animate({scrollTop: value });
but how can I get the var value. I tried it with
var value = $('#scroll p').hasClass('active').position().top;
But somehow it does not work.
Some help is much appreciated.
You need to check scrollTop() for the container #scroll and add that back to the position() arg.
var $scroll = $('#scroll');
$('p').click(function(e){
var $this = $(this);
$scroll.animate({
"scrollTop": $this.position().top + $scroll.scrollTop()
}, 1000);
});
http://jsfiddle.net/yCEap/1/
To just get the value:
var value = $('#scroll').scrollTop();

move blocks between two divs

So I have two divs and inside there gona be some blocks:
<div class="list-block 01">
<span>21#epos.com</span>
<span class="moveSym" id="01">+</span>
</div>
if one clicks on
+
whole block moves to other div.
Everything works but only to move ech block to another div once,
but I need them to go both ways as much as .moveSym clicked.
my JS
//remove block on click
$('.del-block').on('click', function() {
var block = $(this).attr('id');
$('.' + block).remove();
})
//move form list blocks to different fields
$('.leftSide01 .moveSym').click(function() {
console.log($(this).attr('id'));
var id = $(this).attr('id');
$(this).text("-");
$('.leftSide01 .list-block.' + id).appendTo('.rightSide01');
})
$('.rightSide01 .moveSym').click(function() {
console.log($(this).attr('id'));
var id = $(this).attr('id');
$(this).text("+");
$('.rightSide01 .list-block.' + id).appendTo('.leftSide01');
})
I know there are plugins for this, but I really want to write it by myself and learn :)
Fiddle http://jsfiddle.net/A1ex5andr/CRvVK/
Need to use event delegation, because the handler to be executed depends on the parent element.
//move form list blocks to different fields
$('.leftSide01').on('click', '.moveSym', function () {
console.log($(this).attr('id'));
var id = $(this).attr('id');
$(this).text("-");
$('.leftSide01 .list-block.' + id).appendTo('.rightSide01');
})
$('.rightSide01').on('click', '.moveSym', function () {
console.log($(this).attr('id'));
var id = $(this).attr('id');
$(this).text("+");
$('.rightSide01 .list-block.' + id).appendTo('.leftSide01');
})
Demo: Fiddle
You can really simplify this logic into one function that works for both (if there are only ever going to be two divs) . . .
$('.moveSym').click(function() {
console.log($(this).attr('id')); // I just left in, because you had it in the original code :)
var targetParent = $(".rightSide01");
var linkText = "-";
if ($(this).parent(".rigthSide01") > 0) {
linkText = "+";
targetParent = $(".leftSide01");
}
$(this).text(linkText);
$(this).parent().appendTo(targetParent);
});
This code starts out assuming that the block is on the left-hand side . . . it sets up the targetParent value (i.e., where the block will move to) to the right-hand side and the new link text to be "-".
After that, it checks to see if the block is actually on the right-hand side, instead, and, if it is, then it updates the variables with the values needed to move it to the left.
At that point, it updates the text in the "move-sym" span element to the final linkText value, and moves its parent block to the new target div (the targetParent value).
No need to worry about the delegation or event handlers in this one, because the function is the same, regardless of the location, and will travel with the "move-sym" span element, wherever it goes.

remove an .append() to return an element to it's original state

I'm loading up a ul for a image slider but I need to remove the images (ul) and revert back to the original state (before javascript manipulations) when the slider is closed because I will later need to reload the ul for another set of different images.
Here is how I'm loading the slider.
var get_images = [ "show_1.jpg", "show_2.jpg", "show_3.jpg", "show_4.jpg"];
$.each(get_images, function(i,img){
$('#container ul').append('<li><img src="'+img+'"/></li>');
});
I think this might be what you are looking for:
var get_images = ["show_1.jpg", "show_2.jpg", "show_3.jpg", "show_4.jpg"];
var original = $('#container ul').html();
$.each(get_images, function (i, img) {
$('#container ul').append('<li><img src="' + img + '"/></li>');
});
$("#revert").click( function() {
$('#container ul').html(original);
});
The revert button is for demonstration purposes. The idea is basically that you save your original content so that you can revert back to it later if needed.
Fiddle
If the ul was initially empty you can use .empty() to get it back to that state.
$('#container ul').empty()
How about getting the last one you added and deleting it like this.:
$('#container ul li:last').remove();
If you have added 3, then repeat that line 3 times. Each one gets the last added element and removes it.
Another way
You can also keep track of what is added with:
var addedList = [];
$.each(get_images, function(i,img){
var added = $.parseHTML('<li><img src="'+img+'"/></li>');
$('#container ul').append(added);
addedList.push(added);
});
Delete with something like:
for (var i=0; i < addedList.length; ++i) {
$(addedList[i]).remove();
}
addedList = [];

JQuery: Using :not(.active) selector, and adding an Active class, to the item selected

I'm new to Javascript and am having a bit of an issue with using a NOT selector, and adding a class during the function, hopefully this will make sense to someone.
I am creating a small gallery, and my goal is to have clickable navigation, however the active image will redirect to another page when clicked.
Code is as follows:
$("ul#mainGallery li:not(.active) a").click(function(){
var thisListClass = $(this).parent().attr('class');
var activeListId = $(this).parent().attr('id');
var newMarginLeft = (activeListId-3) * -200;
var animateAction = {};
animateAction['margin-left'] = newMarginLeft + 'px';
$("ul#mainGallery").animate(animateAction, 1000);
$('li.active img').animate({width:'100px', height:'100px'},1000)
$(this + 'img').animate({width:'300px', height:'300px'},1000)
$(li.active).removeClass('active');
$(this).parent().addClass('active');
return false;
I know there is likely a much better way to do this, but I can't get my head around it.
Edit: I should probably say what the problem is...
When an active image is clicked, it follows the hyperlink all is well.
When a non active image is clicked, it begins the animation, then (i assume) when the 'active' class is added, instead of returning false, it returns true and follows the hyperlink.
You are binding the click event to $("ul#mainGallery li:not(.active) a") whenever that code is run (presumably on document load). The items which are not active at that point will have that item bound, and changing the class afterwards on other items won't bind this event to them. You will need to either change how you bind it or check inside the function whether the item has that class.
Something like this:
$("ul#mainGallery li a").click(function(){
if(!$(this).parent().hasClass('active')){
var thisListClass = $(this).parent().attr('class');
var activeListId = $(this).parent().attr('id');
var newMarginLeft = (activeListId-3) * -200;
var animateAction = {};
animateAction['margin-left'] = newMarginLeft + 'px';
$("ul#mainGallery").animate(animateAction, 1000);
$('li.active img').animate({width:'100px', height:'100px'},1000)
$(this + 'img').animate({width:'300px', height:'300px'},1000)
$('li.active').removeClass('active');
$(this).parent().addClass('active');
return false;
}
EDIT, or if you prefer to continue using the same selector with the :not and everything, then switch your click function to .live()
To stop the default behaviour use the preventDefault() function
$("ul#mainGallery li:not(.active) a").click(function(e){
e.preventDefault(); // will stop the default behaviour
}
Read more on Jquery docs

Categories

Resources