I am working on a project where i have to implement a search bar which should be in my header component , when ever i try to search the search is working fine but at the same time the search options are overlapping the my content below it. how can i resolve this?
I tried adding zIndex both using css and noraml jsx way both dint work for me bellow is my code.
Header.js
import React, { Component } from 'react';
import Autocomplete from 'react-autocomplete';
import { getStocks, matchStocks } from './data';
class Header extends Component {
state = { value: '' };
render() {
return (
<div style={{ marginTop: 0, marginLeft: 0 }}>
<div className="callout primary" id="Header">
<div className="row column">
<h1>{this.props.name}</h1>
<div style={{ zIndex: 10 }}> // this is where i am trying to set the zIndex
<Autocomplete
classNames={{ autocompleteContainer: 'ac-container' }}
value={ this.state.value }
inputProps={{ id: 'states-autocomplete' }}
wrapperStyle={{ position: 'relative', display: 'inline-block' }}
items={ getStocks() }
getItemValue={ item => item.name }
shouldItemRender={ matchStocks }
onChange={(event, value) => this.setState({ value }) }
onSelect={ value => this.setState({ value }) }
renderMenu={ children => (
<div className = "menu">
{ children }
</div>
)}
renderItem={ (item, isHighlighted) => (
<div
className={`item ${isHighlighted ? 'item-highlighted' : ''}`}
key={ item.abbr } >
{ item.name }
</div>
)}
/>
</div>
</div>
</div>
</div>
);
}
}
export default Header;
Related
I'm building a website with React and Bootstrap which would have a static footer. The footer will contain two buttons - Back, and Next. Clicking 'back' decrements an index, and clicking 'next' would increment the index. Ideally this index would keep track of which js component to show or hide using a ternary statement with with display: 'inline' or 'none'. I've tried useState in the App.js file, AND in the Footer.js file, but I am unable to pass the useState values between components it seems. Is there a better way to do this? I have provided some of my code which does not work.
Footer.js:
import React from "react";
import { useState } from "react";
const Footer = (props) => {
const [pageIndex, setPageIndex] = useState(0);
return (
<div className="container-lg">
<div class="row justify-content-between mt-5">
<button
onClick={setPageIndex(pageIndex - 1)}
>
Back
</button>
<button
onClick={setPageIndex(pageIndex + 1)}
>
Next
</button>
</div>
</div>
);
};
export default Footer;
App.js:
function App() {
return (
<div className="App">
<div style={{display: Footer.pageIndex === 0 ? 'inline' : 'none'}}>
<Component />
</div>
<div style={{display: Footer.pageIndex === 1 ? 'inline' : 'none'}}>
<AnotherComponent />
</div>
<Footer />
</div>
);
}
export default App;
Few issues with your code: 1) className, not the class in react. 2) Error in your onClick parameters. 3) You need to move state up to the App component.
const {useState} = React;
function App() {
const [pageIndex, setPageIndex] = useState(0);
return (
<div className="App">
<div style={{ display: pageIndex === 0 ? "inline" : "none" }}>
<Component />
</div>
<div style={{ display: pageIndex === 1 ? "inline" : "none" }}>
<AnotherComponent />
</div>
<Footer setPageIndex={setPageIndex} />
</div>
);
}
const Footer = ({ setPageIndex }) => {
return (
<div className="container-lg">
<div className="row justify-content-between mt-5">
<button onClick={() => setPageIndex((prev) => prev - 1)}>Back</button>
<button onClick={() => setPageIndex((prev) => prev + 1)}>Next</button>
</div>
</div>
);
};
const Component = (props) => {
return <p>Component</p>;
};
const AnotherComponent = (props) => {
return <p>AnotherComponent</p>;
};
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App />
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<div id="root"></div>
Shift the state of the footer to be at the parent which is App.js
import React from "react";
import { useState } from "react";
const Footer = (props) => {
const { setPageIndex, pageIndex } = props;
return (
<div className="container-lg">
<div class="row justify-content-between mt-5">
<button onClick={()=> setPageIndex(pageIndex - 1)}>Back</button>
<button onClick={()=> setPageIndex(pageIndex + 1)}>Next</button>
</div>
</div>
);
};
export default Footer;
and then you could pass the setPageIndex as prop to the footer.
function App() {
const [pageIndex, setPageIndex] = useState(0);
return (
<div className="App">
<div style={{ display: Footer.pageIndex === 0 ? "inline" : "none" }}>
<Component />
</div>
<div style={{ display: Footer.pageIndex === 1 ? "inline" : "none" }}>
<AnotherComponent />
</div>
<Footer setPageIndex={setPageIndex} pageIndex={pageIndex} />
</div>
);
}
export default App;
I'm trying to implement drag and drop behaviour using React JS and react-dropzone library with showing thumbnails.
The code is as follows:
import React from "react";
import ReactDOM from "react-dom";
import Dropzone from "react-dropzone";
import "./styles.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
dropzone1: [],
dropzone2: []
};
}
addFilesToDropzone(files, dropzone) {
let files_with_preview = [];
files.map(file => {
file["preview"] = URL.createObjectURL(file);
files_with_preview.push(file);
});
const new_files = [...this.state[dropzone], ...files_with_preview];
this.setState({ [dropzone]: new_files });
}
render() {
return (
<div className="App">
<Dropzone
onDrop={files => {
this.addFilesToDropzone(files, "dropzone1");
}}
>
{({ getRootProps, getInputProps }) => (
<div {...getRootProps()} className="">
<input {...getInputProps()} />
<div style={{ height: 100, backgroundColor: "yellow" }}>
Drop some files here
{dropzone1.map(file => (
<img
src={file.preview}
alt={file.path}
style={{ width: 40, height: 40 }}
/>
))}
</div>
</div>
)}
</Dropzone>
<div style={{ display: "flex", flexDirection: "row", marginTop: 25 }}>
<div style={{ width: "100%" }}>
DROPZONE 2
<Dropzone
onDrop={files => {
this.addFilesToDropzone(files, "dropzone2");
}}
>
{({ getRootProps, getInputProps }) => (
<div {...getRootProps()} className="">
<input {...getInputProps()} />
<div style={{ height: 100, backgroundColor: "yellow" }}>
Drop some files here
{this.state.dropzone2.map(file => (
<img
src={file.preview}
alt="dsds"
style={{ width: 40, height: 40 }}
/>
))}
</div>
</div>
)}
</Dropzone>
</div>
</div>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here is the example on codesandbox.
Everything works fine when I drag files from a folder on my computer, but I want to be able to drag thumbnails generated with dropzone 1 to a dropzone 2. But that doesn't work.
Any idea how to do that?
Yes, that doesn't work because that's not what react-dropzone is designed for. Quote from the website,
Simple React hook to create a HTML5-compliant drag'n'drop zone for files.
Use react-dnd or react-beautiful-dnd instead.
You can use another package: react-file-drop
I need to click on the custom arrows, what would the slider work. I know that there is a trigger in JQuery or something, but what can i do in react ?
You can see api slick-slider on this link https://react-slick.neostack.com/docs/example/custom-arrows
..................................................................................................................................................................
import React, { Component } from "react";
import Slider from "react-slick";
function SampleNextArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "red" }}
onClick={onClick}
/>
);
}
function SamplePrevArrow(props) {
const { className, style, onClick } = props;
return (
<div
className={className}
style={{ ...style, display: "block", background: "green" }}
onClick={onClick}
/>
);
}
export default class CustomArrows extends Component {
render() {
const settings = {
dots: true,
infinite: true,
slidesToShow: 3,
slidesToScroll: 1,
nextArrow: <SampleNextArrow />,
prevArrow: <SamplePrevArrow />
};
return (
<div>
<h2>Custom Arrows</h2>
// CLICK HERE
<div><span>arrows<span><span>arrows<span></div>
<Slider {...settings}>
<div>
<h3>1</h3>
</div>
<div>
<h3>2</h3>
</div>
<div>
<h3>3</h3>
</div>
<div>
<h3>4</h3>
</div>
<div>
<h3>5</h3>
</div>
<div>
<h3>6</h3>
</div>
</Slider>
</div>
);
}
}
I found this solution
document.getElementsByClassName('slick-next')[0].click()
but I do not know if it is good to use in react
guys! Have a problem with rerendering of slider component. After choosing another SELECT option, other images are to be loaded to carousel component. But!! Nothing happens! Props of component are being changed, and developer tools show slides (images) are changed, but nothing happens on DOM.
Below i post code. What do you think? Where is the problem?
import React from 'react';
import CarouselSlider from "react-carousel-slider";
import { FormControl } from 'react-bootstrap';
class StampChoose extends React.Component {
changeSamplesType = (e) => {
const sampleType = e.target.value;
this.props.changeSamplesType(sampleType);
this.forceUpdate();
}
render() {
let btnWrapperStyle = {
position: "relative",
borderRadius: "50%",
height: "50px",
width: "50px",
textAlign: "center"
}
let btnStyle = {
display: "inline-block",
position: "relative",
top: "90%",
transform: "translateY(-50%)",
fontSize: "36px"
}
let rBtnCpnt = (<div style = {btnWrapperStyle} >
<div style = {btnStyle} className = "material-icons" >
<i className="fas fa-angle-right"></i>
</div>
</div>);
let lBtnCpnt = (<div style = {btnWrapperStyle} >
<div style = {btnStyle} className = "material-icons" >
<i className="fas fa-angle-left"></i>
</div>
</div>);
let iconItemsStyle = {
padding: "0px",
background: "transparent",
margin:"0 5px",
height: "80%"
};
const titles = this.props.titles;
const slides = this.props.slides;
return (
<React.Fragment>
<FormControl componentClass="select" onChange={ this.changeSamplesType }>
<option value="type1">{ titles['type1'] }</option>
<option value="type2">{ titles['type2'] }</option>
<option value="type3">{ titles['type3'] }</option>
<option value="type4">{ titles['type4'] }</option>
</FormControl>
<CarouselSlider
sliderBoxStyle = {{height: "150px", width: "90%", background: "transparent", overflow: "hidden"}}
accEle = {{dots: false}}
newState={ this.state }
slideCpnts = {slides}
itemsStyle = {iconItemsStyle}
buttonSetting = {{placeOn: 'middle-outside'}}
rBtnCpnt = {rBtnCpnt}
lBtnCpnt = {lBtnCpnt}
/>
</React.Fragment>
)
}
}
export default StampChoose;
import React from 'react';
import { Grid, Row, Col, ControlLabel } from 'react-bootstrap';
import { samples, titles} from '../../../samples-stamps';
import StampChoose from './StampChoose';
const Sample = (props) => (
<React.Fragment>
{
<div>
<img src={ `images/samples/${props.img}` } alt={ props.title } />
</div>
}
</React.Fragment>
);
class StampsSamples extends React.Component {
state = {
sampleType: 'type1'
}
changeSamplesType = (sampleType) => {
this.setState({ sampleType });
}
render() {
const sampleType = this.state.sampleType;
let slides = Object.keys(samples[sampleType]).map((item, i) => {
return (
<div>
<Sample
key={i}
title={ samples[sampleType][item].title }
img={ samples[sampleType][item].img }
productId={ samples[sampleType][item].id }
/>
</div>
);
});
return (
<Grid>
<Row>
<Col md={ 4 }>
<ControlLabel>Примерный образец оттиска <br/>
<small>(выберите образец оттиска)</small>
</ControlLabel>
</Col>
<Col md={ 8 }>
<StampChoose
slides={ slides }
titles={ titles }
changeSamplesType={ this.changeSamplesType }
/>
</Col>
</Row>
</Grid>
);
}
}
export default StampsSamples;
In your Sample Component your returning an object inside of React.Fragment. Does it have anything to do with that? What if you remove the { and } inside there and try? Like below. Don't know if thats the issue but try. You also have an extra DIV in your map method for the slides. If you check the instructions for the React Carousel Slider they dont use these extra DIVs and {}
<React.Fragment>
<div>
<img src={ `images/samples/${props.img}` } alt={ props.title } />
</div>
</React.Fragment>
I am using infinite scroll plugin for react.js and for some reason it is not working the way it is supposed to work.
The problem is that all the requests are made at once when the page loads, and not like for example a request should be made for each time I scroll.
My code looks like below:
import React from 'react';
import {Route, Link} from 'react-router-dom';
import FourthView from '../fourthview/fourthview.component';
import {withRouter} from 'react-router';
import {Bootstrap, Grid, Row, Col, Button, Image, Modal, Popover} from 'react-bootstrap';
import traineeship from './company.api';
import Header from '../header/header.component';
import InfiniteScroll from 'react-infinite-scroller';
require('./company.style.scss');
class Traineeship extends React.Component {
constructor(props) {
super(props);
this.state = {
companies: [],
page: 0,
resetResult: false,
hasMore: true,
totalPages: null,
totalElements: 0,
};
}
componentDidMount() {
this.fetchCompanies(this.state.page);
}
fetchCompanies = page => {
let courseIds = '';
this.props.rootState.filterByCourseIds.map(function (course) {
courseIds = courseIds + '' + course.id + ',';
});
traineeship.getAll(page, this.props.rootState.selectedJob, courseIds.substring(0, courseIds.length - 1), this.props.rootState.selectedCity).then(response => {
if (response.data) {
const companies = Array.from(this.state.companies);
if(response.data._embedded !== undefined){
this.setState({
companies: companies.concat(response.data._embedded.companies),
totalPages: response.data.page.totalPages,
totalElements: response.data.page.totalElements,
});
}
if (page >= this.state.totalPages) {
this.setState({hasMore: false});
}
} else {
console.log(response);
}
});
};
render() {
return (
<div className={"wrapperDiv"}>
{/*{JSON.stringify(this.props.rootState)}*/}
<div className={"flexDivCol"}>
<div id="header2">
<div style={{flex: .05}}>
<img src="assets/img/icArrowBack.png" onClick={() => this.props.history.go(-1)}/>
</div>
<div style={{flex: 3}}>
<Header size="small"/>
</div>
</div>
<div id="result">
<div className={"search"}>
<h2 style={{fontSize: 22}}>Harjoittelupaikkoja</h2>
<p className={"secondaryColor LatoBold"} style={{fontSize: 13}}>{this.state.totalElements} paikkaa löydetty</p>
</div>
<div className={"filters"}>
<h5 style={{marginTop: '30px', marginBottom: '10px'}} className={"primaryColor"}>
<strong>Hakukriteerit</strong></h5>
{
this.props.rootState.filters.map((filter, key) => (
<div key={key} className={"filter"}>{filter.title}</div>
))
}
</div>
<div className={"searchResults"}>
<h5 style={{marginTop: '30px', marginBottom: '10px'}} className={"primaryColor"}>
<strong>Hakutulokset</strong></h5>
<InfiniteScroll
pageStart={0}
loadMore={this.fetchCompanies}
hasMore={this.state.hasMore}
loader={<div className="loader" key={0}>Loading ...</div>}
useWindow={false}
>
{
this.state.companies.map((traineeship, key) => (
<div id={"item"} key={key}>
<div className={"companyInfo"}>
<div className={"heading"}>
<div id={"companyDiv"}>
<p className={"LatoBlack"} style={{
fontSize: '18px',
lineHeight: '23px'
}}>{traineeship.name}</p>
</div>
{
traineeship.mediaUrl == null
? ''
:
<div id={"videoDiv"}>
<div className={"youtubeBox center"}>
<div id={"youtubeIcon"}>
<a className={"primaryColor"}
href={traineeship.mediaUrl}>
<span style={{marginRight: '3px'}}><Image
src="http://www.stickpng.com/assets/images/580b57fcd9996e24bc43c545.png"
style={{
width: '24px',
height: '17px'
}}/></span>
<span> <p style={{
fontSize: '13px',
lineHeight: '24px',
margin: 0,
display: 'inline-block'
}}>Esittely</p></span>
</a>
</div>
<div id={"txtVideo"}>
</div>
</div>
</div>
}
</div>
<div className={"location"}>
<div id={"locationIcon"}>
<Image src="assets/img/icLocation.png"
style={{marginTop: '-7px'}}/>
</div>
<div id={"address"}>
{
traineeship.addresses.map((address, key) => {
return (
<a href={"https://www.google.com/maps/search/?api=1&query=" + encodeURI("Fredrikinkatu 4, Helsinki")}>
<p key={key} className={"primaryColor"} style={{fontSize: '13px'}}>{address.street}, {address.city}</p>
</a>
)
})
}
</div>
</div>
<div className={"companyDescription"}>
<p className={"secondaryColor"} style={{
fontSize: '14px',
lineHeight: '20px'
}}>{traineeship.description}</p>
</div>
<div>
{
traineeship.images.map((image, key) => {
return (
<img id={"thumbnail"} width={"100%"}
src={image.url}
style={{
width: '80px',
height: '80px',
marginRight: '10px',
marginBottom: '10px'
}}
alt=""
key={key}
/>
)
})
}
</div>
<div className={"companyContacts"} style={{marginTop: '20px'}}>
<p className={"contactInfo"}>URL: {traineeship.website}</p>
<p className={"contactInfo"}>Email: {traineeship.email}</p>
<p className={"contactInfo"}>Puh: {traineeship.phonenumber}</p>
<p className={"contactInfo"}>Contact: {traineeship.contact}</p>
</div>
</div>
</div>
))
}
</InfiniteScroll>
</div>
</div>
</div>
</div>
);
}
}
export default withRouter(Traineeship);
What can I do so I can eliminate all the request are made when the page is load, I mean this is even worse sending let say 20 request one after another within a second or so.
Any suggestion what is wrong with my code?
by removing useWindow={false} it is working now!
Update: Haven't seen that you are using react-infinite-scroller. If you want to build the loader yourself, see my previous answer. With the plugin you can set a threshold.
The answer lies in here: Question: Infinite Scrolling
What you basically need to do is to set a variable in state, isLoading: false, and change it when data comes in via fetch, when data loading done set it back to false. In your infinite scroll function check (this.state.isLoading).