pass onChange func props doesn't work material-ui-picker react - reactjs

It is necessary to pass from the child component of the props it is a change, but the validation of the piker disappeared and the state does not change
My Stateless Component
import { KeyboardDatePicker } from "#material-ui/pickers";
import MomentUtils from "#date-io/moment";
import { MuiPickersUtilsProvider } from "#material-ui/pickers";
const Picker = ({dateOnChange,dateOfOrdinance}) => {
<MuiPickersUtilsProvider utils={MomentUtils}>
<KeyboardDatePicker
inputVariant="outlined"
clearable
label="От:"
value={dateOfOrdinance}
onChange={dateOnChange}
format="YYYY-MM-DD"
InputAdornmentProps={{ position: "start" }}
/>
</MuiPickersUtilsProvider>
}
My parent Component
export default class Case extends Component {
state={dateOfOrdinance: new Date()}
render() {
return (
<Picker dateOnChange={(date)=>
this.setState({dateOfOrdinance: date}) />
)
}
}
If I declare it in the parent, then everything will be fine, there will be validation and the state will change

There is problems in this line,
<Picker dateOnChange={(date)=> this.setState({dateOfOrdinance: date}) />
You have not passed dateOfOrdinance as props here, do this to pass data
<Picker dateOfOrdinance={this.state.dateOfOrdinance} dateOnChange={(date)=> this.setState({dateOfOrdinance: date}) />

Related

How to custom title of weekday of Material-ui DateRangePicker

I spend almost half day but can't not found any solution to customize the title of week day of Material-ui DateRangePicker. Instead of "S", "M",..., I want to show the title as I expected.
Already tried to custom the dateAdapter but this not helps.
I see that Material-ui has component called MuiPickersUtilsProvider which I can customize the day title as I want but this component not support date-range picker.
I would highly appreciate any advices. Here is my code so far:
import * as React from 'react';
import TextField from '#mui/material/TextField';
import AdapterDateFns from '#mui/lab/AdapterDateFns';
import LocalizationProvider from '#mui/lab/LocalizationProvider';
import Box from '#mui/material/Box';
import MobileDateRangePicker from '#mui/lab/MobileDateRangePicker';
export class CustomDateFns extends AdapterDateFns {
getWeekdays() {
return ['AA', 'BB', 'CC', 'DD', 'EE', 'FF', 'GG'];
}
}
export default function ResponsiveDateRangePicker() {
const [value, setValue] = React.useState([null, null]);
return (
<LocalizationProvider dateAdapter={CustomDateFns}>
<MobileDateRangePicker
inputFormat="dd/MM/yyyy"
startText="Start date"
endText="End date"
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
clearable={!!value[0] && !!value[1] ? true : false}
clearText="Reset"
cancelText=""
okText="Confirm"
toolbarTitle=""
renderInput={(startProps, endProps) => (
<React.Fragment>
<TextField {...startProps} />
<Box sx={{ mx: 2 }}> to </Box>
<TextField {...endProps} />
</React.Fragment>
)}
/>
</LocalizationProvider>
);
}
Here is what current it shows:
What I expect is:
The only way I found until now is manipulating the DOM, then set innerHTML. But I don't think this is a good way because we can't control DOM as this is generated by library, not by me.

React admin custom input component with text input base style

I created a DateTimePicker component for my react-admin project:
import { DateTimePicker, DateTimePickerProps, MuiPickersUtilsProvider } from "#material-ui/pickers";
import { FC } from "react";
import { FieldTitle, InputProps, useInput } from "react-admin";
import MomentUtils from "#date-io/moment";
import moment from "moment";
import "moment/locale/fr";
interface DateTimeInputProps extends InputProps<DateTimePickerProps> {
label: string;
}
export const DateTimeInput: FC<DateTimeInputProps> = ({ source, label, resource, options }) => {
const {
input: { value, onChange },
isRequired,
} = useInput({ source });
return (
<MuiPickersUtilsProvider
libInstance={moment}
utils={MomentUtils}
locale='fr'
>
<DateTimePicker
label={<FieldTitle
label={label}
source={source}
resource={resource}
isRequired={isRequired}
/>}
value={value || null}
onChange={onChange}
format="llll"
ampm={false}
{...options}
/>
</MuiPickersUtilsProvider>
);
}
It works great, however the design does not follow the other classic inputs:
What is the simplest way to keep the same design across custom material-ui components?
There are 3 variants to choose from that are applied to MUI input elements: outlined, filled and standard. You need to provide DateTimePicker with inputVariant prop set to filled to get a "greyish" look. Plus you need to pass a className prop so that react-admin can pass parent controled classses (this should fix width issues).
<DateTimePicker {...props} inputVariant="filled" className={props.className} />
You can see the look of outlined, filled and standard clicking link below:
https://mui.com/components/text-fields/#basic-textfield

Prevent Chip component to send a REST request

I have the following code:
import React from 'react';
import PropTypes from 'prop-types';
import Chip from '#material-ui/core/Chip';
import withStyles from '#material-ui/core/styles/withStyles';
const styles = {
root: {
margin: 4,
},
};
function CustomChipField({ root, classes, record, onClick }) {
return (
<Chip className={classes.root} label={`${record.name}`} onClick={onClick} />
);
}
CustomChipField.propTypes = {
classes: PropTypes.shape({}).isRequired,
record: PropTypes.shape({}),
onClick: PropTypes.func.isRequired,
};
CustomChipField.defaultProps = {
record: {},
};
export default withStyles(styles)(CustomChipField);
What is it? It is a custom Chip component inheriting material-ui's chip.
But what I haven't figured out yet is why it sends REST request when I click it.
The example of such a request: http://localhost:3000/#/users/{"name"3A"whatever_name"}
I have an onClick prop overriden, and it was my attempt to override it but it doesn't do anything.
I use this component in the SingleFieldList of react-admin, and maybe the problem in react-admin but I use custom Chip component directly inherited from material-ui.
The code from react-admin:
export const UserList = props => (
<List {...props}>
<Datagrid rowClick="edit">
<TextField source="id" />
<TextField source="username" />
<ArrayField source="some_array">
<SingleFieldList>
<CustomChipField
source="name"
size="small"
clickable={true}
onClick={handleClick}
/>
</SingleFieldList>
</ArrayField>
</Datagrid>
</List>
);
And once again - onClick prop doesn't work.
So the question is: how to whether prevent Chip component sending a REST-request, whether to customize it.
This worked for me:
<SingleFieldList linkType={false}>
<CustomChipField />
</SingleFieldList>

Add text to Switch formcontrol and change it in toggle using material ui

I am using Material UI's Switch component and I want to add text inside it. Also I need to make it square in shape.
How to I add text inside the Switch component. It should say on when selected and off when default. I am using Material UI's Switch inside Formcontrol in reactjs form.
<FormControlLabel
label="Private ? "
labelPlacement="start"
control={
<Switch
checked={this.state.checked}
onChange={this.handleChange}
color='primary'
/>
}
/>
Here is an example of how to change the text based on the state of the Switch as well as the styles for a square Switch:
import React from "react";
import FormControlLabel from "#material-ui/core/FormControlLabel";
import Switch from "#material-ui/core/Switch";
import { withStyles } from "#material-ui/core/styles";
const styles = {
// use "icon" instead of "thumb" in v3
thumb: {
borderRadius: 0
}
};
class SwitchLabels extends React.Component {
state = {
checked: true
};
handleChange = event => {
this.setState({ checked: event.target.checked });
};
render() {
return (
<FormControlLabel
control={
<Switch
classes={this.props.classes}
checked={this.state.checked}
onChange={this.handleChange}
value="checked"
color="primary"
/>
}
labelPlacement="start"
label={this.state.checked ? "On" : "Off"}
/>
);
}
}
export default withStyles(styles)(SwitchLabels);

Wrapper component for admin-on-rest

I would like to create a new component that contains Inputs and Fields from aor and use it in <SimpleForm> and <TabbedForm> as below:
const WrapperComp = () => {
return (
<div>
<TextFieldLabel muiTheme={muiTheme}>Title Example</TextFieldLabel>,
<TextInput source="status"/>,
<TextField source="status"/>
</div>
)
}
<SimpleForm>
<WrapperComp />
</SimpleForm>
but I get Uncaught Error: The TextInput component wasn't called within a redux-form <Field>. Did you decorate it and forget to add the addField prop to your component?.
Any help would be appreciated. Thanks!
You need to use Field from redux-form to decorate your AOR inputs and use TextField from AOR and pass {...props} as pointed by kunal pareek
import React from 'react';
import {
LongTextInput,
ImageField,
ImageInput,
TextField
} from 'admin-on-rest';
import { Field } from 'redux-form';
const CustomGroupComp = (props) => (
<div>
<TextField source="status" {...props} />
<Field name="staffComment" component={LongTextInput} label="staffComment" {...props} />
<Field name="adminComment" component={LongTextInput} label="resources.faults.fields.adminComment" {...props} />
<Field multiple name="fileA" component={ImageInput} accept="image/*">
<ImageField source="path" title="title"/>
</Field>
</div>
);
export default CustomGroupComp;
AOR SimpleForm works by passing the Redux-Form props into its children components. Since you are wrapping up your component, those props aren't passing down to the components you need. You will need to explicitly do this now. So something like
const WrapperComp = (props) => {
return (
<div>
<TextFieldLabel {...props} muiTheme={muiTheme}>Title Example</TextFieldLabel>,
<TextInput {...props} source="status"/>,
<TextField {...props} source="status"/>
</div>
)
}

Resources