Responsive two column panel layout in priority order - javascript

I've been working on a way to display panels on a homepage, the page is responsive and would start off with all the panels being 100% wide and stacking and then at a certain breakpoint the panels would split into two columns.
My work in progress is here http://codepen.io/charge-valtech/pen/aIEGf
This works nicely with the panels flowing in priority order from left to right. However the problem is this page would need to be dynamic, so any of the panels could be "switched off". So if you got rid of the third panel, because of the way floats work the fourth panel tries to go over to the right, even though float: left has been specified.
Using clearing would keep it to the left, but then there would be a gap where the third panel was...
I hope this makes some sense and was just interested in how other people might approach the problem. I'm thinking JavaScript might be the way to go but wouldn't really know how to go about detecting if there's white space available.
Cheers

I thought I'd share my solution for this, since masonry was a bit overkill for this and didn't work as cleanly as I would've liked.
I have two classes in my css left-widget and right-widget, these are then set their widths and floats using a grid system, which essentially gives them float left and float right and 49.something% width.
By default I give all the widgets the left-widget class, and then with some jquery I do this:
$('.left-widget').each(function (index, value) {
var widgetPosition = $(this).position().left;
if (widgetPosition >= 30) {
$(this).removeClass('left-widget').addClass('right-widget');
}
});
$('.right-widget').each(function (index, value) {
var widgetPosition = $(this).position().left;
if (widgetPosition <= 30) {
$(this).removeClass('right-widget').addClass('left-widget');
}
});
This now does exactly what I wanted it to do, sticking the widgets to the right if they fit.

Use CSS media queries:
#media (max-width: 1000px) {
#box-js {display:none}
}
The CSS rule for #box-js will only be executed when the screen with is below 1000px.

Related

JS fadeIn & BootStrap | issue auto calculate left % margin

First, have a look there and click on the switch (Incoming/Right Now): https://ilovesubiaco.com.au/events-search/
As you can see my switch is working, but on my "Right Now" events, my Tiles are stacking up on each other.
The reason is that my elements.style for the main div of each (col-lg-3 col-sm-4 col-xs-12 masonery_item event-now-tile) is not calculating the left properly as it should, probably because my tiles are not displayed when my html is loaded.
I ran some test trying to remove the first "fadeOut(0)" to see if I could tweak it.
In that case, my tiles have the right % left per element but the issue is that my tiles are still taking up white space after display none.
I also tried to reload my div with the JS ".load" but it doesn't look good so I may not know how to use it properly.
How do I force the BootStrap library to recalculate my div Left:%; space when I switch for the first time?
Here is my JS:
jQuery(document).ready(function(){
$(".event-now-tile").fadeOut(0);
$('#event-inc-now-switch').on('switchChange.bootstrapSwitch', function (e, data) {
var state=$(this).bootstrapSwitch('state');//returns true or false
if(state){
$(".event-now-tile").fadeOut(500);
$(".event-inc-tile").fadeIn(500);
}else{
$(".event-inc-tile").fadeOut(500);
$(".event-now-tile").fadeIn(500);
}
});
});
Thanks !!
The solution was pretty simple, replace the position of my tile
.event-now-tile{
position:relative !important;
}
It's the way display is set with the fades with jQuery. Any dives which have a certain %value are stacked on each other if the display of them is set to Absolute.
I have been helped by #Davidkamer on the JS chat for this answer. Thanks to him!

Dynamic bootstrap nav wrapping menu items

I have a Bootstrap 3.3.7 page with a navbar component along the top of the page. It all works perfectly when populated with static data, but when I'm trying to populate the menu with new drop down lists based on some ajax loads from the server the menu line wraps even though there is loads of horizontal space.
I assume it is setting some fixed width based on the initial menu, and then failing to cope with the dynamic widening. If I manually narrow the page the point the nav collapses, and then widen it again then the reflow catches up and it all ends up back on one line.
Is there any way to force the Bootstrap nav to reflow programatically?
The specific element I need to make wider is ".navbar-right", and if I hand code CSS to make it wider after the dynamic addition then this works, but I'd rather not hard-code arbitrary constants into the code given that the menus are not constant and the font may change.
Answering my own question (although would appreciate any better alternatives if anyone knows any) - this seems to work OK.
// Perform the dynamic update
var htmlOutput = $.render.mytemplate(params);
$("#mynavtemplate").replaceWith(htmlOutput);
// Measure the total width of the children of .navbar-right
var newWidth = 0;
$(".navbar-right").children().each(function(){ newWidth += $(this).width(); });
// Force .navbar-right to be at least as wide as the sum of children
$(".navbar-right").css("min-width", newWidth);

Find out how wide a set of children is

I am working on a WP theme, and am having some trouble with the navigation.
The basic markup looks like this:
#navbar
ul.main-nav
li.menu-item.drop-submenu
ul.submenu
li.menu-item.drop-submenu
ul.submenu
li.menu-item.drop-submenu
etc. (any menu item can have unlimited submenus)
li.menu-item.drop-submenu
ul.submenu
li.menu-item
li.menu-item
li.menu-item
Now the problem I'm having is that a menu item with 2 or more submenus spanning to the right will eventually overflow off viewport. I'm using jquery to calculate the width and offset of the submenus and apply a class that will cause the submenus to drop on the left instead should they cause overflow. This was relatively easy to do for the "top-level" submenus, but i'm drawing a blank for the nested submenus.
Basically, i'm looking for a way to find out what set of submenus spans most to the right, but not the collective width of all nested subs, if that makes any sense...
I'm not even sure how to explain this properly, so if something is unclear i will try my best to clarify. Thank you in advance, any push in the right direction will be much appreciated.
EDIT: Made a JSFiddle
Basically, i'm looking for a way to find out what set of submenus
spans most to the right, but not the collective width of all nested
subs, if that makes any sense...
So, this will select all of the innermost submenus, which in your case would*(right?)* be those furthest to the right.
var $rightmost = $(".main-nav").find('.submenu:not(:has(.submenu))');
You could repeatedly select elements in the following way, adding a .left class to all outlying .submenus until all pass the in-viewport check you're running. Maybe put it in a while loop and see if your query results have a length, then run your checking and handling logic within.
var $rightmost = $(".main-nav").find('.submenu:not(:has(.submenu)):not(.left)');
lol. it's late here and i'm delirious, so if this sucks or doesn't make a clear argument, speak up!
Admittedly: I did not check this, so also speak up if it's funky.
Assumption
because of this,
I'm using jquery to calculate the width and offset of the submenus and
apply a class that will cause the submenus to drop on the left instead
should they cause overflow.
I'm operating under the assumption that you've already coded the viewport logic.
Edit: this works
though it could be optimized... And I didn't at all do it in the I think cool way I proposed. GSD
You could have a look at the Jquery positionCalculator that allows your script to check for collisions automatically (See the Bootstrap dropdown example at the bottom of the page).

scroll bar not visible in jquery tabs

First up, I know this question is probably asked several times, but everyone's layout is different!
I have a mapping application and with a left side tool bar. This tool bar has jquery tabs. I cant get a scroll bar on these tabs. even after overloading .ui-tabs-panel. I know just by adding a height:somepx here gives me scroll bars, but thats not what i want. I want the height to be always till all the way down. I have tried several things but nothing works :(
I suspect its because of my other layout properties which are there to keep the layout liquid (make map adjust to screen sizes and keep left side bar constant).
Here is the stripped down version in Jsbin:
http://jsbin.com/exeguw/edit#source
Can some one please help me get the vertical scroll bar?
Thanks!
If you set the tab div to the height of the #map div (adjusted for tab headers) after the tabs are created, then overflow will kick in and make the contents scrollable:
javascript:
function ResizeTabs() {
$("div.scroll-tab").height($("#map").height() - 80);
}
$(function() {
$(window).resize(ResizeTabs);
$('#tabs').tabs({
create: ResizeTabs
});
});
Updated jsBin.
EDIT: now handles window resizing as well!
Try this
http://jsbin.com/exeguw/9/edit#javascript,html,live

Is it okay to rely on javascript for menu layout?

I have a website template where I do not know the number of menu items or the size of the menu items that will be required. The js below works exactly the way I want it to, however this is the most js I've every written. Are there any disadvantages or potential problems with this method that I'm not aware of because I'm a js beginner? I'm currently manually setting the padding for each site. Thank you!
var width_of_text = 0;
var number_of_li = 0;
// measure the width of each <li> and add it to the total with, increment li counter
$('li').each(function() {
width_of_text += $(this).width();
number_of_li++;
});
// calculate the space between <li>'s so the space is equal
var padding = Math.floor((900 - width_of_text)/(number_of_li - 1));
// add the padding the all but the first <li>
$('li').each(function(index) {
if (index !== 0)
{
$(this).css("padding-left", padding);
}
});
You can do this hackily in CSS, using display: inline-block, and text-align: justify
<ul>
<li>thing</li>
<li>thing2</li>
<li>thing3</li>
<li>thing4</li>
<li class="hack"></li>
</ul>
And then:
ul { text-align: justify }
li { display: inline-block }
li.hack { width: 100% } /* force the justified text to wrap */
Demo
​
Yes, there are disadvantages of using JS for formatting.
It is strongly recommended to avoid using JS for formatting and positioning, use CSS whenever possible.
Javascript is interpreted and run very differently from browser to browser, from OS to OS, from OS/browser version to version.
CSS rendering is a native browser engine function and its rendering priority is higher than that of JS.
CSS rendering is much more speedy than JS.
Etc.
What you are doing now I would never suggest doing. IMHO, this is a very wrong approach. JS is absolutely definetely misused in this case. You have to use CSS for this task, and I would suggest posting a question about how to use CSS correctly for this task.
I would suggest having a default spacing between them in a way that would not push them out of their container. The extra javascript to enable them to space equally should be an enhancement only.
I think the answer to your question is, if it works, then it works (and will continue to work), but that doesn't mean that this is the best way to handle it. If you *care about the best way, then investigate how to improve your approach using mostly (or even exclusively) CSS. If you're just looking to get the job done, and it's working, then you're good to go.
Depending on your site visitors, there will be around 3% who visit you with JS disabled. And you want the site to work for them to. Maybe not the unnessecary parts of the site but you want the critical parts to work. Navigation is one of the most important parts of a website.
Make sure the navigation works without JS (doesn't have to be as fancy as with JS) and then you could make some improvements with JS.
You don't need JavaScript as long as you can rely on a CSS algorithm that adapt width to its content: the table layout algorithm :)
See http://jsfiddle.net/r9yrM/1/ from my previous answer for examples.
Don't forget to have a minimum padding on each "cell", text stuck to a border isn't very readable (and ugly). You'll also probably want text-align: center on cells (last CSS rule).
With JS, you could decide of a maximum number of tabs (or a minimum "reasonable" width) and above (below) that number, add a class on the parent that will trigger each tab to render as float: left and block and not table-cell anymore. Then it'll occupy 2 or more lines (like the extension Tab Mix Plus on Firefox)
Note: there're at least 2 algorithms for table: with and without table-layout: fixed, depending on freedom left to the browser when adapting.
Note on your jQuery code above: "each li except the first" can be expressed by $('li + li') (the first one isn't preceded by a li)

Categories

Resources