I'm trying to filter api results based on what the user enters in a search bar or when the specific category buttons are clicked. The problem is that whenever I combine maps to allow for this functionality I get strange results. Am I writing the syntax the correct way? I am new to React.
<div id="buy-grid" className="product-grid">
<div className="content">
<h3>Search for Products</h3>
<form>
<input type="text" onChange={handleChange} />
<h3>Top Results</h3>
</form>
<div className="grid">
{response.map((element, index) =>{
if(element.name.includes(inputVal)){
return(
<div className="product-card one" key={index}>
<p>{element.name}</p>
<img src= {element.image}></img>
</div>)
}
else if(element.category.includes(buttonVal)){
return(
<div className="product-card two" key={index}>
<p>{element.name}</p>
<img src= {element.image}></img>
</div>)
}
})}
</div>
</div>
</div>
I've got this component that is throwing me error that I don't recognize:
import React from 'react';
const Search = () => {
return (
<section className='section'>
<div className='container'>
<div className='row'>
<div className='columns'>
<div className='column is-full'>
<h3 id='branding' className='title is-size-3'>search</h3>
<form>
<div className='field'>
<div className='control has-icons-right'>
<input type='text' name='search' className='input is-medium' autofocus='autofocus' required />
<span className='icon is-medium is-right'>
<i className="fas fa-search fa-2x" />
</span>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
)
}
export default Search;
As soon as I add file uploading input below the text input like this:
<div className='field'>
<div className='control has-icons-right'>
<input type='text' name='search' className='input is-medium' autofocus='autofocus' required />
<span className='icon is-medium is-right'>
<i className="fas fa-search fa-2x" />
</span>
</div>
<div className='field'>
<input type='file' name='file' value='Photo' />
</div>
</div>
I get error output from Firefox Dev Edition: InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable. The Opera browser throws similar error.
Can I get any feedback as to why React throws this error when including input tag for uploading files ?
screenshot:
Remove value from an input
<input type='file' name='file' />
here is full example working with files
https://www.geeksforgeeks.org/file-uploading-in-react-js/
i have a component within which i want to display the card that accepts the list and another card next to it that displays ImageComponent if state.complete. if not displays the status text.
As you see from code below,
render() {
return (
<OuterComponent>
<div className="wrapper">
<div className="card">
<form onSubmit={this.on_submit}>
<div className="top_content">
<div className="title">title</div>
</div>
<div className="content">
<label>
<div>
<SvgOne />
Plus button
</div>
<input
type="file"
onChange={this.handle_files}
multiple />
</label>
<ul className="files_list">
{this.state.files.map((f, index) => (
<li key={f.name}>
</li>
))}
</ul>
</div>
<div className="bottom_content">
<button type="submit">
Submit
</button>
</div>
</form>
</div>
{(this.state.loading || this.props.list_id) &&
<div>
{this.state.complete
? <Fragment>
<div className="content">
<ChildComponentOne/>
</div>
<div className="bottom_content">
<div className="title">title</div>
</div>
</Fragment>
: <Fragment>
<div className="content">
{this.state.failed &&
<div>
<SvgRetry/>
</div>}
<div className="cancel_button">
<SvgClose/>
</div>
<div className={status_classes.join(' ')}>
{this.get_text}...
</div>
</div>
<div className="bottom_content">
{list && list.listname
? <div className="title">title</div>
: <div/>}
</div>
</Fragment>
}
</div>
</div>
</OuterComponent>
);
}
I have used the div with classname "content" repeatedly. It contains ImageComponent if the state.complete if not displays some other content with in. I have duplicated the code. But i wanted it to be a seperate component such that it could be used elsewhere.
What could be the best approach in this case. Could someone provide some insight into this. thanks.
I'm using bootstrap with react, and the compiler is failing on grounds that there is unterminated JSX contents. I've been through it a dozen times, and whichever way the ternary results, I don't see any unclosed tags. I'm new to react, so I suppose something else must be wrong. To cut down on code, I've only included the return():
<div className="container-fluid">
<div className="row">
<div className="col-12">
<SearchBar />
</div>
</div>
{this.state.results ? (
<div className="row">
<div className="col-12">
<div className="row">
<div className="col-6 offset-md-3">
<div className="row">
<div className="col">
<InputRange
maxValue={this.state.maxPrice}
minValue={this.state.minPrice}
value={this.state.priceRange}
formatLabel={x => {
return `£${x}`;
}}
onChange={value => this.setState({ priceRange: value })}
/>
</div>
</div>
<div className="row">
<div className="col">
Selection: {visibleResults.length}
</div>
</div>
<div>
</div>
<div className="row">
<div className="col-6 offset-md-3">
{visibleResults.map((item, index) => (
<Link to={`/listing/${item.id}`}>
<SearchResult result={item} key={index} />
</Link>
))}
</div>
</div>
</div>
</div>
) : (
<div className="row">
<div className="col">
<h1>LOADING...</h1>
</div>
</div>
)}
</div>
)
You need to close the div here:
<div className="row">
<div className="col">
Selection: {visibleResults.length}
</div>
</div>
<div> // This should be </div>
</div>
I have a reactJS application which renders from a map function. This is what some of the output looks like:
I am generating data for 3 beneficiaries and I am giving the user the option of deleting each beneficiary. The data is pulled from a database. Once the user has deleted whichever beneficiaries he/she wants to delete, the data will be written back to the database.
When a user clicks on the Delete this Beneficiary buttion, an onclick function is called. That function will set a flag (beneDeleteFlag) associated with that particular beneficiary. That data is written to the state with a setstate() so reactJS will re-render. When the render occurs, I set the classname of each section to either hide_div or show_div (which are classes in my .css file which set visibility to hidden or visible. This is the code that executes to render each beneficiary:
return idArray.map( item => (
<div>
<div className={item.visibility}>
<div className="beneficiary_background">
<div className="row">
<div className="col-3 text-left text_14">
<label>Name:</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisName} value={item.beneName} maxLength="33"/>
</div>
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label>SSN:</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisMid} value={item.beneMid} maxLength="9"/>
</div>
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label>Address 1:</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisAddr1} value={item.beneAddr1} maxLength="20"/>
</div>
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label>Address 2:</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisAddr2} value={item.beneAddr2} maxLength="20"/>
</div>
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label>Address 3:</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisAddr3} value={item.beneAddr3} maxLength="20"/>
</div>
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label>City</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisCity} value={item.beneCity} maxLength="20"/>
</div>
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label>State</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisState} value={item.beneState} maxLength="2"/>
</div>
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label>Zip Code</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisZip} value={item.beneZip} maxLength="5"/>
</div>
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label id="lblName">Spouse</label>
</div>
{this.renderSpouse(item.thisSpouse, item.beneSpouse)}
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label id="lblName">Primary</label>
</div>
{this.renderPrimary(item.thisPorS, item.benePorS)}
</div>
<div className="row">
<div className="col-3 text-left text_14">
<label id="lblName">Percent</label>
</div>
<div className="col-9 text-left text_14">
<input type="text" id={item.thisPct} value={item.benePct} maxLength="3"/>
</div>
</div>
<div className="spacer">
</div>
<div className="row">
{this.renderDeleteButton(item.thisDelete)}
</div>
<div className="spacer">
</div>
</div>
</div>
<div className="spacer">
</div>
</div>
))
At the top of the render, there is a line of code that reads
<div className={item.visibility}>
{item.visibility} will contain hide_div for any beneficiary that the user elects to delete.
My issue is that when the delete the beneficiary button is clicked (I clicked on the button for the second beneficiary), and the {item.visibility} gets populated with hide_div, this is what gets rendered:
As you can see, the render occurs, but it just hides the . I though with bootstrap, the next would float up and not leave any whitespace between the two 's that are visible.
Any suggestions?
Try using reduce over map so you can selectively render your items instead of hiding the ones you don't want to see.
Something along the lines of:
return idArray.reduce( (all, item, idx) => {
if (item.visibility !== 'hide_div') {
all.push(
<div key={idx}>
<div className="beneficiary_background">
...
</div>
</div>
)
}
return all
}, [])
You won't need to set className for hidden items anymore
if you're using visibility: hidden, it will indeed leave the space there. Visibility Hidden leaves the space that should be occupied by the content hidden if it was visible. If you want no space left at all, use display: none instead. It will act the same way but without space left for the element.
you can filter the data which have been marked as deleted using filter function in javascript:
const array = [{beneDeleteFlag: true, data: 'data 1'}, {beneDeleteFlag: false, data: 'data 2'}, {beneDeleteFlag: false, data: 'data 3'}, {beneDeleteFlag: true, data: 'data 4'}]
const newArray = array.filter((item) => item.beneDeleteFlag !== true)
console.log(newArray)
and the reason why you still got the empty space in your UI, it's because you're using visibility: 'hidden' in your CSS, you should use display: 'none' instead.