Bootstrap: Toggle visibility of elements for browsers, not for print? - javascript

I have a list of elements that can contain a large number of sub-elements.
For keeping the layout clearly arranged the element-long are by default invisible. When the user clicks the Show more entry the visibility of element-short and element-long is toggeled via JavaScript (.children('.element-short, .element-long').toggle()).
<div class="element-short" style="display: none;">
<p>Heading</p>
<ul> [truncated sub-element list] </ul>
<div>Show more</div>
</div>
<div class="element-long" style="display: block;">
<p>Heading</p>
<ul> [full sub-element list] </ul>
</div>
The problem is now that this changes the visibility for both, on-screen and printing. However for printing I want that all element-long sections are printed and the element-short section are always hidden, independently if the user has clicked the show more button before or not.
Bootstrap has a lot of visible-*-block classes, however these classes only target a special display size and not the general visibility in the web browser.
How can I show/hide a section via JavaScript only in the web browser, but keep it always visible or hidden while printing?

This seems to do the trick:
CSS:
#media print {
.element-short {
display: none !important
}
.element-long {
display: block !important
}
}

maybe you can use media query
#media print {
.show-me-when-print {
visibility: visible;
display: block;
}
}
#media screen {
.hide-me-in-screen {
display: none;
}
}
and add those class to your item
<div class="item hide-me-in-screen show-me-when-print">
show me when print
</div>
https://jsfiddle.net/3zqetL69/

Related

Why toggling doesn't work on Firefox Developer Tools?

I don't know why my javascript code is not toggling on firefox developers tools, and that's my code:
const hamburger = document.querySelector('.header .nav-bar .nav-list .hamburger');
const mobile_menu = document.querySelector('.header .nav-bar .nav-list .menu');
const header = document.querySelector('.header-container')
hamburger.addEventListener('click',() => {
hamburger.classList.toggle('active');
});
Maybe you can check, if your element is clicked or not with console.log()
hamburger.addEventListener('click', function(){
console.log("test")
})
I suggest you not to use arrow function in addEventListener, because of 'this' problem in arrow function
When you open developer tools in Firefox, on the left hand side of the menu there are tab header for "inspect", "console", network" and so on.
On the right hand side of the same menu bar, there is an icon of a framed document that shows "Select an iframe as the currently targeted document" when you hover over it. Click the icon and select the iframe containing the .header-container element.
Assuming the correct nested elements have been set up in HTML, the posted code now runs if you paste it after the script input prompt and press enter, and you can click the hamburger icon to toggle its active cf class.
Use of the const declaration in the pasted script prevents it being run more than once without reloading the page, which is a good thing - an even number of anonymous listeners that each toggle active would not affect the class list of the hamburger element.
FWIW, some HTML that can be used to show the code in the post "just works" when run in the Firefox console:
<style>
div { margin: 0.5rem; margin-left: 2rem; border: thin solid maroon;}
.active {background-color: yellow;}
</style>
<div class="header-container">
.header-container
<div class="header">
.header
<div class="nav-bar">
.nav-bar
<div class="nav-list">
.nav-list
<div class="hamburger">
.hamburger
</div>
<div class="menu">
.menu
</div>
(nav-list)
</div>
(nav-bar)
</div>
(header)
</div>
(header-container)
</div>
However, if the hamburger menu structure is inside an iframe element it needs to be selected first to prevent generating an error that hamburger is null.

How to click only on the text of a header and not the empty whitespace to the right? [duplicate]

This question already has answers here:
How can I make a div not larger than its contents?
(43 answers)
Closed 2 years ago.
I am trying to make a link on a header be clickable on the text of the header only. Problem is, in my case, the link is still clickable, even when there is no text(it still clicks on empty blue space to the right).
Example:
as you can see, the whole blue is clickable, but I just want the click to end after the "Hello World Link" word.
Is there a way to allow to click only on the text "Hello World Link" and not the rest of blue empty space to the right?
My code:
<a href="blah blaha ">
<div class="headerText">
<h2>#title</h2>
</div>
</a>
CSS:
.headerText{
h2:hover {
background-color: yellow;
}
}
Simply use display: inline-block; on your .headerText DIV
.headerText {
display: inline-block;
}
.headerText h2:hover {
background-color: yellow;
}
<a href="blah blaha ">
<div class="headerText">
<h2>#title</h2>
</div>
</a>
SCSS:
.headerText{
display: inline-block;
h2:hover {
background-color: yellow;
}
}
For applying link to text only, move the a element just above the text element(here h2).
Try this:
<div class="headerText">
<a href="blah blaha ">
<h2>#title</h2>
</a>
</div>
Also check the style of h2. If it has a fixed width wider than the text, it may cause again this problem. Better to provide an HTML,CSS snippet in the question.
I don't know whitch are the defined styles of yours components, but on some cases you can use the css empty pseudo class, and set the pointer-events property as none. This approach just work in the case that the element doesn't have any children and also the element content is empty.
a:empty {
pointer-events:none;
}

Vanilla JS (no jQuery) - How to toggle more than one class at once?

I am dealing with a legacy system and I can't rewrite the whole css.
So I find myself in need to toggle 2 classes on the same element when another one is clicked (imagine clicking on a button to hide/show a modal).
The following is the code for the modal.
Where the modal window is by default .hidden (without the class "visible") and on click it is .visible (without the class "hidden").
function openModal(modalID) {
document.getElementById(modalID)
.classList.toggle('hidden');
document.getElementById(modalID)
.classList.toggle('visible');
}
I agree to accept the
<a href="#"
onclick="openModal('tandcmodal')">
terms and conditions
</a>
of this website.
<div id="tandcmodal"
class="hidden">
Content of the modal
</div>
So, I believe there must be a way to toggle more than one class at once with .toggle().
Or isn't it?
Unfortunately, .toggle accepts only one argument: the one class name you wish to toggle. To be DRY, you'll have to iterate over an array of class names, or save the classList in a variable and call .toggle twice:
function openModal(modalID) {
const { classList } = document.getElementById(modalID);
classList.toggle('hidden');
classList.toggle('visible');
}
.hidden {
display: none;
}
.visible {
display: block;
}
I agree to accept the
<a href="#" onclick="openModal('tandcmodal')">
terms and conditions
</a> of this website.
<div id="tandcmodal" class="hidden">
Content of the modal
</div>
But note that usually there's no need for both a hidden and a visible class. Often you can have just a hidden class, and add it / remove it, letting the default display style take effect when hidden is not active:
function openModal(modalID) {
document.getElementById(modalID).classList.toggle('hidden');
}
.hidden {
display: none;
}
I agree to accept the
<a href="#" onclick="openModal('tandcmodal')">
terms and conditions
</a> of this website.
<div id="tandcmodal" class="hidden">
Content of the modal
</div>
Also note that inline attribute handlers behave very strangely, have escaping problems, and are generally considered to be quite poor practice - they should probably be avoided in almost all cases. Consider adding the event listener using Javascript instead:
document.querySelector('a').addEventListener('click', () => openModal('tandcmodal'));
function openModal(modalID) {
document.getElementById(modalID).classList.toggle('hidden');
}
.hidden {
display: none;
}
I agree to accept the
<a href="#">
terms and conditions
</a> of this website.
<div id="tandcmodal" class="hidden">
Content of the modal
</div>

Issue with overflow:hidden/visible toggle on hover. Gif available in post

As you can see above, I cannot select the overflowed events on the calendar date. It looks like it's because I have the overflow:hidden/visible toggle triggering on the class of the calendar date: '#cell-shell'.
Here is the HTML code for that specific date:
<td>
<div id="09" class="cell-shell>
<div class="date-num">9</div>
<div class="event-wrap>
<span></span> <!--these hold edit buttons when editor is logged in-->
<span></span>
<div id="e1" class="cell-data">Event 1</div>
</div>
<div class="event-wrap>
<span></span>
<span></span>
<div id="e2" class="cell-data">Event 2</div>
</div>
<div class="event-wrap>
<span></span>
<span></span>
<div id="e3" class="cell-data">Event 3</div>
</div>
<div class="event-wrap>
<span></span>
<span></span>
<div id="e4" class="cell-data">Event 4</div>
</div>
... <!-- pattern repeats-->
</div>
</td>
Here is my current relevant CSS:
.cell-shell {
height: 152px;
width: 152px;
overflow: hidden;
}
.cell-shell:hover {
overflow:visible;
}
.event-wrap {
position: relative;
display: inline-block;
font-size: 0;
}
.event-wrap:hover {
opacity: .5;
}
Is there any way through CSS or JS that I can prioritize the '#cell-data' elements? I need to be able to click on those events 6 & 7 and beyond, but once my mouse wanders out of the '9' '.cell-shell' box into the '16' '.cell-shell' box, '16' seems to take over.
EDIT: I added more information as requested by david. I thought it was irrelevant but perhaps not. I added the elements as well as the children below them. I also added in the event-wrap CSS
It looks like it's not because you mouse over 16, but because your mouse went between the event divs, thereby touching the 16 div between the event divs.
See the frame below where you're over an event on top of 16 just before you cross the gap:
The way that hover works is that if the mouse is over any sub-element of the element with hover, that hover CSS will continue to be used. But the moment the mouse leaves the border-box of the sub-element AND is outside of the element with over, the hover CSS will stop working.
I bet that if you're fast and accurate enough, you can get the mouse to clip over the gap between frames and keep it open. But your users might not find that useful. ;P
One method that might fix this would be making sure that the event divs have no space between them. That means no margins separating them.
In order to keep your current visual without having to add too much code, you can do something like the following:
...
<div class="event-wrapper"><div id="e1" class="cell-data">Event 1</div></div>
<div class="event-wrapper"><div id="e2" class="cell-data">Event 2</div></div>
...
...where the event-wrapper class looks like:
.event-wrapper {
margin: 0px;
padding: 0px;
}
Another method might be having the whole date box expand its size, but that might require some changes to how the layout works in order to keep it from messing things up.
Anyway, I hope that helps.
Use z-index to give priority to your cell-data elements over '16'.
Find a sample demo of it's usage below:
https://www.w3schools.com/cssref/pr_pos_z-index.asp
Add CSS property z-index: -1 into your css.
.cell-shell {
height: 152px;
width: 152px;
overflow: hidden;
z-index: -1 // Here
}
.cell-shell:hover {
overflow:visible;
z-index: -1 //Here
}
Hope it will work for you.

What's the "active state" for a Bootstrap data-toggle called?

I'm trying to emulate a feature on Wikipedia's mobile pages. If you visit http://en.m.wikipedia.org/wiki/Mammal and scroll down to the heading "Distinguishing Features," then click it, you'll see the down arrow (chevron) change to an up arrow.
I inserted the two choices into my header via spans...
<h2 id="where" class="H2Toggle" data-toggle="collapse" data- target=".Header2,.Where,#glyph2">
<span class="glyphicon glyphicon1 glyphicon-chevron-down"></span>
<span id="glyph2" class="glyphicon glyphicon2 glyphicon-remove-sign"></span>
</h2>
I then added a CSS style - span#glyph2 { display: none; }
Now only the first span displays by default, but when I click on the header BOTH spans display. So I need to figure out how to make the first span not display when I click the header, then reappear when I click it again.
I could do it for a particular screen size. For example, I could make one span or the other appear or not appear if the screen is 1,000 pixels wide or wider. But I need a CSS style (or JavaScript function) that makes a character appear/disappear according to whether or not a header has been clicked.
So I guess what I'm asking is "What's the name of the default active vs the inactive state in Bootstrap?"
Bootstrap will apply the collapsed class to the trigger when the element it controls is collapsed. Otherwise, no such class is applied. You can use this to write an appropriate CSS rule.
.only-collapsed { display: none; }
.collapsed .only-collapsed { display: inline; }
.collapsed .only-expanded { display: none; }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<div data-toggle="collapse" data-target="#target">Header <span class="only-collapsed">Expand</span> <span class="only-expanded">Collapse</span></div>
<div id="target" class="collapse in">Hello, world!</div>

Categories