i want to disabled button if textbox null in react - javascript

return (
{jobstate.jobs.map((data,i) =>{
<form>
<input type="text" placeholder="Post a comment" onChange={(e) => jobcmthandler(e,data._id,i) } />
<button type="button" onClick={postcmt} >Send</button>
</form>
})}
)
I generate dynamic HTML using the map function and I want to disabled button if text null for induvial form and also how to get text value on button click in react js

I can't really see why you'd want to do this but here you go (example):
import React, { useState } from "react";
export default function App() {
return ["Name", "Age"].map((label) => <Form label={label} />);
}
function Form({ label }) {
const [readValue, writeValue] = useState("");
return (
<form>
<label>{label}</label>
<input
type="text"
placeholder="Post a comment"
onChange={(e) => writeValue(e.target.value)}
value={readValue}
/>
<button
type="button"
onClick={() => console.log("Submit")}
disabled={readValue === ""}
>
Send
</button>
</form>
);
}

Related

Can not set focus on checkbox in React JS

I am using react hook forms to create forms in my application:
import "./styles.css";
import { useForm } from "react-hook-form";
export default function App() {
const { register, setFocus, handleSubmit } = useForm({
defaultValues: { inputText: "", inputCheckbox: false }
});
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)} className="form">
<br />
<label>inputCheckbox</label>
<input type="checkbox" {...register("inputCheckbox")} />
<br />
<br />
<label>inputCheckbox2</label>
<input type="checkbox" {...register("inputCheckbox")} />
<button
onClick={() => {
setFocus("inputCheckbox");
}}
>
setFocus inputCheckbox
</button>
<br />
<br />
<button type="submit">Submit</button>
</form>
</div>
);
}
I try to set focus when i click on the button, but it does not work, why and how to fix using the library API?
demo: https://codesandbox.io/s/icy-feather-eh1crv?file=/src/App.js:0-899

React state change from within button's click handler is preventing form submission

Consider the code below:
function Item({name, _key})
{
console.log('rendering Item')
const [updatingName, setUpdatingName] = useState(false);
const nameInputElement = useRef();
useEffect(() => {
if (updatingName) {
nameInputElement.current.focus();
}
}, [updatingName]);
function onUpdateClick() {
setUpdatingName(true);
}
function onCancelClick() {
setUpdatingName(false);
}
return (
<div>
<input ref={nameInputElement} type="text" defaultValue={name} name="name"
disabled={!updatingName} />
{!updatingName
? <>
<button key={1} type="button" onClick={onUpdateClick}>Update</button>
<button key={2} type="submit" name="delete" value={_key}>Remove</button>
</>
: <>
<button key={3} type="submit" name="update" onClick={(e) => {setUpdatingName(false)}}>Save</button>
<button key={4} type="button" onClick={onCancelClick}>Cancel</button>
</>}
</div>
)
}
function ItemList({title})
{
return <>
<h1>{title}</h1>
<form method="post" onSubmit={(e) => {console.log('submitting');e.preventDefault()}}>
<Item name={'small'} _key={0} />
</form>
</>
}
export default ItemList;
The problem that I am facing is the click of the Save button. When it's clicked, as you can see, I trigger a state change. But at the same time, I also want the button to cause the underlying <form>'s submission.
(To check whether the form is submitted, I've prevented its default submit mechanism and instead gone with a simple log.)
However, it seems to be the case that when the state change is performed from within the onClick handler of the Save button, it ceases to submit the form. If I remove the state change from within the handler, it then does submit the form.
Why is this happening?
Live CodeSandbox demo
When you call setUpdatingName(false) in save button's click handler, the button is removed from the DOM before submitting. You can add the logic for showing the buttons in ItemList, like below:
function ItemList({ title }) {
const [updatingName, setUpdatingName] = useState(false);
return (
<>
<h1>{title}</h1>
<form
method="post"
onSubmit={(e) => {
e.preventDefault();
setUpdatingName(false);
console.log("submitting");
}}
>
<Item
name={"small"}
_key={0}
updatingName={updatingName}
setUpdatingName={setUpdatingName}
/>
</form>
</>
);
}
export default ItemList;
function Item({ name, _key, updatingName, setUpdatingName }) {
console.log("rendering Item");
const nameInputElement = useRef();
useEffect(() => {
if (updatingName) {
nameInputElement.current.focus();
}
}, [updatingName]);
function onUpdateClick() {
setUpdatingName(true);
}
function onCancelClick() {
setUpdatingName(false);
}
return (
<div>
<input
ref={nameInputElement}
type="text"
defaultValue={name}
name="name"
disabled={!updatingName}
/>
{!updatingName ? (
<>
<button key={1} type="button" onClick={onUpdateClick}>
Update
</button>
<button key={2} type="submit" name="delete" value={_key}>
Remove
</button>
</>
) : (
<>
<button key={3} type="submit" name="update">
Save
</button>
<button key={4} type="button" onClick={onCancelClick}>
Cancel
</button>
</>
)}
</div>
);
}
Also, you could use useTransition to ask React to delay the state update, so the submission happens first:
function Item({ name, _key }) {
console.log("rendering Item");
const [isPending, startTransition] = useTransition();
const [updatingName, setUpdatingName] = useState(false);
const nameInputElement = useRef();
useEffect(() => {
if (updatingName) {
nameInputElement.current.focus();
}
}, [updatingName]);
function onUpdateClick() {
setUpdatingName(true);
}
function onCancelClick() {
setUpdatingName(false);
}
return (
<div>
<input
ref={nameInputElement}
type="text"
defaultValue={name}
name="name"
disabled={!updatingName}
/>
{!updatingName ? (
<>
<button key={1} type="button" onClick={onUpdateClick}>
Update
</button>
<button key={2} type="submit" name="delete" value={_key}>
Remove
</button>
</>
) : (
<>
<button
key={3}
type="submit"
name="update"
onClick={(e) => {
startTransition(() => setUpdatingName(false));
}}
>
Save
</button>
<button key={4} type="button" onClick={onCancelClick}>
Cancel
</button>
</>
)}
</div>
);
}

Take user input and onclick button it should load url according to input in new tab in react js

I want to take city name as input and on button click it should call specific url https://www.google.com/maps/search/tourist+places+in+ mumbai with ending url with input value in react. It should open the url in new tab
Destination.jsx (file name)
import React from 'react'
const Destination = () => {
return (
<div>
<h1>Destination</h1>
<input type="text" name="place" class="form-control" id="place" placeholder="Enter place" />
<button type="Submit" id="submit"> Search </button>
</div>
)
}
export default Destination
You can do like this to search places in new tab.
import React from 'react';
const Destination = () => {
const handleSearch = (e) => {
window.open(
`https://www.google.com/maps/search/tourist+places+in+${e.target.place.value}`,
'_blank'
);
};
return (
<div>
<h1>Destination</h1>
<form onSubmit={handleSearch}>
<input
type="text"
name="place"
class="form-control"
id="place"
placeholder="Enter place"
/>
<button type="Submit" id="submit">
Search
</button>
</form>
</div>
);
};
export default Destination;
Create a state:
const [destination, setDestination] = useState("");
Then use this state to populate your search query like this:
<input type="text" name="place" class="form-control" id="place" placeholder="Enter place" value={destination} onChange={(e) => setDesitnation(e.target.value)} />
and then when you submit you can call a custom function on the onClick() of button:
<button id="submit" onClick={searchDestination}> Search </button>
The function might go somwthing like this:
const searchDestination = () => {
window.location.href = `https://www.google.com/maps/search/tourist+places+in+${destination}`;
}

react-hook-form doesn't work when using material UI button

This is my code without material UI button:
const {register, handleSubmit} = useForm();
const onSubmit = (data) => {
console.log(data)
}
const handleChange = (e) => {
console.log(e.target.files)
}
...
<form id="myFile" onSubmit={handleSubmit(onSubmit)}>
<input id="file1" type="file" {...register("file1")} onChange={handleChange}/>
<input type="submit"/>
</form>
This works for me, but when I try to add material UI button instead of input, I get onChange value but when I click submit. I don't get any form data.
const {register, handleSubmit} = useForm();
const onSubmit = (data) => {
console.log(data)
}
const handleChange = (e) => {
console.log(e.target.files)
}
...
<form id="myFile" onSubmit={handleSubmit(onSubmit)}>
<input id="file1" type="file" {...register("file1")} onChange={handleChange}
style={{display:"none"}}/>
<label htmlFor="file1">
<Button variant="contained" component="span">
Choose file
</Button>
</label>
<input type="submit"/>
</form>
Is there any solution here?
You are forget to mention the type of the button
for Default material ui button type is
type="button"
Check this git Document
you should mention
type="submit"
So do like this
<Button type="submit" variant="contained" component="span">
Choose file
</Button>
You can try something like this:
import React, { useState } from 'react';
import { Button, TextField } from '#material-ui/core';
import useForm from 'react-hook-form';
import { object, string } from 'yup';
const Form: React.FC = () => {
const schema = object().shape({
username: string().required('username required'),
password: string().required('password required'),
});
const { register, handleSubmit, errors } = useForm({ validationSchema: schema });
const onSubmit = (data: any) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextField
name="username"
error={!!errors.username}
label="Username"
helperText={errors.username ? errors.username.message : ''}
type="email"
inputRef={register}
fullWidth
/>
<TextField
name="password"
error={!!errors.password}
label="Password"
inputRef={register}
helperText={errors.password ? errors.password.message : ''}
type="password"
fullWidth
/>
<Button
color="secondary"
type="submit"
variant="contained"
fullWidth
>
Submit
</Button>
</form>
);
};
ref: How to use react-hook-form with ant design or material UI
Currently your submit event is controlled by the whole form element <form onSubmit={handleSubmit(onSubmit)}> but this is possible only when the form has a relevant submit button like <input type="submit"/> but when you use materail ui, MUI button doesnt distincts submit type even if mentioned.
So the solution is to move your onSubmit function at form to down the onClick event of your new MUI button.
The code that works is:
<Button onClick={handleSubmit(onSubmit)} type="submit" variant="contained" component="span"> Submit </Button>

React Redux Form: form is submiting with old values

I have a FieldArray in Redux Form that I push objects inside this array and right after that I have a callback to trigger a function to make a POST request.
When I submit the form I get the old values, because the push() method of the Redux Form is an async dispach from redux.
// Parent component
<FieldArray
name="myObjects"
component={ChildComponent}
onSubmitObjects={this.onSubmit} />
// Function
onSubmit = async () => {
const { getFormValues } = this.props;
const data = {
myObjects: getFormValues.myObjects
}
try {
// const contact = await Service.updateUser(data);
} catch (e) {
console.log(e)
}
}
I need to submit the form with the new values added in the array right after the push method.
// Function inside ChildComponent
addNewObject = () => {
const { fields, onSubmitObjects} = this.props;
fields.push({
number: 1,
name: 'Foo',
});
if (onSubmitObjects) {
onSubmitObjects(); // cb() to trigger a function in the parent component
}
}
Is there a way to call the callback with the new values right after the push method?
You should use a form with redux-form handleSubmit to wrap your FieldArray. You can optionally pass your custom submit function (to make API requests, submit validation, etc.) to handleSubmit so it'd look like this <form onSubmit={handleSubmit(this.onSubmit)}> ...
See this example from redux-form official docs:
FieldArraysForm.js
import React from 'react'
import {Field, FieldArray, reduxForm} from 'redux-form'
import validate from './validate'
const renderField = ({input, label, type, meta: {touched, error}}) => (
<div>
<label>{label}</label>
<div>
<input {...input} type={type} placeholder={label} />
{touched && error && <span>{error}</span>}
</div>
</div>
)
const renderHobbies = ({fields, meta: {error}}) => (
<ul>
<li>
<button type="button" onClick={() => fields.push()}>Add Hobby</button>
</li>
{fields.map((hobby, index) => (
<li key={index}>
<button
type="button"
title="Remove Hobby"
onClick={() => fields.remove(index)}
/>
<Field
name={hobby}
type="text"
component={renderField}
label={`Hobby #${index + 1}`}
/>
</li>
))}
{error && <li className="error">{error}</li>}
</ul>
)
const renderMembers = ({fields, meta: {error, submitFailed}}) => (
<ul>
<li>
<button type="button" onClick={() => fields.push({})}>Add Member</button>
{submitFailed && error && <span>{error}</span>}
</li>
{fields.map((member, index) => (
<li key={index}>
<button
type="button"
title="Remove Member"
onClick={() => fields.remove(index)}
/>
<h4>Member #{index + 1}</h4>
<Field
name={`${member}.firstName`}
type="text"
component={renderField}
label="First Name"
/>
<Field
name={`${member}.lastName`}
type="text"
component={renderField}
label="Last Name"
/>
<FieldArray name={`${member}.hobbies`} component={renderHobbies} />
</li>
))}
</ul>
)
const FieldArraysForm = props => {
const {handleSubmit, pristine, reset, submitting} = props
return (
<form onSubmit={handleSubmit}>
<Field
name="clubName"
type="text"
component={renderField}
label="Club Name"
/>
<FieldArray name="members" component={renderMembers} />
<div>
<button type="submit" disabled={submitting}>Submit</button>
<button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
</div>
</form>
)
}
export default reduxForm({
form: 'fieldArrays', // a unique identifier for this form
})(FieldArraysForm)

Categories