open a overlay with form onFocus in react - html

Hello I've searching a way to display a overlay with a form when I give the focus to a certain input field. I want to do this using react. How can I do this?
my code
import React, { Component } from 'react';
class Middle extends Component {
constructor(props) {
super(props);
this.state = {
posts: []
}
}
render() {
function popup_ques(e) {
e.preventDefault();
alert("now the overlay should appear");
}
return (
<div className="middle_div">
<input className='post_data_input' placeholder="Ask your question here" ref="postTxt"
onClick={popup_ques}/>
</div>
);
}
}
export default Middle;
I have written a function to display an alert when the input field is clicked.. instead of the alert I want to display a transparent overlay with a form.
I want to do something like this
http://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_overlay
Thanks inadvance.

So here i have written code to change the className of the side bar. Every time you call toggleSideBar it will change className from hideSideBar to showSideBar and vice versa. css for hideSideBar and showSideBar should be written as in the link of code school. Hope it will work.
import React, { Component } from 'react';
class Middle extends Component {
constructor(props) {
super(props);
this.state = {
sidebar: 'hideSideBar',
posts: [],
}
}
toggleSideBar() {
if(this.state.toggleBar === 'showSideBar') {
this.setState({ toggleBar: 'hideSideBar' });
} else {
this.setState({ toggleBar: 'showSideBar' });
}
}
render() {
return (
<div className="middle_div">
<input
className='post_data_input'
placeholder="Ask your question here"
ref="postTxt"
onClick={this.toggleSideBar.bind(this)}
/>
<div className={this.state.sidebar} />
// This will be the sidebar
</div>
</div>
);
}
}
export default Middle;

I have created a react component based on link you have given in question.
I hope this will help you in somewhat way to achieve what you want.
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
style : {
width : 350
}
};
this.openNav = this.openNav.bind(this);
this.closeNav = this.closeNav.bind(this);
}
componentDidMount() {
document.addEventListener("click", this.closeNav);
}
componentWillUnmount() {
document.removeEventListener("click", this.closeNav);
}
openNav() {
const style = { width : 350 };
this.setState({ style });
document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
document.addEventListener("click", this.closeNav);
}
closeNav() {
document.removeEventListener("click", this.closeNav);
const style = { width : 0 };
this.setState({ style });
document.body.style.backgroundColor = "#F3F3F3";
}
render() {
return (
<div>
<h2>Fullscreen Overlay Nav Example</h2>
<p>Click on the element below to open the fullscreen overlay navigation menu.</p>
<p>In this example, the navigation menu will slide in, from left to right:</p>
<span style={{fontSize:30,cursor:"pointer"}} onClick={this.openNav}>☰ open</span>
<div
ref = "snav"
className = "overlay"
style = {this.state.style}
>
<div className = "sidenav-container">
<div className = "text-center">
<h2>Form</h2>
<p>This is a sample input form</p>
</div>
<a
href = "javascript:void(0)"
className = "closebtn"
onClick = {this.closeNav}
>
×
</a>
<div className = "list-group">
{/*your form component goes here */}
{this.props.children}
</div>
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<Test/>,
document.getElementById('test')
);
.overlay {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0, 0.9);
overflow-x: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
top: 25%;
width: 100%;
text-align: center;
margin-top: 30px;
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #818181;
display: block;
transition: 0.3s;
}
.overlay a:hover, .overlay a:focus {
color: #f1f1f1;
}
.overlay .closebtn {
position: absolute;
top: 20px;
right: 45px;
font-size: 60px;
}
#media screen and (max-height: 450px) {
.overlay a {font-size: 20px}
.overlay .closebtn {
font-size: 40px;
top: 15px;
right: 35px;
}
}
.overlay h2, .overlay p {
color:white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="test"></div>

Related

React make a full-page Carousel

I am trying to make an animation that scrolls from left to right the child elements of a div, I have looked around but none of the other questions with answers seem to work, so far this is what I have accomplished:
Home.css:
#keyframes scroll {
20% {
transform: translateX(-100vw);
}
40% {
transform: translateX(-200vw);
}
60% {
transform: translateX(-300vw);
}
80% {
transform: translateX(-400vw);
}
100% {
transform: translateX(0vw);
}
}
.section {
display: flex;
flex-direction: row;
font-family: Arial, sans-serif;
font-weight: bold;
transition: 1s;
width: 100vw;
height: 100vh;
animation-name: scroll;
animation-duration: 1s;
}
.child1 {
background-color: #c0392b;
flex: none;
width: 100vw;
height: 100vh;
}
.child2 {
background-color: #e67e22;
flex: none;
width: 100vw;
height: 100vh;
}
.child3 {
background-color: #27ae60;
flex: none;
width: 100vw;
height: 100vh;
}
.child4 {
background-color: #2980b9;
flex: none;
width: 100vw;
height: 100vh;
}
.child5 {
background-color: #8e44ad;
flex: none;
width: 100vw;
height: 100vh;
}
Home.jsx:
import { forwardRef, useEffect, useRef, useState } from "react";
import { Link } from "react-router-dom";
import './Home.css';
const Child1 = forwardRef((props, ref) => {
return <div className="child1">
<h1>Child1</h1>
</div>;
});
const Child2 = forwardRef((props, ref) => {
return <div className="child2">
<h1>Child2</h1>
</div>;
});
const Child3 = forwardRef((props, ref) => {
return <div className="child3">
<h1>Child3</h1>
</div>;
});
const Child4 = forwardRef((props, ref) => {
return <div className="child4">
<h1>Child4</h1>
</div>;
});
const Child5 = forwardRef((props, ref) => {
return <div className="child5">
<h1>Child5</h1>
</div>;
});
function Home() {
let section = useRef();
let [currentSection, setCurrentSection] = useState(0);
useEffect(() => {
window.addEventListener("keypress", (event) => {
if(event.key === "d") {
// scroll right (play animation forwards by one step)
} else if(event.key === "a") {
// scroll left (play animation backwards by one step)
}
});
});
return <div ref={section} className="section">
<Child1></Child1>
<Child2></Child2>
<Child3></Child3>
<Child4></Child4>
<Child5></Child5>
</div>
}
export default Home;
The problem is that the animation plays all at the beginning and I cannot figure out a way to play it only when the keyboard event is triggered, if the event.key is an "a" then the elements should scroll to the left otherwise if the event.key is a "d" then the elements should scroll to the right.
Here is the link to the CodeSandbox.
As I understood you want to make parent scrollable only with pressing keys "a" and "d". I think I have found a solution which would work for you.
My solution:
Removing keyframes and separating it into 5 different classes. So here is CSS file:
.section1 {
transform: translateX(0);
}
.section2 {
transform: translateX(-100vw);
}
.section3 {
transform: translateX(-200vw);
}
.section4 {
transform: translateX(-300vw);
}
.section5 {
transform: translateX(-400vw);
}
.section {
display: flex;
flex-direction: row;
font-family: Arial, sans-serif;
font-weight: bold;
transition: 1s;
width: 100vw;
height: 100vh;
animation-name: scroll;
animation-duration: 1s;
}
.child1 {
background-color: #c0392b;
flex: none;
width: 100vw;
height: 100vh;
}
.child2 {
background-color: #e67e22;
flex: none;
width: 100vw;
height: 100vh;
}
.child3 {
background-color: #27ae60;
flex: none;
width: 100vw;
height: 100vh;
}
.child4 {
background-color: #2980b9;
flex: none;
width: 100vw;
height: 100vh;
}
.child5 {
background-color: #8e44ad;
flex: none;
width: 100vw;
height: 100vh;
}
Now I added some JS behaviour to appropriately 'scroll' left or right. I divided moving left or right into functions, and adding numberOfSections as constant. Here is JS file:
import { forwardRef, useCallback, useEffect, useRef, useState } from "react";
import { Link } from "react-router-dom";
import "./Home.css";
const Child1 = forwardRef((props, ref) => {
return (
<div className="child1">
<h1>Child1</h1>
</div>
);
});
const Child2 = forwardRef((props, ref) => {
return (
<div className="child2">
<h1>Child2</h1>
</div>
);
});
const Child3 = forwardRef((props, ref) => {
return (
<div className="child3">
<h1>Child3</h1>
</div>
);
});
const Child4 = forwardRef((props, ref) => {
return (
<div className="child4">
<h1>Child4</h1>
</div>
);
});
const Child5 = forwardRef((props, ref) => {
return (
<div className="child5">
<h1>Child5</h1>
</div>
);
});
const numberOfSections = 5;
function Home() {
const section = useRef();
const [currentSection, setCurrentSection] = useState(1);
const moveLeft = () => {
section.current.classList.remove(`section${currentSection}`);
section.current.classList.add(`section${currentSection - 1}`);
setCurrentSection((prevSection) => prevSection - 1);
};
const moveRight = () => {
section.current.classList.remove(`section${currentSection}`);
section.current.classList.add(`section${currentSection + 1}`);
setCurrentSection((prevSection) => prevSection + 1);
};
const changeSection = (event) => {
if (event.key === "d") {
if (currentSection < numberOfSections) {
moveRight();
}
} else if (event.key === "a") {
if (currentSection > 1) {
moveLeft();
}
}
};
useEffect(() => {
window.addEventListener("keypress", changeSection);
return () => window.removeEventListener("keypress", changeSection);
}, [currentSection]);
return (
<div ref={section} className="section">
<Child1></Child1>
<Child2></Child2>
<Child3></Child3>
<Child4></Child4>
<Child5></Child5>
</div>
);
}
export default Home;
I have tested it and it works.
By the way, my suggestions is to wrap some of these functions into useCallback if you plan to expand Home component. And I suggest to use some of npm packages compatible with React for directly manipulating CSS within JS, such as styled-components, which in this case would make it a lot easier to create Carousel, becouse now in order to create more Child components, you need to make new CSS classes.
But this above fixes the given problem. I hope I helped you :)
this solution is tightly cuppled to your example but from my perspective, you could make it more generic.
I didn't use CSS animation instead I used the scrollTo method to achieve scroll behavior.
codesandbox link
Home.jsx
import { forwardRef, useEffect, useRef, useState } from "react";
import "./styles.css";
// I not using forwardRef and ref at all
const Child1 = forwardRef((props, ref) => {
return (
<div className="child1">
<h1>Child1</h1>
</div>
);
});
const Child2 = forwardRef((props, ref) => {
return (
<div className="child2">
<h1>Child2</h1>
</div>
);
});
const Child3 = forwardRef((props, ref) => {
return (
<div className="child3">
<h1>Child3</h1>
</div>
);
});
const Child4 = forwardRef((props, ref) => {
return (
<div className="child4">
<h1>Child4</h1>
</div>
);
});
const Child5 = forwardRef((props, ref) => {
return (
<div className="child5">
<h1>Child5</h1>
</div>
);
});
function App() {
let section = useRef();
let [currentSection, setCurrentSection] = useState(0);
useEffect(() => {
const handler = (event) => {
if (event.key === "d") {
if (currentSection === 4) return;
setCurrentSection((prev) => prev + 1);
} else if (event.key === "a") {
if (currentSection === 0) return;
setCurrentSection((prev) => prev - 1);
}
};
window.addEventListener("keypress", handler);
// you should clean up you EventListener
return () => {
window.removeEventListener("keypress", handler);
};
}, [currentSection]);
useEffect(() => {
window.scrollTo({
behavior: "smooth",
left: window.innerWidth * currentSection,
top: 0,
});
}, [currentSection]);
return (
<div ref={section} className="section">
<Child1></Child1>
<Child2></Child2>
<Child3></Child3>
<Child4></Child4>
<Child5></Child5>
</div>
);
}
export default App;
Home.css
.section {
display: flex;
flex-direction: row;
font-family: Arial, sans-serif;
font-weight: bold;
transition: 1s;
width: 100vw;
height: 100vh;
}
.child1 {
background-color: #c0392b;
flex: none;
width: 100vw;
height: 100vh;
}
.child2 {
background-color: #e67e22;
flex: none;
width: 100vw;
height: 100vh;
}
.child3 {
background-color: #27ae60;
flex: none;
width: 100vw;
height: 100vh;
}
.child4 {
background-color: #2980b9;
flex: none;
width: 100vw;
height: 100vh;
}
.child5 {
background-color: #8e44ad;
flex: none;
width: 100vw;
height: 100vh;
}

How can I make a song progress bar for my audio player?

I've made a simple audio player, but now I want to add a song progress bar that fills up the timeline as the song plays, this is my html:
<div id="ap-timeline" onClick={this.mouseMove} ref={(timeline) => { this.timeline = timeline }}>
<div id="ap-handle" onMouseDown={this.mouseDown} ref={(handle) => { this.handle = handle }} />
<div id="ap-handle-circle" onMouseDown={this.mouseDown} ref={(handleCircle) => { this.handleCircle = handleCircle }} />
</div>
And this is my CSS:
#ap-timeline{
display: flex;
flex-direction: row;
align-items: center;
width: 550px;
height: 4px;
border-radius: 15px;
background: $audio-slider-gray;
margin: 0 10px;
#ap-handle {
background: $white;
height: 4px;
}
#ap-handle-circle {
width: 13px;
height: 13px;
border-radius: 50%;
background: $white;
transform: scale(0.25);
}
}
}
The ap-handle is the progress bar that I'm trying to use to fill up the timeline as the song plays.
I'm not much of a react person so excuse any poor practices here:
#progress-bar {
height: 20px;
background: red;
transform: scaleX(0);
transform-origin: center left;
}
class App extends Component {
constructor() {
super();
this.interval = null; // setInterval
this.audioEl = new Audio(
"https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3"
);
this.audioEl.addEventListener("canplaythrough", () => {
this.setState({
duration: this.audioEl.duration
});
});
this.state = {
currentTime: 0,
duration: 0
};
}
playAudio() {
this.audioEl.play();
// requestAnimationFrame would probably be better, but
// for example sake we'll use setInterval
this.interval = setInterval(() => {
this.setState({
currentTime: this.audioEl.currentTime,
progress: Math.ceil((this.audioEl.currentTime / this.audioEl.duration) * 100) / 100
});
}, 100);
}
stopAudio() {
clearInterval(this.interval);
this.audioEl.pause();
}
render() {
return (
<div>
<button onClick={() => this.playAudio()}>Play</button>
<button onClick={() => this.stopAudio()}>Stop</button>
<div
style={{ transform: `scaleX(${this.state.progress})` }}
id="progress-bar"
/>
</div>
);
}
}
Blitz

How do I make a content div scrollable? React and CSS

Learning React.js framework and need some pointers on styling. CSS isn't my forte.
How do I style the static content div in the middle and make it scrollable only within the div?
No styling:
https://i.imgur.com/26wNAfH.jpg
How to style this?
https://i.imgur.com/c5nYCOz.jpg
Here's the scroll function:
https://storage.googleapis.com/hatchways-app.appspot.com/assessments/data/frontend/part%202.mp4
app.css
.name {
font-weight: bold;
font-size: 20px;
}
.centered {
margin: auto;
width: 50%;
border: 3px solid green;
padding: 10px;
}
.center {
position: fixed;
width: 500px;
height: 200px;
top: 50%;
left: 50%;
margin-top: -100px; /* Negative half of height. */
margin-left: -250px; /* Negative half of width. */
}
.content {
text-align: center;
border: 2px solid grey;
border-radius: 5px;
position: fixed;
/* center the div */
right: 0;
left: 0;
margin-right: auto;
margin-left: auto;
/* give it dimensions */
min-height: 10em;
width: 90%;
/* just for example presentation */
top: 5em;
background-color: white;
}
Output: https://i.imgur.com/Eyv6hab.png
HTML:
import React, { Component } from "react";
import "../App.css";
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
const API = "https://www.hatchways.io/api/assessment/students";
class App extends Component {
constructor(props) {
super(props);
this.state = {
students: [],
isLoading: false,
error: null
};
}
componentDidMount() {
this.setState({ isLoading: true });
fetch(API)
.then(response => {
if (response.ok) {
return response.json();
} else {
throw new Error("Something went wrong ...");
}
})
.then(data =>
this.setState({ students: data.students, isLoading: false })
)
.catch(error => this.setState({ error, isLoading: false }));
}
render() {
const { students, isLoading, error } = this.state;
if (error) {
return <p>{error.message}</p>;
}
if (isLoading) {
return <p>Loading ...</p>;
}
return (
<body>
<div className="content">
<div>
{students.map(student => (
<div key={student.id}>
<p>
<img src={student.pic} />
</p>
<p className="name">
{student.firstName} {student.lastName}
</p>
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p> Skill: {student.skill}</p>
<p>Average: {student.grades}</p>
</div>
))}
</div>
</div>
{/* <div class="card mb-3">
{students.map(student => (
<div class="row no-gutters">
<div class="col-md-4">
<img src={student.pic} class="card-img" alt="..." />
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">
{student.firstName} {student.lastName}
</h5>
<p class="card-text">
<p>Email: {student.email}</p>
<p>Company: {student.company}</p>
<p> Skill: {student.skill}</p>
<p>Average: {student.grades}</p>
</p>
</div>
</div>
</div>
))}
</div> */}
</body>
);
}
}
export default App;
This might not help I am unfamiliar with that JS framework. I am only posting this because nobody has answered and maybe this can help.
<style>
scroll
{
max-height: 400px;
overflow-y: scroll;
}
</style>
<div class="scroll">

How to indent list and sublist menu?

I am trying to style the list and sublist menu. Some list items have name and some list items having sublist items having svg added infront of list item. in doing so, the list item without sublist item is not indented correctly. how can i achieve it. could somebody help me. Below is what i have tried.
return (
{this.props.expanded &&
<Drawer className="drawer">
<header>
<h4>List items</h4>
</header>
<ListItems listitemss={this.props.listitems} />
</Drawer>
}
</div>
);
};
}
class ListItemss extends React.PureComponent {
render() {
return <ul className="listitems_list">
<div className="lists">
{this.props.layers.map((list, index) => {
return <List key={index} list={list} />
})}
</div>
</ul>
}
}
class List extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
expanded: false,
hidden: false,
};
}
expand = () => {
this.setState({expanded: true});
};
collapse = () => {
this.setState({expanded: false});
};
hide_layer = () => {
this.setState({hidden: true});
};
show_layer = () => {
this.setState({hidden: false});
};
render() {
return <li>
<div className="list">
{this.props.list.children && !this.state.expanded &&
<SvgAccDown width="14" height="8" onClick={this.expand} />
}
{this.props.list.children && this.state.expanded &&
<SvgAccUp width="20" height="18" onClick={this.collapse} />
}
<span>{this.props.list.name}</span>
</div>
{this.props.list.children && this.state.expanded &&
<ListItems lists={this.props.list.children}/>
}
</li>;
}
}
.listitems_list {
height: 100%;
overflow: auto;
.lists {
height: 100%;
margin-left: 12px;
overflow: auto;
.list {
background-color: #fff;
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
span {
padding-right: 12px;
padding-top: 12px;
padding-bottom: 12px;
padding-left: 2px;
font-size: 16px;
font-weight: bold;
}
}
}
}
If it is an external CSS file, and you are using something like Create React App, you can just import 'mystyle.css;`

display a overlay when input is clicked in react

I'm trying to display a overlay when a certain Input field is clicked. I'm doing this in react. How can I do this?
This is my code
import React, { Component } from 'react';
import cam from '../../Resources/img/cam.png';
import SinglePost from '../../Components/Post/single_post';
class Middle extends Component {
constructor(props) {
super(props);
this.state = {
posts: []
}
}
render() {
function popup_ques(e) {
e.preventDefault();
alert("now the overlay should appear");
}
return (
<div className="middle_div">
<input className='post_data_input' placeholder="Ask your question here" ref="postTxt" onClick={popup_ques}/>
</div>
);
}
}
export default Middle;
What is the approach I should take?
I have created a sample react component.
I hope this will help you in somewhat way to achieve what you want.
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
style : {
width : 350
}
};
this.openNav = this.openNav.bind(this);
this.closeNav = this.closeNav.bind(this);
}
componentDidMount() {
document.addEventListener("click", this.closeNav);
}
componentWillUnmount() {
document.removeEventListener("click", this.closeNav);
}
openNav() {
const style = { width : 350 };
this.setState({ style });
document.body.style.backgroundColor = "rgba(0,0,0,0.4)";
document.addEventListener("click", this.closeNav);
}
closeNav() {
document.removeEventListener("click", this.closeNav);
const style = { width : 0 };
this.setState({ style });
document.body.style.backgroundColor = "#F3F3F3";
}
render() {
return (
<div>
<h2>Fullscreen Overlay Nav Example</h2>
<p>Click on the element below to open the fullscreen overlay navigation menu.</p>
<p>In this example, the navigation menu will slide in, from left to right:</p>
<span style={{fontSize:30,cursor:"pointer"}} onClick={this.openNav}>☰ open</span>
<div
ref = "snav"
className = "overlay"
style = {this.state.style}
>
<div className = "sidenav-container">
<div className = "text-center">
<h2>Form</h2>
<p>This is a sample input form</p>
</div>
<a
href = "javascript:void(0)"
className = "closebtn"
onClick = {this.closeNav}
>
×
</a>
<div className = "list-group">
{/*your form component goes here */}
{this.props.children}
</div>
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<Test/>,
document.getElementById('test')
);
.overlay {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0, 0.9);
overflow-x: hidden;
transition: 0.5s;
}
.overlay-content {
position: relative;
top: 25%;
width: 100%;
text-align: center;
margin-top: 30px;
}
.overlay a {
padding: 8px;
text-decoration: none;
font-size: 36px;
color: #818181;
display: block;
transition: 0.3s;
}
.overlay a:hover, .overlay a:focus {
color: #f1f1f1;
}
.overlay .closebtn {
position: absolute;
top: 20px;
right: 45px;
font-size: 60px;
}
#media screen and (max-height: 450px) {
.overlay a {font-size: 20px}
.overlay .closebtn {
font-size: 40px;
top: 15px;
right: 35px;
}
}
.overlay h2, .overlay p {
color:white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="test"></div>
Input:
<input onFocus={() => this.setState({show_overlay: true})} />
somewhere arround in same render() function add overlay div:
<div
style={{display: this.state.show_overlay === true ? 'block' : 'none'}}
>
overlay
</div>
of course add styling to div as needed to have proper overlay effect, what's needed by your UI
To turn overlay off, you will need to add another event listener on some action, like e.g. click
<button onClick={() => this.setState({show_overlay: false})}>
Close overlay
</button>