Home > Mobile >  I can't edit the input form in the DisplayChooseMovie
I can't edit the input form in the DisplayChooseMovie

Time:01-15

My first part of the project is using useState for the state control. Second part of the project is using Radux for state control.I am using react radux for state. I have select a movie in the Member.jsx for edit and I display it in DisplayChoooseMovie for edit. I use input tag to display the movie data. I am using reducer function showSelectMovieForEdit in recordSlice.js in AssignmentTwo folder to display the movie for edit. Then I use onChange in the info['movie name'] to update the 'movie name' in the movie date. I don't know why I can change the value of the name in the input tag. It always keep the name it had.

My DisplayChooseMovie.jsx

import { showSelectMovieForEdit, saveMovieAfterEdit, saveMovieChangeName } from "./RecordSlice";
import { useSelector, useDispatch } from 'react-redux';

 export default function DisplayChooseMovie(){
        
    const records = useSelector(function (store) {
        return store.record.value;
    });
    
    const dispatch = useDispatch();  
    
    const tableRows =(records)=> 
      //Display the movie list in a table  
      records. Map((info,num) => {
          return (
           info.displayOneMovie && (
          <div>
            <input type={"text"}  maxLength={"100"}  value={info.id} ></input><br></br>  
          <input type={"text"} name={"moviesName"} id={"moviesName"} value={info['movie name']} onChange={(event)=>{saveMovieChangeName({"id":info.id, "movie name": event.target.value })}}></input><br></br>
          <textarea id={"changeMovieDescription"}   rows={"10"} cols={"20"} value={info.description}></textarea><br></br>
          <input type={"text"} id={"changeMovieGenre"} value={info. Genre}></input><br></br>
          <input type={"text"} id={"changeLeadActor"} value={info['lead actor']}></input><br></br>
          <input type={"text"} id={"changeRating"} value={info.rating}></input><br></br>
          <input type={"text"} id={"changeMovieLanguage"} value={info. Language}></input>
          </div>
          ))
      }) 
  
      return (
          <div>
          {tableRows(records)}
            
            <div style={{ marginTop:"10px",textAlign:"center" }}><input type={"button"} value={"Save Change Button"} onClick={()=>{dispatch(saveMovieAfterEdit(records))}}></input></div>
          </div>)
}

My Member.jsx

import { useDispatch } from 'react-redux';
 import { showSelectMovieForEdit } from '../AssignmentTwo/recordSlice';


export default function Member({data, ondeleteHandler, onChangeIdHandler, checkHideShowHandler, onClickShowItemHandler}){
      
      const dispatch = useDispatch();  
      
      const tableRows =(data)=> 
        //Display the movie list in a table  
        data.map((info,num) => {
            return (
             info. Display && (
            <tr key={info.id}>
              <td style={{ border: "2px solid #696969", color: 'white', textAlign: 'center'}}>{info.id}</td>
              <td style={{ border: "2px solid #696969", color: 'white', textAlign: 'center'}}>{info['movie name']}</td>
              <td style={{ border: "2px solid #696969", color: 'white', textAlign: 'center', margin: '1px auto'}}>{info.description}</td>
              <td style={{ border: "2px solid #696969", color: 'white'}}>{info.genre}</td>
              { 
              info['lead actor'].map((data)=><td style={{ border: "2px solid #696969", color: 'white'}}>
                {data}</td>)}
              <td style={{ border: "2px solid #696969", color: 'white', textAlign: 'center'}}>{info. Rating}</td>
              <td style={{ border: "2px solid #696969", color: 'white', textAlign: 'center'}}>{info. Language}</td>
              <td style={{ border: "2px solid #696969", textAlign: "center" }}><input type={"checkbox"} id={"deletemovies"} name={"deletemovies"} onChange={(event) => onChangeIdHandler(event,info.id)}></input></td>
              <td style={{ border: "2px solid #696969", textAlign: "center"}}><input type={"checkbox"} id={"showHideMovies"} name={"showHideMovies"} onChange={(event) => checkHideShowHandler(event,info.id)}></input></td> 
              <td style={{ border: "2px solid #696969", textAlign: "center"}}><input type={"checkbox"} id={"showHideMovies"} name={"showHideMovies"} onChange={(event) => dispatch(showSelectMovieForEdit(info.id))}></input></td> 
            </tr> 
            ))
        }) 
    
        return (
            <div>
              <table style = {{ width: "100%", marginTop: "50px", backgroundColor: "black", borderCollapse: "collapse"}}>
                <thead style={{ border: "2px solid #ea4915"}}>
                  <tr>
                    <th style={{ border: "2px solid #696969", color: 'white', backgroundColor: "black"}}>Id</th>
                    <th style={{ border: "2px solid #696969", color: 'white', backgroundColor: "black" }}>Name</th>
                    <th style={{ border: "2px solid #696969" , color: 'white', backgroundColor: "black"}}>Description of Movies</th>
                    <th style={{ border: "2px solid #696969" , color: 'white', backgroundColor: "black"}}>Genre</th>
                    <th style={{ border: "2px solid #696969" , color: 'white', backgroundColor: "black"}} colSpan={"2"}>Actors</th>
                    <th style={{ border: "2px solid #696969" , color: 'white', backgroundColor: "black"}}>Rating</th>
                    <th style={{ border: "2px solid #696969" , color: 'white', backgroundColor: "black"}}>Language</th>
                    <th style={{ border: "2px solid #696969" , color: 'white', backgroundColor: "black"}}>Remove Items</th>
                    <th style={{ border: "2px solid #696969" , color: 'white', backgroundColor: "black"}}>Hide Items</th>
                    <th style={{ border: "2px solid #696969" , color: 'white', backgroundColor: "black"}}>Select Movie for Edit</th>
                  </tr>
                </thead>
                <tbody>{tableRows(data)}</tbody>
              </table>
              <div className="buttonSeparation">
                <ol style={{ textAlign: "center", listStyleType: "none", listStylePosition: "inside"}}>
                    <li style={{ border: "2px solid #696969", width: '89px', listStyle: "none", display: "inline-block"}}>
                      <input  type={"button"} onClick= {ondeleteHandler} value={"Delete Items"}></input>
                    </li>
                    <li style={{ display: "inline-block", border: "2px solid #696969", width: '135px',marginLeft: "10px"}}>
                      <input  type={"button"} value={"Show the hide items"} onClick={onClickShowItemHandler} ></input>
                  </li>
                  
                </ol>
              </div>      
              </div>)
}

My recordSlice.js

import { createSlice } from '@reduxjs/toolkit';
import { datamovielist } from '../App';

export const recordSlice = createSlice({
    name: 'Record Slice',
    initialState: {
        value: [
            { "id": 1,"movie name" : "Ticket to Paradise","display":"true","description":"Academy Award® winners George Clooney and Julia Roberts reunite on the big screen as exes who find themselves on a shared mission to stop their lovestruck daughter from making the same mistake they once made","genre" :"Comedy", "lead actor": ["George Clooney", "Julia Roberts"],"rating":5,"displayOneMovie":false,"language":"english"},
            { "id": 2, "movie name": "Black Panter","display":true,"description":"Queen Ramonda (Angela Bassett), Shuri (Letitia Wright), M’Baku (Winston Duke), Okoye (Danai Gurira) and the Dora Milaje (including Florence Kasumba), fight to protect their nation from intervening world powers in the wake of King T’Challa’s death.","genre":"Action","lead actor":["Angela Bassett","Letitia Wright"],"rating":6,"displayOneMovie":false,"language":"english"},
            { "id":3, "movie name": "Smile","display":true,"description":"After witnessing a bizarre, traumatic incident involving a patient, Dr. Rose Cotter (Sosie Bacon) starts experiencing frightening occurrences that she can't explain.","genre":"Drama","lead actor":["Sosie Bacon","Jessie T. Usher"],"rating":6,"displayOneMovie":false,"language":"english"},
            {"id":4,"movie name":"Come Back Home","display":true,"description":"In the cold winter, a group of Shenzhen tourist families take a trip to the northeast Changbai Mountain. It was originally intended to be a happy and harmonious holiday, but due to the negligence of his father, an 8-year-old boy is unfortunately lost.","genre":"Mistery","lead actor":["Donnie Yen", "Han Xue"],"rating":6,"displayOneMovie":false,"language":"mandarian"},
            {"id":5,"movie name":"Ajoomma","display":true,"description":"Auntie (Hong Huifang), is a middle-aged Singaporean woman who has dedicated the best years of her life to caring for her family. Now widowed with her grown up son, Sam (Shane Pow) about to fly the roost, Auntie is left to contend with a whole new identity beyond her roles of daughter, wife, and mother.","genre":"Drama","lead actor":["Hong Huifang", "Jung Dong-Hwan"],"rating":4,"displayOneMovie":false,"language":"mandarian"}
        ], // No records initially
    },
    reducers: {
        showSelectMovieForEdit: function(state,action){
           for(let i=0;i<state.value.length;i  ){
            if(state.value[i].id===action.payload){
                state.value[i].displayOneMovie = true
            }
           }
        },
        
        saveMovieAfterEdit: function(state,action){
            alert(action.payload)
        },

        saveMovieChangeName: function(state,action){
            alert(action.payload)
        },

    },
}); 

// Use these to update the state in your component
export const { showSelectMovieForEdit, saveMovieAfterEdit, saveMovieChangeName } = recordSlice.actions;

// This part goes into the store.
export default recordSlice.reducer

My storage.js

import { configureStore } from '@reduxjs/toolkit'
import recordReducer from './recordSlice';


export default configureStore({
  reducer: {
    // Register reducers here
    record: recordReducer
  }
})

My App.js

import LoggedInForm from "./AssignmentOne/LoggedInForm"
import AddMember from "./AssignmentOne/AddMember";
import Member from "./AssignmentOne/Member";
import ChooseGenre from "./AssignmentOne/ChooseGenre";
import { Provider } from 'react-redux';
import storage from "./AssignmentTwo/storage";
import DisplayChooseMovie from "./AssignmentTwo/DisplayChooseMovie";

//Json data of movie list
const dataMovielist = [{ "id": 1,"movie name" : "Ticket to Paradise","display":"true","description":"Academy Award® winners George Clooney and Julia Roberts reunite on the big screen as exes who find themselves on a shared mission to stop their lovestruck daughter from making the same mistake they once made","genre" :"Comedy", "lead actor": ["George Clooney", "Julia Roberts"],"rating":5,"displayOneMovie":false,"language":"english"},
{ "id": 2, "movie name": "Black Panter","display":true,"description":"Queen Ramonda (Angela Bassett), Shuri (Letitia Wright), M’Baku (Winston Duke), Okoye (Danai Gurira) and the Dora Milaje (including Florence Kasumba), fight to protect their nation from intervening world powers in the wake of King T’Challa’s death.","genre":"Action","lead actor":["Angela Bassett","Letitia Wright"],"rating":6,"displayOneMovie":false,"language":"english"},
{ "id":3, "movie name": "Smile","display":true,"description":"After witnessing a bizarre, traumatic incident involving a patient, Dr. Rose Cotter (Sosie Bacon) starts experiencing frightening occurrences that she can't explain.","genre":"Drama","lead actor":["Sosie Bacon","Jessie T. Usher"],"rating":6,"displayOneMovie":false,"language":"english"},
{"id":4,"movie name":"Come Back Home","display":true,"description":"In the cold winter, a group of Shenzhen tourist families take a trip to the northeast Changbai Mountain. It was originally intended to be a happy and harmonious holiday, but due to the negligence of his father, an 8-year-old boy is unfortunately lost.","genre":"Mistery","lead actor":["Donnie Yen", "Han Xue"],"rating":6,"displayOneMovie":false,"language":"mandarian"},
{"id":5,"movie name":"Ajoomma","display":true,"description":"Auntie (Hong Huifang), is a middle-aged Singaporean woman who has dedicated the best years of her life to caring for her family. Now widowed with her grown up son, Sam (Shane Pow) about to fly the roost, Auntie is left to contend with a whole new identity beyond her roles of daughter, wife, and mother.","genre":"Drama","lead actor":["Hong Huifang", "Jung Dong-Hwan"],"rating":4,"displayOneMovie":false,"language":"mandarian"}]

function App(props){
    
    //Initial movie item id
    let moviesitemsid = [];
    //Initial hide movie id
    let hidemoviesid = [];
    
    //useState of movieid, datamovielist, isLogin and hideshowmovieid
    const [moviesid, setmoviesid] = React.useState(moviesitemsid);
    const [datamovielist, setdatamovielist] = React.useState(dataMovielist);
    const [isLogin, setIsLoggedIn] = React.useState(false)
    const [hideshowmoviesid, sethideshowmoviesid] = React.useState(hidemoviesid);
    
    //Add a new movie list to the original dataMovieList
    const onSubmitHandler = (newHobbies) => {
        setdatamovielist([...datamovielist, newHobbies]);
      };

    //Add a false boolean to the display if the id is the same
    //so that we can hide the movie list
    const checkHideShowHandler = (event, id) => {
        if (event.target.checked === true) {
          let copy = [...datamovielist];
          for(let c=0; c< copy.length; c  ){
              if(id === copy[c].id){
                copy[c].display = false;
              }
            } 
          setdatamovielist(copy);  
          if (hideshowmoviesid.length === 0) {
              sethideshowmoviesid([id]);
          } else {
              addHideShowMoviesId(id);
          }
              
        } } 
    
    //Add a true to the display so that the hide movie
    //appear again    
    const onClickShowItemHandler = () => {
          let copy = [...datamovielist];
          for (let i = 0; i < hideshowmoviesid.length; i  ) {
            for(let c=0; c< copy.length; c  ){
              if(hideshowmoviesid[i] === copy[c].id){
                copy[c].display =true;
              }
          };
         }
         setdatamovielist(copy);
         sethideshowmoviesid([]);
        }
    
    //Add a new movie id to the original id for the hide and show event
    function addHideShowMoviesId(newmoviesid) {
          sethideshowmoviesid([...hideshowmoviesid, newmoviesid]);
        }

    //Add a new movie id to the original movie id
    function addMoviesId(newmoviesid) {
        setmoviesid([...moviesid, newmoviesid]);
      }  
    
    //Delete the movie list  
    const ondeleteHandler = (event) => {
        event.preventDefault();
        let copy = [...datamovielist];
        for (let i = 0; i < moviesid.length; i  ) {
          copy = copy.filter((item, index) => moviesid[i] !== item.id);
        }
        setdatamovielist(copy);
        setmoviesid([]);
      };
    
    //Check the movie Id whether it is the start of the movie data, then pass it to the movie id 
    //container. If it is not the start of the movies data, add it to the original movie id. Also
    //delete it if the checkbox is not checked. This is for the ondeleteHandler. The movie id store
    //the list of id in the movie data  
    const checkIdEventHandler = (event, id) => {
        if (event.target.checked === true) {
          if (moviesid.length === 0) {
            setmoviesid([id]);
          } else {
            addMoviesId(id);
          }
        } else {
          let copy = [...moviesid];
          copy = copy.filter((data) => data !== id);
          setmoviesid(copy);
        }
      };
    
    //Show the movie according to the genre  
    function setgenreHandler(event,genrename){
        event.preventDefault();
        let data = [...datamovielist]
        for(let i =0; i<data.length; i  ){
          if(genrename.toLowerCase() === data[i].genre.toLowerCase() ){
             data[i].display= true;
          }else {
            data[i].display = false;
          }

          if(genrename.toLowerCase() === "none"){
            for(let i=0; i < data.length; i   ){
              data[i].display = true;
            }
          }
        }
        setdatamovielist(data);
       
    }

    return(        
      <div>
        <Provider store={storage}>
           <LoggedInForm setIsLoggedIn = {setIsLoggedIn}/>
           {
          //  isLogin &&  
                        <div> <AddMember onSubmitHandler={onSubmitHandler} />
                              <Member data = {datamovielist} onClickShowItemHandler={onClickShowItemHandler} ondeleteHandler={ondeleteHandler} onChangeIdHandler={checkIdEventHandler} checkHideShowHandler={checkHideShowHandler} setgenreHandler={setgenreHandler}/>
                              <ChooseGenre setgenreHandler={setgenreHandler} />
                              <DisplayChooseMovie />
                        </div>}
        </Provider>      
      </div>
    )
}

export {dataMovielist} 

const root = ReactDOM.createRoot(document.getElementById('root'));
root. Render(<App/>);

I am new to React. I don't know why I can't edit the movielist in DisplayChooseMovie. Please look at the code in Member.jsx, recordSlice.js, storage.js and DisplayChooseMovie.jsx as these are files that I added the new code. The rest of the code it ok. Hope you can sole for me. I never include some files as it is not important.Thanks

CodePudding user response:

<input type={"text"} maxLength={"100"} value={info.id}>

since value = {info.id} the input will always show info.id if you want to change it's value, you need to update info.id with onChange

saveMovieChangeName({"id":info.id, "movie name": event.target.value })

this is not updating, this is showing an alert

CodePudding user response:

In your reducer (recordSlice.js) you have to update the state. Actually, you are just making an alert.

To do this, instead of having

saveMovieChangeName: function(state,action) {
    alert(action.payload)
},

You should have

saveMovieChangeName: function(state,action) {
    state.value[action.payload.id] = action.payload["movie name"] // <-- here is the update
    alert(action.payload)
},

  • Related