I'm trying to use the MUI toggle group with React Hook Form however I can't get the value to post when submitting the form. My toggle group component looks like this:
import FormatAlignCenterIcon from '#material-ui/icons/FormatAlignCenter';
import FormatAlignLeftIcon from '#material-ui/icons/FormatAlignLeft';
import FormatAlignRightIcon from '#material-ui/icons/FormatAlignRight';
import FormatAlignJustifyIcon from '#material-ui/icons/FormatAlignJustify';
import ToggleButton from '#material-ui/lab/ToggleButton';
import ToggleButtonGroup from '#material-ui/lab/ToggleButtonGroup';
import React from 'react';
import {Controller} from "react-hook-form";
export default function TestToggleGroup(props) {
const {control} = props;
const [alignment, setAlignment] = React.useState('left');
const handleAlignment = (event) => {
setAlignment(event[1]);
};
return (
<Controller
name="ToggleTest"
as={
<ToggleButtonGroup
value={alignment}
exclusive
onChange={handleAlignment}
aria-label="text alignment"
>
<ToggleButton value="left" aria-label="left aligned" key="left">
<FormatAlignLeftIcon/>
</ToggleButton>
<ToggleButton value="center" aria-label="centered" key="center">
<FormatAlignCenterIcon/>
</ToggleButton>
<ToggleButton value="right" aria-label="right aligned" key="right">
<FormatAlignRightIcon/>
</ToggleButton>
<ToggleButton value="justify" aria-label="justified" disabled key="justify">
<FormatAlignJustifyIcon/>
</ToggleButton>
</ToggleButtonGroup>
}
value={alignment}
onChange={(e) => {
handleAlignment(e);
}}
valueName={"alignment"}
control={control}
/>
);
}
Not sure exactly what I'm doing wrong but any assistance would be greatly appreciated.
My workaround was using an effect to manually set the value using setValue and then using getValues() inside your handleSubmit function to get the values.
const { control, setValue } = props;
//Effect
React.useEffect(() => {
setAlignment('ToggleTest', alignment);
}, [alignment, setAlignment]);
Related
I got TextField to work, now the Material UI Select will turn red if no selection is made but stays red after selection is made and won't let form submit. I'm using Yup as validation library.Maybe I keep using wrong Yup type I try String and array but I can't get it to work.
import {
makeStyles,
Box,
Select,
FormControl,
InputLabel,
MenuItem,
Typography,
} from "#material-ui/core";
import * as yup from 'yup';
import { yupResolver } from '#hookform/resolvers'
import { useForm, Controller } from "react-hook-form";
const FormFields = ({ typeOfInquiry, typeOfProviderSupplier, feedbackform }) => {
const schema = yup.object().shape({
typeofInquiry: yup.array().nullable().required(),
});
const { handleSubmit, control, reset, errors } = useForm();
return (
<Controller
style={{ minWidth: 220 }}
name="typeofInquiry"
render ={({ field: { ...field }, fieldState })=>{
console.log(props)
return ( <Select {...field} >
{typeOfInquiry.map((person) => (
<MenuItem key={person.value} value={person.value} >
{person.label}
</MenuItem>
))}
</Select>
)
}}
control={control}
defaultValue=" "
/>
<Typography className={classes.red}>{errors.typeofInquiry?.message}</Typography>
</FormControl>
</form>
);
}
You've to pass the ref to the TextField component.
Here is a working example
👉🏻 https://codesandbox.io/s/exciting-pateu-3n0i9
You should do something similar with Select.
Some examples with MUI: https://codesandbox.io/s/react-hook-form-v7-controller-5h1q5?file=/src/Mui.js
I am trying to update my react native app to fetch data from the backend every few seconds. Below is my code where I want the data in the transaction history table to update automatically. What is the best way to do this?
import React from 'react';
import PropTypes from 'prop-types';
import { View, StyleSheet, ActivityIndicator, Text, FlatList } from 'react-native';
import TransactionShape from '../../data/model-shapes/Transaction';
import TransactionListItem from '../../components/wallets/TransactionListItem';
import CardStyles from '../../utils/styling/Cards';
import Colors from '../../utils/styling/Colors';
const keyExtractor = ({ id }) => id;
function renderTransactionItem({ item: transaction }) {
return <TransactionListItem transaction={transaction} />;
}
const TransactionHistorySection = ({ transactions, isFetching }) => {
return (
<View style={CardStyles.sectionCard}>
{isFetching ? (
<ActivityIndicator size="large" />
) : (
<View>
<Text style={styles.sectionHeading}>Transaction History</Text>
{transactions.length ? (
<FlatList
data={transactions}
keyExtractor={keyExtractor}
renderItem={renderTransactionItem}
/>
) : (
<Text style={styles.growContainer}>No Transactions</Text>
)}
</View>
)}
</View>
);
};
You coud use a setInterval(function(){ fetch_something }, 3000);
function to run the function to fetch your data on interval you want. then whenever the data change your flatlist will shown the new data
I know that with an InputField one is able to pass down the variant="filled" prop to get input box filled. However, is it also possible to pass down a prop with the similar effect using a Material UI date picker (not using the native datepicker from the browser)?
Example of filled input:
I think you are looking for inputVariant={"filled"} prop
import "date-fns";
import React from "react";
import Grid from "#material-ui/core/Grid";
import DateFnsUtils from "#date-io/date-fns";
import {
MuiPickersUtilsProvider,
KeyboardTimePicker,
KeyboardDatePicker
} from "#material-ui/pickers";
export default function MaterialUIPickers() {
// The first commit of Material-UI
const [selectedDate, setSelectedDate] = React.useState(
new Date("2014-08-18T21:11:54")
);
const handleDateChange = date => {
setSelectedDate(date);
};
return (
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Grid container justify="space-around">
<KeyboardDatePicker
inputVariant={"filled"}
disableToolbar
variant="inline"
format="MM/dd/yyyy"
margin="normal"
id="date-picker-inline"
label="Date picker inline"
value={selectedDate}
onChange={handleDateChange}
KeyboardButtonProps={{
"aria-label": "change date"
}}
/>
</Grid>
</MuiPickersUtilsProvider>
);
}
Working sandbox project link
The #material-ui/pickers has been moved to the #mui/lab.
Checkout the migration guide Here !
Below is a sample code to implement the same
import React from "react";
import TextField from "#mui/material/TextField";
import AdapterDateFns from "#mui/lab/AdapterDateFns";
import LocalizationProvider from "#mui/lab/LocalizationProvider";
import DatePicker from "#mui/lab/DatePicker";
export default function filledDatePicker() {
const [selectedDate, setSelectedDate] = React.useState(new Date());
const handleDateChange = date => {
setSelectedDate(date);
};
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
value={selectedDate}
onChange={handleDateChange}
renderInput={(props) => (
<TextField {...props} variant="filled" label="Select Date" />
)}
/>
</LocalizationProvider>
);
}
I have a react app that uses package mui-datatables. I want to be redirected to "/edit-form" onRowClick, but it didn't work (nothing happens, no errors either).
import React, { Component } from "react";
import { Link as RouterLink } from "react-router-dom";
import Link from "#material-ui/core/Link";
import MUIDataTable from "mui-datatables";
class DataTable extends Component {
state={...}
redirectToForm = props => <RouterLink to="/edit-form" {...props}/>
render() {
const options = {
onRowClick: rowData => this.redirectToForm(rowData)
};
return (
<Link
color="secondary"
className={classes.button}
component={this.goToDetailedTable}
>
Detail
</Link>
<MUIDataTable
title={title}
columns={value.state.columnName}
data={value.state.rowData}
options={options}
/>
)
}
When I console.log(rowData), it did print out the row data:
const options = {
onRowClick: rowData => console.log(rowData)
};
Instead of using <Link/> try calling history from the history package and then just history.push('edit/form').
The RTL demo provided in material ui guides seems does not work for components.
As they said in the Right-to-left guide internally they are dynamically enabling jss-rtl plugin when direction: 'rtl' is set on the theme but in the demo only the html input is rtl and TextField isn't.
Here's the demo code from https://material-ui-next.com/guides/right-to-left/#demo
import React from 'react';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import TextField from 'material-ui/TextField';
const theme = createMuiTheme({
direction: 'rtl', // Both here and <body dir="rtl">
});
function Direction() {
return (
<MuiThemeProvider theme={theme}>
<div dir="rtl">
<TextField label="Name" />
<input type="text" placeholder="Name" />
</div>
</MuiThemeProvider>
);
}
export default Direction;
Once you have created a new JSS instance with the plugin, you need to
make it available to all components in the component tree. JSS has a
JssProvider component for this:
import { create } from 'jss';
import rtl from 'jss-rtl';
import JssProvider from 'react-jss/lib/JssProvider';
import { createGenerateClassName, jssPreset } from '#material-ui/core/styles';
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
// Custom Material-UI class name generator.
const generateClassName = createGenerateClassName();
function RTL(props) {
return (
<JssProvider jss={jss} generateClassName={generateClassName}>
{props.children}
</JssProvider>
);
}