onSubmit() form is not working or triggered - javascript

I'm trying to implement a function that will accept an attribute called customer_name to create a new customer. Here is my code:
import { connect } from 'react-redux'
import React, { useState, useEffect } from 'react'
import { createCustomer, initialCreate } from '../../redux'
const CreateCustomer = ( { createCustomer, initialCreate, userData } ) => {
const returnNull = () => {
return null
}
const [actionType, setActionType] = useState('')
const [formData, setFormData] = useState({
customer_name: ''
});
const { customer_name } = formData;
const [effectRan, setEffectRan] = useState(false)
const onChange = e => setFormData({
...formData,
[e.target.name]: e.target.value
})
useEffect(() => {
if(!effectRan) {
setEffectRan(true)
initialCreate()
}
}, [effectRan])
const onClick = e => {
e.preventDefault()
setActionType(e.target.name)
console.log(actionType)
};
const onSubmit = e => {
console.log('first')
console.log(actionType);
e.preventDefault();
actionType === 'create' ? createCustomer(customer_name) : returnNull();
initialCreate();
}
return userData ? (
<div>
<form onSubmit={e => onSubmit(e)}>
<table className="table">
<thead>
<tr>
<th scope="col">Customer Name</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input
placeholder=''
className='form-control'
id="InputCustomerName"
name="customer_name"
value={customer_name}
onChange={e => onChange(e)}
>
</input>
</td>
<td>
<button
type="submit"
name="create"
className="btn btn-primary"
onClick={e => onClick(e)}
>Create
</button>
</td>
</tr>
</tbody>
</table>
</form>
</div>
) : (
<div className="text-center">
<div className="spinner-border" role="status">
<span className="sr-only">Loading...</span>
</div>
</div>
)
};
const mapStateToProps = state => ({
// is authenticated?
isAuthenticated: state.auth.isAuthenticated,
userData: state.customer.customer,
createSuccess: state.customer.createSuccess
})
const mapDispatchToProps = dispatch => {
return {
createCustomer: (customer_name) => dispatch(createCustomer(customer_name)),
initialCreate: () => dispatch(initialCreate())
}
}
export default connect(mapStateToProps, mapDispatchToProps) (CreateCustomer);
The problem is my submit button seems not working, I can't see any information in my console when I clicked the create button. While I can see the information in the onClick method which means the button is clicked.

I uncommented my code one by one, I found that I can't have two preventDefault() in both onClick and onSubmit.
So, I uncommented the preventDefault() in my onClick() function.
I'm sorry, I'm not very familiar with react.js, I need to look up some information about this preventDefault()

Related

react ternary operator problem, solvable only with jquery?

I'm new to React and try to make a simple crud with Springboot.
at certain point I need to use a ternary operator, but it doesn't work. I used it before in React with no problem, I don't understand why now is not working.
So I used a function and is working, except when I have to empty a div, which gave me a problem and need to use jquery. So now the code is working, I just would like to know what I'm doing wrong in the ternary and in emptying the div with javascript.
I will post the full working code, then just the piece of code that would like to use vs the code that is actually working.
Thanks for your patience
import { React, useState, useEffect } from "react";
import { useHistory } from "react-router";
import ServiceUtente from "../service/ServiceUtente";
import $ from "jquery";
const Utente = () => {
const history = useHistory();
const [utenti, setUtenti] = useState([]);
const [isDeleted, setIsDeleted] = useState(false);
const [searchBy, setSearchBy] = useState("");
let checkedNome = false;
let checkedEmail = false;
let checkedProfilo = false;
useEffect(() => {
retrieveUtenti();
}, [isDeleted]);
// retrieve data from db and store it into utenti
const retrieveUtenti = () => {
ServiceUtente.utenteGetAll()
.then((response) => {
setUtenti(response.data);
})
.catch((e) => {
console.log(e);
});
};
const viewUtente = (id) => {
history.push(`/view-utente/${id}`);
};
const aggiungiUtente = () => {
history.push("/aggiungi-update-utente/_add");
};
const deleteUtente = (id) => {
ServiceUtente.utenteDelete(id)
.then((response) => {
setIsDeleted(!isDeleted);
})
.catch((e) => {
console.log(e);
});
};
const updateUtente = (id) => {
history.push(`/aggiungi-update-utente/${id}`);
};
const handleSearch = (e) => {
setSearchBy(e.target.value);
};
const handleNome = (e) => {
checkedNome = e.target.checked;
console.log("nome: " + checkedNome);
nomeForm();
};
const handleEmail = (e) => {
checkedEmail = e.target.checked;
console.log("email: " + checkedEmail);
};
const handleProfilo = (e) => {
checkedProfilo = e.target.checked;
console.log("profilo: " + checkedProfilo);
};
const formSearchBy = () => {
// console.log("");
};
const nomeForm = () => {
if (checkedNome === true) {
document.getElementById("nomeForm").innerHTML = `
<input
type="text"
className="form-control"
placeholder="Search Utente"
value="${searchBy}"
onChange="${handleSearch}"
/>`;
} else {
// document.getElementById("nomeForm").innerHTML = "";
$("#nomeForm").empty();
}
};
return (
<div className="row">
<div className="col-sm-10 offset-1">
<h2 className="login-title my-4" style={{ textAlign: "center" }}>
GM Utente
</h2>
{/* ***********************SEARCH BAR****************************************** */}
<form onClick={formSearchBy}>
<h4 style={{ textAlign: "center" }}>
Spuntare i campi desiderati per la ricerca
</h4>
<div className="form-check">
<input
onChange={handleNome}
className="form-check-input"
type="checkbox"
name="nomeCheck"
value=""
id="nomeUtente"
/>
<label className="form-check-label" htmlFor="nomeUtente">
Nome Utente
</label>
<div id="nomeForm">{nomeForm()}</div>
</div>
<div
className="input-group-append my-2 text-center"
style={{ textAlign: "center" }}
>
<button
className="btn btn-success"
type="submit"
id="button-addon2"
>
Search
</button>
</div>
</form>
{/* ***********************END SEARCH BAR*********************************** */}
<button
type="button"
className="btn btn-primary my-2"
onClick={() => aggiungiUtente()}
>
Aggiungi Utente
</button>
<table
className="table table-striped table-bordered"
style={{ textAlign: "center" }}
>
<thead>
<tr>
<th>Id Utente</th>
<th>Nome Utente</th>
<th>Email</th>
<th>Password</th>
<th>Profilo Utente</th>
<th>Azioni</th>
</tr>
</thead>
<tbody>
{utenti.map((utente) => (
<tr key={utente.idUtente}>
<td>{utente.idUtente}</td>
<td>{utente.nomeUtente}</td>
<td>{utente.email}</td>
<td>{utente.password}</td>
<td>{utente.profiloUtente.nomeProfilo}</td>
<td>
<button
onClick={() => viewUtente(utente.idUtente)}
type="button"
className="btn btn-secondary mx-1"
>
Details
</button>
<button
onClick={() => updateUtente(utente.idUtente)}
type="button"
className="btn btn-warning mx-1"
>
Update
</button>
<button
onClick={() => deleteUtente(utente.idUtente)}
type="button"
className="btn btn-danger mx-1"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
};
export default Utente;
All this code is working but I would like to use this
{checkedNome === true ? (
<input
type="text"
className="form-control"
placeholder="Search Utente"
value={searchBy}
onChange={handleSearch}
/>
) : null}
Instead of this function
const nomeForm = () => {
if (checkedNome === true) {
document.getElementById("nomeForm").innerHTML = `
<input
type="text"
className="form-control"
placeholder="Search Utente"
value="${searchBy}"
onChange="${handleSearch}"
/>`;
} else {
// document.getElementById("nomeForm").innerHTML = "";
$("#nomeForm").empty();
}
};
Also, in this function, why the Jquery syntax is working and the '.innerHTML = "";' commented out is not?
Thanks
Issue
The issue is that you aren't updating any state in order to trigger a render. checkedNome is declared in the function body and mutating it won't trigger React to do anything.
let checkedNome = false;
const handleNome = (e) => {
checkedNome = e.target.checked; // <-- mutation
console.log("nome: " + checkedNome);
nomeForm(); // <-- DOM mutation
};
Solution
Move the checkedNome into component state:
const [checkedNome, setCheckedNome] = React.useState(false);
Update handleNome to enqueue a state update:
const handleNome = (e) => {
const { checked } = e.target;
setCheckedNome(checked);
};
Update the render return to conditionally render the input:
<div id="nomeForm">
{checkedNome && (
<input
type="text"
className="form-control"
placeholder="Search Utente"
value={searchBy}
onChange={handleSearch}
/>
)}
</div>

input fields not keeping original value if no edit is made react

I have this: this is the whole page, just do block out any confusion.
import React, { useState, useEffect } from "react";
import axios from "axios";
import { useHistory } from "react-router-dom";
const EditServicesPage = () => {
const history = useHistory()
const [myData, setMyData] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [showEditButton, setShowEditButton] = useState(false);
const [fields, setFields] = useState({
updatedByCNUM: myData.updatedByCNUM,
content: myData.content,
site: myData.site
})
var idFromListServicesPage = history.location.state.id
console.log("22: " + idFromListServicesPage)
useEffect(() => {
axios
.post('/getDocToEdit', {id : idFromListServicesPage})
.then((res) => {
console.log("line 28 esp.js: " + res.data)
setMyData(res.data);
setIsLoading(true);
})
.catch((error) => {
// Handle the errors here
console.log(error);
})
.finally(() => {
setIsLoading(false);
});
}, []);
const deleteById = (id) => {
console.log(id);
axios
.post(`/deleteDoc`, { id: id })
.then(() => {
console.log(id, " worked");
window.location = "/admin/content";
})
.catch((error) => {
// Handle the errors here
console.log(error);
});
};
// const editById = (id) => {
// console.log(id);
// // window.location = "/admin/services/:site";
// axios
// .post(`/editDoc`, { id: id })
// .then(() => {
// console.log(id, " worked");
// window.location = "/admin/services/:site";
// })
// .catch((error) => {
// // Handle the errors here
// console.log(error);
// });
// };
const handleInputChange = e => setFields(f => ({...f, [e.target.name]: e.target.value}))
const editById = (id, site, content, updatedByCNUM) => {
console.log(id, site, content, updatedByCNUM);
axios
.post(
'/editDoc',
({
id: id,
location: site,
content: content,
updatedByCNUM: updatedByCNUM
})
)
.then(() => {
console.log(id, " worked");
window.location = "/admin/services";
})
.catch((error) => {
console.log(error);
});
};
const onClickEdit = (e, _id) => {
e.preventDefault();
var site = document.getElementById("site").value;
var content = document.getElementById("content").value;
var updatedByCNUM = document.getElementById("updatedByupdatedByCNUMhide").value;
console.log(site, content, updatedByCNUM)
editById(_id, site, content, updatedByCNUM);
};
const onTyping = (name, value) => {
setMyData({ ...myData, [name]: value });
if (value.length > 0) {
setShowEditButton(true);
} else {
setShowEditButton(false);
}
};
return (
<table id="customers">
<h1>Edit Services Page</h1>
<tr>
<th>site</th>
<th>content</th>
<th>updatedByCNUM</th>
<th>Actions</th>
</tr>
<tr>
<td>
<input
// ref={site.ref}
type="text"
value={myData.site}
onInput={(e) => onTyping(e.target.name, e.target.value)}
onChange={handleInputChange}
placeholder={myData.site}
name="site"
id="site"
/>{" "}
{/* <input
type="text"
placeholder={site}
onChange={(e) => onTyping(e.target.value)}
name="site"
id="site"
/> */}
</td>
<td>
<input
// ref={content.ref}
type="text"
value={myData.content}
onInput={(e) => onTyping(e.target.name, e.target.value)}
onChange={handleInputChange}
placeholder={myData.content}
name="content"
id="content"
/>
</td>
<td>
<input
type="text"
placeholder={myData.updatedByCNUM}
name="updatedByupdatedByCNUMhide"
id="updatedByupdatedByCNUMhide"
readOnly
/>{" "}
</td>
<td>
{/* <input type="hidden" placeholder={myData.updatedByCNUM} name="updatedByCNUM" id="updatedByCNUM" value={updatedByCNUM}/>{" "} */}
</td>
<td>
<button
onClick={(e) => {
e.preventDefault();
deleteById(idFromListServicesPage);
}}
disabled={isLoading}
>
Delete
</button>
<button
onClick={(e) => {
e.preventDefault();
editById(idFromListServicesPage);
}}
>
Edit
</button>
{showEditButton && (
<button onClick={(e) => onClickEdit(e, idFromListServicesPage)}>Submit Edit</button>
)}
</td>
</tr>
</table>
);
};
export default EditServicesPage;
however, when I edit a field, as in type into either site, or content, the original values of the unedited fields don't stay. so If I type a new value into site, and then leave content as the original, then it doesn't send content original value back to the backend, and keeps it null. I don know why. can anyone help?
wrap your inputs in a form, and give it an initialValue. it must work.
Get initial form value with javascript
A few ideas after a quick look:
Inside your try use onChange instead of onType
Keep track of your new typed value with a state, and then setOldState(updatedValues) when you submit
Once submitted, re-setUpdatedValues to whichever initial value you'd like
on you inputs.

Create a search bar in Firestore retrieved data in React and add a functionality of Edit/Update & Delete buttons

Below is my code, as of now its working perfectly but I am not able to add a search bar in
it. I am new to the React.js I tried many solutions but didn't get the solution and also I need a functionality for update and delete buttons. thanks in advance
import React from "react";
import { db } from "../firebase";
import "../App.css";
function TillDateData() {
const [contacts, setContacts] = React.useState([]);
React.useEffect(() => {
const fetchData = async () => {
const data = await db.collection("contacts").orderBy("createdDate").get();
setContacts(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
fetchData();
}, []);
return (
<div className="myclass">
<table className="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">City</th>
<th scope="col">Contact No.</th>
<th scope="col">Date</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{Object.keys(contacts).map((id) => {
return (
<tr key={id}>
<td>{contacts[id].name}</td>
<td>{contacts[id].email}</td>
<td>{contacts[id].city}</td>
<td>{contacts[id].contact}</td>
<td>{contacts[id].createdDate}</td>
<td>
<button className="btn btn-primary btn-sm">Edit</button>
</td>
<td>
<button className="btn btn-danger btn-sm">Delete</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
}
export default TillDateData;
import React, { useState } from "react";
import { db, fire } from "../firebase";
import "../App.css";
function TillDateData() {
const [search, setSearch] = useState("");
const [users, setUsers] = React.useState([]);
const [contactsData, setContactsData] = useState(users); //iterate this in table
const deleteContact = (id) => {
db.collection('users').doc(id).delete()
};
const changeSearch = (val) => {
setSearch(val);
if (val != "") {
setContactsData(
users.filter((contact) => {
contact.name.toLowerCase().includes(val.toLowerCase()) ||
contact.email.toLowerCase().includes(val.toLowerCase()) ||
contact.city.toLowerCase().includes(val.toLowerCase()) ||
contact.number.toLowerCase().includes(val.toLowerCase());
})
);
} else {
setContactsData(users);
}
};
React.useEffect(() => {
const fetchData = async () => {
const data = await db.collection("users").orderBy("createdDate").get();
setUsers(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
fetchData();
}, []);
return (
<>
<input type="text" onChange={(e) => changeSearch(e.target.value)} />
<div className="myclass">
<table className="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">City</th>
<th scope="col">Contact No.</th>
<th scope="col">Date</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{Object.keys(contactsData).map((id) => {
return (
<tr key={id}>
<td>{users[id].name}</td>
<td>{users[id].email}</td>
<td>{users[id].city}</td>
<td>{users[id].number}</td>
<td>{users[id].createdDate}</td>
<td>
<button className="btn btn-primary btn-sm">Edit</button>
</td>
<td>
<button
className="btn btn-danger btn-sm"
onClick={()=> deleteContact(contact[id].id)}
>
Delete
</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
</>
);
}
export default TillDateData;
just changed some variables remaining same
After a lot of struggle I found a way how to add a search bar functionality in firestore retrieved data. here is my code
import React, { useState, useEffect } from "react";
import { db } from "../firebase";
import "../App.css";
function RetrieveData() {
const [contacts, setContacts] = useState([]);
const [search, setSearch] = useState("");
const [filteredContacts, setFilteredContacts] = useState([]);
useEffect(() => {
const fetchData = async () => {
const data = await db.collection("contacts").orderBy("createdDate").get();
setContacts(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
fetchData();
}, []);
useEffect(() => {
setFilteredContacts(
contacts.filter(
(user) =>
user.name.toLowerCase().includes(search.toLowerCase()) ||
user.city.toLowerCase().includes(search.toLowerCase())
)
);
}, [search, contacts]);
return (
<>
<div className="App">
<h1>Contact Details</h1>
<input
type="text"
placeholder="Search"
onChange={(e) => setSearch(e.target.value)}
/>
</div>
<div>
{filteredContacts.map((contact) => [
<ol>
<b>Consumer Details :</b> {<br />}
{contact.name},{<br />}
{contact.email},{<br />}
{contact.city},{<br />}
{contact.contact},{<br />}
</ol>,
])}
</div>
</>
);
}
export default RetrieveData;
For delete an update try the following code
const deleteContact = (id) => {
//Delete contact with the passed id
}//same for update or edit contacts
<tr>
....
<td><button onClick={()=> deleteContact(contact[id].id)}></td>//same for
update
</tr>
Search Bar
For search bar Do following steps
1- Make search state
const [search, setSearch] = useState('')
const [contacts, setContacts] = useState([])//used just to store contacts from api
const [contactsData, setContactsData] = useState(contacts)//iterate this in table
2- Write an searchChange handler
const changeSearch = (val) => {
setSearch(val)
if(val!=''){
setContactsData(contacts.filter(constact => {
contact.name.includes(val) ||
contact.fname.includes(val)//same other fields added by following OR
condition
}))
}
else{
setContactsData(contacts)
}
}
3- Make a search text field
<input type='text' onChange={(e)=> changeSearch(e.target.value)}
Note: use Objects.keys(contactsData).map after updation
Update and Delete function
1- for update
const UpdateContent = (id) => {
//call an api that delete the content from DB(firebase) for the provided id in parameters or in body.
}
component:
<tr>
Delete functionality also describe in the top section of answer
.....
<button onClick={() => UpdateContent(content[i].id)}/>

Condition before inserting an item and show message in reactjs

I'm developing an application in React.JS
I need to put a condition before inserting.
The code:
const App = () => {
const [item, setItem] = useState([])
const [category, setCategory] = useState([])
const categories = category.map(elem => ({
value: elem.id,
label: elem.cat,
}));
const [category_select, setCategorySelect] = React.useState(null);
function handleChangeCategory(value) {
setCategorySelect(value);
}
useEffect(() => {
getItems()
}, [])
useEffect(() => {
getCategories()
}, [])
const getItems = async () => {
const response = await axios.get(REQUEST_1)
setItem(response.data)
}
const getCategories = async () => {
const response = await axios.get(REQUEST_2)
setCategory(response.data)
}
const addItems = () => {
axios.post(`${REQUEST_1}`, {cat: category_select.value});
};
const body = () => {
return item && item.map((elem,j) => {
return (
<tr key={elem.id}>
<td><span>{elem.cat}</span></td>
</tr>
)
})
}
return (
<>
<div>
<div>
<div>
<div>
<NoSsr>
<Select
classes={classes}
styles={selectStyles}
inputId="category"
TextFieldProps={{
label: 'Category',
InputLabelProps: {
htmlFor: 'category',
shrink: true,
},
placeholder: 'Category...',
}}
options={categories}
components={components}
value={category}
onChange={handleChangeCategory}
/>
</NoSsr>
<span>Select</span>
</div>
<div>
<label> </label>
<span onClick={addItems}></span>
</div>
</div>
<div>
<div>
<div>
<table>
<thead>
<tr>
<th>
<span>Category</span>
</th>
</tr>
</thead>
<tbody>
{body()}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</>
)
}
export default App;
The idea is to check if the item to be inserted already exists, and if it is already inserted, show a message through a popup.
How do I add this condition in the const addItems = () => {...} and the popup? Do I have to put that condition here?
How can I do it, suggestions?
You should check if the selected category already exists in addItems method.
You can use React packages like reactjs-popup to display a popup.
const [isShow, setIsShow] = useState(false)
const addItems = () => {
// check if selected category already exists
if (!category.some(elem => elem.cat === category_select.value)) {
axios.post(`${REQUEST_1}`, {cat: category_select.value});
}
else {
// update popup modal open state and display popup
setIsShow(true);
}
};
...
return (
...
{ isShow && <h1>Error</h1> }
...)

'is not iterable' Using hooks to make an API call from seperate folder

I create a small app that before had pre-created data. const users = { [id:1, name: ... etc but I decided to go a little further and use the api https://randomuser.me that way I could at least play around with some of the Hooks that React provides.
However in my playing around it seems I've ran into an error that I cannot seem to understand. I've logged out my API call and I am getting the users back, but I'm not able to place them in the table next to it.
There is a few files so I will add them all to make it readable.
Once again the error I'm getting intially is 'users is not iterable' when I click the Add User button, as well as it showing on load up that there isn't any new users, when I can see the API call has fired and logged that it does have users pulled from the API
App.js
import React, { useEffect, useState } from 'react';
import UserTable from './tables/UserTable'
import AddUserForm from './forms/AddUserForm'
import { getUsers } from './services/getUsers.services'
const App = () => {
const [users, setUsers] = useState([])
useEffect(() => {
getUsers().then(users => {
setUsers(users);
console.log(users)
});
}, []);
const addUser = (user) => {
user.id = users.length + 1
setUsers([...users, user])
}
return (
<div className="container">
<h1> CRUD with Hooks :)</h1>
<div className="flex-row">
<div className="flex-large">
<h2>Add user</h2>
<AddUserForm addUser={addUser} />
</div>
<div className="flex-large">
<h2>View Users</h2>
<UserTable users={users} />
</div>
</div>
</div>
);
}
export default App;
getUsers.services.js
export const getUsers = async () => {
const data = await fetch('https://randomuser.me/api/?results=5');
return data.json()
}
addUserForm
import React, {useState} from 'react'
const AddUserForm = (props) => {
const initialFormState = {id: null, name: '', username: ''}
const [user,setUser] = useState(initialFormState)
const handleInputChange = (event) => {
const {name , value} = event.target
setUser({...user, [name]: value })
}
return (
<form
onSubmit={(event) => {
event.preventDefault()
if (!user.name || !user.username) return
props.addUser(user)
setUser(initialFormState)
}}
>
<label>Name</label>
<input
type='text'
name='name'
value={user.name}
onChange={handleInputChange}
/>
<label>Username</label>
<input
type='text'
name='username'
value={user.username}
onChange={handleInputChange}
/>
<button>Add New User</button>
</form>
)
}
export default AddUserForm
UserTable.js
import React from 'react'
const UserTable = (props) => (
<table>
<thead>
<tr>
<th>Name</th>
<th>Username</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{props.users.length > 0 ? (
props.users.map((user) => (
<tr key={user.id}>
<td>{user.name}</td>
<td>{user.username}</td>
<td>
<button className="button muted-button">Edit</button>
<button className="button muted-button">Delete</button>
</td>
</tr>
))
) : (
<tr>
<td colSpan={3}>No users</td>
</tr>
)}
</tbody>
</table>
)
export default UserTable

Categories