I am a beginner in Web Development.
Why can't I place the pagination bar to be horizontally centered?
I have tried to include width:100% and even display: block.
However, results are the same.
Thank you for your help.
I want to put the pagination in the center of the red border.
App.js
...
<Pagination postsPerPage={imagePerPage} totalPosts={totalImages} paginate= {paginate}/>
...
Pagination.js
import React , { useState, useRef, useEffect, useContext } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
const Pagination = ({ postsPerPage, totalPosts, paginate }) => {
const pageNumbers = [];
const [currentPage,setCurrentPage] = useState(1);
for (let i = 1; i <= Math.ceil(totalPosts / postsPerPage); i++) {
pageNumbers.push(i);
}
const totalNumOfPages = pageNumbers.length;
useEffect(() => {
console.log("Cureent Page:")
console.log(currentPage);
},[currentPage]);
return (
<nav>
<ul className='pagination' style={{width:'100%',margin:'auto',border: '1px solid red' }}>
<li class="page-item">
<a class="page-link" aria-label="Previous"
onClick={() =>{
if (currentPage > 1){
paginate(currentPage-1);
setCurrentPage(currentPage-1);
}
}
}
>
<span aria-hidden="true">«</span>
<span class="sr-only">Previous</span>
</a>
</li>
{pageNumbers.map(number => (
<li key={number}
className={ `page-item ${(currentPage === number)? 'active' : '' }`}>
<a onClick={() =>{ paginate(number);setCurrentPage(number)}} className='page-link' >
{number}
</a>
</li>
))}
<li class="page-item">
<a class="page-link" aria-label="Next"
onClick={() =>{
if (currentPage < totalNumOfPages){
paginate(currentPage+1);
setCurrentPage(currentPage+1);
}
}
}
>
<span aria-hidden="true">»</span>
<span class="sr-only">Next</span>
</a>
</li>
</ul>
</nav>
);
};
export default Pagination;
Looks like you are using Bootstrap. .pagination is configured to be a Flex container. This is why your li elements are already displayed in a row. You can still use the concept of auto margins, but instead of doing it on the parent, you can use this property on the children.
li.page-item:first-child {
margin-left: auto;
}
li.page-item:last-child {
margin-right: auto;
}
First, you need to put your elements into div as below, and move the ul style part to a separate div.
<div className="text-center">
<div style={{width:'100%', border: '1px solid red', height : '40px'}}>
<nav>
<ul className='pagination' >
....
Second, override pagination class with
.pagination {
display: inline-flex;
}
Here is the live demo.
Related
I have a button navigation and when you click on a button, the active class is added. My goal is for the active class to be added to the button clicked, but remove that class of active on all other buttons if present. The 'About' button will have a class of active on page load.
Not sure how to translate this to React, in JavaScript on click I would remove the class from all the elements in a loop and add a class to the target clicked if it did not already have the active class.
Code Sandbox - https://codesandbox.io/s/toggle-active-on-class-clicked-remove-from-the-rest-r467l1?file=/src/App.js
export default function Header() {
const [active, setActive] = useState(true);
const toggleColor = function (e) {
// on load, 'About' button has active class
// when clicking another menu item add active class, remove active from the rest of buttons
console.log(e.target);
};
return (
<header className="header-img-container">
<nav>
<ul>
<li>
<button onClick={toggleColor} className={active ? "active" : ""}>
About
</button>
</li>
<li>
<button onClick={toggleColor}>Skills</button>
</li>
<li>
<button onClick={toggleColor}>Projects</button>
</li>
<li>
<button onClick={toggleColor}>Words</button>
</li>
</ul>
</nav>
</header>
);
}
There are so many ways to solve that problem. You can try this if it's meet your requirements.
import "./styles.css";
import { useState } from "react";
const list = ["About", "Skills", "Projects", "Words"];
export default function Header() {
const [activeLink, setActiveLink] = useState("About");
return (
<header className="header-img-container">
<nav>
<ul>
{list.map((item) => (
<li key={item}>
<button
onClick={() => setActiveLink(item)}
className={activeLink === item ? "active" : ""}
>
{item}
</button>
</li>
))}
</ul>
</nav>
</header>
);
}
Create a state like this
const [active, setActive] = useState({About: true, Skills: false, Projects: false, Words: false})
А change local parameter to add a class to element. For example
<li>
<button onClick={() => {
setActive({...active, About: false, Skills: true, Projects: false,
Words: false })
}}>Skills</button>
</li>
There are many possible approaches, here is a basic example that uses an object type active state to store the value for each list item.
const [active, setActive] = useState({ About: true })
The list data is stored in an array so it can be mapped in the JSX part of the component.
const itemList = ["About", "Skills", "Projects", "Words"]
While index is not an ideal key it is used here just for example purpose.
{
itemList.map((item, index) => (
<li key={index}>
<button
onClick={() => toggleColor(item)}
className={active[item] ? "active" : ""}
>
{item}
</button>
</li>
));
}
toggleColor sets value for active, and it specify that active should always be in the format of {About: true}, {Skills: true} and such. The !!! covers the case when certain keys are not existing in the object.
const toggleColor = function (item) {
setActive((prev) => {
return { [item]: !!!prev[item] };
});
};
Below is the full example, it runs in the snippet for convenience.
function Header() {
const [active, setActive] = React.useState({ About: true });
const itemList = ["About", "Skills", "Projects", "Words"];
const toggleColor = function (item) {
// on load, 'About' button has active class
// when clicking another menu item add active class, remove active from the rest of buttons
setActive((prev) => {
return { [item]: !!!prev[item] };
});
};
return (
<header className="header-img-container">
<nav>
<ul>
{itemList.map((item, index) => (
<li key={index}>
<button
onClick={() => toggleColor(item)}
className={active[item] ? "active" : ""}
>
{item}
</button>
</li>
))}
</ul>
</nav>
</header>
);
}
const App = () => {
return (
<div>
<Header />
</div>
);
};
ReactDOM.render(<App />, document.querySelector("#root"));
.App {
font-family: sans-serif;
text-align: center;
}
button {
padding: 6px;
}
.active {
border: 1px solid pink;
color: hotpink;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script>
I am trying to achieve two things:
(1) each time I click on the red arrow icon in the sidebar, I want the sidebar to collapse or open. From the below video, you'd see that the active and inactive states are already there. However, the sidebar doesn't collapse on inactive.
(2) each time I click on the Content menu, which is a drowndown menu, it doesn't open the submenu. Also, from the below video, you'd notice that the active and inactive states are already there. However, the dropdown still doesn't open on active.
Below is the video that clearly shows the error:
https://www.loom.com/share/6e0488101cee4c5b9bac7ded782b8807
Docs.js Page
import React from "react";
import { Helmet } from "react-helmet";
import SideMenu from "../docs/SideMenu";
const Docs = () => {
return (
<div className="">
<Helmet>
<title>Docs :: MyApp</title>
<meta name="description" content="MyApp" />
</Helmet>
<SideMenu />
</div >
)
};
export default Docs
SideMenu.js Component
import React, { useState } from "react";
import { Helmet } from "react-helmet";
import * as Icon from "react-bootstrap-icons";
import MenuItems from "./MenuItems";
const SideMenu = () => {
const [inActive, setInActive] = useState(false)
return (
<div className="">
<div className={`side-menu ${inActive ? "inActive" : ""}`}>
<Helmet>
<title>Docs :: MyApp</title>
<meta name="description" content="MyApp" />
</Helmet>
<div className="top-section">
<div className="logo">
<img src="/assets/media/logos/naked.png" alt="MyApp" />
</div>
<div onClick={() => setInActive(!inActive)} className="toggle-back">
{inActive ? (<Icon.ArrowLeftSquareFill />) : (<Icon.ArrowRightSquareFill />)}
</div>
</div>
<div className="search-bar">
<button className="search-bar-btn">
<Icon.Search />
</button>
<input type="text" placeholder="search" />
</div>
<div className="divider"></div>
<div className="main-menu">
<ul>
{menuItems.map((menuItem, index) => (
<MenuItems
key={index}
name={menuItem.name}
to={menuItem.to}
subMenu={menuItem.subMenu || []} />
))}
{/*<li>
<a className="menu-item">
<Icon.ArrowRightSquareFill className="menu-icon" />
<span>Dashboard</span>
</a>
</li>
<MenuItems
name={"Content"}
subMenu={[
{ name: 'Courses' },
{ name: 'Videos' },
]}
/>
<li>
<a className="menu-item">
<Icon.ArrowRightSquareFill className="menu-icon" />
<span>Support</span>
</a>
</li>*/}
</ul>
</div>
<div className="side-menu-footer">
<div className="avatar">
<img src="/assets/media/avatars/aa/brooks_lloyd.png" alt="MyApp" />
</div>
<div className="user-info">
<div className="font-size-h6">Title</div>
<div className="font-size-sm">Subtitle</div>
</div>
</div>
</div>
</div>
);
};
export default SideMenu
const menuItems = [
{ name: "Dashboard", to: "/" },
{ name: "Content", to: "/", subMenu: [{ name: "Courses" }, { name: "Videos" }], },
{ name: "Design", to: "/" },
];
MenuItems.js Component
import React, { useState } from "react";
import * as Icon from "react-bootstrap-icons";
const MenuItems = (props) => {
const { name, subMenu } = props;
const [expand, setExpand] = useState(false);
return (
<div className="">
<li>
<a onClick={() => setExpand(!expand)} className="menu-item">
<Icon.ArrowRightSquareFill className="menu-icon" />
<span>{name}</span>
</a>
{
subMenu && subMenu.length > 0 ? (
<ul className={`sub-menu ${expand ? "active" : ""}`}>
{subMenu.map((menu, index) =>
<li key={index}>
<a className="sub-menu">
<Icon.ArrowRightSquareFill className="menu-icon" />
{menu.name}
</a>
</li>
)}
</ul>) : null}
</li>
</div>
);
};
export default MenuItems
Docs.css File that contains the suspected errors, which are the side-menu and sub-menu lines:
.side-menu {
position: fixed;
background: #000;
width: 300px;
height: 100%;
box-sizing: border-box;
padding: 30px 20px;
transition: width .2s ease-in;
}
.side-menu.inactive {
width: 80px;
}
.side-menu .main-menu .sub-menu {
color: #333;
margin-left: 20px;
border-left: 1px solid #666;
box-sizing: border-box;
padding-left: 30px;
max-height: 0;
overflow: hidden;
transition: max-height .2s ease-in;
}
.side-menu .main-menu .sub-menu.active {
max-height: 200px;
}
buttonI need to style the anchor tag to look like a rectangular tile (which I'm already doing) and when clicked on that tile/anchor tag, I need to do the following 2 things:
Keep it selected and highlight it with Green colour.
On selection or change in selection between TILE-1, TILE-2 and TILE-3, I need to fetch the value of the text in the input field.
Can someone please share any guidelines on how this can be done, please?
const showTile = (): ReactElement => {
<ul className="tileList">
<li>
<button href="#Tile1" class="tile" >
TILE-1
</button >
</li>
<li>
<button href="#Tile2" class="tile">
TILE-2
</button >
</li>
<li>
<button href="#Tile3" class="tile">
TILE-3
</button >
</li>
</ul>
};
const showTextBox = (): ReactElement => {
<input type="text" value="">
};
const [selectedTile, setSelectedTile] = useState("");
const [textVal, setTextVal] = useState("");
return (<div> {showTile} {showTextBox} </div>);
ul,
li {
list-style: none;
}
.tileList > li button {
color: grey;
background-colour: yellow;
border: 1px solid #ffffff;
padding: 10px 15px;
font-size: 13px;
}
use dynamic class for selected tie and a variable for assigned to it
and for changing value make a 2D array and insert the ties value in there then a simple function for changing ties values
its like a puzzle app search for puzzle functions to see more
I solved it like this.
state ={
selected: false
}
selectedHandle = () => {
const {selected} = this.state
this.setState({selected: true})
}
<li onClick={() => this.selectedHandle()}>
<a href="#Tile1" class={{selected === true ? "active" : "passive"}} >
TILE-1
</a>
</li>
for fetching the value you can following this question how to use event.target.value in li
I have a Navbar with tabs, and I want to make a function called onClick that gets the event, and adds a class to that tab "active". But, when I click another tab, it should remove a class from the previous tab and add it to that one.
Sample of my code:
const [clickedTab, setClickedTab] = useState(true);
function Click() {
if (clickedTab === true) {
console.log(clickedTab);
tab.classList.add("active");
}
else {
console.log("Error!");
}
}
In React use the model (via useState() in this case) to make changes to the view.
Set the activeId of the tab in the state, and if the tab's id is equal to activeId pass set it's active to true. The tab itself can add/remove the className.
const { useState } = React;
const Tab = ({ id, active, setActive }) => (
<li
className={`tab ${active ? 'active' : ''}`}
onClick={() => setActive(id)}
>
{id}
</li>
);
const Example = ({ tabs }) => {
const [activeId, setActive] = useState();
return (
<ul className="tabs">
{tabs.map(id => (
<Tab
key={id}
id={id}
setActive={setActive}
active={id === activeId}
/>
))}
</ul>
);
}
const tabs = [1, 2, 3, 4];
ReactDOM.render(
<Example tabs={tabs} />,
root
);
.tabs {
display: flex;
list-style: none;
}
.tab {
height: 1em;
width: 2em;
border: 1px solid red;
text-align: center;
cursor: pointer;
}
.active {
background: red;
}
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<div id="root"></div>
Here is a simple example so you can get the idea; we hold current active element id in a state then based on that we decide what class name it should have; no need to use classList's add or remove
function Header () {
const [active, setActive] = React.useState();
return (
<header>
<ul>
<li
className={active === 1? "red":"blue"}
onClick={()=>setActive(1)}
>a</li>
<li
className={active === 2? "red":"blue"}
onClick={()=>setActive(2)}
>b</li>
<li
className={active === 3? "red":"blue"}
onClick={()=>setActive(3)}
>c</li>
</ul>
</header>
);
}
ReactDOM.render( <Header />, app );
.red{background:red}.blue{background:blue}li{color:#fff;width:30px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
I have the following react component
export interface IDivBodyVisible {
isVisible: string;
}
export default class NavDropDownItem extends React.Component<{ItemContent: string}, IDivBodyVisible> {
constructor(props: any) {
super(props);
this.state = {
isVisible: 'none'
}
}
render() {
return (
<div className="divBox" >
<div className="divHeader" onClick={this.SwitchVisibility}>
<Icon className="icon" iconName="ChevronDown"/>
{this.props.ItemContent}
</div>
{
this.state.isVisible !== 'block' ? null :
<div className="divBody">
<ul className="ItemList">
<li>
<a className="miau" title="item1" onClick={this.ConsoleLog}>Item 1</a>
</li>
<li>
<a title="item2" onClick={this.ConsoleLog}>Item 2</a>
</li>
<li>
<a title="item3" onClick={this.ConsoleLog}>Item 3</a>
</li>
</ul>
</div>
}
</div>
)
}
private ConsoleLog = () : void => {
console.log("Test");
}
private SwitchVisibility = (): void => {
this.setState({
isVisible : this.state.isVisible === 'none' ? 'block' : 'none'
});
}
}
At the moment if I click on the icon, the divbody appears instantly. Instead, I want that the divbody slights very smooth. I already tried to give the .divBox a transition ease-out 0.2, but that didn´t do anything.
Is there any advice what I can try?