OnClick passing undefined - reactjs

I am trying to pass an onClick value, but it passes undefined. Works well if it is not a Card/Paper/Div but I need this "button" to be a Card/paper/div
onClick={() => this.handleChange('bostadstyp')}
onClick={ value='villa', handleChange('bostadstyp')}
render() {
const { bostadstyp } = this.props;
const { auth } = this.props;
const { value, values, handleChange, handleClick } = this.props;
const { backgroundColori } = this.props;
const backgroundColor2 = "#F09515";
const aa = "";
// const imageUrl = window.innerWidth >= "1600px" ? Banner1 : Banner2;
// {if (!auth.uid) return <Redirect to="/loggain" />;}
return (
<div>
<img
className="stars3"
src={Logo}
width="15%"
align="center"
marginBottom="10px"
/>
<img src={Logo} width="15%" align="center" marginBottom="10px" />
<div style={{ backgroundColor: "#F1F1F1", padding: "30px" }}>
<h2
style={{
marginTop: "0px",
marginLeft: "10%",
color: "#F09515",
fontFamily: "Avenir",
fontWeight: "bold"
}}
>
{" "}
Dina Preferenser{" "}
</h2>
</div>
<form
className="background123"
style={{
backgroundColor: "#fdfdfd",
marginTop: "0px",
marginBottom: "0px"
}}
>
<Card
className="row xl12 l12 m12 s12"
style={{
marginLeft: "10%",
marginRight: "10%",
padding: "30px",
backgroundColor: "#fdfdfd"
}}
>
<br />
<div className="col xl6 l6 m12 s12">
<h4
style={{
fontFamily: "Avenir",
fontWeight: "bold",
color: "#F09515"
}}
>
1. Välj din boendestyp
</h4>
<p className="texti" style={{ fontSize: "16px" }}>
Vi behöver den här uppgift då vissa avtal endast gäller för
vissa anläggningstyper.
</p>
</div>
<div className="col xl6 l6 m12 s12">
<Card
className="row cardi xl12 l12 m12 s12"
style={{ width: "270%", backgroundColor: `white` }}
value={"villa"}
onClick={handleChange("bostadstyp")}
>
<div className=" col xl7 l7 m6 s6">
<img src={villa} width="50px" />
</div>
<div className="col xl5 l5 m5 s5">
<h6
className="texti"
style={{ fontSize: 16, textAlign: "right" }}
>
Villa/radhus
</h6>
</div>
</Card>
</div>
</Card>
</form>
</div>
);
}
I expect to 'values.bostadstyp' get the value 'villa'

because you are using function in the class so you must using this.handleChange instead of handleChange
<Card onClick={() => this.handleChange('bostadstyp' )}>
....
</Card>

You need to attach the onClick() listener to a <CardActionsArea/> component which should be nested inside your <Card/> component
Something like
<Card className="row cardi xl12 l12 m12 s12" style={{ width: '270%', backgroundColor: `white` }} value={'villa'} onClick={handleChange('bostadstyp' )} >
<div className=" col xl7 l7 m6 s6">
<img src={villa} width="50px" />
</div>
<div className="col xl5 l5 m5 s5">
<h6 className="texti" style={{ fontSize: 16, textAlign: "right" }}>Villa/radhus</h6>
</div>
</Card>
Also, I suggest looking into the <CardActions/> documentation, the example here shows how its used

Can you try below code in your card element:
<Card className="row cardi xl12 l12 m12 s12"
style={{ width: '270%', backgroundColor: `white` }} value={'villa'}
onClick={(e) => {
e.preventDefault();
this.handleChange('bostadstyp');
}}>
The issue may be due to one of the below reasons:
1. handleChange() not bound with this.
2. To pass values from onClick handler you should use (e) => func('value')
3. The click is happening inside form element, its better to include event.preventDefault()

You need user arrow function:
onClick={() => { this.handleChange('bostadstyp' ) }}
<Card className="row cardi xl12 l12 m12 s12" style={{ width: '270%', backgroundColor: `white` }} value={'villa'} onClick={() => { this.handleChange('bostadstyp' ) }} >
<div className=" col xl7 l7 m6 s6">
<img src={villa} width="50px" />
</div>
<div className="col xl5 l5 m5 s5">
<h6 className="texti" style={{ fontSize: 16, textAlign: "right" }}>Villa/radhus</h6>
</div>
</Card>
UPDATE
Handle Change from parent component:

Make sure your handleChange is bound properly by explicitly binding it or using an arrow function syntax:
this.handleChange = this.handleChange.bind(this) // In component's constructor
// or
handleChange = (value, input) => {
this.setState({
[input]: value
});
};
onClick expects a function to invoke, so you need to wrap your handler into one:
<Card onClick={() => handleChange('villa', 'bostadstyp')}></Card>

Related

How to keep the checkbox state saved after page refresh?

I am making a product comparison page. I am trying to keep the checkbox checked after page refresh. Actually I have a products page where each product has a checkbox beneath it. When I click the checkbox, that specific product is added to local Storage + comparison page which I have made. But when I refresh the page, that product is saved but checkbox is unchecked but I want to keep checkbox checked and if checkbox is unchecked, that specific item should be removed from comparison page. How do I solve this query. I have tried several times but not able to do this?? Below is my code
function Home()
{
let history = useHistory()
const getLocalItems = () => {
let compare = localStorage.getItem('compare')
console.log(compare)
if(compare){
return JSON.parse(localStorage.getItem('compare'))
}
else{
return []
}
}
const [comparison,showcomparison] = useState(getLocalItems())
const [item,setItems] = useState()
const [show,setShow] = useState(false)
function onAdd(record){
const exist = comparison.find((x) => x.id === record.id)
if(exist){
showcomparison(comparison.map((x) => x.id === record.id ? {...exist, quantity: exist.quantity+1} : x)
);
}
else
{
showcomparison([...comparison,{...record,quantity: 1}])
}
}
useEffect(() => {
localStorage.setItem('compare',JSON.stringify(comparison))
}, [comparison])
const removeAll = () => {
showcomparison([])
}
return(
<div className="Home">
{
records.map(record => {
return(
<div className='container' key={record.id} onAdd = {onAdd}>
<div className='row'>
<div className='col-xl-3'>
<img style={{width: '100%', height: 'auto'}} src={record.img1} alt=""/><br></br>
<input type='checkbox' value={record.img1} onChange={() => onAdd(record)} style={{paddingRight: '30%'}}/>Compare
</div>
<div className='col-xl-4'>
<p style={{textAlign: 'left', fontWeight: 'bold', fontSize: '18px'}}>{record.title}</p>
<p style={{textAlign: 'left', fontWeight: 'bold', fontSize: '18px'}}>{record.title2}</p>
<p style={{textAlign: 'left', fontWeight: 'bold', fontSize: '18px'}}>{record.title3}</p>
<p style={{textAlign: 'left', fontSize: '15px'}}>MFG#: {record.MFG} | CDW#: {record.CDW}</p>
<p style={{fontWeight: '650', textAlign: 'left'}}>Laptop Type: {record.Type}</p>
<p style={{fontWeight: '650',textAlign: 'left'}}>Screen size: {record.size}</p>
<p style={{fontWeight: '650',textAlign: 'left'}}>Processor Type: {record.ptype}</p>
<p style={{fontWeight: '650',textAlign: 'left'}}>Processor Speed: {record.pspeed}</p>
<p style={{fontWeight: '650',textAlign: 'left'}}>Hard Drive Capacity: {record.capacity}</p>
</div>
<div className='col-xl-3'>
<ul>
<li style={{color: 'green', marginBottom: '1px', textAlign: 'left', fontSize: '13.5px', fontWeight: '640'}}><p>{record.Availability}</p></li>
</ul>
<p style={{fontSize: '13px', textAlign: 'left'}}>Ships today if ordered within 6 hrs 21 mins</p>
<h4 style={{textAlign: 'left', fontFamily: '"Source Serif Pro",serif', fontWeight: 'bold'}}>{record.price}</h4>
<p style={{textAlign: 'left'}}>Advertised Price</p>
<div className='input-group'>
<button type='button' onClick={handleDecrement} className='input-group-text'>-</button>
<div className="form-control text-center"> {quantity} </div>
<button type='button' onClick={handleIncrement} className='input-group-text'>+</button>
</div><br></br>
<button style={{width: '100%', background: '#150404', color: 'white', fontSize: '17.5px', fontWeight: '600', height: '18%'}}>Add to Cart</button>
</div>
</div><hr></hr>
</div>
)
})
}
You can use useRef on the input checkbox, use the following property to set it checked or unchecked.
checkRef.current.checked=false
<input type='checkbox' ref={checkRef} value={record.img1} onChange={() =>
onAdd(record)} style={{paddingRight: '30%'}}/>Compare
use the checkRef.current to change the value with useState.

How to close only one Div at a time in React?

Code:-
const [Close, setClose] = useState(true)
<div className="allDivs">
{item.map((item, index) => {
// console.log("myDivs", myDivs);
return (
<Fragment key={index} >
<div className="tableHeaderBody" id="CLOSEDIV" style={{display: Close ? 'initial' : 'none'}}>
<div className="TableText">
<div className="TableTextHide"></div> <div style={{ color: "white" }} id="SHOW">{item.val}</div></div>
<div className="CloseIcon" id="CloseBtn"><FaCircle style={{ color: "#FC0000", width: "10px", height: "10px", alignItems: "right" }} onClick={() => setClose(false)} /></div>
</div>
</Fragment>
)
})
}
</div>
I want that when i click the Red circle at any div (show in image) it close the div, but right now when i click the One div red circle its closes all the div
please help.
Try this:
Create a new component ChildComponent:
export default function ChildComponent({item}) {
const [Close, setClose] = useState(true) // Every Child now has it's own setClose controll
return (
<Fragment>
<div className="tableHeaderBody" id="CLOSEDIV" style={{display: Close ? 'initial' : 'none'}}>
<div className="TableText">
<div className="TableTextHide"></div>
<div style={{ color: "white" }} id="SHOW">{item.val}</div>
</div>
<div className="CloseIcon" id="CloseBtn">
<FaCircle style={{ color: "#FC0000", width: "10px", height: "10px", alignItems: "right" }} onClick={() => setClose(false)} />
</div>
</div>
</Fragment>
)
}
Pass the ChildComponent to your component shown above:
<div className="allDivs">
{item.map((item, index) => (
<div key={index}>
<ChildComponent item={item} />
</div>
))}
</div>

How to use ternary operator inside map

I am trying to use a ternary operator inside a map, but not to sure why this is wrong? Getting a parsing error at the end of the ternary
code:
return(
<div className='Card'>
<div className='TableTopbar ScheduleGrid'>
<div>id</div>
<div>interval</div>
<div>project_id</div>
<div>database</div>
<div>create_timestamp</div>
<div>create_user_id</div>
<div>Edit</div>
</div>
{scheduleData.map((schedule)=>
{UsageMode === 'Read' ?
<div className='Table ScheduleGrid'>
<div>{schedule.id}</div>
<div>{schedule.interval}</div>
<div>{schedule.project_id}</div>
<div>{schedule.database}</div>
<div>{schedule.create_timestamp}</div>
<div>{schedule.create_user_id}</div>
<div>
<EditIcon
style={{padding: '2px', width: '0.8em', height: '0.8em', marginRight: '5px'}}
className='CircleButton'
onClick={onEditScheduleClick}
/>
</div>
</div>
:
<div>ID</div>
}
)
)
export default scheduleRowTwo
Updated code:
return(
<div className='Card'>
<div className='TableTopbar ScheduleGrid'>
<div>id</div>
<div>interval</div>
<div>project_id</div>
<div>database</div>
<div>create_timestamp</div>
<div>create_user_id</div>
<div>Edit</div>
</div>
{scheduleData.map((schedule)=>
(
{UsageMode === 'Read' ?
<div className='Table ScheduleGrid'>
<div>{schedule.id}</div>
<div>{schedule.interval}</div>
<div>{schedule.project_id}</div>
<div>{schedule.database}</div>
<div>{schedule.create_timestamp}</div>
<div>{schedule.create_user_id}</div>
<div>
<EditIcon
style={{padding: '2px', width: '0.8em', height: '0.8em', marginRight: '5px'}}
className='CircleButton'
onClick={onEditScheduleClick}
/>
</div>
</div>
:
<div>ID</div>
}
)
)
export default scheduleRowTwo
Updated error:
Apparently, your outermost div does not have a closing tag, thus resulting in an error.
Also, you're missing a return statement.
return (
<div className="Card">
<div className="TableTopbar ScheduleGrid">
<div>id</div>
<div>interval</div>
<div>project_id</div>
<div>database</div>
<div>create_timestamp</div>
<div>create_user_id</div>
<div>Edit</div>
</div>
{scheduleData.map((schedule) => {
return UsageMode === "Read" ? (
<div className="Table ScheduleGrid">
<div>{schedule.id}</div>
<div>{schedule.interval}</div>
<div>{schedule.project_id}</div>
<div>{schedule.database}</div>
<div>{schedule.create_timestamp}</div>
<div>{schedule.create_user_id}</div>
<div>
<EditIcon
style={{
padding: "2px",
width: "0.8em",
height: "0.8em",
marginRight: "5px",
}}
className="CircleButton"
onClick={onEditScheduleClick}
/>
</div>
</div>
) : (
<div>ID</div>
);
})}
</div>
);
Try this code. Should work.
You should enclose this code block with parentheses because you're trying to implicitly return an object (without the return keyword):
{UsageMode === 'Read' ?
<div className='Table ScheduleGrid'>
<div>{schedule.id}</div>
<div>{schedule.interval}</div>
<div>{schedule.project_id}</div>
<div>{schedule.database}</div>
<div>{schedule.create_timestamp}</div>
<div>{schedule.create_user_id}</div>
<div>
<EditIcon
style={{padding: '2px', width: '0.8em', height: '0.8em', marginRight: '5px'}}
className='CircleButton'
onClick={onEditScheduleClick}
/>
</div>
</div>
:
<div>ID</div>
}

How to access variables outside of map function?

Have looped over some data in my applicaition but I was wondering if I could access variables outside the map function?
I am trying to read a count of my data, however the object.unit_test_count(which is shown in asteriks) is coming back as object is not defined? How do I access that unit_test_count from the objectsToShow.map function? (also shown in asteriks)
<div className={getGridClassName()} style={{backgroundColor: 'var(--main-color)', color: '#fff', fontWeight: '500'}}>
<div />
**<div>Object{object.unit_test_count}</div>**
<div />
{props.location.pathname === '/requesttest' ?
<React.Fragment>
<div style={{textAlign: 'center'}}># Unit Tests</div>
<div style={{textAlign: 'center'}}>Select</div>
</React.Fragment>
:
<React.Fragment>
<div style={{textAlign: 'center'}}>Passes</div>
<div style={{textAlign: 'center'}}>Fails</div>
<div style={{textAlign: 'center'}}>
<Tooltip title={'hello'}>Errors<InfoIcon/>
</Tooltip>
</div>
<div style={{textAlign: 'center'}}>N/A<InfoIcon /></div>
<div style={{textAlign: 'center'}}># Units Tests</div>
</React.Fragment>
}
</div>
{!objectsToShow ? null : **objectsToShow.map(object =>**
<div key={object.object} className={getGridClassName(object)}>
<div style={{display: 'flex', justifyContent: 'flex-end'}}>
<Tooltip title={object.relation.charAt(0).toUpperCase() + object.relation.substr(1).toLowerCase()}>
<div className='RelationInitialBox' style={{backgroundColor: getRelationColor(object.relation)}}>
{object.relation.charAt(0).toUpperCase()}
</div>
</Tooltip>
</div>
<div
className='ClickableText'
style={{wordBreak: 'break-all'}}
onClick={() => onObjectClick(object.object)}
>
{object.object}
</div>
<div>{object.is_critical ? 'Critical' : ''}</div>
{props.location.pathname === '/requesttest' ?
<React.Fragment>
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
<div style={{textAlign: 'center'}}>
<Checkbox mainColor changeHandler={props.handleObjectsCheckbox} data={object} />
</div>
</React.Fragment>
:
<React.Fragment>
<div style={{color: 'green', textAlign: 'center'}}>{object.unit_test_passes}</div>
<div style={{color: 'red', textAlign: 'center'}}>{object.unit_test_fails}</div>
<div style={{color: 'red', textAlign: 'center'}}>{object.unit_test_errors}</div>
<div style={{textAlign: 'center'}}>{object.unit_test_not_applicable}</div>
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
</React.Fragment>
}
</div>
)}
Update syntax error:
Syntax error image
objectsToShow.map(item =>
<div className='Card' style={{overflow: 'visible'}}>
<div className={getGridClassName()} style={{backgroundColor: 'var(--main-color)', color: '#fff', fontWeight: '500'}}>
<div />
<div>Object{item.unit_test_count}</div>
<div />
{props.location.pathname === '/requesttest' ?
<React.Fragment>
<div style={{textAlign: 'center'}}># Unit Tests</div>
<div style={{textAlign: 'center'}}>Select</div>
</React.Fragment>
:
<React.Fragment>
<div style={{textAlign: 'center'}}>Passes</div>
<div style={{textAlign: 'center'}}>Fails</div>
<div style={{textAlign: 'center'}}>
<Tooltip title={'hello'}>Errors<InfoIcon/>
</Tooltip>
</div>
<div style={{textAlign: 'center'}}>N/A<InfoIcon /></div>
<div style={{textAlign: 'center'}}># Units Tests</div>
</React.Fragment>
}
</div>
)
{!objectsToShow ? null : objectsToShow.map(object =>
<div key={object.object} className={getGridClassName(object)}>
<div style={{display: 'flex', justifyContent: 'flex-end'}}>
<Tooltip title={object.relation.charAt(0).toUpperCase() + object.relation.substr(1).toLowerCase()}>
<div className='RelationInitialBox' style={{backgroundColor: getRelationColor(object.relation)}}>
{object.relation.charAt(0).toUpperCase()}
</div>
</Tooltip>
</div>
<div
className='ClickableText'
style={{wordBreak: 'break-all'}}
onClick={() => onObjectClick(object.object)}
>
{object.object}
</div>
<div>{object.is_critical ? 'Critical' : ''}</div>
{props.location.pathname === '/requesttest' ?
<React.Fragment>
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
<div style={{textAlign: 'center'}}>
<Checkbox mainColor changeHandler={props.handleObjectsCheckbox} data={object} />
</div>
</React.Fragment>
:
<React.Fragment>
<div style={{color: 'green', textAlign: 'center'}}>{object.unit_test_passes}</div>
<div style={{color: 'red', textAlign: 'center'}}>{object.unit_test_fails}</div>
<div style={{color: 'red', textAlign: 'center'}}>{object.unit_test_errors}</div>
<div style={{textAlign: 'center'}}>{object.unit_test_not_applicable}</div>
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
</React.Fragment>
}
</div>
)}
<PageNumbers pageNumbersList={pageNumbers} currentPage={currentPage} onClick={onPageNumberClick} />
</div>
)
})
objectsView.propTypes = {
objects: PropTypes.array,
status: PropTypes.oneOf(['', 'Failed', 'Success', 'Unresolved']),
onObjectClick: PropTypes.func,
handleObjectsCheckbox: PropTypes.func
}
export default withRouter(objectsView)
In this below line,
<div style={{textAlign: 'center'}}>{object.unit_test_count}</div>
map() will check for the property on the variable name you passed to map at
{!objectsToShow ? null : **objectsToShow.map(object =>**
So you can change that variable name to something else.
Or
You can assign object.unit_test_count to any other variable and use it inside the loop.

how to create a file tree explorer/view using react js?

I have an react js application whose landing page(index page) allows the user to create a new folder or new view.
As seen in the screenshot the folders and views are displayed in the tile view format.I would like to change the view to a tree structure similar to the file explorer seen on ide such as visual studio code or eclipse.
My render function for the landing page-
render() {
const formList = localStorage.getItem("FormList") !== null ? JSON.parse(localStorage.getItem("FormList")) : [];
const { openmodal, newfolder, foldername, folderList, formView, alertMessage, alert } = this.state;
const folderid = this.props.history.location.pathname;
let fid = folderid.replace('/folder/', '');
return (
<div className="bacgrounImage">
<AlertFunction type={alert} msg={alertMessage} />
<Container fluid>
<Row>
<Col lg="12"
className="spilt folderheader"
>
<div style={{ paddingTop: '7px', paddingLeft: '3%' }}>
<NavLink to={fid === '/' ? "/formcreate" : '/formcreate/' + fid} >
<button className='butt' onClick={() => {
localStorage.setItem('viewId', null);
}} style={{ float: 'right', width: '14%', height: '43px', marginLeft: '10px' }} onClick={e => this.layoutset(e, null, null)}>
<h6 style={{ fontWeight: '500' }}>Create New View</h6>
</button>
</NavLink>
{newfolder === null &&
<button className='butt' type='button' onClick={this.folderName} style={{ width: '15%%', float: 'right' }} >
<img src={require('./image/newFolder.svg')} />
<span style={{ fontWeight: '500' }}>Create New Folder</span></button>
}
</div>
<div>
<h4>File List</h4>
</div>
</Col>
<Col lg='12' className='newfolder folderList'>
<div style={{ display: newfolder === 2 ? 'block' : 'none', padding: '8px 8px 16px 1px' }}>
<span style={{ padding: '6px 18px', cursor: 'pointer' }} onClick={e => this.backToForm(e)}><i className="fa fa-arrow-left" aria-hidden="true" ></i></span>
</div>
{(folderList !== undefined && folderList.length > 0) &&
folderList.map((val, i) => {
return <div key={i + "create"} className='list' id={val.id} onDoubleClick={() => this.folderClick(val.id, 1)}>
<img src={require('./image/folder.svg')} style={{ width: '48px' }} />
<span>{val.name}</span>
</div>
}
)
}
{(formView !== undefined && formView.length > 0) &&
formView.map((val, i) =>
<div key={i + "create"} className='list' id={val.id} onDoubleClick={() => this.folderClick(val.id, 2)}>
<img src={require('./image/file.svg')} style={{ width: '48px' }} />
<span>{val.name}</span>
</div>)
}
{
(folderList !== undefined && folderList.length === 0 && formView !== undefined && formView.length === 0) &&
<div className='noDataFound'>No data found </div>
}
{newfolder === 1 &&
<div className='list' style={{ backgroundColor: '#d3daff' }}>
<img src={require('./image/folder.svg')} style={{ width: '48px' }} />
<input value={foldername} onChange={e => this.setState({ foldername: e.target.value })} onKeyPress={this.createnewFolder} type='text' style={{ width: '72%', marginLeft: '2px', height: '27px' }} onFocus={this.handleFocus} />
</div>
}
</Col>
<div lg="12">
<Formlisting formList={formList} openmodal={openmodal} toggle={this.toggle} />
</div>
</Row>
</Container>
</div>
);
}
How do i modify the render function to change the view from the tile view to tree structure view as seen in the screenshot.Plz help?

Resources