Here is my scenario:
I'm creating a sidebar menu with AngularJS. When the user selects the hamburger icon, it should slide the menu to the right. When the user selects the remove button, the menu should slide to the left (off the screen).
Current Scenario:
The menu opens and closes as expected. However, the rest of the content on the page disappears when the menu opens. I've spent time looking on the web, but cannot isolate the issue. Any tips or suggestions?
Here is my repository:
https://bitbucket.org/ChaseHardin/teaplanner/
Code:
Controller
"use strict";
teaApp.controller("menuController", function($scope) {
$scope.toggled = false;
$scope.toggle = function() {
$scope.toggled = !$scope.toggled;
}
});
View
<div ng-controller="menuController">
<h3 class="glyphicon glyphicon-menu-hamburger" id="menu-align-hamburger" ng-click="toggle()" ng-show="!toggled"></h3>
<div class="menu-box" ng-show="toggled">
<h3 class="glyphicon glyphicon-remove" id="menu-align-remove" ng-click="toggle()"></h3>
</div>
<div>
<h1 class="text-center">Hello StackOverflow!!</h1>
</div>
</div>
CSS
.menu-box {
background-color: #403b41;
width: 20%;
height: 100vh;
}
#menu-align-hamburger {
padding-left: 15px;
cursor: pointer
}
#menu-align-remove {
padding-left: 15px;
cursor: pointer;
color: dimgrey;
}
When your menu expands, it ends up taking up the entire content area, pushing your "Hello" text below the sidebar.
Create a more flexible layout, such as applying display:inline-block to both the menu and the content area will cause the content to simply "move over" when the menu opens rather than getting pushed below the menu.
P.S., if you scroll down far enough, you'll see that your content is still there. it's just hidden from view, depending on your resolution.
Related
I'm creating a user card where there's a menu button on the top of the card when clicked, it should show a menu. Whenever I click on the menu of the first item in the loop, then it shows fine. However, there are many user cards and when I click on the menu button of the other cards, the menu still shows on the first card and not on the card that I click. What am I doing wrong here?
<template>
<div class="custom-users" v-if="users && users.length > 0">
<user-card
v-for="user in users"
:key="user.userId"
#open-menu="openMenu"
>
</user-card>
<div class="menu" v-if="showMenu">
<p>Delete</p>
</div>
</div>
</template>
<script>
export default{
data() {
return {
showMenu: false,
};
},
methods: {
openMenu(){
this.showMenu = !this.showMenu;
},
}
}
</script>
<style scoped>
.custom-users{
position: relative;
}
.menu{
position: absolute;
height: 100px;
width: 100px;
top: 60px;
right: 25px;
z-index: 9999;
}
</style>
Absolutely positioned elements are positioned absolutely relative to their most recent parent that has position: relative on it (or position: absolute as well).
You need to put both elements inside a container that has position: relative so that the dropdown will be positioned relative to the card, not to the whole container.
The menu is currently positioned relative to custom-users, which is common to all <user-card>. It simply looks like it's associated with the first <user-card> because they both are aligned to the top left (in normal flow).
Move the menu
<div class="menu" v-if="showMenu">
<p>Delete</p>
</div>
Inside the <user-card> component, apply position: relative; to it's top most element and make the below state and method part of <user-card> as well.
data() {
return {
showMenu: false,
};
},
methods: {
openMenu(){
this.showMenu = !this.showMenu;
},
}
This won't be a big problem for now since menu is only created conditionally. If menu turns out to be a large component on it's own, you can give it the ability to be displayed at coordinates passed in as props in future.
I am trying to create a sticky menu using CSS Bootstrap affix and list-group menu.
I manage to get most of it to work except for when the user scrolls down.
When the user scrolls down, the menu seems to take the entire with of the page.
I tried to set it up via data attributes
using something like this
<div class="container">
<div class="row">
<div class="col-md-3" id="leftCol">
<div data-spy="affix">
<div class="list-group list-group-root well">
<a class="list-group-item" href="#introduction">Introduction</a>
<a class="list-group-item" href="#features">Features</a>
<a class="list-group-item" href="#dependencies">Dependencies</a>
</div>
</div>
</div>
<div class="col-md-9" id="mainCol">
Some long text for the body along with some tables.
</div>
</div>
</div>
But the data attribute did not make the menu stick! it just kept it on the top.
So I tried to use JS to get the job done like this
$(function(){
$('#leftCol').affix({
offset: {
top: 100,
bottom: function () {
return (this.bottom = $('.footer').outerHeight(true))
}
}
});
});
I created jsFiddle to show you the current behavior.
How can I fix this affix so when the user scrolls down the menu maintain the same shape?
First of all, you should use either data-attributes or JS.
I updated your jsFiddle. The position of id="leftCol" was changed:
<div class="col-md-3" >
<div id="leftCol">
...
</div>
</div>
and style was added:
#leftCol {
width: 220px;
}
Also, you should add media queries to remove affix from mobile view.
As an "unacceptable" workaround, I set a max width of the menu to 250px like so
.list-group.list-group-root {
padding: 0;
max-width: 250px;
}
I am not sure how to get it to work without adding a max-with the max with should be defined by the parent. In this case class="col-md-3"
UPDATED
javascript to the rescue!
I added the following JS code to solve this problem once an for all.
It basically resize the menu everytime affix.bs.affix event is fired
$(document).on('affix.bs.affix', '#docs-menu', function() {
$(this).width($(this).width());
});
From the docs
affix.bs.affix => This event fires immediately before the element has
been affixed.
Ok I believe I got most of the code working like you want it to. The main changes I made were adding this CSS:
#leftCol {
display: block;
height: auto;
padding: 0;
width: 100%;
}
.navbar-fixed-top-again {
position: static;
top: 60px;
z-index:1031;
}
.navbar-inner {
background: red;
padding: 5px;
}
.affix {
position: fixed !important;
}
and I changed up some of the structure on your HTML:
<div class="container body-content">
<div>made up content to allow the navigation to scroll more before it becomes sticky. This height will need to be set in the data-offset-top which is in the leftCol DIV just below this content. The same will apply if you need to set it for a footer offset.</div>
<!-- new nav section -->
<div class="col-md-3 navbar-fixed-top-again" id="leftCol" data-spy="affix" data-offset-top="80">
<div class="navbar-inner">
<div class="list-group list-group-root well">
*the rest of your code*
</div>
</div>
</div>
</div>
The main problem now is having a sticky navigation menu with variable height. If you notice when you scroll your reading content underneath jumps up and gets hidden. It seems that it is possible to fix this using JavaScript (link to SO question).
Heres the link to your updated Fiddle. Hope that helps.
Say I have a blank page and a button (somewhere in the top right corner). When I click that button I want to be able to create a square on the page (A contact card). And when I click it again I want to be able to create another card next to it with the same dimensions and so on (i.e every click adds a card till theres 4 in a roll then starts on the bottom of the card untill whole page is filled).
I am unsure on how I can accomplish this. I know how to insert a button and a click event just not sure how I can structure this. Would I need to use flex?
Thanks in advance,
I am trying to visualize how I can tackle this problem.
Would I need to use flex?
In 2016, flex would be the best way to approach creating horizontal rows, each containing 4 equal-width elements, yes.
But if you want a legacy-browser solution, you can also use
display: inline-block;
float: left;
width --px;
and a container with an explicitly specified width which means that every :nth-of-type(4n+1) element will start on a new row.
For instance:
.card {
display: inline-block;
float: left;
width: 100px;
margin: 12px;
}
means each card requires 124px of space (12px + 100px + 12px).
So if you give the .card-container an explicit width of 4 x 124:
.card-container {
width: 496px;
}
then after every 4 cards, the next card will begin on a new row.
Here's a quick prototype using jQuery and Twitter Bootstrap.
When pressing the button, the first card with class card-hidden is shown and has it's card-hidden class removed. The next button press will show the next card until there's no cards left.
HTML
<html>
<body>
<button id="button">Add</button>
<div class="container">
<div class="row">
<div class="card card-hidden col-xs-3">1</div>
<div class="card card-hidden col-xs-3">2</div>
<div class="card card-hidden col-xs-3">3</div>
<div class="card card-hidden col-xs-3">4</div>
</div>
</div>
</body>
</html>
CSS
.card {
height: 200px;
}
.card-hidden {
display: none;
}
JS
$("#button").on("click", function(e) {
if ($(".card-hidden").length > 0) {
$(".card-hidden").first().slideToggle(function() {
$(this).removeClass("card-hidden");
});
} else {
console.log("No more cards to show.");
}
});
This question already has answers here:
How to prevent a click on a '#' link from jumping to top of page?
(24 answers)
Closed 7 years ago.
I've been working on a new project recently and used the fixed top menu.
In the top navigation menu I have and unnumbered inline list.
I've got an element which is clickable and after click() it shows the vertical options that are inside the div.
I'm not sure if it's just the css mistake I did or I need to add something to make this work, but every time I click on this <li> element it navigates me to the top of the page and then shows the content of the div.
It's working at least, but I want the users to be satisfied with the functions on website, so I don't want the click() function to navigate me to the top of the page, but just to show fixed <div> from navbar that is aligned to my fixed navbar. Thanks for help.
**EDIT:**I forgot to say that after the <div> show() function I can easily move with that showed div on the site and it's fixed where it should be, but once again when I click on it to collapse it, the click() function navigates me to the top.
Here's the code:
HTML:
<li class="navbar_item navbar_item_left navbar_item_actions" onclick=">
<a class="navbar_item_link navbar_item_link_for_actions refresher" href="#">Click me!</a>
<div class="actions-dropdown">
First link
Second link
Third link
</div>
</li>
CSS:
.actions-dropdown {display: none; position: fixed; background-color: rgba(154, 210, 78, 1); width: 250px;}
.actions-dropdown a {color: rgb(250, 250, 250); padding: 8px; font-size: 15px; text-decoration: none; display: block; text-align: left; float: left; width: 234px;}
JS:
$(document).ready(function(){
$(".navbar_item_actions").click(function(){
var display = $(".actions-dropdown").css('display');
if(display == 'none'){
$(".actions-dropdown").show(400);
} else {
$(".actions-dropdown").hide(400);
}
});
});
Cancel the click so the default action (following the link) will not execute.
$(".navbar_item_actions").click(function(e){
e.preventDefault();
/* rest of code */
});
Use preventDefault on the event.
$(".navbar_item_actions").click(function(event){
var display = $(".actions-dropdown").css('display');
if(display == 'none'){
$(".actions-dropdown").show(400);
} else {
$(".actions-dropdown").hide(400);
}
event.preventDefault();
});
I want to make a similar navigation menu like what m.facebook.com did.
but this, i want to make it nicely animated slide out from left side of the website.
Flow ::
Click a button > (Menu is hidden by default) Menu Slide out, push the main container to right a bit to fit the menu > Click again > Menu Slide in and hidden again.
I got no idea to make it with javascript or jquery or ajax while i'm new to web development and there are too much of effect scripting language. May i know to achieve this, which is perfect in smoothness ?
Something along these lines... http://jsfiddle.net/HfdXY/
HTML:
<div id="menu">Menu</div>
<button id="openMenu">Toggle menu</button>
CSS:
#menu {
height: 300px;
width: 0px;
border: 1px solid black;
display: none;
}
JS:
$("#openMenu").click(function() {
var menu = $("#menu");
if ($(menu).is(":visible")) {
$(menu).animate({width: 0}, 1000, function() {$(menu).hide();});
} else {
$(menu).show().animate({width: 100}, 1000);
}
});