Converting jquery to react - addclass and removeclass functions without toggling - javascript

I am attempting to create 2 grid resize buttons for a gallery list. One is for a smaller grid (.museum-grid) and another for a large grid (.large-grid).
When I click #museum-grid-btn I want to do the following:
addclass .museum-grid to #gallery-list
removeclass .large-grid from #gallery-list
addclass .grid-active to #museum-grid-btn
removeclass .grid-active from #museum-grid-btn
When I click #large-grid-btn I want to do the opposite:
addclass .large-grid to #gallery-list
removeclass .museum-grid from #gallery-list
addclass .grid-active to #large-grid-btn
removeclass .grid-active from #museum-grid-btn
I'm doing it this way instead of using toggle bc for interface purposes I felt it would be weird to allow toggling on the grid size button selections. I want to click on a grid size and then if I click on it again the same state stays in place. Only when I click on the other option do I want the grid size to change. This is reflected in the jquery. I am having a hard time figuring out how to translate this to react bc it is not as simple as toggling; although maybe I am overlooking an easier method.
Here is the jquery I have for this
$(document).ready(function(){
$('#museum-grid-btn').on('click', function(e) {
$('#gallery-list').addclassName("museum-grid");
$('#gallery-list').removeclassName("large-grid");
$('#museum-grid-btn').addclassName("grid-active");
$('#large-grid-btn').removeclassName("grid-active");
e.preventDefault();
});
$('#large-grid-btn').on('click', function(e) {
$('#gallery-list').addclassName("large-grid");
$('#gallery-list').removeclassName("museum-grid");
$('#large-grid-btn').addclassName("grid-active");
$('#museum-grid-btn').removeclassName("grid-active");
e.preventDefault();
});
});
And the html
<body>
<section id="main">
<div id="the-gallery">
<div id="search">
<input type="search" id="gallery-search" name="q" placeholder="#">
<div id="filter-btn" class="control-btn">
<button id="filter-icon"><img src="img/gallery-filter.svg"/></button>
</div>
<div id="large-grid-btn" class="control-btn">
<button id="large-grid-icon"><i class="fas fa-th-large"></i></i></button>
</div>
<div id="museum-grid-btn" class="control-btn grid-active">
<button id="museum-grid-icon"><i class="fas fa-th"></i></button>
</div>
</div>
<ul id="gallery-list" class="museum-grid">
<li class="gallery-item">
<img src="img/00001.jpg">
<div class="listing-title-row">
<h2>#00001</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00002.jpg">
<div class="listing-title-row">
<h2>#00002</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00003.jpg">
<div class="listing-title-row">
<h2>#00003</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00004.jpg">
<div class="listing-title-row">
<h2>#00004</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00005.jpg">
<div class="listing-title-row">
<h2>#00005</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00006.jpg">
<div class="listing-title-row">
<h2>#00006</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00007.jpg">
<div class="listing-title-row">
<h2>#00007</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00008.jpg">
<div class="listing-title-row">
<h2>#00008</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00009.jpg">
<div class="listing-title-row">
<h2>#00009</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
<li class="gallery-item">
<img src="img/00010.jpg">
<div class="listing-title-row">
<h2>#00010</h2>
<div class="listing-views"><i class="fas fa-eye"></i> 1.5k</div><div class="listing-likes"><a><i class="fas fa-heart"></i></a> 100</div>
</div>
</li>
</ul>
</div>
</section>
</body>
.grid-active changes the style of the selected button to indicate it is selected.
.museum-grid and .large-grid changes the size of the grid list items
What would be the appropriate way to acive this functionality in a react template? I am familiar with using usestate and making a toggle function onClick but what If I want to do the above? I appreciate and guidance.
Added information:
I am so new to react that I'm not 100% sure if this is a functional or class component. I just want to get it working. I have done some work to get the filter menu to expand and close using a toggle. Here is the code I have for that from my tsx file. Maybe you can tell me which I am using - functional or class components?
import React, { useState } from "react";
function VisionExplorer() {
// Creating a state for the filter pane.
const [filterToggled, setFilterToggled] = useState(false);
const ToggleFilter = ()=>{
filterToggled ? setFilterToggled(false) : setFilterToggled(true);
}
<main id="main" className={filterToggled ? "filter-open" : ""}>
<div id="filter-btn" className="control-btn" onClick={ToggleFilter}>
<button id="filter-icon">
<img src="/assets/images/gallery-filter.svg" />
</button>
</div>
This bit of code toggles the filter-open class to the main div which I use css to open and close the filter pane. I use the toggle on the filter button. Is this a function or class component?

You can use state to assist with this in React.
I don't know if you are using function components or class components.
Here is an example using a function component:
const ComponentA = () => {
// Set up a state variable to control the mode (Normal / Large) of the component.
// mode will be the value stored for the current render.
// setMode is a function that lets you update mode.
// https://reactjs.org/docs/hooks-state.html
const [mode, setMode] = useState('Normal');
// On large button click handler.
const onLargeClick = () => {
// When setMode is called the component will rerender with the new value.
setMode('Large');
};
// On normal button click handler
const onNormalClick = () => {
// When setMode is called the component will rerender with the new value.
setMode('Normal');
};
return (
<>
{ /* Swap size related class name based on mode value */ }
<div
className={mode === 'Large' ? 'classLarge' : 'classNormal'}
>
Text
</div>
{ /* Swap active class name for normal button based on mode value */ }
<div
onClick={onNormalClick}
className={mode === 'Normal' ? 'classActive' : undefined}
>
Normal
</div>
{ /* Swap active class name for large button based on mode value */ }
<div
onClick={onLargeClick}
className={mode === 'Large' ? 'classActive' : undefined}
>
Large
</div>
</>
)
};
NOTE: Instead of using ternary statements for class names you could look at a package like clsx.

Related

Bulma burger isn't shown

I have a problem with the Bulma framework. I have a small navbar for desktop and want to add a navbar burger. But it doesn't work. I tried the js script created by Bulma as an example and one from a yt video. Both didn't work. Can somebody Please help me? Down will find the html part and the js script:
js/index.js
document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Add a click event on each of them
$navbarBurgers.forEach( el => {
el.addEventListener('click', () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
});
index.html
<script src="js/index.js"></script>
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="index.html">
<h1 class="title">10.8</h1>
</a>
<a role="button" class="navbar-burger" data-target="navMenu" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
<div class="navbar-menu" id="navMenu">
<div class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item">
Home
</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
More
</a>
<div class="navbar-dropdown">
<a class="navbar-item">
About
</a>
<a class="navbar-item">
Jobs
</a>
<a class="navbar-item">
Contact
</a>
<hr class="navbar-divider">
<a class="navbar-item">
Report an issue
</a>
</div>
</div>
</div>
<div class="navbar-end">
<!-- navbar items -->
</div>
</div>
</div>
</nav>
Well if watched a small video produced from Bulma, tried the code from theire website and watched another video. I also tried to write my own script but it also does'nt work.
I hope sb can help me to fix it cause this must be successfully really quick.
You have a div that doesn't close in the right place.
There is a div with duplicate className.
Properly closing and removing that div everything works as expected.
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Add a click event on each of them
$navbarBurgers.forEach(el => {
el.addEventListener('click', () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.4/css/bulma.min.css" rel="stylesheet"/>
<body>
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" href="index.html">
<h1 class="title">10.8</h1>
</a>
<a role="button" class="navbar-burger" data-target="navMenu" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div class="navbar-menu" id="navMenu">
<div class="navbar-start">
<a class="navbar-item">
Home
</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
More
</a>
<div class="navbar-dropdown">
<a class="navbar-item">
About
</a>
<a class="navbar-item">
Jobs
</a>
<a class="navbar-item">
Contact
</a>
<hr class="navbar-divider">
<a class="navbar-item">
Report an issue
</a>
</div>
</div>
</div>
<div class="navbar-end">
<!-- navbar items -->
</div>
</div>
</nav>
</body>

How to select certain elements in a group of elements with the same class tag using jquery

I am trying this sidebar of a dashboard and it looks like this
The top child or the one with the brighter green color on it has a class active_link which basically tells you that you are in this part of the dashboard. So the idea is that I want the class active link to be added to the certain element that I have clicked upon while the rest who are not clicked don't have (Meaning that if the element already have the active_link but it is not the one that I have clicked upon then the class will be removed however if it does not have the active_link class and it is the one I clicked it will be added to that certain element). However, I have a problem.I tried running this code:
$(function(){
$(".sidebar_link").click(function(){
$(".sidebar_link").each(function(index){
if($(this).data('clicked', true)){
if($(this).hasClass('active_link') == false){
$(this).addClass('active_link');
}
}else{
if($(this).hasClass('active_link')){
$(this).removeClass('active_link');
}
}
});
});
})
And this is what happened:
Which what I could tell is just a disaster, any tips? Thank you in advance! Here is the HTML
<div class="sidebar_menu">
<div class="sidebar_link active_link">
<i class="fa fa-home"></i>
Dashboard
</div>
<h2>MANAGE</h2>
<div class="sidebar_link">
<i class="fa fa-building-o"></i>
See Admin Notif
</div>
<div class="sidebar_link">
<i class="fa fa-wrench"></i>
Update Profile
</div>
<div class="sidebar_link">
<i class="fa fa-archive"></i>
Donate
</div>
<div class="sidebar_link">
<i class="fa fa-handshake-o"></i>
Connect
</div>
<div class="sidebar_logout">
<i class="fa fa-power-off"></i>
Log out
</div>
</div>
You can simply use $(".sidebar_link").not($(this)).removeClass("active_link") to remove class from other sidebar which is not been clicked by user.
Demo Code :
$(".sidebar_link").click(function() {
$(".sidebar_link").not($(this)).removeClass("active_link")
$(this).toggleClass('active_link');
});
.active_link {
background-color: green
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="sidebar_menu">
<div class="sidebar_link active_link">
<i class="fa fa-home"></i>
Dashboard
</div>
<h2>MANAGE</h2>
<div class="sidebar_link">
<i class="fa fa-building-o"></i>
See Admin Notif
</div>
<div class="sidebar_link">
<i class="fa fa-wrench"></i>
Update Profile
</div>
<div class="sidebar_link">
<i class="fa fa-archive"></i>
Donate
</div>
<div class="sidebar_link">
<i class="fa fa-handshake-o"></i>
Connect
</div>
<div class="sidebar_logout">
<i class="fa fa-power-off"></i>
Log out
</div>
</div>

Display None to classes

<div id="left-option-navigation">
<div id="left-option-expand">
<i onclick="openColl()" class="fas fa-angle-double-left"></i>
</div>
<div class="left-navigation-option" href=""><i class="fas fa-tachometer-alt"></i><span class="left-navigation-option-text">Dashboard</span></div>
<div class="left-navigation-option" href=""><i class="far fa-file-alt"></i><span class="left-navigation-option-text">Documents</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-tags"></i><span class="left-navigation-option-text">Products</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-archive"></i><span class="left-navigation-option-text">Stock</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-print"></i><span class="left-navigation-option-text">Reporting</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-user-friends"></i><span class="left-navigation-option-text">Customers & Suppliers</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-heart"></i><span class="left-navigation-option-text">Promotions & Actions</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-key"></i><span class="left-navigation-option-text">Users & Security</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-wallet"></i><span class="left-navigation-option-text">Payement Types</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-globe"></i><span class="left-navigation-option-text">Countries</span></div>
<div class="left-navigation-option" href=""><i class="fas fa-percent"></i><span class="left-navigation-option-text">Tax Rates</span></div>
<div class="left-navigation-option" href=""><i class="far fa-building"></i><span class="left-navigation-option-text">My Company</span></div>
</div>
<script>
function openColl()
{
document.getElementById("left-option-navigation").style.width = "100px";
}
</script>
Hey this is my code so i want to know that how can I hide left-navigation-option-text span class when i call openColl() function onclick.By setting the style of the particular class to display none is the solution but how can I trigger this function onclick and apply to this whole class.
So, if I understand you correctly, you want to apply the class to all left-navigation-option-text classes at the same time, correct?
You can do it like this:
function openColl() {
let optionText = document.querySelectorAll('.left-navigation-option-text');
optionText.forEach( el => el.classList.toggle('hidden') );
}
First, you get all elements with the class name left-navigation-option-text and store it in a variable named optionText. Then you loop over all Elements and toggle the class .hidden to all off them.
In your css file you create a class .hidden and set it to display:none.

How do you move a div into another using javascript?

I have two divs of the same size, and when I click a button on one of the divs, it will get larger. I want to move the smaller div into the bottom-right corner of the larger div, and when I click the button again the divs will return to their original size and position.
Before:
--- ---
| 1 | | 2 |
--- ---
After:
---------
| 2 |
| ---|
| | 1 |
---------
Here's my javascript for resizing so far:
function resizeSubscriber() {
var subscriberPanel = document.getElementById('dvOtherPerson');
var publisherPanel = document.getElementById('dvYou');
var classSetting = subscriberPanel.getAttribute('class');
if (classSetting == 'col-xl-4') {
subscriberPanel.setAttribute('class', 'col-xl-12');
}
else {
subscriberPanel.setAttribute('class', 'col-xl-4');
}
}
here is my asp code
<div id="dvOtherPerson" class="col-xl-4">
<div>
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">
Rachel Hawkins
</h3>
</div>
</div>
<div class="m-portlet__head-tools">
<ul class="m-portlet__nav">
<li class="m-portlet__nav-item">
<a href="" class="m-portlet__nav-link m-portlet__nav-link--icon">
<a href="" class="m-portlet__nav-link m-portlet__nav-link--icon">
<i class="fa fa-volume-up text-success"></i>
</a>
<a href="" class="m-portlet__nav-link m-portlet__nav-link--icon">
<i class="fa fa-refresh"></i>
</a>
<a onclick="resizeSubscriber();" href="#" class="m-portlet__nav-link m-portlet__nav-link--icon">
<i class="fa fa-expand"></i>
</a>
</li>
</ul>
</div>
</div>
<div class="m-portlet__body">
<img src="./img/temp/users/video_rachel.jpg" class="img-fluid" />
</div>
</div>
<%-- <div id="videos">
<div id="subscriber"></div>
</div>--%>
</div>
<div id="dvYou" class="col-xl-4">
<div class="m-portlet m-portlet--fit">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">
Me
</h3>
</div>
</div>
<div class="m-portlet__head-tools">
<ul class="m-portlet__nav">
<li class="m-portlet__nav-item">
<a href="" class="m-portlet__nav-link m-portlet__nav-link--icon">
<i class="fa fa-microphone-slash text-danger"></i>
</a>
<a href="" class="m-portlet__nav-link m-portlet__nav-link--icon">
<i class="fa fa-refresh"></i>
</a>
</li>
</ul>
</div>
</div>
<div class="m-portlet__body">
<div id="publisher"></div>
</div>
</div>
</div>
Use appendChild, and it will move the source element to a target element, e.g.
target_element.appendChild(source_element)
As commented, to apply different CSS style, do like this and the source_element will automatically change when inside the target_element
source_element {...}
target_element source_element {...}
If you can use jQuery, you can use the method append():
$(<OUTER_SELECTOR>).append($(<INNER_SELECTOR>));

Issue with foundation used in .vue single file components

I have realised that there is a problem when using Zurb Foundation classes in .vue single file components. At first I could not get a Reveal Modal to work inside the .vue component but it was working when I use the same code in a blade or html file. Then I noticed a pattern because when I tried to use the Foundation's Orbit inside the component it failed, at first I thought it was an error but then I used the same code in a blade file and it worked. Other foundation classes such as row, grid and buttons are working just fine.
Has anyone experienced the same issue? And how can I work around it?
Here is the code for the modal:
<a data-open="video" class="button warning" href="">WATCH VIDEO</a>
<div id="video" class="reveal" data-reveal>
<div class="lead">
<button class="close-button" data-close aria-label="Close modal" type="button">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="flex-video">
<iframe width="1280" height="720" :src="url" frameborder="0" allowfullscreen></iframe>
</div>
</div>
And for the orbit I used the basic example in the foundation docs for testing.
<div class="orbit" role="region" aria-label="Favorite Space Pictures" data-orbit>
<ul class="orbit-container">
<button class="orbit-previous"><span class="show-for-sr">Previous Slide</span>◀︎</button>
<button class="orbit-next"><span class="show-for-sr">Next Slide</span>▶︎</button>
<li class="is-active orbit-slide">
<img class="orbit-image" src="assets/img/orbit/01.jpg" alt="Space">
<figcaption class="orbit-caption">Space, the final frontier.</figcaption>
</li>
<li class="orbit-slide">
<img class="orbit-image" src="assets/img/orbit/02.jpg" alt="Space">
<figcaption class="orbit-caption">Lets Rocket!</figcaption>
</li>
<li class="orbit-slide">
<img class="orbit-image" src="assets/img/orbit/03.jpg" alt="Space">
<figcaption class="orbit-caption">Encapsulating</figcaption>
</li>
<li class="orbit-slide">
<img class="orbit-image" src="assets/img/orbit/04.jpg" alt="Space">
<figcaption class="orbit-caption">Outta This World</figcaption>
</li>
</ul>
<nav class="orbit-bullets">
<button class="is-active" data-slide="0"><span class="show-for-sr">First slide details.</span><span class="show-for-sr">Current Slide</span></button>
<button data-slide="1"><span class="show-for-sr">Second slide details.</span></button>
<button data-slide="2"><span class="show-for-sr">Third slide details.</span></button>
<button data-slide="3"><span class="show-for-sr">Fourth slide details.</span></button>
</nav>
</div>
There is an issue when using vue components with foundation js components and that's why they are not showing as explained here
So I added this directive in my script tag:
Vue.directive('f-orbit', {
bind: function (el) {
new Foundation.Orbit($(el))
},
unbind: function (el) {
$(el).foundation.destroy()
}
})
And in my template I added v-f-orbit instead of the default data-orbit:
<div class="contemporary orbit" role="region" aria-label="Contemporary Pictures" v-f-orbit>
I hope this will assist someone who is stuck.
Phillis's answer above is absolutely correct. Just thought I would throw in another example, of a Foundation 6.4 dropdown-menu and Vue.js 2.
Create the custom directive called dropdown and add v-dropdown to the parent element and it should be working.
<ul class="dropdown menu" v-dropdown>
<li>
Navigate Site <i class="fas fa-chevron-down"></i>
<ul class="menu vertical">
<li><i class="far fa-car"></i> Auto</li>
<li><i class="far fa-home"></i> Residential</li>
<li><i class="far fa-building"></i> Commercial</li>
<li><i class="far fa-building"></i> Safety & Security</li>
<li><i class="far fa-gem"></i> Specialty Solutions</li>
<li><i class="fal fa-id-badge"></i></i> Dealers</li>
<li><i class="far fa-building"></i> Madico U</li>
<li><i class="far fa-building"></i> Company</li>
</ul>
</li>
</ul>
Vue.directive('dropdown', {
bind: function (el) {
new Foundation.DropdownMenu($(el));
}
});

Categories

Resources