Why does the margin apply only when .info is active - javascript

Why does the 50px margin between the two lists only appear when .info is active? The gap should always be there and the text should appear within the gap once number 1-8 is selected. All suggestions are welcome.
// Get references to the two sets of boxes
var numbers = document.querySelectorAll(".click");
var letters = document.querySelectorAll(".border");
// Turn each node list into proper arrays:
numbers = Array.prototype.slice.call(numbers);
letters = Array.prototype.slice.call(letters);
// Loop through all the number boxes
numbers.forEach(function(box, index){
// Set up the click event handlers for all the number boxes
box.addEventListener("click", function(){
// Remove borders from each of the letter boxes
letters.forEach(function(box){
box.classList.remove("showBorder");
});
// Apply the border to only the one clicked element
var info = document.getElementsByClassName('info')[0];
info.style.display = 'inline';
letters[index].classList.add("showBorder");
});
});
.list-box li {display: inline-block;list-style-type: none;padding: 1em;background:red;}
.list-box {margin:50px auto;padding:0;}
.box-sleeve li {display: inline-block;list-style-type: none;padding: 1em;background:red;}
.box-sleeve {margin:50px auto;padding:0;}
.showBorder { border: 3px dashed black; }
.info {margin:auto; position: relative;padding-left:3em;display:none}
<ul class="list-box">
<li class="click">1</li>
<li class="click">2</li>
<li class="click">3</li>
<li class="click">4</li>
<li class="click">5</li>
<li class="click">6</li>
<li class="click">7</li>
<li class="click">8</li>
</ul>
<div class="info">Regular length for your collar size</div>
<ul class="box-sleeve">
<li class="border">a</li>
<li class="border">b</li>
<li class="border">c</li>
<li class="border">d</li>
<li class="border">e</li>
<li class="border">f</li>
<li class="border">g</li>
<li class="border">h</li>
</ul>

// Get references to the two sets of boxes
var numbers = document.querySelectorAll(".click");
var letters = document.querySelectorAll(".border");
// Turn each node list into proper arrays:
numbers = Array.prototype.slice.call(numbers);
letters = Array.prototype.slice.call(letters);
// Loop through all the number boxes
numbers.forEach(function(box, index){
// Set up the click event handlers for all the number boxes
box.addEventListener("click", function(){
// Remove borders from each of the letter boxes
letters.forEach(function(box){
box.classList.remove("showBorder");
});
// Apply the border to only the one clicked element
var info = document.getElementsByClassName('info')[0];
info.style.visibility = 'visible';
letters[index].classList.add("showBorder");
});
});
.list-box li {display: inline-block;list-style-type: none;padding: 1em;background:red;}
.list-box {margin:50px auto;padding:0;}
.box-sleeve li {display: inline-block;list-style-type: none;padding: 1em;background:red;}
.box-sleeve {margin:50px auto;padding:0;}
.showBorder { border: 3px dashed black; }
.info {margin:auto; position: relative;padding-left:3em; visibility: hidden;}
<ul class="list-box">
<li class="click">1</li>
<li class="click">2</li>
<li class="click">3</li>
<li class="click">4</li>
<li class="click">5</li>
<li class="click">6</li>
<li class="click">7</li>
<li class="click">8</li>
</ul>
<div class="info">Regular length for your collar size</div>
<ul class="box-sleeve">
<li class="border">a</li>
<li class="border">b</li>
<li class="border">c</li>
<li class="border">d</li>
<li class="border">e</li>
<li class="border">f</li>
<li class="border">g</li>
<li class="border">h</li>
</ul>
Instead of display:none
Get rid of display
and include
visibility:hidden
When the click is invoked set visibility:visible to the info element.

Related

How to target every first two or three elements alternatively in javascript loop

I am able to target only first 2 elements with change in background color. Like, first 2 elements background to red, and next 2 elements leaving as it is. And background red to 4th and 5th element..so on. I want to target every 2 elements alternatively. How can i change a variable value dynamically which can be easy everytime like if var count = 2; every first 2 elements red...if count = 4; every first 4 elements to red and next 4 to gray....Actually I wanted to use styling with dynamic value like element[i].clientWidth etc to elements. I just used background color for this example so that i can change it later according to my styling if once it works.
<style>
ul li {
list-style-type: none;
display: inline-block;
padding: 10px;
}
<style>
<ul id="pix" class="select">
<li class="">one</li>
<li class="">two</li>
<li class="">three</li>
<li class="">four</li>
<li class="">five</li>
<li class="">six</li>
<li class="">seven</li>
<li class="">eight</li>
<li class="">nine</li>
<li class="">ten</li>
</ul>
<script>
var pix = document.getElementById("pix");
var piximgs = pix.children;
var i;
for (i = 0; i < piximgs.length; i++) {
piximgs[i].style.background = "gray";
// if (i && (i % 2 == 0)) {
piximgs[i % 2].style.background = "red";
// }
}
</script>
Here is a modified solution with a variable count:
<style>
ul li {
list-style-type: none;
display: inline-block;
padding: 20px;
background-color: gray;
}
</style>
<ul id="pix" class="select">
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
<li>five</li>
<li>six</li>
<li>seven</li>
<li>eight</li>
<li>nine</li>
<li>ten</li>
</ul>
<script>
var count = 3;
Array.from(document.querySelectorAll("#pix li"))
.forEach((li,i)=>
li.style.backgroundColor=Math.floor(i/count)%2?"red":"gray");
</script>
You could have a flag - next - which you toggle whenever there is a match for the mod division, so that you track that the next element should also be red.
<style>
ul li {
list-style-type: none;
display: inline-block;
padding: 20px;
background-color: gray;
}
</style>
<ul id="pix" class="select">
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
<li>five</li>
<li>six</li>
<li>seven</li>
<li>eight</li>
<li>nine</li>
<li>ten</li>
</ul>
<script>
var pix = document.getElementById("pix");
var piximgs = pix.children;
var i;
var next = false;
for (i = 0; i < piximgs.length; i++) {
if(next) {
piximgs[i].style.background = "red";
next = false;
}
if (i % 4 == 0) {
piximgs[i].style.background = "red";
next = true;
}
}
</script>

Add pagination to the filtering with slider, and show filtered content onload

I'm trying to change the code to following requirements.
Change the "prev" and "next" button to pagination (e.g. 1 2 3 4 and so on)
Show the "Category 1" content instead of show all contents. To display the filtered content onload as shown below. I did this but not sure is it good enough or not.
Actually I'm still not familiar with jQuery and javaScript. I have been trying to figure out the following code the past few weeks, but failed. Hoping that some of you could provide me with some advice. Thanks!
//Show filtred image onload
$(document).ready(function(){
$('div.filter a:first-child').trigger('click');
});
var visible = "";
$('div.filter').delegate('a', 'click', function (event) {
visible = '.' + this.href.slice(this.href.indexOf("#") + 1);
pagination();
event.preventDefault();
});
var itemsNumber = 8;
var min = 0;
var max = itemsNumber;
function pagination(action) {
var totalItems = $("li" + visible).length;
if (max < totalItems) {//Stop action if max reaches more than total items
if (action == "next") {
min = min + itemsNumber;
max = max + itemsNumber;
}
}
if (min > 0) {//Stop action if min reaches less than 0
if (action == "prev") {
min = min - itemsNumber;
max = max - itemsNumber;
}
}
$("li").hide();
$("li" + visible).slice(min, max).show();
}
pagination();
//Next
$("#next").click(function() {
action = "next";
pagination(action);
})
//Previous
$("#prev").click(function() {
action = "prev";
pagination(action);
})
#item-wrapper {
width:250px;
margin:30px 0 0 30px;
}
.items li {
font-family:arial;
font-size:13px;
background-color:#ccc;
margin-bottom:1px;
padding:5px;
}
.ctrl-nav {
background-color:#999;
padding:5px;
overflow:hidden;
}
.ctrl-nav a {
font-family:arial;
font-size:13px;
padding:5px 10px;
color:#fff;
}
.ctrl-nav a#prev{
float:left;
}
.ctrl-nav a#next{
float:right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filter">
category 1
category 2
</div>
<div id="item-wrapper">
<ul class="items">
<li class="category-1">item 1</li>
<li class="category-1">item 2</li>
<li class="category-1">item 3</li>
<li class="category-1">item 4</li>
<li class="category-1">item 5</li>
<li class="category-1">item 6</li>
<li class="category-2">item 7</li>
<li class="category-2">item 8</li>
<li class="category-2">item 9</li>
<li class="category-2">item 10</li>
<li class="category-2">item 11</li>
<li class="category-2">item 12</li>
<li class="category-1">item 13</li>
<li class="category-1">item 14</li>
<li class="category-2">item 15</li>
</ul>
<div class="ctrl-nav">
PreviousNext
</div>
</div>
Here you have my approach...
CSS:
div.ctrl-nav a {
padding: 5px;
margin-right: 2px;
color: white;
background: black;
}
div.ctrl-nav a.selected {
background: red;
}
JQUERY:
var selCatId = null;
var pageLength = 3;
// Filters.
$('div.filter').on('click','a',function(e) {
e.preventDefault();
// Get the category id from the href attribute.
selCatId = $(this).attr('href').substring(1);
// Create pagination.
var nPages = Math.ceil($('div#item-wrapper ul.items li.'+selCatId).length / pageLength),
pages = [];
// Create and show page numbers.
for (var i=1; i<=nPages; i++)
pages.push(''+i+'');
$('div.ctrl-nav').html(pages.join(''));
// Activate page number selection.
$('div.ctrl-nav a').click(function(e) {
e.preventDefault();
var pageInit = (parseInt($(this).text())-1)*pageLength;
$('div#item-wrapper ul.items li').hide()
.filter('.'+selCatId)
.slice(pageInit,pageInit+pageLength)
.show();
// Mark the active page.
$('div.ctrl-nav a').removeClass('selected').filter(this).addClass('selected');
});
// Show first page of the selected category.
$('div.ctrl-nav a:first').trigger('click');
});
// Show 'Category 1' when page loads.
$('div.filter a:first').trigger('click');
... and a working file... https://fiddle.jshell.net/rigobauer/zpdk9e6q/
NOTE: When you select a new category, it goes to the first page of that category.
I hope it helps

Setting threshold on max number of classes selected/activated on click on multiple divs/id's

I've been working on a skill tree 'persay' and I ran into an interesting problem.
I have my code setup to allow a user to click a talent to show that particular talent has been selected up to a max number of 4 talents total. Once you have selected 4 talents you have to deselect a talent to select a different one.
My problem comes when I duplicate the talent tree for a second talent tree on the same page(for a second hero/class essentially or a second party member out of your party). I can't figure out how to make the same 'threshold of a max of 4 talents' on other skill trees standalone. What happens is that they all share the same threshold across all trees. I have tried making separate id's each and even changing the variable names within each function.
var skillTotal = 0;
var skillSelected = 0;
$( "#selectable01>li.skill-slot" ).bind( "click", function ( e ) {
var threshold = 4;
var price = 1;
if ($(this).hasClass('selected')) {
skillTotal = skillTotal - 1;
skillSelected--;
$(this).toggleClass('selected');
}
else if (price + skillTotal <= threshold) {
skillTotal = skillTotal + price;
skillSelected++;
$(this).toggleClass('selected');
}
});
$( "#selectable02>li.skill-slot" ).bind( "click", function ( e ) {
var threshold = 4;
var price = 1;
if ($(this).hasClass('selected')) {
skillTotal = skillTotal - 1;
skillSelected--;
$(this).toggleClass('selected');
}
else if (price + skillTotal <= threshold) {
skillTotal = skillTotal + price;
skillSelected++;
$(this).toggleClass('selected');
}
});
/* NOT USING THIS CURRENTLY
$( "#campSelectable>li.camp-slot" ).bind( "click", function ( e ) {
var campThreshold = 3;
var campPrice = 1;
if ($(this).hasClass('selected')) {
campTotal = campTotal - campPrice;
selectedCamp--;
$(this).toggleClass('selected');
}
else if (campPrice + campTotal <= campThreshold) {
campTotal = campTotal + campPrice;
selectedCamp++;
$(this).toggleClass('selected');
}
}); */
.skill-slot, .camp-slot{
border:2px solid black;
width:100px;
margin: 5px;
opacity: .4;
}
.skill-slot:hover, .camp-slot:hover {
opacity: 1;
}
.raffle-slot.taken{
background:red;
}
.selected{
background: rgb(255, 128, 128);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="calc">
<ol class="roster" id="selectable01">
<li class="skill-slot">1</li>
<li class="skill-slot">2</li>
<li class="skill-slot">3</li>
<li class="skill-slot">4</li>
<li class="skill-slot">5</li>
<li class="skill-slot">6</li>
<li class="skill-slot">7</li>
</ol>
<ol class="roster" id="selectable02">
<li class="skill-slot">1</li>
<li class="skill-slot">2</li>
<li class="skill-slot">3</li>
<li class="skill-slot">4</li>
<li class="skill-slot">5</li>
<li class="skill-slot">6</li>
<li class="skill-slot">7</li>
</ol>
</div>
Here are the things I have tried:
Initially my identifier was : $( "#calc>ol>li.skill-slot" ).on so I began adding additional id's to drill down further and make sure that my functions were targeting specific div's, so I moved to this: $( "#calc>#selectable01>li.skill-slot" ).on and $( "#calc>#selectable02>li.skill-slot" ).on
The reason I didn't want to target a second ID is because I'll be using templates that are appended to the #calc div effectively replacing the current roster with a new one. I also did this for testing to see if I could resolve the issue by making them their own individual id's, which didn't work.
A way simpler approach using Event delegation. Toggle .selected to either deactivate the current .skill-slot, or to activate it if there are less than 4 .selected.skill-slots in this group.
$('#selectable01, #selectable02').on('click', '.skill-slot', function(e){
if($(this).hasClass('selected') || $('.selected.skill-slot', e.delegateTarget).length < 4){
$(this).toggleClass('selected');
}
});
.skill-slot, .camp-slot{
border:2px solid black;
width:100px;
margin: 5px;
opacity: .4;
}
.skill-slot:hover, .camp-slot:hover {
opacity: 1;
}
.raffle-slot.taken{
background:red;
}
.selected{
background: rgb(255, 128, 128);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="calc">
<ol class="roster" id="selectable01">
<li class="skill-slot">1</li>
<li class="skill-slot">2</li>
<li class="skill-slot">3</li>
<li class="skill-slot">4</li>
<li class="skill-slot">5</li>
<li class="skill-slot">6</li>
<li class="skill-slot">7</li>
</ol>
<ol class="roster" id="selectable02">
<li class="skill-slot">1</li>
<li class="skill-slot">2</li>
<li class="skill-slot">3</li>
<li class="skill-slot">4</li>
<li class="skill-slot">5</li>
<li class="skill-slot">6</li>
<li class="skill-slot">7</li>
</ol>
</div>
As you are using global variables for the count and total, this obviously leads to a global limit. To make the limit local to each of the groups, you could use data attributes of these ol elements, so they work independently from each other. With some other little improvements, your code could look like this:
$("#selectable01, #selectable02").data("skillTotal", 0).data("skillSelected", 0);
$("#selectable01>li.skill-slot,#selectable02>li.skill-slot").on("click", function () {
var threshold = 4,
price = 1,
sign = $(this).hasClass('selected') ? -1: 1,
$p = $(this).parent(),
newPrice = $p.data("skillTotal") + sign*price;
if (newPrice > threshold) return;
$p.data("skillTotal", newPrice)
.data("skillSelected", $p.data("skillSelected") + sign);
$(this).toggleClass('selected');
});
.skill-slot, .camp-slot{
border:2px solid black;
width:100px;
margin: 5px;
opacity: .4;
}
.skill-slot:hover, .camp-slot:hover {
opacity: 1;
}
.raffle-slot.taken{
background:red;
}
.selected{
background: rgb(255, 128, 128);
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="calc">
<ol class="roster" id="selectable01">
<li class="skill-slot">1</li>
<li class="skill-slot">2</li>
<li class="skill-slot">3</li>
<li class="skill-slot">4</li>
<li class="skill-slot">5</li>
<li class="skill-slot">6</li>
<li class="skill-slot">7</li>
</ol>
<ol class="roster" id="selectable02">
<li class="skill-slot">1</li>
<li class="skill-slot">2</li>
<li class="skill-slot">3</li>
<li class="skill-slot">4</li>
<li class="skill-slot">5</li>
<li class="skill-slot">6</li>
<li class="skill-slot">7</li>
</ol>
</div>
You're storing skillSelected outside of the event handlers so each event handler is reading that variable. You might need to get a running total of how many are selected each time the event handler is triggered.

Change background color on anchor in listitem when clicked

I have menu constructed by ul li with anchor tags in each. Css is applied to the anchor
and anchor:hover however I want the selected item to show that it is selected be changing the background a different color. anchor:active does not work.
I am trying javascript but not yet successful. Can this be soley done through css? I have looked at so many examples, but none actually worked right.
JAVASCRIPT
<script type="text/javascript">
function ChangeColor(obj) {
var li = document.getElementById(obj.id);
li.style.background = "#bfcbd6";
}
</script>
HTML
<div id="navigation">
<ul>
<li><a onclick="changecolor(this);" href="Default.aspx">Home</a></li>
<li><a onclick="changecolor(this);" href="View.aspx">View</a></li>
<li><a onclick="changecolor(this);" href="About.aspx">About</a></li>
</ul>
</div>
CSS - Simplified
#navigation ul {
list-style-type: none;
}
#navigation li
{
float: left;
}
#navigation a
{
background-color: #465c71;
}
#navigation a:hover
{
background-color: #bfcbd6;
}
you don't need to get id again for handling element. obj references the actual element.
<script type="text/javascript">
function ChangeColor(obj) {
obj.style.backgroundColor = "#bfcbd6";
}
</script>
Edit: And javaScript is case sensitive, so you should check your function names.
Here is a jsFiddle Demo
I have found a way to use JavaScript to solve this situation. This works for having MasterPage. Changing the id of the selected tab will then reference the css for that
selected tab only while setting the other tabs id's to null.
HTML
<div id="navbar">
<div id="holder">
<ul id="menulist">
<li><a onclick="SelectedTab(this);" href="#" id="onlink" >Home</a></li>
<li><a onclick="SelectedTab(this);" href="#" id="" >Products</a></li>
<li><a onclick="SelectedTab(this);" href="#" id="">Services</a></li>
<li><a onclick="SelectedTab(this);" href="#" id="">Gallery</a></li>
<li><a onclick="SelectedTab(this);" href="#" id="" >Contact</a></li>
</ul>
</div>
</div>
JavaScript
function SelectedTab(sender) {
var aElements = sender.parentNode.parentNode.getElementsByTagName("a");
var aElementsLength = aElements.length;
var index;
for (var i = 0; i < aElementsLength; i++)
{
if (aElements[i] == sender) //this condition is never true
{
index = i;
aElements[i].id="onlink"
} else {
aElements[i].id=""
}
}
}
Css for changing the background color after tab has been selected
#holder ul li a#onlink
{
background: #FFF;
color: #000;
border-bottom: 1px solid #FFF;
}

drag and drop from one column to another using jquery

I need an example of dragging an item from one column and dropping it into another using jquery
Are there any such examples out there?
You can do this with jquery sortable: http://jqueryui.com/demos/sortable/#connect-lists
Here I have done complete bins using jquery UI sortable. i think it should be helpful to you.
Demo: http://codebins.com/bin/4ldqp9g
HTML:
<div class="demo">
<ul id="sortable1" class="connectedSortable">
<li class="ui-state-default">
Item 1
</li>
<li class="ui-state-default">
Item 2
</li>
<li class="ui-state-default">
Item 3
</li>
<li class="ui-state-default">
Item 4
</li>
<li class="ui-state-default">
Item 5
</li>
</ul>
<ul id="sortable2" class="connectedSortable">
<li class="ui-state-highlight">
Item 1
</li>
<li class="ui-state-highlight">
Item 2
</li>
<li class="ui-state-highlight">
Item 3
</li>
<li class="ui-state-highlight">
Item 4
</li>
<li class="ui-state-highlight">
Item 5
</li>
</ul>
</div>
<!-- End demo -->
<div class="demo-description">
<p>
Sort items from one list into another and vice versa, by passing a selector
into the
<code>
connectWith
</code>
option. The simplest way to do this is to
group all related lists with a CSS class, and then pass that class into the
sortable function (i.e.,
<code>
connectWith: '.myclass'
</code>
).
</p>
</div>
CSS:
#sortable1, #sortable2
{
list-style-type: none;
margin: 0;
padding: 0 0 2.5em;
float: left;
margin-right: 10px;
}
#sortable1 li, #sortable2 li
{
margin: 0 5px 5px 5px;
padding: 5px;
font-size: 1.2em;
width: 120px;
overflow:visible;
display:block;
}
JQuery:
$(function() {
var itemclone, idx;
$("#sortable1, #sortable2").sortable({
start: function(event, ui) {
//create clone of current seletected li
itemclone = $(ui.item).clone();
//get current li index position in list
idx = $(ui.item).index();
//If first li then prepend clone on first position
if (idx == 0) {
itemclone.css('opacity', '0.5');
$(this).prepend(itemclone);
}
//Else Append Clone on its original position
else {
itemclone.css('opacity', '0.7');
$(this).find("li:eq(" + (idx - 1) + ")").after(itemclone);
}
},
change: function(event, ui) {
//While Change event set clone position as relative
$(this).find("li:eq(" + idx + ")").css('position', 'relative');
},
stop: function() {
//Once Finish Sort, remove Clone Li from current list
$(this).find("li:eq(" + idx + ")").remove();
},
connectWith: ".connectedSortable"
}).disableSelection();
});
Demo: http://codebins.com/bin/4ldqp9g

Categories