Upon clicking the image icon, it should open the image gallery. However, in this case it does not work. The interesting thing is the exact implementation works on another page. Below is a component which I then call to a page. The implementation that works is a component called to a separate page also. I cannot see any fundamental difference that would account for an error. No error pertaining to this is logged either. Does anyone know what could possibly be wrong by looking at this? Or is able to point me in the right direction for troubleshooting?
export default function Step1AddItems() {
const [image, setImage] = useState({ preview: "", raw: "" });
const handleItemChange = e => {
if (e.target.files.length) {
setImage({
preview: URL.createObjectURL(e.target.files[0]),
raw: e.target.files[0]
});
}
};
const handleItemUpload = async e => {
e.preventDefault();
const formData = new FormData();
formData.append("image", image.raw);
await fetch("", {
method: "POST",
headers: {
"Content-Type": "multipart/form-data"
},
body: formData
});
};
// if(props.currentStep !== 1) {
// return null;
// }
//Markup for step 1 UI
return(
<Row>
<Col size="md-6" fixed>
<div>
<label htmlFor="item-upload-button">
{image.preview ? (
<img src={image.preview} alt="dummy" width="300" height="300" />
) : (
<img src={require("../../images/store.jpg")} style={{justifyContent: "center", alignItems: "center"}} alt="placeholder" width="100" height="100" />
// <>
// <span className="fa-stack fa-2x mt-3 mb-2">
// <i className="fas fa-circle fa-stack-2x" />
// <i className="fas fa-store fa-stack-1x fa-inverse" />
// </span>
// {/* <h5 className="text-center">Upload your photo</h5> */}
// </>
)}
</label>
<input
type="file"
id="upload-button"
style={{ display: "none" }}
onChange={handleItemChange} />
<br/>
<button onClick={handleItemUpload}>Upload</button>
</div>
<div>
<label htmlFor="item-upload-button">
{image.preview ? (
<img src={image.preview} alt="dummy" width="300" height="300" />
) : (
<img src={require("../../images/store.jpg")} style={{justifyContent: "center", alignItems: "center"}} alt="placeholder" width="100" height="100" />
// <>
// <span className="fa-stack fa-2x mt-3 mb-2">
// <i className="fas fa-circle fa-stack-2x" />
// <i className="fas fa-store fa-stack-1x fa-inverse" />
// </span>
// {/* <h5 className="text-center">Upload your photo</h5> */}
// </>
)}
</label>
<input
type="file"
id="upload-button"
style={{ display: "none" }}
onChange={handleItemChange} />
<br />
<button onClick={handleItemUpload}>Upload</button>
</div>
<br />
<div>
<label htmlFor="item-upload-button">
{image.preview ? (
<img src={image.preview} alt="dummy" width="300" height="300" />
) : (
<img src={require("../../images/store.jpg")} style={{justifyContent: "center", alignItems: "center"}} alt="placeholder" width="100" height="100" />
// <>
// <span className="fa-stack fa-2x mt-3 mb-2">
// <i className="fas fa-circle fa-stack-2x" />
// <i className="fas fa-store fa-stack-1x fa-inverse" />
// </span>
// {/* <h5 className="text-center">Upload your photo</h5> */}
// </>
)}
</label>
<input type="file"
id="upload-button"
style={{ display: "none" }}
onChange={handleItemChange} />
<br />
<button onClick={handleItemUpload}>Upload</button>
</div>
<div>
<label htmlFor="item-upload-button">
{image.preview ? (
<img src={image.preview} alt="dummy" width="300" height="300" />
) : (
<img src={require("../../images/store.jpg")} style={{justifyContent: "center", alignItems: "center"}} alt="placeholder" width="100" height="100" />
// <>
// <span className="fa-stack fa-2x mt-3 mb-2">
// <i className="fas fa-circle fa-stack-2x" />
// <i className="fas fa-store fa-stack-1x fa-inverse" />
// </span>
// {/* <h5 className="text-center">Upload your photo</h5> */}
// </>
)}
</label>
<input
type="file"
id="upload-button"
style={{ display: "none" }}
onChange={handleItemChange} />
<br />
<button onClick={handleItemUpload}>Upload</button>
</div>
</Col>
</Row>
)}```
It was a typo - I changed <label htmlFor="item-upload-button"> to <label htmlFor="upload-button"> and it worked - the image gallery window opened up.
Related
I have a reactjs app that shows the google map. In the map section, there is a center marker. I also have button that when clicked, the map should smoothly move back to the center. Now, the button does work, but it does not animate. Kindly help.
The center is from derived coordinates. Also, if anyone knows how I can define the coordinates using the geolocator to get the current location on the map, kindly help.
This is my code
import React, { useState, useEffect, useRef } from 'react';
import { Link, useNavigate } from "react-router-dom";
import Menubar from "../../components/menubar/Menubar"
import axios from 'axios';
import { UserContext } from "../../UserContext";
import toast, { Toaster } from 'react-hot-toast';
import ActionSheet from "actionsheet-react";
import { useJsApiLoader, GoogleMap, Marker, Autocomplete, DirectionsRenderer } from '#react-google-maps/api'
import Skeleton from 'react-loading-skeleton';
function AddFarm() {
let navigate = useNavigate();
const [loading, setLoading] = useState(false);
const user = React.useContext(UserContext);
const [show, setShow] = useState(false);
const ref = useRef();
const handleOpen = () => {
ref.current.open();
};
const handleClose = () => {
ref.current.close();
}
const center = { lat: -1.1797562, lng: 36.9064927 }
const { isLoaded } = useJsApiLoader({
googleMapsApiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY,
libraries: ['places'],
})
const [map, setMap] = useState(/** #type google.maps.Map */(null))
if (!isLoaded) {
return <Skeleton />
}
return (
<div>
<Menubar />
<div className="appHeader bg-primary text-light">
<div className="left">
<a onClick={() => navigate(-1)} className="headerButton goBack">
<i className="fi fi-rr-angle-left"></i> </a>
</div>
<div className="pageTitle">Add Farm</div>
<div className="right">
</div>
</div>
<div id="appCapsule">
<div className="section mt-3 mb-3">
<form onSubmit={submitFarm}>
<div className="form-group basic">
<div className="input-wrapper">
<label className="label" >Name</label>
<input type="text" className="form-control" onChange={handleInput} value={farmInput.farmname} name="farmname" placeholder=" Enter farm name" />
<i className="clear-input">
<i className="fi fi-rr-cross-circle"></i> </i>
</div>
<div className="invalid-feedback">
{errorlist.farmname}
</div>
<div className="input-info">Give your farm a name</div>
</div>
<div className="form-group basic">
<div className="input-wrapper">
<label className="label" >County</label>
<select className="form-control custom-select" onChange={handleInput} value={farmInput.county_id} name="county_id">
<option value="0">Select County</option>
{
county && county.map((item) => {
return (
<option value={item.id} key={item.id}>{item.countyname}</option>
)
})
}
</select>
</div>
<div className="invalid-feedback">
{errorlist.county_id}
</div>
<div className="input-info">Enter the county your farm is</div>
</div>
<div className="form-group basic">
<div className="input-wrapper">
<label className="label" >Location</label>
<input type="text" className="form-control" onChange={handleInput} value={farmInput.farmlocation} name="farmlocation"
placeholder="Enter farm location" />
<i className="clear-input">
<i className="fi fi-rr-cross-circle"></i> </i>
</div>
<div className="input-info">Enter exactly where you farm is located</div>
</div>
<div className="mt-2">
<button onClick={handleOpen} className="btn btn-primary btn-block btn-lg">Map your Farm</button>
</div>
<ActionSheet
ref={ref}
mouseEnable={false}
touchEnable={false}
sheetStyle={{
borderTopLeftRadius: 0,
borderTopRightRadius: 0,
height: '100%'
}}>
<div className="appHeader bg-primary text-light">
<div className="left">
<a onClick={() => setShow(true)} className="headerButton toggle-searchbox">
<i className="fi fi-rr-search"></i> </a>
</div>
<div className="pageTitle">Map your Farm</div>
<div className="right">
<a onClick={handleClose} className="headerButton">
<i className="fi fi-rr-cross"></i></a>
</div>
</div>
<div id="search" className={show ? "appHeader no-boxshadow show" : "appHeader"}>
<div className="search-form">
<div className="form-group searchbox">
<input type="text" className="form-control" placeholder="Search..." />
<i className="input-icon">
<i className="fi fi-rr-search"></i> </i>
<a onClick={() => setShow(false)} className="ml-1 close toggle-searchbox">
<i className="fi fi-rr-cross-circle"></i> </a>
</div>
</div>
</div>
<div className="section full mt-6 h100">
<GoogleMap
center={center}
zoom={18}
mapContainerStyle={{ width: '100%', height: '100%' }}
options={{
zoomControl: false,
streetViewControl: false,
mapTypeControl: false,
fullscreenControl: false,
mapTypeId: "satellite"
}}
onLoad={map => setMap(map)}
>
<Marker position={center} />
</GoogleMap>
<div class="fab-button animate bottom-right dropdown show bottom-high">
<a onClick={() => {
map.panTo(center, { animate: true, duration: 2.0 })
map.setZoom(18)
}} class="fab" data-toggle="dropdown" aria-expanded="true">
<i class="fi fi-rr-marker"></i>
</a>
</div>
<div className="form-button-group transparent-bg">
<button className="btn btn-primary btn-block btn-lg spinner-btn">{loading ? <><span className="spinner-border spinner-border-sm mr-05" role="status" aria-hidden="true"></span>Updating Profile</> : <>Update Profile</>}</button>
</div>
</div>
</ActionSheet>
</form>
</div>
</div>
</div>
);
}
export default AddFarm;
I have 2 Components, ApplicationOverview.js and ApplicationModal.jsx. Basically, I have a button "Add Application" on my ApplicationOverview.js page which opens the Modal in which I want to fill in some input fields and upload an image there, which is then shown on the ApplicationOverview page as a panel through predefined HTML.
The way I currently implemented it is with the .insertAdjacentHTML method which works, but on the one hand I've been told that implementing it this way makes my page vulnerable to XSS, and on the other hand, events that are added like this are not working. Is there a safe way to let React handle this by passing the HTML to ApplicationOverview.js and append it to an existing div element? Nothing I have searched for so far has worked for me.
ApplicationModal.jsx:
import React from "react";
import placeholder from "../icons/placeholder.png";
var name = "";
var comment = "";
var filename = "";
var id = 0;
const ApplicationModal = ({ setOpen }) => {
const [state, setState] = React.useState("");
const [stateComment, setStateComment] = React.useState(placeholder);
const [file, setFile] = React.useState({placeholder});
React.useEffect(() => {
function handleEscapeKey(event) {
if (event.code === "Escape") {
setOpen(false);
}
}
document.addEventListener("keydown", handleEscapeKey);
return () => document.removeEventListener("keydown", handleEscapeKey);
});
const handleComment = (e) => {
setStateComment(e.target.value);
};
const handleChange = (e) => {
setState(e.target.value);
};
//Method which adds new panels to ApplicationOverview.js
const addNewApplication = () => {
if (state !== "" && stateComment !== "") {
document
.getElementById("center")
.insertAdjacentHTML(
"beforeend",
`<div class='overview-box' id=${id}> <img class='image' src=${file} alt='placeholder'/> <div class='box-content'><h3 class='overview-h3' id='new-headline'>${state}</h3> <p class='overview-p'>${stateComment}</p><h3 class='overview-h3-second'>Connected Products</h3><h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p> </h1> <div class='module-button' id='configure'> <button type='button' class='btn btn-secondary'></button> <div class='button-animation'></div> <div class='button-content'> <span class='content-text'>Configure</span> </div> </div> </div> </div>`
);
id++;
setOpen(false);
} else if (state === "" && stateComment !== "") {
document
.getElementById("center")
.insertAdjacentHTML(
"beforeend",
`<div class='overview-box' id = ${id}> <img class='image' src=${file} alt='placeholder'/> <div class='box-content'><h3 class='overview-h3' id='new-headline'>${state}</h3> <p class='overview-p'>${stateComment}</p><h3 class='overview-h3-second'>Connected Products</h3><h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p> </h1> <div class='module-button' id='configure'> <button type='button' class='btn btn-secondary'></button> <div class='button-animation'></div> <div class='button-content'> <span class='content-text'>Configure</span> </div> </div> </div> </div>`
);
id++;
setOpen(false);
} else if (state !== "" && stateComment === "") {
document
.getElementById("center")
.insertAdjacentHTML(
"beforeend",
`<div class='overview-box' id=${id}> <img class='image' src=${file} alt='placeholder'/> <div class='box-content'><h3 class='overview-h3' id='new-headline'>${state}</h3> <p class='overview-p'>${stateComment}</p><h3 class='overview-h3-second'>Connected Products</h3><h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p> </h1> <div class='module-button' id='configure'> <button type='button' class='btn btn-secondary'></button> <div class='button-animation'></div> <div class='button-content'> <span class='content-text'>Configure</span> </div> </div> </div> </div>`
);
id++;
setOpen(false);
} else {
alert("Please fill in atleast one value.");
}
};
function openDialog() {
document.getElementById("inputUpload").click();
}
function loadFile(e) {
console.log(e.target.files);
setFile(URL.createObjectURL(e.target.files[0]));
}
document.addEventListener("click", function(e) {
})
name = state;
comment = stateComment;
filename = file;
return (
<React.Fragment>
<div className="modalDark" style={{ paddingRight: "250px" }}>
<div class="modal-dialog">
<div class="modal-content" style={{ width: "800px" }}>
<div class="modal-close">
<div class="module-button" style={{ left: "750px" }}>
<button
class="btn btn-link "
onClick={() => setOpen(false)}
></button>
<div class="button-animation"></div>
<div class="button-content new">
<i class="icon icon-dc_close"></i>
</div>
</div>
</div>
<div class="modal-header">
<h3>Add new Application</h3>
</div>
<div class="modal-body">
<div
class="module-input form-group has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px", width: "350px" }}
>
<label for="demo-default">Customer Name</label>
<div class="input-animation-wrapper">
<input
type="text"
id="demo-default"
class="form-control "
value={state}
maxLength="42"
placeholder="[Application Name]"
onChange={(e) => handleChange(e)}
/>
<div class="input-animation"></div>
</div>
</div>
<div
class="module-textarea form-group floating-label has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px" }}
>
<label for="demo-3">Customer Short text</label>
<div
class="input-animation-wrapper"
style={{ width: "350px" }}
>
<textarea
id="demo-3"
class="form-control"
rows="9"
placeholder="Short description of Customer; max. 280 characters"
maxLength={180}
value={stateComment}
onChange={(e) => handleComment(e)}
style={{ width: "350px" }}
></textarea>
<div class="label-area"></div>
<div class="input-animation"></div>
</div>
</div>
<img
class="image"
alt="Customer Logo"
id="logo"
src={file}
style={{
left: "420px",
bottom: "280px",
position: "absolute",
height: "250px",
}}
/>
<div
class="module-button"
style={{
left: "500px",
bottom: "200px",
position: "absolute",
zIndex: "1",
}}
>
<button
type="file"
class="btn btn-light"
onClick={() => openDialog()}
id="fileUpload"
>
<input
type="file"
hidden={true}
accept="image/*"
id="inputUpload"
onChange={(e) => loadFile(e)}
></input>
</button>
<div class="button-animation"> </div>
<div class="button-content">
<span class="content-text">Upload Logo</span>
</div>
</div>
<div
class="module-button"
style={{ bottom: "50px", width: "100px", textAlign: "center" }}
>
<button
type="button"
class="btn btn-secondary btn"
onClick={() => addNewApplication()}
id="adding"
></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Add</span>
</div>
</div>
</div>
</div>
</div>
</div>
</React.Fragment>
);
};
export default ApplicationModal;
export { name, comment, filename };
ApplicationOverview.js:
import React from "react";
import placeholder from "../icons/placeholder.png";
import ApplicationModal from "../components/ApplicationModal.jsx";
const ApplicationOverview = () => {
const [open, setOpen] = React.useState(false);
return (
<div id="wrapper">
{open && <ApplicationModal setOpen={setOpen} />}
<div class="component-headline">
<h4 style={{ color: "gray", display: "inline" }}>
Application overview
</h4>
<div
class="module-button"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
marginLeft: "1032px",
}}
onClick={() => setOpen(true)}
>
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div
class="button-content"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
}}
>
<span class="content-text" style={{ color: "black" }}>
Add Application
</span>
</div>
</div>
</div>
<hr style={{ marginTop: "-20px" }} />
<!-- This is where the added content should be appended to, below are three examples -->
<!-- of hardcoded panels that should be normally added through the Modal" -->
<div class="center-content" id="center">
<div class="overview-box">
<img
class="image"
src={placeholder}
alt="placeholder"
/>
<div class="box-content">
<h3 class="overview-h3">Press</h3>
<p class="overview-p">This Application is used for maintenance</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src={placeholder}
alt="placeholder"
/>
<div class="box-content">
<h3 class="overview-h3">Tooling Machine</h3>
<p class="overview-p">
This Application is used for drilling records
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src={placeholder}
alt="placeholder"
/>
<div class="box-content">
<h3 class="overview-h3">Storing Unit</h3>
<p class="overview-p">
This Application is used to store parameters
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default ApplicationOverview;
Modal Window
ApplicationOverview
You can put your useState in the ApplicationOverview.js and pass them as props to the ApplicationModal. So when the applicationModal set the useState the ApplicationOverview has the data and can simply display it.
in your ApplicationOverview:
const [state, setState] = React.useState("");
const [stateComment, setStateComment] = React.useState(placeholder);
const [file, setFile] = React.useState({placeholder});
return (
<div id="wrapper">
{open && <ApplicationModal setOpen={setOpen} setState={setState} state={state} setFile={setFile} file={file} setStateComment={setStateComment} stateComment={stateComment}/>
rest of your HTML
)
then where you want to display the result in the ApplicationOverview you can:
{state && stateComment { display what you want}}
So basically, I have a functional component that shows a reactstrap dropdown.
Here's how it looks. according to the picture i want to be able to click on the box and the dots show in green (the dropdown box is shown in red) without closing the dropdown (by default, it closes when clicked on).
Right now, I'm using stopImmediatePropagation which is incorrect and throws an error:
Uncaught TypeError: e.stopImmediatePropagation is not a function
But meanwhile preserves the functionality i want (it prevents closing the dropdown which i assume has something to do with not letting event propagate to the parent)
And here's the code, Any insight or solution?
import React from "react"
import { ImAttachment } from "react-icons/im"
import { FiMoreVertical } from "react-icons/fi"
import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from "reactstrap"
import Avatar from "src/#core/components/avatar"
import { VscTriangleRight } from "react-icons/vsc"
import BpmsIconButton from "src/components/#bpms/Buttons/BpmsIconButton"
const Items = (props) => {
const {
title = "title",
subtitle = "subtitle",
itemAvatar,
color = "",
actions = null,
index = -1
} = props
const stopBubbling = (e) => {
e.stopImmediatePropagation()
}
return (
<DropdownItem tag="div" className="dropdown-item-custom" onClick={stopBubbling}>
<div className="text-nowrap">
<div className="d-flex flex-row justify-content-start">
<a className="d-flex no-pointer">
<div className="d-flex cursor-pointer">
{!/\//.test(itemAvatar) ? ( // string containing / indicates of url
<Avatar
className="rounded"
color={`light-${color}`}
size="lg"
icon={<span>{itemAvatar}</span>}
/>
) : (
<Avatar
className="rounded rounded-circle"
color={color}
size="lg"
icon={<img src={itemAvatar} alt="item" />}
/>
)}
</div>
<div className="text-custom">
<div className="flex-column">{title}</div>
<div className="flex-column text-muted">{subtitle}</div>
</div>
</a>
<UncontrolledDropdown>
<DropdownToggle tag="a">
<span className="dropdown-file-type">
<span className="dropdown-file-type-text">
<BpmsIconButton icon={<FiMoreVertical size={20} />} />
</span>
</span>
</DropdownToggle>
<DropdownMenu className="dropdown-menu-inside-custom">
<DropdownItem tag="div" onClick={() => actions().edit(index)}>
<div className="text-nowrap">
<div className="d-flex flex-row justify-content-start">
<a className="d-flex">
<div className="action-text-custom">ویرایش</div>
</a>
</div>
</div>
</DropdownItem>
<DropdownItem tag="div" onClick={() => actions().remove(index)}>
<div className="text-nowrap">
<div className="d-flex flex-row justify-content-start">
<a className="d-flex">
<div className="action-text-custom">حذف</div>
</a>
</div>
</div>
</DropdownItem>
<DropdownItem tag="div" onClick={() => actions().view(index)}>
<div className="text-nowrap">
<div className="d-flex flex-row justify-content-start">
<a className="d-flex">
<div className="action-text-custom">مشاهده</div>
</a>
</div>
</div>
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</div>
</div>
</DropdownItem>
)
}
const GeneralTab = (props) => {
const { general, items, settings } = props || {}
const {
Icon: HeaderIcon = ImAttachment,
ActionsIcon: MoreIcon = FiMoreVertical,
text = "اسناد و مدارک",
index,
generalActions = null,
itemActions = null
} = general || {}
const { color = "" } = settings || {}
const stopBubbling = (e) => {
e.stopImmediatePropagation()
}
return (
<UncontrolledDropdown>
<DropdownToggle tag="div" className="p-0 general-tab-hover">
<div className="text-nowrap">
<div className="d-flex flex-row justify-content-start">
<a className="d-flex me-5">
<HeaderIcon size={20} className="title-icons" />
<span>
{`${text}`}
{index && `(${index})`}
</span>
</a>
</div>
</div>
</DropdownToggle>
<DropdownMenu className={`mt-0 dropdown-menu-custom border-top border-${color}`}>
<DropdownItem
key="fixed"
tag="div"
className={`dropdown-item-custom text-${color}`}
onClick={stopBubbling}
>
<div className="text-nowrap">
<div className="d-flex flex-row justify-content-start">
<a className="d-flex no-pointer">
<span className="dropdown-file-type">
<span className="dropdown-file-type-no-height">
<HeaderIcon size={20} className="" />
</span>
</span>
<span className="text-custom">{text}</span>
</a>
<div className="d-flex cursor-pointer">
<UncontrolledDropdown>
<DropdownToggle tag="a">
<span className="dropdown-file-type">
<span className="dropdown-file-type-no-height">
<MoreIcon size={20} />
</span>
</span>
</DropdownToggle>
<DropdownMenu className="dropdown-menu-inside-custom">
<DropdownItem tag="div" onClick={generalActions().newItem}>
<div className="text-nowrap">
<div className="d-flex flex-row justify-content-start">
<a className="d-flex">
<div className="action-text-custom">جدید</div>
</a>
</div>
</div>
</DropdownItem>
<DropdownItem tag="div" onClick={generalActions().downloadAll}>
<div className="text-nowrap">
<div className="d-flex flex-row justify-content-start">
<a className="d-flex">
<div className="action-text-custom">دانلود همه</div>
</a>
</div>
</div>
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</div>
</div>
</div>
</DropdownItem>
<div className="dropdown-scrollbar">
{Array.isArray(items) &&
items.map((item, idx) => (
<Items key={idx} {...item} actions={itemActions} />
))}
</div>
</DropdownMenu>
</UncontrolledDropdown>
)
}
export default GeneralTab
I am getting list of object in categoryData
{this.props.categoryData.map((data) => (
<div class=" p-0" style={{ width: "12%" }}>
<div class="th-cat-link">
<img
alt=" "
src={data.photo_desktop}
width="50"
class="fluid-image"
/>
<p class="th-cat-name">{data.package_category_name}</p>
</div>
</div>
))}
How to add Show more on 8th position if the length of list exceeds 8. the remaining will show up in next row upon clicking show more
use slice to take only 8 and the check if the length is more than 8 display the button
{
this.props.categoryData.slice(0,8).map((data) => (
<div class=" p-0" style={{ width: "12%" }}>
<div class="th-cat-link">
<img
alt=" "
src={data.photo_desktop}
width="50"
class="fluid-image"
/>
<p class="th-cat-name">{data.package_category_name}</p>
</div>
</div>
))
}
{
this.props.categoryData.length > 8 && <button>Show More</button>
}
Try this one
import React, { Fragment, Component } from "react";
class App extends Component {
render() {
return (
<Fragment>
{this.props.categoryData.map((data) => (
<div class=" p-0" style={{ width: "12%" }}>
<div class="th-cat-link">
<img
alt=" "
src={data.photo_desktop}
width="50"
class="fluid-image"
/>
<p class="th-cat-name">{data.package_category_name}</p>
</div>
</div>
))}
{this.props.categoryData.length > 8 && <button>Show More</button>}
</Fragment>
);
}
}
export default App
This Works for me
state = {
isMore: false,
};
handleMoreTheme = () => {
let moreClicked = this.state.isMore;
this.props.handleMore(!moreClicked);
};
render() {
var allActivity = (
<React.Fragment>
{this.props.categoryData.map((data) => (
<div class=" p-0" style={{ width: "11.11%" }}>
<div class="th-cat-link">
<img
alt=" "
src={data.photo_desktop}
width="50"
class="fluid-image"
/>
<p class="th-cat-name">{data.package_category_name}</p>
</div>
</div>
))}
</React.Fragment>
);
var lessActivity = (
<React.Fragment>
{this.props.categoryData.slice(0, 8).map((data) => (
<div class=" p-0" style={{ width: "11.11%" }}>
<div class="th-cat-link">
<img
alt=" "
src={data.photo_desktop}
width="50"
class="fluid-image"
/>
<p class="th-cat-name">{data.package_category_name}</p>
</div>
</div>
))}
</React.Fragment>
);
return (
<div
class="row">
{this.state.isMore ? allActivity : lessActivity}
<div
class=" p-0"
style={{ width: "11.11%" }}
onClick={() => this.handleMoreTheme()}
>
<div class="th-cat-link ">
<img alt=" " src={E1} class="fluid-image" />
<p class="th-cat-name">
{this.state.isMore ? "Less Theme" : "More Theme"}
</p>
</div>
</div>
</div>
);
}
Hi i have a form component where my form data is, I'm trying to pass it into another component called "airtime-data-mtn.js" to make up part of a whole page. i.e the form is just a part of the whole page, the airtime-data component already has information rendered, page information. Note: I had done something similar where i passed a form into another component but there in the render method I was not rendering other information about the page just the form alone
since it is a form i simply tried passing it like <mtnform onSubmit={this.handleSubmit}/> but I noticed instead of it to be blue to show it is a form it's doesn't change color. I believe it is seeing it as JSX and not a form. When I add a route and use the form as the component it renders the form as expected but when i try to pass it into the airtime component, it does not work as expected
render() {
return (
<form
name="airtime-form"
className="airtime-form"
onSubmit={this.handleSubmit}
>
<div style={{ margin: "20px 0" }}>
<select
ref="constantVal"
className="select"
onChange={this.handleDropDownChange}
>
{this.state.obj.map(item => {
return (
<option key={item.Id} value={item.Name}>
{item.Name}
</option>
);
})}
</select>
</div>
<div style={{ margin: "20px 0" }}>
<input
type="number"
value={this.state.Price}
onChange={this.handlePriceChange}
placeholder="Amount"
/>
</div>
<div style={{ margin: "20px 0" }}>
<input
type="text"
value={this.state.ParameterRegEx}
onChange={this.handleNumberChange}
placeholder="Phone Number"
/>
</div>
<div style={{ margin: "20px 0" }}>
<input
type="text"
value={this.state.Email}
onChange={this.handleEmailChange}
/>
</div>
<div style={{ margin: "20px 0", fontSize: "20px" }}>
*Email is required for notification purposes
</div>
<div>
<button type="submit" className="btn btn-submit">
Submit
</button>
</div>
</form>
);
}
render() {
const { isLoaded } = this.state;
if (!isLoaded) {
return (
<div className="center">
<img src={Spinner} alt="loading spinner" />
</div>
);
} else {
return (
<body
style={{
backgroundImage: "url(" + background + ")",
backgroundSize: "cover",
backgroundRepeat: "no-repeat"
}}
>
<section>
<div className="row">
<div
className="col span-2-of-3"
style={{ backgroundColor: "#3C444C" }}
>
<div className="row">
<h2>
<img
src={mtn}
alt="mtn logo"
style={{ display: "inline-block" }}
/>
Airtime & Data
</h2>
</div>
<div className="row">
<mtnform></mtnform>
</div>
</div>
<div className="col span-1-of-3">
<div className="rhs-content">
<div className="row">
<h2 className="text-transform">use payarena today</h2>
</div>
<div className="row">
<h3 className="select-headings">Airtime & Data</h3>
<form onSubmit={this.onUrlSelected.bind(this)}>
<select ref="items" className="select">
{this.state.airtime.map(item => {
return (
<option key={item.id} value={item.Url}>
{item.Name}
</option>
);
})}
</select>
<button type="submit" className="btn btn-submit">
Go
</button>
</form>
</div>
<div className="row">
<h3 className="select-headings">Bills Payment</h3>
<form onSubmit={this.onSecondUrlSelected.bind(this)}>
<select ref="items1" className="select">
{this.state.bills.map(item => {
return <option value={item.Url}>{item.Name}</option>;
})}
</select>
<button type="submit" className="btn btn-submit">
Go
</button>
</form>
</div>
<div className="row">
<h3 className="select-headings">Collections & Levies</h3>
<form onSubmit={this.onThirdUrlSelected}>
<select ref="items2" className="select">
{this.state.collectionsAndLevies.map(item => {
return <option value={item.Url}>{item.Name}</option>;
})}
</select>
<button type="submit" className="btn btn-submit">
Go
</button>
</form>
</div>
<div className="row">
<h3 className="select-headings">The Lotteries</h3>
<form onSubmit={this.onFourthUrlSelected}>
<select ref="items3" className="select">
{this.state.lottery.map(item => {
return <option value={item.Url}>{item.Name}</option>;
})}
</select>
<button type="submit" className="btn btn-submit">
Go
</button>
</form>
</div>
<div className="row">
<p>Pay using any of the following</p>
<img src={logomask} alt="logo mask" className="logo-mask" />
</div>
</div>
{/*eslint-disable-next-line react/jsx-no-duplicate-props*/}
<section className="row" className="next-rhs">
<p>Download the Payarena app</p>
<ul className="main-nav">
<li>
<img src={googlestore} alt="google play store" />
</li>
<li>
<img src={appstore} alt="app store" />
</li>
</ul>
</section>
</div>
</div>
</section>
<footer className="footer">
<div className="row">
<div className="col span-1-of-3">
<img
src={palogo}
alt="pa-logo"
style={{
display: "block",
marginLeft: "30px;"
}}
/>
<p>An innovation from Unified Payments Limited</p>
</div>
<div className="col span-2-of-3">
<div className="row">
<div className="col span-1-of-3">
<h2>Page Links</h2>
<p>
{" "}
<a
href="/about"
style={{ textDecoration: "none", color: "white" }}
>
About Us
</a>
</p>
<p>
{" "}
<a
href="/services"
style={{ textDecoration: "none", color: "white" }}
>
Our Services
</a>
</p>
<p>
{" "}
<a
href="/about"
style={{ textDecoration: "none", color: "white" }}
>
The Team
</a>
</p>
</div>
<div className="col span-1-of-3">
<h2>Support Links</h2>
<p>
<a
href="/contact"
style={{ textDecoration: "none", color: "white" }}
>
Contact Us
</a>
</p>
<p>
<a
href="/faqs"
style={{ textDecoration: "none", color: "white" }}
>
FAQs
</a>
</p>
</div>
<div className="col span-1-of-3">
<h2>Social Links</h2>
<p>
{" "}
<a
href="https:/www.twitter.com"
style={{ textDecoration: "none", color: "white" }}
>
<i
className="icon ion-logo-twitter"
style={{ color: "white", margin: "0 10px" }}
/>
Twitter
</a>
</p>
<p>
{" "}
<a
href="https://www.facebook.com"
style={{ textDecoration: "none", color: "white" }}
>
<i
className="icon ion-logo-facebook"
style={{ color: "white", margin: "0 10px" }}
/>
Facebook
</a>
</p>
<p>
{" "}
<a
href="https://www.linkedin.com"
style={{ textDecoration: "none", color: "white" }}
>
<i
className="icon ion-logo-linkedin"
style={{ color: "white", margin: "0 10px" }}
/>
Linkedin
</a>
</p>
</div>
</div>
</div>
</div>
</footer>
<footer
className="footer"
style={{ backgroundColor: "white", color: "black" }}
>
<div className="row">
<p style={{ float: "left" }}>
Copyright © Unified Payments 2019.
</p>
</div>
</footer>
</body>
);
}
}
Please any help would be fantastic. I'm stuck and trumped