Burger menu icon opens and closes a hidden sidebar, at the same time I want the icon to change to an X when the sidebar is open.
Button
<span style="font-size:16px;cursor:pointer" onclick="toggleNav()"><i onclick="myFunction(this)" class="fas fa-bars"></i> </span>
Menu Scripts
<script>
function toggleNav() {
var sidenav = document.getElementById("mySidenav"),
main = document.getElementById("main");
sidenav.style.width = sidenav.style.width === "250px" ? '0' : '250px';
wrapper.style.marginLeft = wrapper.style.marginLeft === "250px" ? 'auto' : '250px';
}
</script>
<script>
function myFunction(x) {
x.classList.toggle("fas fa-times");
}
</script>
Probably making a glaringly obvious mistake but I've googled as many times as I can and still can't figure it out.
You cannot toggle multiple classes like you did
You have to do two calls
function toggleNav() {
/* var sidenav = document.getElementById("mySidenav"),
main = document.getElementById("main");
sidenav.style.width = sidenav.style.width === "250px" ? '0' : '250px';
wrapper.style.marginLeft = wrapper.style.marginLeft === "250px" ? 'auto' : '250px';*/
}
function myFunction(x) {
x.classList.toggle("fa-bars");
x.classList.toggle("fa-times");
}
i {
height: 20px;
width: 20px;
background-color: red;
display: block;
}
<span style="font-size:16px;cursor:pointer" onclick="toggleNav()"><i onclick="myFunction(this)" class="fas fa-bars"></i> The red square represent your icon</span>
Related
i have a navbar and i want to scroll it horizontally. I use "Tab" and "Tabs" from react-bootstrap. I couldn't figure out how to do this. ( I tried to wrap nav with div, but it didn't work because every tab has its own items )
I tried this:
const outsider = document.getElementsByClassName('products-tabs sub-tabs nav nav-tabs');
const distance = 200;
const scrollLft = () => {
outsider.scrollLeft -= 900;
console.log(outsider);
};
<Tab
className="products-tab"
id="products-tab"
eventKey={index}
title={subcategories.categoryName}
key={`${index + 1}_tab`}
>
{subcategories?.subcategories?.length > 1 ? (
<>
<Button onPress={scrollLft} className="brand-arrow-button">
<i className="icon-Arrow_Simple_left" align="left" />
</Button>
<Button
onPress={() => onClickLeft()}
className="brand-arrow-button-right"
>
<i className="icon-Arrow_simple_rightt" align="left" />
</Button>
<div id="menum">
<Tabs
className="products-tabs sub-tabs"
defaultActiveKey="sub-0"
id="menu-subcategories"
onSelect={e => {
const selectedTabIndex = parseInt(e.split('-')[1], 10);
setActiveSubcategory(selectedTabIndex);
}}
>
{subcategories?.subcategories
?.concat(subcategories?.subcategories)
.map((subcategoryItem, subIndex) => (
<Tab
eventKey={'sub-' + subIndex}
title={subcategoryItem?.name}
key={`${subIndex + 1}_subTab`}
>
**Items
</Tab>
))}
</Tabs>
And this is my css:
&.sub-tabs {
border-radius: 15px;
margin-left: -1px;
margin-right: -16px;
padding-bottom: 1px;
margin-top: 10px;
flex: none;
overflow-x: scroll;
white-space: nowrap !important;
When i click to the button, nothing happens.
This is the console output:
enter image description here
In React, you can use the useRef() Hook to get the reference of a component (similar to document.getElementsByClassName()). Then, you can apply horizontal scrolling using element.current.scrollLeft.
Example:
import { useRef } from 'react'
const App = () => {
const scrollElement = useRef(null)
const scrollLeft = () => {
scrollElement.current.scrollLeft = 50
}
return (
<div className = 'App'>
<div className = 'ScrollMenu' ref = {scrollElement}>
<a href = '#home'>Home</a>
<a href = '#news'>News</a>
<a href = '#contact'>Contact</a>
<a href = '#about'>About</a>
</div>
<button onClick = {scrollLeft}>Click me</button>
</div>
)
}
Here is a live example.
I have been racking my brain how I could include a toggle menu on my website, after some searching I found the below and have implemented it, which is great!
http://jsfiddle.net/hhcsz5cr/
<div>
<h1><button class="button" data-circle="travel">
<i class="fa fa-plus-square"></i>
</button> Travel</h1>
</div>
<div class="travel options">
<ul>
<li>Travel</li>
<li>Vehicles</li>
</ul>
</div>
var localStorageKey = "app_state";
// to preserve state, you first need to keep track of it
var default_state = {
biographies: false,
pictures: false,
poetry: false
}
var saved_state = localStorage.getItem(localStorageKey);
// ternary operator which means if `saved_state` is true we parse it and use that value for `state`; otherwise use `default_state`
var state = saved_state ? JSON.parse(saved_state) : default_state;
$(function() {
init();
$('.button').on('click', function() {
var circle = $(this).attr('data-circle');
toggleCircle(circle, !state[circle]);
$(this).find('i').toggleClass('fa-minus fa-plus');
});
});
function init() {
for(var key in state) {
var is_displayed = state[key];
if ( is_displayed ) {
$(this).find('i').toggleClass('fa-minus fa-plus');
} else {
$(this).find('i').toggleClass('fa-plus fa-plus');
}
console.log(is_displayed);
toggleCircle(key, is_displayed);
}
}
function toggleCircle(circle, is_displayed) {
if (is_displayed) {
$('.'+circle).show()
state[circle] = true;
} else {
$('.'+circle).hide()
state[circle] = false;
}
localStorage.setItem(localStorageKey, JSON.stringify(state));
}
But.. if you minimize a menu then refresh the icon shows a - even though its already minimize.
Is there any way I can change this?
I realise the code above is not my own and I can't find the person to credit! My jquery is terrible.
Any help would be appreicated.
Thanks
jsFiddle DEMO (since SO snippets do not allow localStorage from Iframe)
Use IDs, not classes. IDs are unique, not classes.
Store the entire ID as the object property i.e: "#pictures": false,
Store the entire selector inside data-* i.e: data-toggle="#biographies"
Use "is-*" classes as state CSS helpers: "is-hidden", "is-expanded"
You don't have to use .fa classes, just use CSS and font-family
Make use of Object.assign() to override your default values with the ones in Local Storage (if any).
Loop your object key value pairs using Object.entries() when initing your menu states.
// Override defaults with localStorage
const state = Object.assign({
"#biographies": false, // Feel free to change this default boolean
"#pictures": false,
"#poetry": false
}, JSON.parse(localStorage.state || "{}"));
const toggle = (k, v) => {
$(k).toggleClass('is-hidden', !v);
$(`[data-toggle="${k}"]`).toggleClass('is-expanded', v);
};
// On init
Object.entries(state).forEach(([k, v]) => toggle(k, v));
// On click
$("[data-toggle]").on("click", function() {
const id = this.dataset.toggle; // Get ID i.e: "#pictures"
state[id] = !state[id]; // Flip boolean
toggle(id, state[id]); // Trigger UI changes
localStorage.state = JSON.stringify(state); // Store into LS
});
.is-hidden {
display: none;
}
[data-toggle] i:before{
font-family: "FontAwesome";
font-style: normal;
content: "\f067"; /* Plus */
}
[data-toggle].is-expanded i:before{
content: "\f068"; /* Minus */
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css">
<div id="biographies" class="is-hidden">Biography</div>
<div id="pictures" class="is-hidden">Pictures</div>
<div id="poetry" class="is-hidden">Poetry</div>
<button type="button" class="button" data-toggle="#biographies">
<i></i> biographies
</button>
<button type="button" class="button" data-toggle="#pictures">
<i></i> pictures
</button>
<button type="button" class="button" data-toggle="#poetry">
<i></i> poetry
</button>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
Please try this..
$('.button').click(function(){
var whichbtn = $(this).attr('data-circle');
if($("."+whichbtn).hasClass("hidden")){
$(this).children("i").removeClass("fa-plus").addClass("fa-minus");
}else{
$(this).children("i").addClass("fa-plus").removeClass("fa-minus");
}
$("."+whichbtn).toggleClass("hidden");
});
.hidden{display:none;}
.button{
background:#00cc00;
padding:10px 20px;
margin-right:10px;
border:none;
color:white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="m-3">
<div class="biographies hidden mb-2 font-weight-bold">Biography</div>
<div class="pictures hidden mb-2 font-weight-bold">Pictures</div>
<div class="poetry hidden mb-2 font-weight-bold">Poetry</div>
<button class="button" data-circle="biographies">
<i class="fa fa-plus"></i> biographies
</button>
<button class="button" data-circle="pictures">
<i class="fa fa-plus"></i> pictures
</button>
<button class="button" data-circle="poetry">
<i class="fa fa-plus"></i> poetry
</button>
</div>
I add js for click event of button and get the attribute of data-circle of it's own for find which button clicked. And fa fa-plus icon changed to fa fa-minus also. Thats only.
toggleClass is used for toggle class when user click the button. First click add class hidden then second click remove class hidden.For more clarifications comment me.
I have created a step form with HTML & jquery which has next and previous buttons for navigating to different steps. I have written jquery function for next buttons, but could'nt do one for previous buttons. Please help me with code.
code to trigger next button
var allNextBtn = $('.nextBtn');
allNextBtn.click(function () {
var curStep = $(this).closest(".setup-content"),
curStepBtn = curStep.attr("id"),
nextStepWizard = $('div.setup-panel div a[href="#' + curStepBtn + '"]').parent().next().children("a"),
curInputs = curStep.find("input[type='text'],input[type='url']"),
isValid = true;
$(".form-group").removeClass("has-error");
for (var i = 0; i < curInputs.length; i++) {
if (!curInputs[i].validity.valid) {
isValid = false;
$(curInputs[i]).closest(".form-group").addClass("has-error");
}
}
if (isValid) nextStepWizard.removeAttr('disabled').trigger('click');
});
I would suggest another approach to your problem:
You want to create a stepper
In the stepper, you would like to show pages of a form
The stepper needs to have controls: prev, next (, first, last?)
The controls should take form validation into account (on the current page)
You want to do DOM manipulation with jQuery
Consider the following snippet:
var currentPage = 1
jQuery(document).ready(function($) {
// init first page
updatePage(0)
jQuery(".btn.next").on('click', function(e) {
e.preventDefault()
// checking for last item & if page input fields are valid
const direction = ($('.page').length > currentPage && validatePage()) ? 1 : 0
updatePage(direction)
})
jQuery(".btn.prev").on('click', function(e) {
e.preventDefault()
// checking for fist item
const direction = 1 < currentPage ? -1 : 0
updatePage(direction)
})
})
// simple validation function
function validatePage() {
const inputValue = jQuery(`[data-page-order="${ currentPage }"]`).find('input').val()
return inputValue !== ''
}
// simple page visibility update function
function updatePage(direction) {
if (direction === 1 || direction === -1) {
currentPage += direction
$(".page.visible").fadeOut().removeClass('visible')
$(`[data-page-order="${ currentPage }"]`).fadeIn().addClass('visible')
} else {
$(".page.visible").removeClass('visible')
$(`[data-page-order="${ currentPage }"]`).addClass('visible')
}
}
form {
width: 50%;
}
.pages {
position: relative;
height: 50px;
background-color: rgba(0, 0, 0, 0.2);
display: flex;
justify-content: center;
align-items: center;
}
.pages>.page {
display: block;
position: absolute;
display: none;
}
.pages>.page.visible {
display: block;
}
.controls {
display: flex;
justify-content: space-between;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<form>
<div class="pages">
<div class="page" data-page-order="1">
<label for="input1">Input 1:
<input id="input1" type="text" />
</label>
</div>
<div class="page" data-page-order="2">
<label for="input2">Input 2:
<input id="input2" type="text" />
</label>
</div>
<div class="page" data-page-order="3">
<label for="input3">Input 3:
<input id="input3" type="text" />
</label>
</div>
</div>
<div class="controls">
<button class="btn prev">PREV</button>
<button class="btn next">NEXT</button>
</div>
</form>
</div>
You can see that with the manipulation of a single variable (currentPage) prev & next steps can be done - with validation rules, form pages appear/disappear with a fadeIn/fadeOutand all.
I do hope that this snippet gives you the idea about how to solve a problem like this - break it down to requirements that are simple and then don't overcomplicate :) Just add one feature at a time (like prev/next, validation, etc.).
Hi i have code like this:
$(document).ready(function() {
$("#toggle").click(function() {
var elem = $("#toggle").text();
if (elem == "Show more") {
$("#toggle").text("Show less");
$("#text").slideDown();
} else {
$("#toggle").text("Show more");
$("#text").slideUp();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="btn-container">
<button id="toggle">Show more</button>
</div>
In show more i would like to add a icon /f078 and in show less /f106.
How to add? I tried by css and html tags but it doesnt work.
I am able to display file image and title on mouseovering for respective file. But for all filename the image and title is displaying in same place.
I need to display the respective image and title on above of respective filename. When page gets loaded I saw this small box. I don't know why.
After moving mouseover on first filename or second filename it will display the image and title in the same place as below.
HTML :
<style>
.hover-image {
width: 30px;
height: 30px;
border-radius: 20%;
position: absolute;
margin-top: -10px;
margin-left: 5px;
}
img.hover-image {
border: none;
box-shadow: none;
}
.hover-title {
color:black;
position: absolute;
margin-top: -20px;
}
</style>
<div class="file-image-tags1">
<ul>
<span style="width: 200px;"><a ng-show="hideHoveredImage==false;" class="hover-title">{{hoverTitle}}<img class="hover-image" src="{{hoveredImage}}"></a></span>
<li ng-repeat="image in files | filter :'image'" >
<div class="file-tag-baloon1" ng-mouseover="hoverImg(image.id)" ng-mouseleave="hoverOut()">
<span>
<a ng-click="photoPreview(image.id);" >{{image.fileshortname}}</a>
</span>
<span><a ng-click="removeImage(image.id)" class="remove1">X</a></span>
</div>
</li>
</ul>
</div>
Use the angular built in directives,
Check out the below code
HTML
<span ng-hide="show">
<img ng-src="https://unsplash.it/200/300/?random" />
</span>
<br/>
<span ng-mouseover="show=!show" ng-mouseleave="show=!show">
Image name </span>
Angular Controller
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.show="false";
});
Update 1:
Based on the comment I updated as below
Angular Controller
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.show = "false";
$scope.arrayofJson = [{
imageTitle: "someImageName1",
imagePath: "http://lorempixel.com/400/200/",
show: "false"
}, {
imageTitle: "someImageName2",
imagePath: "https://unsplash.it/200/300/?random",
show: "false"
}, {
imageTitle: "someImageName3",
imagePath: "https://unsplash.it/200/300/?random",
show: "false"
}, {
imageTitle: "someImageName4",
imagePath: "https://unsplash.it/200/300/?random",
show: "false"
}
];
});
HTML
<div ng-repeat="item in arrayofJson">
<span ng-hide="item.show">
<img ng-src="{{item.imagePath}}" /> </span>
<br/>
<span ng-mouseover="item.show=!item.show" ng-mouseleave="item.show=!item.show">
{{item.imageTitle}} </span>
</div>
The plunker remains the same and it is updated. Check out the LIVE DEMO
Try -
.file-image-tags1
{
position : absolute;
}
You can do this using ng-if ng-show/hide like below example.
$scope.hoverIn = function(){
this.hoverImage = true;
};
$scope.hoverOut = function(){
this.hoverImage = false;
};
<ul>
<span ng-mouseover="hoverIn()" ng-mouseleave="hoverOut()">Hover Me</span>
<span ng-show="hoverImage">
<img>.....</a>
</span>
</li>
</ul>
in function you can pass the file name and you can do much more