Recreate "Styles" drop down area of Office Ribbon? - javascript

I am trying to recreate the "Styles" section of the Office ribbon:
http://www.winsupersite.com/images/reviews/office2007_b2_06.jpg
I like how it starts out as only one row, then you can scroll through the rows, then click the arrow to expand all into a table like above. Does anyone have any ideas on how to recreate this whole interactivity??

CSS
#container { width:200px;height:50px;overflow-x:hidden;overflow-y:auto;
border:1px solid black; position:relative }
#expander { position:absolute;right:0;bottom:0px;font-size:10px;margin:0;padding:1;
border:1px solid black; border-width:1px 0 0 1px }
.item { float:left; font-size:30px;height:40px;width:50px;
margin:5px; background:gainsboro;text-align:center }
HTML
<div id='container'>
<div class='item'>A</div>
<div class='item'>B</div>
<div class='item'>C</div>
<div class='item'>D</div>
<div class='item'>E</div>
<div class='item'>F</div>
<div class='item'>G</div>
<div class='item'>H</div>
<div class='item'>I</div>
<div class='item'>J</div>
<div class='item'>K</div>
<button id='expander' onclick='expand()'>▲</button>
</div>
JS
function $(id) { return document.getElementById(id); }
function expand() {
$('container').style.overflow = "auto";
$('container').style.height = "300px";
$('container').style.width = "300px";
}
function contract() {
$('container').style.overflow = "hidden";
$('container').style.height = "50px";
$('container').style.width = "200px";
}
...should get you started. It's got a few bugs you'll have to figure out:
When to call contract()
Button isn't positioned directly under scrollbar
Button scrolls with content (and disappears)

Related

How to print an specific DIV with its CSS

I need to print an specific DIV, but every other post I have seen doesn't include the styles within the DIV, is there a way to do this with one function in javascript?
I have already seen this and other posts
Print the contents of a DIV
You can select all other elements and hide them from the page (excluding the target with the use of the :not() CSS pseudo class), then call window.print() to print the page:
btn.addEventListener('click', function(){
document.body.querySelectorAll(':not(.red)').forEach(e => e.style.display = "none");
window.print();
})
div{
height:100px;
border:1px solid;
}
.red{
background-color:red;
}
.blue{
background-color:blue;
}
<div class="red">
red
</div>
<div class="blue">
blue
</div>
<button id="btn">Print Red div</button>
If you want to create a function that accepts an element as a parameter, you can loop through all elements and check whether the current item being looped through is the parameter. If it isn't, hide the element.
Demo:
btn.addEventListener('click', function(){
printWithStyles(document.querySelector('.red'));
})
function printWithStyles(e){
document.body.querySelectorAll("*").forEach(f => f === e ? '' : f.style.display="none");
window.print();
}
div{
height:100px;
border:1px solid;
}
.red{
background-color:red;
}
.blue{
background-color:blue;
}
<div class="red">
red
</div>
<div class="blue">
blue
</div>
<button id="btn">Print Red div</button>
Unfortunately, the function above hides children of the element, which can cause issues. We can counter this by checking whether the element looped through is included in the parameter:
btn.addEventListener('click', function(){
printWithStyles(document.querySelector('.red'));
})
function printWithStyles(e){
document.body.querySelectorAll("*").forEach(f => e.contains(f) ? '' : f.style.display="none");
window.print();
}
div{
height:100px;
border:1px solid;
}
.red{
background-color:red;
}
.blue{
background-color:blue;
}
<div class="red">
<h1>red</1>
</div>
<div class="blue">
blue
</div>
<button id="btn">Print Red div</button>
To unhide all the elements after printing, a lazy way to do it would be:
document.body.querySelector("*").forEach(e => e.style.display="none");
That will show hidden elements prior to printing
Here is a simple way to do so!
$('a.printPage').click(function(){
$('#report-summary').show();
window.print();
return false;
});
#report-summary {
}
#page { size: auto; margin: 25mm 25mm 25mm 25mm; }
#media print {
#search,
.printPage {
display: none !important;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" referrerpolicy="no-referrer"></script>
<div id="report-summary">
Content here ...
</div>
<div class="printbtn">
<a class="printPage" href="#">Print Report</a>
</div>

How can I usa this JavaScript code with more than 2 sections?

I'm new in javascript and Html and I created two scrolling button to go from section1 to section2.
What can I do if I need to have more than two sections?
function f1() {
var elmnt1 = document.getElementById("sez1");
elmnt1.scrollIntoView();
}
function f2() {
var elmnt2 = document.getElementById("sez2");
elmnt2.scrollIntoView();
}
The best way to do this is by creating a pattern to any solution to make it a generic solution.
Mark your sections with an attribute of your liking, e.g.: scroll-to-id="1" and your sections can now look like <div scroll-to-id="1"></div><div scroll-to-id="2"></div><div scroll-to-id="3"></div><div scroll-to-id="4"></div>
Now make a function which will take the number as an input and scroll to the desired section. To get all targeted sections we can call the function document.querySelectorAll('[scroll-to-id]') to get all the elements with the attribute scroll-to-id.
Then find the element with the desired scroll-to-id to go to and scrollTo that element.
Full solution below:
function scrollToSection(sectionId) {
const sections = document.querySelectorAll('[scroll-to-id]');
for(let section of sections) {
if(section.getAttribute('scroll-to-id') == sectionId) {
section.scrollIntoView();
// scrollIntoView doesnot have the best browser supports. It is better to calculate the position of the section and do a scrollTo() or scrollBy()
}
}
}
button {
margin-bottom: 20px;
}
div {
padding-top: 80px;
padding-bottom: 80px;
border: 1px solid #cecece;
}
<button onclick="scrollToSection(1)">Scroll To 1</button>
<button onclick="scrollToSection(2)">Scroll To 2</button>
<button onclick="scrollToSection(3)">Scroll To 3</button>
<button onclick="scrollToSection(4)">Scroll To 4</button>
<div scroll-to-id="1">Hello 1</div>
<div scroll-to-id="2">Hello 2</div>
<div scroll-to-id="3">Hello 3</div>
<div scroll-to-id="4">Hello 4</div>
pass element as an argument to your function
function scroll(el){
el.scrollIntoView()
}
Welcome to Stackoverflow #Francy3k!
Just update your existing function to accept the ID of the section you'd like to scroll to:
.buttons { position:fixed; top:0; left:0; width:100%; background:white; padding:10px 0; text-align:center }
#sez1 { height:300px; background:green; vertical-align:middle }
#sez2 { height:300px; background:red; vertical-align:middle }
#sez3 { height:300px; background:blue; vertical-align:middle }
<div class="buttons">
<button onclick="scrollToSection(1)">Go to SEZ1</button>
<button onclick="scrollToSection(2)">Go to SEZ2</button>
<button onclick="scrollToSection(3)">Go to SEZ3</button>
</div>
<div id="sez1">
</div>
<div id="sez2">
</div>
<div id="sez3">
</div>
<script>
function scrollToSection(index) {
const section = document.getElementById("sez" + index);
section.scrollIntoView();
}
</script>
Provided the section IDs follow the same convention, you should be able to use this pattern.

Displaying a div once its within the viewport

I have 10 div elements, and all of them are 500px width and height;
<div class="cont_1">a lots of content here..</div>
<div class="cont_2">a lots of content here..</div>
<div class="cont_3">a lots of content here..</div>
<div class="cont_4">a lots of content here..</div>
<div class="cont_5">a lots of content here..</div>
<div class="cont_6">a lots of content here..</div>
<div class="cont_7">a lots of content here..</div>
<div class="cont_8">a lots of content here..</div>
<div class="cont_9">a lots of content here..</div>
<div class="cont_10">a lots of content here..</div>
and my css
div{
width:500px;
height:500px;
background:#f0f0f0;
border:1px solid #ccc;
margin:10px;
padding:10px;
}
And my seventh div is hidden with display:none. Once the user scrolls to this element how can I display it?
You'll have to attach a scroll event to your page that checks the position of each element after scrolling:
function CheckIfVisible(elem){
var ElemPos = elem.getBoundingClientRect().top;
elem.style.display = (ElemPos > 0 && ElemPos < document.body.parentNode.offsetHeight)?"block":"none";
}
window.addEventListener("onscroll", function(){
var elem = document.getElementsByClassName("cont_1")[0];
CheckIfVisible(elem);
});
window.addEventListener("onscroll", function(){
var elem = document.getElementsByClassName("cont_2")[0];
CheckIfVisible(elem);
});
window.addEventListener("onscroll", function(){
var elem = document.getElementsByClassName("cont_3")[0];
CheckIfVisible(elem);
});
and so on...

How to show div with slide down effect only with javascript

I Want to show div on click with slideup effect using javascript(not jquery).
Here is my HTML code:-
<div class="title-box">show text</div>
<div class="box"><span class="activity-title">our regions bla bla</span></div>
Kindly advise me asap.
The question states that the solution needs to be done with pure JavaScript as opposed to jQuery, but it does not preclude the use of CSS. I would argue that CSS is the best approach because the slide effect is presentational.
See http://jsfiddle.net/L9s13nhf/
<html><head>
<style type="text/css">
#d {
height: 100px;
width: 100px;
border: 1px solid red;
margin-top: -200px;
transition: margin-top 2s;
}
#d.shown {
margin-top: 100px;
}
</style>
</head>
<body>
<button id="b">Toggle slide</button>
<div id="d">Weeeeeeee</div>
<script type="text/javascript">
var b = document.getElementById('b');
var d = document.getElementById('d');
b.addEventListener('click', function() {
d.classList.toggle('shown');
});
</script>
</body></html>
The basic algorithm is to add a class to the element you want to slide in/out whenever some button or link is clicked (I'd also argue that a button is more semantically appropriate here than an anchor tag which is more for linking web pages).
The CSS kicks in automatically and updates the margin-top of the sliding element to be visible on-screen. The transition property of the element tells the browser to animate the margin-top property for two seconds.
You can try below code:
Working Demo
document.getElementById('bar').onclick = (function()
{
var that, interval, step = 20,
id = document.getElementById('foo'),
handler = function()
{
that = that || this;
that.onclick = null;
id = document.getElementById('foo');
interval =setInterval (function()
{
id.style.top = (parseInt(id.style.top, 10) + step)+ 'px';
if (id.style.top === '0px' || id.style.top === '400px')
{
that.onclick = handler;
clearInterval(interval);
if (id.style.top === '400px')
{
id.style.display = 'none';
}
step *= -1;
}
else
{
id.style.display = 'block';
}
},100);
};
return handler;
}());
You can refer following below:
<div class="title-box">
show text
</div>
<div class="box" id="slidedown_demo" style="width:100px; height:80px; background:#ccc; text-align:center;">
<span class="activity-title">our regions bla bla</span>
</div>

how to determine the element ID of div that is positioned x pixels to the right of visible screen?

Hitting a wall with this one, hope someone can lend a hand. I have a wrapper div containing many fixed-width "content" divs. It's like a table, except that the number of items "per row" aren't fixed, so that whenever the screen size is wide, more items fit onto the screen. Pretty basic.
Also, each of these "content" divs has an adjacent "details" div that is hidden by default ("style=display:none"), and an adjacent "separator" div that is empty, containing only the style "clear:both;".
Each content/details/separator div has a unique number in its ID, so that I can tell they are related (e.g., content123, details1234, separator1234)
Now, when one of these content divs is clicked, I want to reveal its "details" div below it. That part, I've got working partially, by wrapping an anchor tag around the content div, which fires an onClick javascript event, which in turns runs a jQuery statement to make visible the details and separator divs jQuery(".details1234").css("display","block");"
But you can imagine my problem. Once that "separator" div is reveled, it pushes down (clears) any "content" divs that appears to the right of it, ugly. My thought, what I have been wrestling with for hours, is to reveal the "separator" div of the content div, that is the last one appearing in the "row" that was clicked. That way, a new "row" will be opened up by the separator, so that when the "content" div is revealed it appears below the clicked item in the new row. To do that, I need to figure out the elementID of the last content div in the "row", and I was thinking about using the Y-coord of the mouse click event, plus the X-coord = to the right-most edge of the wrapper div minus half the width of the fixed-width content div. Something like that. But I am smashed into a wall and can't figure it out.
Can anyone help me do that? Or offer a different solution?
If sample code would help let me know, I could whip up an example, but it may take some screen space in this post.
Thanks everyone.. going nuts with this.
EDIT: the sample code below is based on my site. When a cell is clicked, you can see its "details" div appear below it, but unfortunately the other divs in the "row" get pushed down. that is the effect I'm trying to avoid. When a cell is clicked, I want the "details" to appear below it, but also the other divs to stay in their positions above the other cell's details, basically I want to keep the "row" intact. In the code, you can see my fruitless experiments using a "separator" div, because my assumption is that if I can insert that after the last div in the row, then the "details" div will become the next row, followed then by the next row of cells. Hope I explained it OK. Thanksgiving feast causing blood to divert from brain ;)
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentcell{
border: 2px solid blue;
padding: 4px;
float: left;
width: 200px;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
width:450px;
display:none;
float:left;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
//now highlight the clicked div and reveal its content div
var contentHI = "#content"+contentid;
var detailsON = "#details"+contentid;
var separatorON = "#separator"+contentid;
$(contentHI).css("border","2px solid green");
//$(separatorON).css("display","block");
$(detailsON).css("display","block");
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01">
<div id="content01" class="contentcell">cell01</div>
<div id="details01" class="details">here are details about cell01</div>
<div id="separator01" class="separator"> </div>
</div>
<div id="contentwrapper02">
<div id="content02" class="contentcell">cell02</div>
<div id="details02" class="details">here are details about cell02</div>
<div id="separator02" class="separator"></div>
</div>
<div id="contentwrapper03">
<div id="content03" class="contentcell">cell03</div>
<div id="details03" class="details">here are details about cell03</div>
<div id="separator03" class="separator"></div>
</div>
<div id="contentwrapper04">
<div id="content04" class="contentcell">cell04</div>
<div id="details04" class="details">here are details about cell04</div>
<div id="separator04" class="separator"></div>
</div>
<div id="contentwrapper05">
<div id="content05" class="contentcell">cell05</div>
<div id="details05" class="details">here are details about cell05</div>
<div id="separator05" class="separator"></div>
</div>
<div id="contentwrapper06">
<div id="content06" class="contentcell">cell06</div>
<div id="details06" class="details">here are details about cell06</div>
<div id="separator06" class="separator"></div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>
User ,
if you give as regular position be default , it pushes the other contents definetly down as they come in squence.
Change the hidden divs position to absolute so that it will go out of sequence and you can position at anywhere on the page by top and left property.
get the offset of the div you want next to...
http://api.jquery.com/offset/
it will have top and left property , use those property's and position next to them.
let me know if you need anything else.
give a bigger z-index for the hidden divs.
What about showing the details div with position: absolute, on top of everything else? (See here, the code's a little messy but you get the idea).
I partially figured it out, but the logic may be very clunky. I basically walk left by 100px from the width of the container div until I find a content div. Plus it doesn't work in IE8, because IE is not getting the same results from jQuery's offset() or position() as firefox, it always reports "19". So in IE, I can never get a Y-coordinate value. I'm too sleepy now to work on this anymore today. If someone can lend a hand or tell me how to improve the javascript that would be cool.
Here is the working code for Firefox (I changed javascript and css of the detail divs, compared to original question):
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentcell{
border: 2px solid blue;
padding: 4px;
float: left;
width: 200px;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
display:none;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
//now highlight the clicked div and reveal its content div
//first, figure out which separator to display.
//1.get the y-pos from the clicked element, this gives y-coord of the row
contentClicked = "#content"+contentid;
var clickedoffset = $(contentClicked).offset();
var ypos = clickedoffset.top;
var wrapperwidth = $("#overallwrapper").width();
for (var xpos=wrapperwidth; xpos>0; xpos-=100){
var elematpos = document.elementFromPoint(xpos, ypos);
var elematposid = elematpos.id;
if (elematposid.substring(0,7) == "content") {
var lastcontentdivID = elematposid.substring(7);
break;
}
}
$(contentClicked).css("border","2px solid green");
var detailsON = "#details"+contentid;
$(detailsON).css("display","block");
var lastidonscreen = "#content"+lastcontentdivID;
$(detailsON).insertAfter(lastidonscreen);
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01">
<div id="content01" class="contentcell">cell01</div>
<div id="separator01" class="separator"> </div>
<div id="details01" class="details">here are details about cell01</div>
</div>
<div id="contentwrapper02">
<div id="content02" class="contentcell">cell02</div>
<div id="separator02" class="separator"></div>
<div id="details02" class="details">here are details about cell02</div>
</div>
<div id="contentwrapper03">
<div id="content03" class="contentcell">cell03</div>
<div id="separator03" class="separator"></div>
<div id="details03" class="details">here are details about cell03</div>
</div>
<div id="contentwrapper04">
<div id="content04" class="contentcell">cell04</div>
<div id="separator04" class="separator"></div>
<div id="details04" class="details">here are details about cell04</div>
</div>
<div id="contentwrapper05">
<div id="content05" class="contentcell">cell05</div>
<div id="separator05" class="separator"></div>
<div id="details05" class="details">here are details about cell05</div>
</div>
<div id="contentwrapper06">
<div id="content06" class="contentcell">cell06</div>
<div id="separator06" class="separator"></div>
<div id="details06" class="details">here are details about cell06</div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>
EDIT:
Blasted IE. I just can't trust it to determine screen coordinates. I got it working though, but only for Firefox. again IE is trying to drive me insane by not handling insertAfter properly. arrgh! here is the final code:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentwrapper{
}
.contentcell{
padding: 4px;
float: left;
width: 200px;
height: 100px;
border: 2px solid blue;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
display:none;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
var contentClicked = "#content"+contentid;
var thisypos = $(contentClicked).offset().top;
var nextdivid = contentClicked;
var countid = contentid;
do
{
var prevdivid = nextdivid;
var nextcontentid = (countid * 1) + 1;
var nextcontentid = '' + nextcontentid;
if ( nextcontentid.length < 2)
{ nextcontentid = "0" + nextcontentid; }
nextdivid = "#content" + nextcontentid;
if ( $(nextdivid).length ) {
var nextypos = $(nextdivid).offset().top;
countid++;
} else {
break;
}
}
while (thisypos == nextypos);
$(contentClicked).css("border","2px solid green");
var detailsON = "#details"+contentid;
$(detailsON).css("display","block");
$(detailsON).insertAfter(prevdivid);
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01" class="contentwrapper">
<div id="content01" class="contentcell">cell01</div>
<div id="separator01" class="separator"> </div>
<div id="details01" class="details">here are details about cell01</div>
</div>
<div id="contentwrapper02" class="contentwrapper">
<div id="content02" class="contentcell">cell02</div>
<div id="separator02" class="separator"></div>
<div id="details02" class="details">here are details about cell02</div>
</div>
<div id="contentwrapper03" class="contentwrapper">
<div id="content03" class="contentcell">cell03</div>
<div id="separator03" class="separator"></div>
<div id="details03" class="details">here are details about cell03</div>
</div>
<div id="contentwrapper04" class="contentwrapper">
<div id="content04" class="contentcell">cell04</div>
<div id="separator04" class="separator"></div>
<div id="details04" class="details">here are details about cell04</div>
</div>
<div id="contentwrapper05" class="contentwrapper">
<div id="content05" class="contentcell">cell05</div>
<div id="separator05" class="separator"></div>
<div id="details05" class="details">here are details about cell05</div>
</div>
<div id="contentwrapper06" class="contentwrapper">
<div id="content06" class="contentcell">cell06</div>
<div id="separator06" class="separator"></div>
<div id="details06" class="details">here are details about cell06</div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>

Categories

Resources