Ionic React cannot select radio button after form error - reactjs

I have a form which is dynamically built using Ionic React and Yup for validation, this is done based on information coming from an API but I have an issue if I do not select a radio button when I press submit the radio buttons become unclickable which means I can never get the error away.
I have created an example here with a hardcoded form rather than it being populated dynamically and if you click Save without doing anything you will then not be able to select the radio buttons but I can't workout where my issue is coming from.
Link to example of my issue
Edit:
Here is the main section of code not working:
import React, { useEffect } from "react";
import { Controller, useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "#hookform/resolvers/yup";
import {
IonList,
IonRadioGroup,
IonItem,
IonLabel,
IonRadio,
IonButton,
IonContent,
IonPage,
setupIonicReact,
IonInput
} from "#ionic/react";
/* Core CSS required for Ionic components to work properly */
import "#ionic/react/css/core.css";
/* Basic CSS for apps built with Ionic */
import "#ionic/react/css/normalize.css";
import "#ionic/react/css/structure.css";
import "#ionic/react/css/typography.css";
/* Optional CSS utils that can be commented out */
import "#ionic/react/css/padding.css";
import "#ionic/react/css/float-elements.css";
import "#ionic/react/css/text-alignment.css";
import "#ionic/react/css/text-transformation.css";
import "#ionic/react/css/flex-utils.css";
import "#ionic/react/css/display.css";
/* Theme variables */
import "./theme/variables.css";
setupIonicReact();
const validationSchema = yup.object().shape({
q7: yup.string().required("selection is required")
});
export default function App() {
const {
register,
reset,
getValues,
handleSubmit,
control,
formState: { errors }
} = useForm({
resolver: yupResolver(validationSchema),
mode: "all"
});
const onSubmit = (data: any) => {
console.log(data);
};
// useEffect(() => {
// reset({
// // q7: "6"
// });
// }, [reset]);
return (
<React.Fragment>
<IonPage className="xion-page" id="main-cntent">
<IonContent className="ion-padding">
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<>
values:{getValues("name")}
<IonInput {...register("name")}></IonInput>
error:{errors["q7"]?.message}
values:{getValues("q7")}
<Controller
control={control}
name="q7"
render={({ field: { onChange, value, ref } }) => (
<>
{console.log(value)}
<IonList>
<IonRadioGroup
ref={ref}
defaultValue=""
// allowEmptySelection={true}
value={value ?? ""}
onIonChange={({ detail: { value } }) =>
onChange(value ?? "")
}
>
<IonItem>
<IonLabel>Type 2</IonLabel>
<IonRadio value="2" slot="start" />
</IonItem>
<IonItem>
<IonLabel>Type 4</IonLabel>
<IonRadio slot="start" value="4" />
</IonItem>
<IonItem>
<IonLabel>Type 6</IonLabel>
<IonRadio slot="start" value="6" />
</IonItem>
</IonRadioGroup>
</IonList>
</>
)}
/>
<br />
<IonButton type="submit">Save</IonButton>
</>
</form>
</div>
</IonContent>
</IonPage>
</React.Fragment>
);
}

Your problem is that you should pass in onChange function js event.
In onIonChange modified event with custom properties.
But you actually passed a value to the function, not an event.
You can find in docks where is standard js event in onIonChange or just setValue
<IonRadioGroup
{...field}
onIonChange={
(event) => {
setValue('q7', event.detail.value)
}
}
>
https://codesandbox.io/s/crimson-breeze-d9fptl?file=/src/App.tsx:2253-2591

Related

Why onChange event is not working properly in a dropdown when taking values as props?

I'm working on a React typescript project and need to create a dropdown with the necessary name and link to navigate as props, which will be displayed as menu items in my dropdown. But when I defined values in the same dropdown.tsx file, the onChange event worked properly. But when I received values as props, the onChange event won't work.
Here is my DropdownComponent.tsx file
import * as React from 'react';
import OutlinedInput from '#mui/material/OutlinedInput';
import MenuItem from '#mui/material/MenuItem';
import Select, { SelectChangeEvent } from '#mui/material/Select';
import SearchOutlinedIcon from '#mui/icons-material/SearchOutlined';
import { Box, Button, InputBase } from '#mui/material';
// React-Router Imports
import { Link as RouterLink } from 'react-router-dom/';
/* eslint-disable-next-line */
export interface DropdownComponentProps {
dashboardnames: Array<{
name: string,
link: string
}>,
renderDashboard:()=>void
}
export function DropdownComponent(props: DropdownComponentProps) {
const [configName, setConfigName] = React.useState<string>();
const handleChange = (event: SelectChangeEvent<typeof configName>) => {
const {
target: { value },
} = event;
setConfigName(value);
};
return (
<Box sx={{ marginTop:-5}}>
<Select
sx={{width:190,height:36}}
displayEmpty
value={configName}
onChange={handleChange}
input={<OutlinedInput />}
renderValue={(selected) => {
if (!selected) {
return <>Mushroom tunnel 1</>;
}
return selected;
}}
inputProps={{ 'aria-label': 'Without label' }}
>
<MenuItem disabled value="">
Frequently visited
</MenuItem>
<div style={{marginLeft:'20px', display:'flex'}}> <InputBase placeholder='search'/>
<div style={{marginLeft:'10px', marginRight:'10px'}}>
<Button><SearchOutlinedIcon /></Button>
</div>
</div>
{props.dashboardnames.map((page) => (
<MenuItem
component={RouterLink}
to={page.link}
key={page.name}
onClick={props.renderDashboard}
>
{page.name}
</MenuItem>
))}
</Select>
</Box>
);
}
export default DropdownComponent;
What's the mistake I've made here? Can someone help me with this issue? Thank you in advance!

How to pass value of speech recognition to text field and edit and view console in that value - reactjs

import React, { useState } from "react";
import TextField from "#mui/material/TextField";
import {} from "#fortawesome/free-solid-svg-icons";
import { Box, Chip, Grid, Typography } from "#mui/material";
import VoiceRecognice from "../component/VoiceRecognice";
import SpeechRecognition, {
useSpeechRecognition,
} from "react-speech-recognition";
import IconButton from "#mui/material/IconButton";
import MicIcon from "#mui/icons-material/Mic";
const addDream = () => {
const [story, setStory] = useState("");
console.log(story);
const {
transcript,
listening,
resetTranscript,
browserSupportsSpeechRecognition,
} = useSpeechRecognition();
if (!browserSupportsSpeechRecognition) {
return <span>Browser doesn't support speech recognition.</span>;
}
};
return (
<>
<Grid item xs={11}>
<TextField
label="Dream story"
multiline
rows={5}
fullWidth
value={transcript}
onChange={(e) => setStory(e.target.value)}
/>
</Grid>
<Grid item xs={1}>
<p>{listening ? "Mic On" : "Mic Off"}</p>
<IconButton color="primary" onClick{SpeechRecognition.startListening}>
<MicIcon />
</IconButton>
</Grid>
</>
);
export default AddDream;
I want to set browser support speech recognition value to TextField value. I want to edit that speech recognition value. In my code, didn't edit value and didn't get the input value. But transcript value is displayed in TextField.
You can use a useEffect hook to update story state with transcript value:
useEffect(() => {
setStory(transcript);
}, [transcript]);
And then in the TextField:
<TextField
label="Dream story"
multiline
rows={5}
fullWidth
value={story}
onChange={(e) => setStory(e.target.value)}
/>

How to get data React UseForm

I'm new to React and still am trying to make sense of a few things. I'm using the react-form-dom library and after looking into the documentation I can't figure out what's going on with my project.
I have created a custom input component that takes in a few parameters. The problem is that when I try to log the value of the inputs I get undefined.
Input.jsx
import React, { useState } from 'react';
import './Input.scss';
export default function Input(props, {register, errors}) {
const [inputVal, setInputVal] = useState('');
const nameChange = (e) => {
setInputVal(e.target.value);
props.nameChange(e.target.value);
}
const legend = <span className='legend'>{props?.legend}</span>;
const showLength = <span className='legend'>{props.maxLength - inputVal.length}</span>;
return (
<div className="input-holder">
<input
ref={register}
type={props.type || 'text'}
id={props.id}
placeholder={props.placeholder}
value={inputVal}
onInput={nameChange}
maxLength={props.maxLength || ""}
/>
{ props.legend ? legend : null}
{ props.showLength && props.maxLength ? showLength : null }
</div>
)
}
Form.jsx
import React from 'react';
import { useForm } from "react-hook-form";
import Button from './Button';
import Input from './Input';
export default function UserForm(props) {
const { register, handleSubmit } = useForm();
function submitForm(data) {
console.log(data)
}
return (
<div className="user-form">
<form onSubmit={handleSubmit(submitForm)}>
<Input
placeholder="Name"
nameChange={(name) => props.userName(name)}
showLength="true"
maxLength="35"
legend="Remaining Char: "
id="name"
register={register}
/>
<Input
placeholder="E-mail"
type="email"
id="email"
register={register}
/>
<Button label="Buy" />
</form>
</div>
)
}
It seems that you are using react-hook-form
Checkout the example here
The onChange you are passing to the input tags are no longer needed with react-hook-form beacuse of register functionality of react-hook-form
also validations will be done react-hook-form
import React from 'react';
import { useForm } from "react-hook-form";
export default function UserForm(props) {
const { register, handleSubmit } = useForm();
const submitForm = (data) => {
console.log(data);
}
const onError = (err) => {
console.error(err);
}
return (
<div className="user-form">
<form onSubmit={handleSubmit(submitForm, onError)}>
<input
{...register("name", { //handles onChange, value, name, ref
maxLength: 35 // Your validations
})}
/>
<button>Buy</button>
</form>
</div>
)
}
Checkout docs for register
Form File Example

React Hook Form errors not working with Chakra UI

I am trying to use ChakraUI and React-Hook-Form to create my form. However, my errors are not working. I have tried not using chakra ui but still it does not work. Here is my code:
import React from 'react'
import { useForm } from "react-hook-form";
import "./App.css"
import { Input } from "#chakra-ui/react"
import { Text } from "#chakra-ui/react"
import {
Alert,
AlertIcon,
AlertTitle,
AlertDescription,
} from "#chakra-ui/react"
function App() {
const { register, handleSubmit, errors } = useForm();
const onSubmit = data => console.log(data);
return (
<div className="app-container">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="header-container">
<Text fontSize="3xl" align="center" className="app-header">Finish the survey</Text>
</div>
<div className="email">
<Text fontSize="xl">Your Email</Text>
<Input name="email" placeholder="Your Email..." type="text" ref={register({ maxLength: { value: 23, message: "test" } })} />
{errors.email && (<span>{errors.email.message}</span>)}
</div>
</form>
</div>
)
}
export default App
Without knowing the version of the library you are using, I can't say for certain, but try changing
const { register, handleSubmit, errors } = useForm();
to
const { register, handleSubmit, formState: { errors } } = useForm();
I ran into the same problem when following their example off of the home page of the library's website and have since put in a PR.

Errors while using context for authentication in a login form (Firebase & React)

I've created a login form and accessing states through a context api. Can't seem to find a problem in my code but these errors are showing up:
Errors: 1-Legacy context API has been detected within a strict-mode tree...
2-findDOMNode is deprecated in StrictMode. findDOMNode was passed an instance of Transition which
is inside StrictMode. Instead, add a ref directly to the element you want to reference.
Code:
import React,{useContext, useState, useEffect} from 'react'
import {auth} from '../firebase/firebase';
const AuthContext= React.createContext();
export function useAuth(){
return useContext(AuthContext);
}
export function AuthProvider({children}) {
const[currentUser,setCurrentUser]= useState();
function login(email, password){
return auth.signInWithEmailAndPassword(email, password)
}
useEffect(()=>{
const unsubscriber= auth.onAuthStateChanged(user=>{
setCurrentUser(user)
})
return unsubscriber
},[])
const value={
currentUser,
login
}
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
)
}
// Login form//
import React, {useRef, useState} from 'react';
import './login.css';
import {Button, Form, FormGroup, Input, Label} from 'reactstrap';
import {useAuth} from '../../context/AuthContext'
import { Alert } from 'reactstrap';
const Login=()=> {
const emailRef = useRef();
const passwordRef=useRef();
const {login} = useAuth();
const[error,setError]=useState();
async function handlesubmit(e){
e.preventDefault()
try{
setError('')
await login(emailRef.current.value,passwordRef.current.value)
}
catch{
setError("Failed to Login")
}
}
return (
<div>
<Form className='login-form' onSubmit={handlesubmit}>
{error && <Alert color="danger">{error}</Alert>}
<h1 className='website'><span className='font-weight-bold'>ApniShop</span>.com</h1>
<FormGroup>
<label>Email</label>
<Input name='email' type='text' placeholder='Email' ref={emailRef}/>
</FormGroup>
<FormGroup>
<label>Password</label>
<Input name='password' type='password' placeholder='password' ref={passwordRef}/>
</FormGroup>
<Button className='btn-lg btn-block' outline color ="danger" type='submit'>Log in</Button>
</Form>
</div>
)
}
export default Login;

Resources