How to change a value inside of displayed component? - javascript

I have written a simple React code which displays a list of Film. Name, image, and "ocena" value, which should be editable. But it is in fact not editable.
I know more or less know why. Because of the value={ocena} during creation of the element in list.
<input value ={ocena} type='number' />
But I have no idea how to make it acually editable and dynamicly change the ocena value as user edits it. Is there a way ? Here is my code:
const Film = ({kk , nazwa, ocena,opis, setOcena,filmy}) => {
console.log({kk})
return(<div className="film">
<img src={kk} width={'80px'} height={'80px'} />
<li className="film_item">{nazwa}</li>
<textarea>{opis}</textarea>
<input value ={ocena} type='number'/>
<button className="delete">DELETE</button>
</div>
)
}
And the lsit itself
const Filmlist = ({filmy, setOcena , ocena}) => {
const [kk , setkk] = useState(filmy.url1);
return(
<div className="filmlist_container">
<ul className="filmlist">
{console.log(filmy)}
{filmy.map((film)=> (
<Film setOcena={setOcena} nazwa ={film.nazwa} opis = {film.opis }
ocena= {film.ocena }kk= {film.url1 } filmy={filmy}/>
))};
</ul>
</div>
)
}
Is there a simple way, or should i rewrite my code for this thing to be possible?

Related

how can i get my button to disappear? in reactjs

i am trying to make my button disappear if my textarea is empty
until now i have made some code for it but i still cant do it
in the code i am trying to make the css dynamic by having it change accoring to some ternery condition id the condition is met the css will allow the button to work and if not the other css class will turn the button off
my problem is that i want the on/off condition to work only when the textfield has more than one letter ( is not empty ) this will help me in my posting application as it will not post any empty posts instead only posts with letters and words ( non empty textarea) will post
here is the code:
function PostingNow() {
const [post, setPost] = useContext(Mycontext);
const tw = useRef('')
const[count,setCount] = useState(false)
return (
<div >
<textarea placeholder='whats up?' className="box" ref={tw}></textarea>
<button className={count?'tweetbutton':'unclickable'} >
Tweet
</button>
</div>
{post.map((post, i) => (
<Postingcomponent name ='user name'image={Photo} key={i} postContent={post}/>
))}
</div>
);
}
export default PostingNow
You can conditionally render your button in the jsx.
First make your textarea a controlled component so you have access to its state.
Then write
{textAreaText && <button ... />}
Make the textarea to be a controlled input
const [textarea, setTextarea] = useState("")
...
<textarea onChange={e => setTextarea(e.target.value)}>{textarea}</textarea>
Then for the button:
{textarea && <button ... />}
For better UX, it's recommended to disable the button instead of removing it from DOM.
<button disabled={!textarea} ... />
If you make the TEXTAREA tag something like:
<textarea placeholder='whats up?' className="box" ref={tw} class='unclickable'
onkeyup="fixPostButton(this, 'postButton', 'unclickable', 'tweetbutton');">
And make the BUTTON:
<button id="postButton" class="unclickable">Tweet</button>
Then this javascript will change the class after each keystroke:
<script>
function fixPostButton(txta, butn, isempty, notempty) {
var classX = (txta.value == '') ? isempty : notempty ;
document.getElementById(butn).className = classX; }
</script>

ReactJS // SearchBar onClick button

I created this search bar for an API. As you can see, the search bar is working with an onChange event. The user is searching the movie thanks to the title. I would like to search a movie with an onClick event with the button. For example, I'm searching Titanic, only this movie must appear.
<form action='/' methode='get' className='Search-Bar'>
<input
type='text'
id='searchbar'
className='searchbar'
placeholder='Rechercher un titre, un réalisateur...'
onChange={(e) => {
setSearchMovie(e.target.value);
}}
/>
<button className='search-button'>
<AiOutlineSearch /> OK
</button>
</form>
This is my code for the filter :
const allMovies = movies
.filter((value) => {
if (searchMovie === '') {
return value;
} else if (value.title.includes(searchMovie)) {
return value;
}
})
.map((movie, index) => {
return ( .............
It's working but I don't know how to search a movie thanks to the button... do you know how can I do this ??
Thank you !
Assuming your onClick is on the button it would be something like this, where you set the value of the movie as the value of the input field.
With your onChange set a value in the component for searchFieldValue and use it with the onClick. Ps your code is only html and JS as far as i can see, not a react related issue.
<button
className='search-button'
onClick={(e) => {
setSearchMovie(searchFieldValue);
}}
>
<AiOutlineSearch /> OK
</button>

React component not sending variable value with onChange event

I am trying to display more than one task using the same react component and a map function. The components is supposed to upload a file and display the file that has been upload or is uploading with an onChange event, an onSubmit event will be added later to send the file to the back-end. Since the component is being dynamically rendered with an onChange event I am sending the li key as a parameter then only rendering the filename to the li that matches based on the key. The issue I am currently having is when I send the key in the onChange the value is not getting to the function. I have even tried setting a state for the key and then pulling that into the function but I get back undefined I have tried 100 other things as well and either get back undefined or 0. This is my first post on here and I am also just a junior dev so I may be missing info needed here if so please let me know.
Here is the code
const onChange = (e, index) => {
setFilename(e.target.files[0].name)
setArrFiles([...arrFiles, {key:index, file:e.target.files[0].name} ])
}
const displayTask = (index) => {
let upload = []
arrFiles.forEach(el => {
if(el.key === index) {
upload.push(el.file)
}
})
return upload.map((file) => (
<li key={index}>{file}</li>
))
}
{database.map((task, index) => (
<li key={index}>
<p>{index}</p>
<div className="userPortal__tasksContainer">
<div className='userPortal__tasksHeader'>
<p className='userPortal__tasksHeaderTitle'>{task.taskTitle}</p>
<p className='userPortal__tasksHeaderInfo'>{task.taskMessage}</p>
</div>
<div className='userPortal__tasksBodyButtons'>
<form className='userPortal__fileUpload'>
<input className='userPortal__inputButton' multiple id='file' type="file" onChange={e => onChange(e, index)}/>
<label htmlFor='file'>Choose File</label>
</form>
<button className='userPortal__tasksBodyButton green'>Task Complete</button>
</div>
<p id='userPortalFooterTitle'>Successfully Uploaded</p>
<div className='userPortal__footer'>
<ul>
{displayTask(index)}
</ul>
</div>
</div>
</li>
))}
The issue here was like a dummy I hard coded the input ID so when referencing the input field it would only get the hard coded value instead of the index of the component.
Here is the updated form.
<form className='userPortal__fileUpload'>
<input className='userPortal__inputButton' multiple id={index} type="file" onChange={(() => (e) => onChange(e, index))()}/>
<label htmlFor={index}>Choose File</label>
</form>
No Do It Like This
const onChange = (e, index) => {
setFilename(e.target.files[0].name);
// Okay You Need To Filter The State In Order To Get The Object With THe Current Index
// Set The File Value Of The Object To e.target.files[0].name
setArrFiles((state) => {
const allFiles = state;
const currentFile = allFiles.filter(
(file) => parseInt(file.key) === parseInt(index)
)[0];
// i converted it to an integer just to prevent further bugs
currentFile.file = e.target.files[0].name;
return [allFiles];
});
};

Validating a value when button is pressed before passing it

Hi I am new to React and I am a little bit confused on how to validate a value before passing it to the partialRefund function I have.
I am trying to set a simple validation to make sure the value is not empty and numeric before passing it to the partialRefund function.
The first line is the code I currently have. The second line is the code I am trying to write for the validation but it is not working.
Any help would be really appreciated! Thanks!
//Current code
{partialRefundSelected ? <div> <input id={`partial_refund_${order_id}`} type='text'/> <button onClick={() => partialRefund(order_deets_obj,"partialRefund",document.getElementById('partial_refund_'+order_id).value)}> Refund Order </button> </div> : ""}
//Code I am trying to use
{partialRefundSelected ? <div> <input id={`partial_refund_${order_id}`} type='text'/> <button onClick={(validateValue(document.getElementById('partial_refund_'+order_id).value)) => partialRefund(order_deets_obj,"partialRefund",document.getElementById('partial_refund_'+order_id).value)}> Refund Order </button> </div> : ""}
On the second line i am trying to pass a function that will validate the value and the pass it to the partialRefund function. But it doesnt seem to be working :(
Use this:
{
partialRefundSelected ?
<div>
<input id={`partial_refund_${order_id}`} type='text'/>
<button onClick={() => {
const validatedValue=validateValue(document.getElementById('partial_refund_'+order_id).value));
partialRefund(order_deets_obj,"partialRefund",validatedValue);
}}> Refund Order
</button>
</div> :
""}
You can do the validation in the onClick callback if you add curly brackets around the parttialRefund call.
export default function App() {
const partialRefundSelected = true;
const order_id = 1;
const order_deets_obj = { deets: "good deets" };
const partialRefund = (deets, someString, someValue) => {
console.log(deets, someString, someValue);
};
return partialRefundSelected ? (
<div>
<input id={`partial_refund_${order_id}`} type="text" />
<button
onClick={() => {
const value = document.getElementById("partial_refund_" + order_id)
.value;
// Do validation here
if (value === "I LOVE CATS") {
partialRefund(order_deets_obj, "partialRefund", value);
}
}}
>
Refund Order
</button>
</div>
) : (
""
);
}
While this is an option in react, I would suggest making your input a Controlled Component. This would allow you to keep the input's text in state instead of needing to pull the text off of the element after a click. Here is an example.

when second or any other image radio button is clicked, the first one gets updated

I have a form where menu has to be uploaded with menu title and type. The type can be food-menu and beverage-menu. Each type will have only 3 images. I have done that part
but when selecting the radio button for menu type, if i select second or other than first radio button, the first radio button gets selected. How do I solve this issue?
The code can be large so here is the demo
https://codesandbox.io/s/zxxrnw2qx4
here is the code in brief
const Preview = props => {
return (
<div>
{props.files.map((file, index) => {
if (['image/png', 'image/jpg', 'image/jpeg'].includes(file.type)) {
return (
<ClientUploadedImage
key={index}
file={file}
id={index}
menu_title={props.menu_title}
type={props.type}
foodmenuError={props.foodmenuError}
handleChange={props.handleChange}
handleTypeChange={props.handleTypeChange}
/>
);
}
return <div>No File to Show Preview</div>;
})}
</div>
);
};
const ClientUploadedImage = props => {
return (
<section id="menus-photo">
<img src={props.file.preview} width={'400px'} height={'auto'} />
<div className="content">
<form className="form">
<Radio
value="food-menu"
label={`Food Menu${props.id}`}
name={props.id}
handleChangeEvent={props.handleTypeChange}
isChecked={props.type[props.id] === 'food-menu'}
/>
<Radio
value="beverages-menu"
label={'Beverages Menu'}
name={props.id}
handleChangeEvent={props.handleTypeChange}
isChecked={props.type[props.id] === 'beverages-menu'}
/>
<InputField
name={props.id}
type="text"
label="Menu Title"
onChange={props.handleChange}
value={props.menu_title[props.id]}
/>
</form>
</div>
</section>
);
};
Your type array is empty in initial state. If you directly select radio button from second image, handleTypeChange is being called with index 1. In the function, ...types.slice(0, index) becomes types.slice(0,1) which eventually performs spread operation on a blank array and your newValue is appended at 0th position which leads to selection of first image radio button. Here you need to handle the blank array condition for first selection inside the function and you will be good to go.

Categories

Resources