Target CSS and JS to specific tables - javascript

I have three tables on a page, there are some responsive features I want applied to 2 of the 3 tables- the 3rd is just a basic 2 column table. The problem I am having is that the css + js is also applying globally to all tables including the third table which I more or less just need as basic without any js bells and whistles.
I have tried applying a class to the table and looking over the script but was unable to fix the issue.
https://codepen.io/GideonB/pen/rgWgPm I recreated the issue in this pen so that you can see as its a bit extensive. Basically the third smaller table has two columns but once the screen size is reduced below 1024px it reduces to one column (inheriting the styling I want applied only to the two larger tables) while hiding the other. Below is the script I am using.
$('ul').on('click', 'li', function() {
var pos = $(this).index() + 2;
$('tr').find('td:not(:eq(0))').hide();
$('td:nth-child(' + pos + ')').css('display', 'table-cell');
$('tr').find('th:not(:eq(0))').hide();
$('li').removeClass('active');
$(this).addClass('active');
});
// Initialize
var mediaQuery = window.matchMedia('(min-width: 640px)');
// Add Event Listener
mediaQuery.addListener(selectElement);
// Function Event Listener
function selectElement(mediaQuery) {
if (mediaQuery.matches) {
$('.sep').attr('colspan', 5);
} else {
$('.sep').attr('colspan', 2);
}
}
// On Load
selectElement(mediaQuery);
Any and all help and suggestions would be greatly appreciated. Basically I just can't seem to figure out how to target the two tables specifically and leave the third alone. Any changes I make to the two upper tables effects the smaller one.

Try adding this to your css outside of your media query, worked for me see code pen below:
table.si-cov-tb td{
display: table-cell;
}
codepen

Related

JQuery rollover tooltip disappears off screen - fiddle included

I'm developing a site that uses isotope to lay out a number of items in grid form.
I'm implementing a rollover system that displays popup boxes with additional info.
The issue is that on narrow screens the popups flow off the screen to the right, example here:
https://jsfiddle.net/wsgfuace/2/
Ideally when rolling over the right half of the screen I'd like the popups to anchor to the lower right hand corner instead of the lower left.
How is this possible please?
I found this code which looks like it could potentially work but am unable to implement it successfully:
$(function() {
$('.item-s').hover(function() {
var win=$(this).find('.big-s:visible');
if(win.length>0) {
var screenwidth=$('body').width();
var width=win.width();
var pos=win.position();
var rightpos=width+pos.left;
if(rightpos>screenwidth) {
var moveleft=rightpos-screenwidth;
win.css('margin-left','-'+moveleft+'px');
} else {
win.css('margin-left','0px');
}
}
});
});
This was solved using a combination of jquery to detect page width and hence cursor position:
$(".item-s").mouseover(function(e){
var pageWidth = $('body').width();
if ( e.pageX > pageWidth / 2 ){
$(this).toggleClass('special');
}
});
and by adding a 'special' div to the CSS to shift the popup as detailed here:
Selecting and manipulating CSS pseudo-elements such as ::before and ::after using jQuery
Updated fiddle for ref here:
https://jsfiddle.net/wsgfuace/5/

Javascript check for empty spaces when css float:left

Okay now.. I really didn't know how to give this one a title. Here is my problem. I am trying to make a page where the body has a class defining the width of another div a.k.a baser.
I have a jQuery script that detects the width of the window and gives body a class hereafter. for example when the width of the window is about 900px - body will be given a class .col_6.
Each card is 150px in width, but when they have the additional class large they will be 300px in width. The problem now is that depending on the order of the cards in HTML, there will be some empty spaces if a card.large should be placed in a space only 150px wide. Then the card will automatically jump to next row and leave an open space of 150px in the previous row.
What I would like to know is - what can I add to my script to perhaps selecting a 150px wide card placed later in the order and move it in the empty spot or filling out the empty spot with a javascript made div ( for other purposes )..
I hope you are able to figure out my problem by reading this.. I have made a jsfiddle that shows my code and the problem. You can try resizing the window when reading the fiddle. It will show you how an empty space will be seen sometimes.
http://jsfiddle.net/EK8q2/4/
here is my javascript/jQuery if it can help you any way..
$(document).ready(function() {
winResize(window.innerWidth);
});
$(window).resize(function() {
winResize(window.innerWidth);
// Room for more functions
});
function winResize(w) {
resizeBaser(w);
// Room for more functions
}
function resizeBaser(w) {
var index = Math.min(10, Math.floor(w / 150));
if (index > 0) {
$('body').alterClass('col_*', 'col_' + index);
}
}
The algorithm as I see it is this:
Attach to load/scroll/resize events:
$(window).on('load scroll resize', function () {
});
There, group the $('.card') elements into an array of rows.
Something like:
var rowsObj = {}, rows = [];
$('.card').each(function(){
var el = $(this),
pos = el.position(),
currentRow = rowsObj[pos.top] || (rowsObj[pos.top] = []);
currentRow.push(el);
});
$.each(rowsObj, function(k, v) {
if (/^\d+(\.\d+)?$/.test(k)) {
rows.push(v);
}
});
// rows now contains array of arrays of $-ed elements
3. Then I'd enumerate the rows from end to start and tried to id all orphan cards (condition: single most narrow card) - having these, I'd search from top to bottom and tried to locate the possible new row (i.e. the last element of that potential row) and orphan.insertAfter(thatElement). Upon insertion, I'd exclude both rows (one containing the orphan, the other - incomplete row) from the array. Do until no pairs (orphan-incomplete) can be formed.
4.Then I'd think on how to extend this logic to widths larger than single card.

Trying to align the position of div's which are of different sizes, so that there will not be any blank spaces between them

Please don't consider my question as a duplicate. I just din't succeed trying Display divs with different sizes with CSS
As suggested in the above post i used Masonry. But failed to get it worked. I am using codeigniter.
Here are the css i am using
#container {
width:90%;
margin:3% 0px 0px 10%;
}
.item {
margin:10px 10px 10px 10px;
float:left;
width:240px;
border:5px solid #f0f0f0;
background-color:#d2dbde;
border-radius:5px;
}
Javascript and js files
<!-- include js files -->
<script type="text/javascript" src="http://www.myappdemo.com/KarmakExpo/js/jquery.min.js"></script>
<script type="text/javascript" src="http://www.myappdemo.com/KarmakExpo/js/jquery.masonry.min.js"></script>
<script type="text/javascript">
$(function() {
$('#container').masonry({
// options
itemSelector : '.item'
});
});
</script>
content
<div id="container">
<div class="item">
<div id="usericon" style="width:240px;height:30px;">
<!-- content -->
</div>
<div id="name">
<!-- content -->
</div>
<div>
<a href="<?php echo $link; ?>">
<img src="<?php echo $picture = ($picture == null) ? '' : $picture; ?>" width="240px" height="auto">
</a>
</div>
I am displaying images,name,date etc in div section
Dynamic divs put in their place
JsFiddle - Demo (number of columns depends on width of document window).
Since it appears you have divs of regular widths, you might try something like this:
Note: Since first answering with this simple demo script, I have substantially altered the linked jsFiddle demo. It now barely resembles this code, but the basics are pretty much the same.
CSS kinda like this
div.column {
display:inline-block; /* "Columns" should be only as wide as their setting, */
vertical-align:top; /* should sit next to each other horizontally, */
width:240px; /* and be vertically aligned. */
height:auto;
margin:10px 0px 10px 10px;
}
div.column div.row {
width:240px; /* All "row" divs are of the same width, */
height:auto; /* but of varying heights */
margin:0px 0px 10px 0px;
padding:0px;
background-color:#00f0f0;
}
JavaScript kinda like this
(function () {
var tdw = 240 + 0 + 10; // Div width + margin-left + margin-right
window.addEventListener("load", function () {
var ww = window.innerWidth, // how much width to play with?
cn = Math.floor(ww / tdw), // how many columns will fit?
cdl = [], // memory
lc = 0, // alternation
c = 0, // iteration
ncd; // element object
while (c++ < cn) {
ncd = document.createElement("div"); // create columns
ncd.setAttribute("class", "column"); // set their class
document.body.appendChild(ncd); // add to page
cdl.push(ncd); // remember them
}
c = 0;
while (c++ < 100) { // this for demo // loop until there're no more
ncd = document.createElement("div"); // create your divs
// this could be where you add your div content
ncd.setAttribute("class", "row"); // set their class
lc = lc < cdl.length ? lc : 0; // alternate column as parent
cdl[lc++].appendChild(ncd); // add the div to the column
ncd.style.height = (200 * Math.random()) + "px"; // this for demo
// or you could add the content via innerHTML
}
}, false);
}());​
This answer was put together whilst assuming a lot. With more detail in the question, I could have provided a more complete answer.
Since being asked to explain...
As I understand the question, it is to find a way to take dynamic information (extracted from where is irrelevant), and fill divs with it. Each of those divs is to be set on the page (presumably within a "feed" container or similar) in columns. Since the width of these (lets call them "infodivs") infodivs is of a set width, we can create columns of fixed widths to contain them. Now the divs are free to be whatever height they need to be (according to the info they contain), and will simply stack up on top of each other, within their parent div.column.
On page load we measure the available width (in a live version accounting for offsets etc), and calculate how many columns will fit horizontally, then create those columns. To save reading and re-reading the DOM, we can store the columns to an array for easy look-up later.
After creating the columns, we are free to add the dynamically created infodivs to the columns, cycling through the column look-up array, utilizing each progressive column (left to right across the screen) for each new infodiv. Once we get to the last column, we set the look-up counter back to zero, and continue loading infodivs.
The method results in each column being filled with an approximately equal number of info divs (dependant on maths). There is however no check of the height of each infodiv, so any column could end up with much longer content than the others. A way around this would be to measure the height of each column as each new infodiv is created, then add that infodiv to the column which is shortest. This would result in columns remaining more closely equal in height.
Note: The demonstration jsFiddle connected to this answer now contains a rudimentary function to dynamically measure the column heights as infodivs are being created. In order to get an accurate reading of the column height(s), each image has a temporary onload listener attached which triggers the creation of the next infodiv. The listener is removed as soon as it's done it's job to free up resources. This method slows overall page loading, but not enough to be impractical. Depending on real circumstances, faster less accurate loading might be more desirable. In that case, discard the image's onload listeners and create infodivs on demand regardless of the state of those previously created.
Further to dynamic measurement: The loading of large amounts of data and/or images (especially images) could be improved by the addition of an onscroll listener triggering a function to load new data (infodivs in this case) only when the visitor is scrolling toward the end of what they already see. This would serve to reduce server stress and increase browser response. Plus: there's no point loading what the visitor may never scroll to look at.
So the code in pseudo terms is something like:
How wide is the screen?
Make (screen-width divided by column-width) columns.
While we have new infodivs being created, add them to the columns.
Don't add them all to one column, but shared them out equally.
The end result is dynamically created divs of info of equal widths, but varying heights, being laid out in a columnized fashion. Their natural tendency is to be as high up their parent as possible, so they'll always be sitting just beneath the infodiv above them.
Since the columns have their display property set to inline, they'll tend to sit side by side where there is space for them. A caveat is that if the width of the column's parent is reduced (after the initial layout is created), the right-most column will be pushed below its fellow columns.
As for the PHP - That's another story :-)

Stopping jQuery equal height divs from calculating hidden content

I am using the following jQuery to giv certain divs with the id's #main, #sidebar, #side-event equal height. On most pages, I am using .hide(); to toggle information within the content section of the site. The problem is when JS caluclates the height of the #main div, it's calculating all of the hidden content as well, which I do not want. How can I alter my code so that the height is equal to the tallest div, and not include the hidden information in the equation? In addition I added the code I am using to hide the information upon page load. Here is my page from the site for referencing the issue. Hoping someone can help me with this issue.
http://shadowfaxdigital.com/cdi/events/mba-essentials-business-design-workshops/
Calculating height:
$("#main, #sidebar, #side-event").addClass("heights");
var highestCol = Math.max($('#main').height(),$('#sidebar').height(), $("#side-event").height());
$('.heights').height(highestCol);
Code used to hide the content in the toggles:
//jQuery toggle
$(".toggle_container").hide();
$("h2.trigger").click(function(){
$(this).toggleClass("active").next().slideToggle("slow");
});
you can add the visible selector, this will check if the element has display:none or opacity:0
var $sfd = jQuery.noConflict();
var cols = $sfd('#main:visible, #sidebar:visible, #side-event:visible');
var maxHeight = 0;
$(cols).each(function(){
$(this).addClass('heights');
maxHeight = Math.max($(this).height(), maxHeight);
});
$sfd('.heights').height(maxHeight);
It's not entirely clear what exactly you're asking for help with. .height() will only include the height of child elements that take up space in the layout. So an item that was hidden with .hide() will be marked display:none and will not be included in the height of any parent elements. But an item that has a zero opacity or visibility:hidden will take up space in the layout and will be included in a parent's height.
In jQuery, you can see if anything is visible with:
$("#main").is(":visible");
Or, you can put it directly into a selector to only include visible items:
$("#main:visible")
So, you could change your code to something like this if you only want to include the visible items in your selector:
var visibleItems = $("#main:visible, #sidebar:visible, #side-event:visible");
var highestCol = Math.max.apply(this, visibleItems.map(function() {
return $(this).height();
}).get());
I ran into this issue aswell today. Googled alot and found this thread. Seems this wasn't properly solved, therefore I'm posting my solution:
My issue was that the height-adjusting script was calculating the heights before the elements were successfully hid with jQuery, I therefore copied my height-equalizing script into a $(document).ready(function() {} );
Like this:
$(document).ready(function()
{
if ($('.sidebar').height() < $('#mainwindow').height())
{
var mainwindowHeight = $('#mainwindow').height();
$(".sidebar").css('height', mainwindowHeight+8+'px');
}
});
This solved it for me.
Hope this helps someone.

Flot graph does not render when parent container is hidden

I was having an issue where a flot graph would not render in a tabbed interface because the placeholder divs were children of divs with 'display: none'. The axes would be displayed, but no graph content.
I wrote the javascript function below as a wrapper for the plot function in order to solve this issue. It might be useful for others doing something similar.
function safePlot(placeholderDiv, data, options){
// Move the graph place holder to the hidden loader
// div to render
var parentContainer = placeholderDiv.parent();
$('#graphLoaderDiv').append(placeholderDiv);
// Render the graph
$.plot(placeholderDiv, data, options);
// Move the graph back to it's original parent
// container
parentContainer.append(placeholderDiv);
}
Here is the CSS for the graph loader div which can be placed
anywhere on the page.
#graphLoaderDiv{
visibility: hidden;
position: absolute;
top: 0px;
left: 0px;
width: 500px;
height: 150px;
}
Perhaps this is better solution. It can be used as a drop in replacement for $.plot():
var fplot = function(e,data,options){
var jqParent, jqHidden;
if (e.offsetWidth <=0 || e.offetHeight <=0){
// lets attempt to compensate for an ancestor with display:none
jqParent = $(e).parent();
jqHidden = $("<div style='visibility:hidden'></div>");
$('body').append(jqHidden);
jqHidden.append(e);
}
var plot=$.plot(e,data,options);
// if we moved it above, lets put it back
if (jqParent){
jqParent.append(e);
jqHidden.remove();
}
return plot;
};
Then just take your call to $.plot() and change it to fplot()
The only thing that works without any CSS trick is to load the plot 1 second after like this:
$('#myTab a[href="#tabname"]').on("click", function() {
setTimeout(function() {
$.plot($(divChartArea), data, options);
}, 1000);
});
or for older jquery
$('#myTab a[href="#tabname"]').click (function() {
setTimeout(function() {
$.plot($(divChartArea), data, options);
}, 1000);
});
The above example is applied to Bootstrap tags for Click funtion. But should work for any hidden div or object.
Working example: http://topg.org/server-desteria-factions-levels-classes-tokens-id388539
Just click the "Players" tab and you'll see the above example in action.
This one is a FAQ:
Your #graphLoaderDiv must have a width and height, and unfortunately, invisible divs do not have them. Instead, make it visible, but set its left to -10000px. Then once you are ready to show it, just set it's left to 0px (or whatever).
OK, I understand better now what you're actually saying... I still think your answer is too complicated though. I just tried this out using a tabbed interface where the graph is in a hidden tab when it's loaded. It seems to work fine for me.
http://jsfiddle.net/ryleyb/dB8UZ/
I didn't have the visibility:hidden bit in there, but it didn't seem necessary...
You could also have visibility:hidden set and then change the tabs code to something like this:
$('#tabs').tabs({
show: function(e,ui){
if (ui.index != 2) { return; }
$('#graphLoaderDiv').css('visibility','visible');
}
});
But given the information provided, none of that seems particularly necessary.
I know this is a bit old but you can also try using the Resize plugin for Flot.
http://benalman.com/projects/jquery-resize-plugin/
It is not perfect because you'll sometimes get a flash of the non-sized graph which may be shrunk. Also some formatting and positioning may be off depending on the type of graph that you are using.

Categories

Resources