Bigcommerce - How to make side subcategories only display when parent category is clicked on? - categories

I literally spent hours trying to do this, yesterday, and found one great answer here: stackoverflow.com/questions/11056808/big-commerce-hover-menu but I can't seem to figure out how to apply it to my store. Basically, Bigcommerce uses a snippet of code called a 'panel' to display categories. This panel is used in both the top category menu and the side menu. Right now, BC expands all categories as follows:
Parent Category
Child Category
Next Child
Next Child
Child Category
Next Child
Next Child
I'd like to know how to keep the top menu looking the same, but how to change the side menu to display as follows:
Parent Category
Child Category
Child Category
And on click:
Parent Category
Child Category
Next Child
Next Child
Child Category
Parent Category
Child Category
Child Category
Next Child
Next Child
Respectively.
The HTML for the side category menu looks like this:
<div class="CategoryList" id="SideCategoryList">
<div class="BlockContent">
<div class="SideCategoryListFlyout">
<ul class="sf-menu sf-horizontal sf-js-enabled">
<li class="">Parent Category
<ul style="display: none; visibility: hidden;">
<li>Child Category
<ul style="display: none; visibility: hidden;">
<li>Next Child</li>
<li>Next Child</li>
<li>Next Child</li>
</ul>
</li>
<li>Child Category
<ul style="display: none; visibility: hidden;">
<li>Next Child</li>
<li>Next Child</li>
<li>Next Child</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
With the following CSS styles:
.Left #SideCategoryList {
display: block;
}
.Left #SideCategoryList ul ul {
color: #5a5353;
}
.Left #SideCategoryList .BlockContent,
.Left .slist .BlockContent {
color: #5a5353;
}
.Left #SideCategoryList li a,
.Left .slist li a,
.Left .afterSideShopByBrand a, .Left #GiftCertificatesMenu li a, .Left #SideAccountMenu li a {
color: #5a5353;
}
.Left #SideCategoryList li a:hover,
.Left .slist li a:hover,
.Left .afterSideShopByBrand a:hover, .Left #GiftCertificatesMenu li a:hover, .Left #SideAccountMenu li a:hover {
color: #5a5353;
}
.Left #SideCategoryList li li a,
.Left .slist li li a {
color: #5A5353;
}
.Left #SideCategoryList li li a:hover,
.Left .slist li li a:hover {
color: #aca9a9;
}
I hope I covered everything, but if you need more clarification, please let me know. Keep in mind, some code is generated by the system automatically (I suspect jquery as when using the inspection tool, hovering over a link automatically changes it's class). Here is the site link:
http://bit.ly/1aHKTke

In Bigcommerce, the side navigation and top menu navigation are often called by the same ID selector.
For this javascript to work only in one area, you want to use a more specific selector such as #SidePanel > #SideCategoryList.
It looks like you may no longer be working on this site, but hope that helps someone.

Related

JQuery sortable does not drop on overflow list items

I have two lists - the first contains a list of items the user can select, and he selects them by dragging them to the second list. I have implemented this with jQuery UI Sortable, and created a basic example on jsfiddle.
So drag an item from the first to the second list - OK. The problem occurs if you scroll down to the bottom of the second list - you are unable to drag an item from the first to the second list. It appears that all list items that overflowed beyond the end of the visible list do not have a drop target associated with them. Same happens when copying in the other direction.
As sortable appears to be aimed at lists, I suspect I am missing a trick. Any ideas?
The jsfiddle example code is:
html
<div class="listDiv">
<ul id="list1" class="connected ui-sortable">
<li id="a">a</li>
<li id="b">b</li>
<li id="c">c</li>
<li id="d">d</li>
<li id="e">e</li>
<li id="f">f</li>
<li id="g">g</li>
<li id="h">h</li>
<li id="i">i</li>
<li id="j">j</li>
</ul>
</div>
<div class="listDiv">
<ul id="list1" class="connected ui-sortable">
<li id="1">1</li>
<li id="2">2</li>
<li id="3">3</li>
<li id="4">4</li>
<li id="5">5</li>
<li id="6">6</li>
<li id="7">7</li>
<li id="8">8</li>
<li id="9">9</li>
<li id="10">10</li>
<li id="11">11</li>
<li id="12">12</li>
<li id="13">13</li>
<li id="14">14</li>
<li id="15">15</li>
</ul>
</div>
js
$(function() {
$( "#list1, #list2" ).sortable({
connectWith: ".connected"
}).disableSelection();
});
css
.listDiv {
overflow:auto;
float: left;
width:400px;
border: 1px solid #999;
}
#list1, #list2 {
list-style-type: none;
height: 200px;
}
#list1 li, #list2 li {
font-size: 11px;
margin: 0 5px 5px;
padding: 5px;
width: 300px;
border: 1px solid #C5DBEC;
font-family: Verdana,Arial,Helvetica,sans-serif;
font-weight: bold;
outline: medium none;
}​
I believe I have nailed down the version of jquery ui sortable in which the bug was introduced - 1.8.12. The following code appears to cause the error:
//We ignore calculating positions of all connected containers when we're not over them
if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
continue;
I have reported this on jquery ui bug 4231 in the hope that they will reopen this (unfixed) bug and fix it in a future release.
So if you are struggling with this problem you can check if the bug has been fixed, or revert back to jquery ui 1.8.11, or otherwise remove the offending code mentioned above and hope for the best!

finding next sibling in a jquery accordian menu

So, my problem is that I can't seem to find the next() sibling down to the following nested ul li. when set to hide. I can find it when it's not set to hide easily by:
This works when I comment out the JS and nothing is hidden:
//$(".vertNavigation li ul a").hide();
Add this to click function:
$(this).next().css("background", "yellow").slideToggle("normal");
Goal is to do the reverse, click on BUTTON ONE and slideDown nested ul and so on. What is it that I'm missing here?
HTML CODE:
</head>
<body>
<div class = "vertNavigation">
<ul>
<li>BUTTON ONE
<ul>
<li>sub menu 1
<li>sub menu 2
<li>sub menu 3
<li>sub menu 4
</ul>
</li>
<li>BUTTON TWO
<ul>
<li>sub menu 1
<li>sub menu 2
<li>sub menu 3
<li>sub menu 4
</ul>
</li>
<li>BUTTON THREE
<ul>
<li>sub menu 1
<li>sub menu 2
<li>sub menu 3
<li>sub menu 4
</ul>
</li>
<li>BUTTON FOUR
<ul>
<li>sub menu 1
<li>sub menu 2
<li>sub menu 3
<li>sub menu 4
</ul>
</li>
</ul>
</div>
</body>
</html>
CSS CODE:
.vertNavigation ul {
list-style-type: none;
padding-left: 0;
margin-lef: 0;
}
.vertNavigation li {
display: inline;
}
.vertNavigation a { /*main menu*/
display: block;
width: 100px;
text-decoration: none;
margin: 2px 0px 2px 0px;
padding: 6px 15px 3px 15px;
background-color: #EAEAEA;
color: #333;
font-size: .8em;
}
.vertNavigation li ul a { /*sub menu*/
text-decoration: none;
border-bottom: solid 1px #333;
border-length: 50px;
margin: 2px 0px 2px 0px;
background-color: #FFF;
color: #333;
}
JS CODE:
google.load("jquery", "1.6.2");
google.setOnLoadCallback(function(){
$(".vertNavigation li ul a").hide();
$(".vertNavigation ul li a").click(function()
{
//$(this).next().slideToggle("normal");
$(this).next().slideDown("normal");
return false;
});
});
Try this:
$(".vertNavigation > ul > li > ul").hide();
$(".vertNavigation > ul > li > a").click(function(e){
e.preventDefault();
$(this).next('ul').slideToggle();
});
Check the live working solution

Dynamic text overflow for mobile phones

How do I get text-overflow to dynamically adjust when a mobile phone's orientation changes? This is how it should look:
Portrait mode
[] This is a very long ... |
[] Super long title is ... |
[] Hello |
[] Lorem ipsum |
Landscape mode
[] This is a very long title, right? |
[] Super long title is so long that ... |
[] Hello |
[] Lorem ipsum |
I've only been able to successfully see the ellipsis when text-overflow is applied to the immediate element, and this element has a hardcoded width. Now you see the problem: since mobile phones have a dynamic width based off of their orientation, this won't work. If you hardcode the width to make it look right in portrait mode, for example, it won't take advantage of the extra space in landscape mode. I already know a Javascript solution, but I wanted to see if anyone knew a clean CSS solution.
HTML
<ol>
<li>
<img src="foo.jpg" />
<p>This is a ver long title, right</p>
</li>
<li>
<img src="bar.jpg" />
<p>Super long title is so long that it can't fit</p>
</li>
</ol>
CSS
li {
}
li img {
float: left;
width: 4em;
height: 4em;
}
li p {
margin: 0 0 0 5em;
white-space: nowrap;
width: 16em;
text-overflow: ellipsis;
}
How about controlling the width for the ol?
CSS:
ol {
width: 100%;
}
li img {
float: left;
width: 4em;
height: 4em;
}
li p {
margin: 0 0 0 5em;
white-space: nowrap;
/* width: 16em; */
text-overflow: ellipsis;
overflow: hidden;
}
.clear {
clear: both;
}
HTML:
<ol>
<li>
<img src="http://www.codefromjames.com/dogquiz/images/dog.png" />
<p>This is a ver long title, right</p>
<div class="clear"></div>
</li>
<li>
<img src="http://www.codefromjames.com/dogquiz/images/dog.png" />
<p>Super long title is so long that it can't fit.
Super long title is so long that it can't fit. </p>
<div class="clear"></div>
</li>
</ol>
Here's a jsfidder demo for this, note that I added an extra <div> at the end of each <li> with clear:both style: http://jsfiddle.net/akuXJ/1/
What if you instead did width: 90%?
Add overflow: hidden to the list items, see this demo fiddle.
HTML:
<ol>
<li>
<img src="foo.jpg" />This is a ver long title, right
</li>
<li>
<img src="bar.jpg" />Super long title is so long that it can't fit
</li>
</ol>
CSS:
li img {
width: 4em;
height: 4em;
vertical-align: middle;
}
li {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
vertical-align: middle;
}
Or, with the images within paragraph's.
Or, with the images outside paragraph's.
Have you tried display table? If it's supported by the device, it might have the effect of assigning a width to the text by treating it as a table cell.
Something like...
ol { display: table; width:100%; }
li { display: table-row; }
li img { display: table-cell; width: 4em; height: 4em; }
li p { display: table-cell; padding-left:5em; white-space: nowrap; text-overflow: ellipsis; }
If that doesn't work, another option might be display: inline-block

How to use firebug console.log to find jquery parent/children in a <ul>

I'm just trying to print back to better understand how to move around the tree traversal using console.log.
When I click on a parent I'd like to print back it's children. I thought it would be easy as
console.log($(event.target).children());
I've tried to use
console.log($(event.target).children("ul li a"));
It gives me []. I'm looking to print out the child's ID.
HTM:
<body>
<div class = "testButton">
<ul>
<li>
Parent One
<ul>
<li> P1 child </li>
</ul>
Parent Two
<ul>
<li> P2 child </li>
</ul>
Parent Three
<ul>
<li> P3 child </li>
</ul>
Parent Four
<ul>
<li> P4 child </li>
</ul>
</li>
</ul>
</div>
</body>
</html>
CSS:
.testButton ul {
list-style-type: none;
padding-left: 0;
margin-left: 0;
}
.testButton li {
display: inline;
}
.testButton a {
display: block;
width: 6em;
text-align: center;
text-decoration: none;
margin: 0em auto .14em;
padding: .1em .5em .1em .5em;
font-size: 2.5em;
}
.upButton {
background-color: #ccc;
color: #000;
}
.overButton {
background-color: #222;
color: #fff;
}
.outButton {
background-color: #ccc;
color: #000;
}
.clickButton {
background-color: #F90;
color: #222;
}
JS:
google.load('jquery', '1.6.2');
google.setOnLoadCallback(function(){
$(".testButton a").addClass("upButton");
$(".testButton a").mouseover(function(event){
$(event.target).removeClass("outButton").addClass("overButton");
});
$(".testButton a").mouseout(function(event){
$(event.target).addClass("outButton");
});
$(".testButton a").click(function(event){
$(".testButton a").removeClass("clickButton");
$(event.target).addClass("clickButton");
$(this).blur();
console.log($(event.target));
console.log($(event.target).children());
console.log($(event.target).parent().children());
console.log($(event.target).siblings());
});
});
This should do the trick for the structure of your ul/li/a tags.
DEMO
For the demo I have just simply alerted the ids for you. You can change these to console.log if you like. So now what I did...
$('.button').click(function() {
$(this).next('ul').children().each(function() {
alert($(this).children('a').attr('id'));
});
});
I added a class 'button' to each of your parents just to make it clear. So now when any item with a class 'button' is clicked, we get the next 'ul' in your html structure - (next() gets the next element at the same hierachy level of your code). Then for each child within that 'ul' I have alerted the id of each anchor within each child (as your structure is <li><a id="..."></li>).

CSS selector for a checked radio button's label

Is it possible to apply a css(3) style to a label of a checked radio button?
I have the following markup:
<input type="radio" id="rad" name="radio"/>
<label for="rad">A Label</label>
What I was hoping is that
label:checked { font-weight: bold; }
would do something, but alas it does not (as I expected).
Is there a selector that can achieve this sort of functionality? You may surround with divs etc if that helps, but the best solution would be one that uses the label ''for'' attribute.
It should be noted that I am able to specify browsers for my application, so best of class css3 etc please.
try the + symbol:
It is Adjacent sibling combinator. It combines two sequences of simple selectors having the same parent and the second one must come IMMEDIATELY after the first.
As such:
input[type="radio"]:checked+label{ font-weight: bold; }
//a label that immediately follows an input of type radio that is checked
works very nicely for the following markup:
<input id="rad1" type="radio" name="rad"/><label for="rad1">Radio 1</label>
<input id="rad2" type="radio" name="rad"/><label for="rad2">Radio 2</label>
... and it will work for any structure, with or without divs etc as long as the label follows the radio input.
Example:
input[type="radio"]:checked+label { font-weight: bold; }
<input id="rad1" type="radio" name="rad"/><label for="rad1">Radio 1</label>
<input id="rad2" type="radio" name="rad"/><label for="rad2">Radio 2</label>
I know this is an old question, but if you would like to have the <input> be a child of <label> instead of having them separate, here is a pure CSS way that you could accomplish it:
:checked + span { font-weight: bold; }
Then just wrap the text with a <span>:
<label>
<input type="radio" name="test" />
<span>Radio number one</span>
</label>
See it on JSFiddle.
I forget where I first saw it mentioned but you can actually embed your labels in a container elsewhere as long as you have the for= attribute set. So, let's check out a sample on SO:
* {
padding: 0;
margin: 0;
background-color: #262626;
color: white;
}
.radio-button {
display: none;
}
#filter {
display: flex;
justify-content: center;
}
.filter-label {
display: inline-block;
border: 4px solid green;
padding: 10px 20px;
font-size: 1.4em;
text-align: center;
cursor: pointer;
}
main {
clear: left;
}
.content {
padding: 3% 10%;
display: none;
}
h1 {
font-size: 2em;
}
.date {
padding: 5px 30px;
font-style: italic;
}
.filter-label:hover {
background-color: #505050;
}
#featured-radio:checked~#filter .featured,
#personal-radio:checked~#filter .personal,
#tech-radio:checked~#filter .tech {
background-color: green;
}
#featured-radio:checked~main .featured {
display: block;
}
#personal-radio:checked~main .personal {
display: block;
}
#tech-radio:checked~main .tech {
display: block;
}
<input type="radio" id="featured-radio" class="radio-button" name="content-filter" checked="checked">
<input type="radio" id="personal-radio" class="radio-button" name="content-filter" value="Personal">
<input type="radio" id="tech-radio" class="radio-button" name="content-filter" value="Tech">
<header id="filter">
<label for="featured-radio" class="filter-label featured" id="feature-label">Featured</label>
<label for="personal-radio" class="filter-label personal" id="personal-label">Personal</label>
<label for="tech-radio" class="filter-label tech" id="tech-label">Tech</label>
</header>
<main>
<article class="content featured tech">
<header>
<h1>Cool Stuff</h1>
<h3 class="date">Today</h3>
</header>
<p>
I'm showing cool stuff in this article!
</p>
</article>
<article class="content personal">
<header>
<h1>Not As Cool</h1>
<h3 class="date">Tuesday</h3>
</header>
<p>
This stuff isn't nearly as cool for some reason :(;
</p>
</article>
<article class="content tech">
<header>
<h1>Cool Tech Article</h1>
<h3 class="date">Last Monday</h3>
</header>
<p>
This article has awesome stuff all over it!
</p>
</article>
<article class="content featured personal">
<header>
<h1>Cool Personal Article</h1>
<h3 class="date">Two Fridays Ago</h3>
</header>
<p>
This article talks about how I got a job at a cool startup because I rock!
</p>
</article>
</main>
Whew. That was a lot for a "sample" but I feel it really drives home the effect and point: we can certainly select a label for a checked input control without it being a sibling. The secret lies in keeping the input tags a child to only what they need to be (in this case - only the body element).
Since the label element doesn't actually utilize the :checked pseudo selector, it doesn't matter that the labels are stored in the header. It does have the added benefit that since the header is a sibling element we can use the ~ generic sibling selector to move from the input[type=radio]:checked DOM element to the header container and then use descendant/child selectors to access the labels themselves, allowing the ability to style them when their respective radio boxes/checkboxes are selected.
Not only can we style the labels, but also style other content that may be descendants of a sibling container relative to all of the inputs. And now for the moment you've all been waiting for, the JSFIDDLE! Go there, play with it, make it work for you, find out why it works, break it, do what you do!
Hopefully that all makes sense and fully answers the question and possibly any follow ups that may crop up.
If your input is a child element of the label and you have more than one labels, you can combine #Mike's trick with Flexbox + order.
label.switchLabel {
display: flex;
justify-content: space-between;
width: 150px;
}
.switchLabel .left { order: 1; }
.switchLabel .switch { order: 2; }
.switchLabel .right { order: 3; }
/* sibling selector ~ */
.switchLabel .switch:not(:checked) ~ span.left { color: lightblue }
.switchLabel .switch:checked ~ span.right { color: lightblue }
/* style the switch */
:root {
--radio-size: 14px;
}
.switchLabel input.switch {
width: var(--radio-size);
height: var(--radio-size);
border-radius: 50%;
border: 1px solid #999999;
box-sizing: border-box;
outline: none;
-webkit-appearance: inherit;
-moz-appearance: inherit;
appearance: inherit;
box-shadow: calc(var(--radio-size) / 2) 0 0 0 gray, calc(var(--radio-size) / 4) 0 0 0 gray;
margin: 0 calc(5px + var(--radio-size) / 2) 0 5px;
}
.switchLabel input.switch:checked {
box-shadow: calc(-1 * var(--radio-size) / 2) 0 0 0 gray, calc(-1 * var(--radio-size) / 4) 0 0 0 gray;
margin: 0 5px 0 calc(5px + var(--radio-size) / 2);
}
<label class="switchLabel">
<input type="checkbox" class="switch" />
<span class="left">Left</span>
<span class="right">Right</span>
</label>
asd
html
<label class="switchLabel">
<input type="checkbox" class="switch"/>
<span class="left">Left</span>
<span class="right">Right</span>
</label>
css
label.switchLabel {
display: flex;
justify-content: space-between;
width: 150px;
}
.switchLabel .left { order: 1; }
.switchLabel .switch { order: 2; }
.switchLabel .right { order: 3; }
/* sibling selector ~ */
.switchLabel .switch:not(:checked) ~ span.left { color: lightblue }
.switchLabel .switch:checked ~ span.right { color: lightblue }
See it on JSFiddle.
note: Sibling selector only works within the same parent. To work around this, you can make the input hidden at top-level using #Nathan Blair hack.
UPDATE:
This only worked for me because our existing generated html was wacky, generating labels along with radios and giving them both checked attribute.
Never mind, and big ups for Brilliand for bringing it up!
If your label is a sibling of a checkbox (which is usually the case), you can use the ~ sibling selector, and a label[for=your_checkbox_id] to address it... or give the label an id if you have multiple labels (like in this example where I use labels for buttons)
Came here looking for the same - but ended up finding my answer in the docs.
a label element with checked attribute can be selected like so:
label[checked] {
...
}
I know it's an old question, but maybe it helps someone out there :)