How to submit the form by Material UI Dialog using ReactJS - javascript

I used the Material UI Dialog to make a form list. In the official case:
<Dialog
title="Dialog With Custom Width"
actions={actions}
modal={true}
open={this.state.open}
>
This dialog spans the entire width of the screen.
</Dialog>
the actions is :
const actions = [
<FlatButton
label="Cancel"
primary={true}
onTouchTap={this.handleClose}
/>,
<FlatButton
label="Submit"
primary={true}
onTouchTap={this.handleClose}
/>,
];
How can I build a form and let Dialog can submit my form data?
------------------------------------------------UPDATE-----------------------------------------------
There is another answer:
Add the attribute of type and form in the Dialog actions button:
const actions = [
<FlatButton
label="Cancel"
primary={true}
onTouchTap={this.handleClose}
/>,
<FlatButton
label="Submit"
primary={true}
onTouchTap={this.handleClose}
type="submit" //set the buttom type is submit
form="myform" //target the form which you want to sent
/>,
];
and give attribute id to the form in the dialog:
<Dialog
title="Dialog With Custom Width"
actions={actions}
modal={true}
open={this.state.open}
>
// here can put child component and the code still work even the form is in the child component
<div className="deal_form">
<form id="myform" onSubmit = {this.handleCreate} >
<TextField value={this.state.staff_number} />
</form>
</div>
</Dialog>

You can put a <form> inside the Dialog, but you must also put your {actions} inside the form, instead of the actions property. Your Submit action button should have type="submit" on it (type="reset" is also supported, and shown below).
jsFiddle: https://jsfiddle.net/14dugwp3/6/
const {
Dialog,
TextField,
FlatButton,
MuiThemeProvider,
getMuiTheme,
} = MaterialUI;
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { open: true };
this.handleClose = this._handleClose.bind(this);
}
_handleClose() {
this.setState({ open: false });
}
render() {
const actions = [
<FlatButton
type="reset"
label="Reset"
secondary={true}
style={{ float: 'left' }}
/>,
<FlatButton
label="Cancel"
primary={true}
onClick={this.handleClose}
/>,
<FlatButton
type="submit"
label="Submit"
primary={true}
/>,
];
return (
<Dialog
title="Dialog With Custom Width"
modal={true}
open={this.state.open}
>
<form action="/" method="POST" onSubmit={(e) => { e.preventDefault(); alert('Submitted form!'); this.handleClose(); } }>
This dialog spans the entire width of the screen.
<TextField name="email" hintText="Email" />
<TextField name="pwd" type="password" hintText="Password" />
<div style={{ textAlign: 'right', padding: 8, margin: '24px -24px -24px -24px' }}>
{actions}
</div>
</form>
</Dialog>
);
}
}
const App = () => (
<MuiThemeProvider muiTheme={getMuiTheme() }>
<Example />
</MuiThemeProvider>
);
ReactDOM.render(
<App />,
document.getElementById('container')
);

In HTML5 form="" attribute can be used as a reference to any form on a page. So button gets form="my-form-id" attribute and form gets id="my-form-id" attribute.
return (
<Dialog
open
actions={[
<RaisedButton type="submit" form="my-form-id" label="Submit" />
]}
>
<form id="my-form-id" onSubmit={handleSubmit(this.onSubmit)}>
<TextField {...fields.username} floatingLabelText="Username" />
</form>
</Dialog>
);
I use Material UI v0.20.

Dialog is a ui component of material ui, it will not submit your form data automatically, if you want to create a form, define it inside the Dialog like this:
<Dialog
title="Dialog With Custom Width"
actions={actions}
modal={true}
open={this.state.open}
>
/*CREATE THE FORM UI HERE*/
<div>Field1</div>
<div>Field2</div>
<div>Field3</div>
</Dialog>
If form contains many field then use the bool in dialog to make the content scrollable autoScrollBodyContent = {true} .
You defined a function this.handleSubmit.bind(this) on submit button click, inside this function call the api and submit the data that you want to submit, once api call is success, close the dialog box.
Please comment if this solves your issue or any other details you want.

Related

React: How to extract values from Modals?

I have a Chakra UI Modal which opens up onClick of a button. I want to be able to extract the values that a user puts into the inputs/radio buttons when they close the Modal. The Modal class and the Modal/Button render is shown below. Since the input and radio buttons are defined within the Modal class, is it possible to get their final values onClose?
Modal.tsx
import React from 'react'
import {
Modal as ChakraModal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
RadioGroup,
Stack,
Radio,
VStack
} from "#chakra-ui/react"
import Button from './Button'
import Input from './Input'
type Props = { isOpen : boolean } & { onClose : () => void} & { label : string }
const Modal = ({ label, isOpen, onClose, ...rest }: Props) => (
<ChakraModal {...rest} isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>{label}</ModalHeader>
<ModalCloseButton />
<ModalBody>
<VStack spacing={4}>
<RadioGroup>
<Stack direction="row">
<Radio value="1">Annually</Radio>
<Radio value="2">Semi-Annual</Radio>
<Radio value="3">Quarterly</Radio>
<Radio value="4">Monthly</Radio>
</Stack>
</RadioGroup>
<Input
label="Custom Interest rate"
name="Custom Interest rate"
/>
</VStack>
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={onClose}>
Save
</Button>
</ModalFooter>
</ModalContent>
</ChakraModal>
)
export default Modal
Render
<Button onClick={onOpen}> Settings </Button>
<Modal
label="Custom Settings"
isOpen={isOpen}
onClose={onClose}
/>
You should probably send a state as the modal's prop.
const [state, setState] = React.useState();
<Modal
label="Custom Settings"
isOpen={isOpen}
onClose={onClose}
onChange={setState}
/>
To get the type of setState, hover over the variable and you can see the type definition.

React Component Re-Renders when updating input using React Hooks

I'm working on a React Project. I'm building a form with about 5 fields in it. I've used React Hooks to manage the state of the updates however when I enter in an input into the field. I can see the component re-render each time I enter a key stroke. the re-render is causing issues because it sets a state of a form field back to empty. Any help would be greatly appreciated!
Thanks,
Link to a gif of the re-render on keystroke can be found here: https://gph.is/g/ZxDqzmN
Link to clearing the form field: https://gph.is/g/4LjmDpd
import React, { useState } from "react";
import styled from "styled-components";
import {
Button,
CardContent,
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
Card as MuiCard,
Paper as MuiPaper,
TextField,
} from "#material-ui/core";
import { spacing } from "#material-ui/system";
export default function EmployeeFormDialog() {
const [open, setDialog] = useState(null);
const [carName, setCarName] = useState([""]);
const onSubmit = (data, event) => {
event.preventDefault();
console.log(data);
setDialog(false);
};
console.log("re-render");
const Card = styled(MuiCard)(spacing);
const Paper = styled(MuiPaper)(spacing);
return (
<Card mb={6}>
<CardContent>
<Paper mt={4}>
<div>
<Button variant="contained" color="primary" onClick={() => setDialog(true)}>
Add New Cars
</Button>
<Dialog open={open} aria-labelledby="form-dialog-title" disableEnforceFocus="true">
<form onSubmit={onSubmit}>
<DialogTitle id="form-dialog-title">Add New Car</DialogTitle>
<DialogContent>
<DialogContentText>To add new car</DialogContentText>
<TextField
onChange={(e) => setCarName(e.target.value)}
defaultValue={carName}
name="carName"
margin="dense"
id="carName"
label="Car Name"
type="text"
fullWidth
/>
<TextField
autoFocus
name="carYear"
margin="dense"
id="carYear"
label="Car Year"
type="text"
fullWidth
/>
</DialogContent>
<DialogActions>
<Button type="button" onClick={() => setDialog(false)} color="primary">
Cancel
</Button>
<Button type="submit" color="primary">
Add Car
</Button>
</DialogActions>
</form>
</Dialog>
</div>
</Paper>
</CardContent>
</Card>
);
}

How to tigger onClick function of another component element

I created one class base component and one functional component. There are three buttons inside the functional component and I called that component to my class based component.
The functional component:
function PanelButton(props){
return (
<div>
<Button.Ripple
color="success"
type="submit"
style={{margin:"5px", width:"110px"}}
>
Submit
</Button.Ripple>
<Button.Ripple
color="primary"
id="clearButton"
type="button"
style={{margin:"5px", width:"110px"}}
>
Clear
</Button.Ripple>
<Button.Ripple color="danger" type="button" style={{margin:"5px", width:"110px"}}>
Close
</Button.Ripple>
</div>
)
}
export default PanelButton;
The class base component, in which I imported the functional component into:
import PanelButton from '../../components/customzied/PanelButton';
class TicketNew extends React.Component{
state = {
alertOption:[],
}
clickClear = () => {
console.log("ok");
}
render() {
const rqst = this.state.rquirdSate;
return (
<Card>
<Formik>
{ ({ errors, touched}) => (
<div>
<Form onSubmit={handleSubmit}>
<CardHeader>
<PanelButton />
</CardHeader>
<CardBody>
<Row />
</CardBody>
</Form>
</div>
)}
</Formik>
</Card>
)
}
}
export default TicketNew;
When I click the button(id = "clearButton") from functional component, I need to run the Click clear function in Class component.
You can pass onClick callback handlers as props to PanelButton to attach to each button's onClick prop. Pass clickClear as callback for clear button.
PanelButton
function PanelButton(props) {
return (
<div>
...
<Button.Ripple
color="primary"
id="clearButton"
type="button"
style={{ margin: "5px", width: "110px" }}
onClick={props.onClear} // <-- attach callback to button's onClick handler
>
Clear
</Button.Ripple>
...
</div>
);
}
TicketNew
class TicketNew extends React.Component {
state = {
alertOption: []
};
clickClear = () => {
console.log("ok");
};
render() {
const rqst = this.state.rquirdSate;
return (
<Card>
<Formik>
{({ errors, touched }) => (
<div>
<Form onSubmit={handleSubmit}>
<CardHeader>
<PanelButton onClear={this.clickClear}/> // <-- pass this.clickClear to onClear prop
</CardHeader>
<CardBody>
<Row></Row>
</CardBody>
</Form>
</div>
)}
</Formik>
</Card>
);
}
}
You can pass the clickClear function as props to the PanelButton component. The PanelButton code will look like the following,
function PanelButton(props){
return(
<div>
<Button.Ripple color="success" type="submit" style={{margin:"5px", width:"110px"}}>
Submit
</Button.Ripple>
<Button.Ripple color="primary" id="clearButton" onClick={props.onClickCallback} type="button" style={{margin:"5px", width:"110px"}}>
Clear
</Button.Ripple>
<Button.Ripple color="danger" type="button" style={{margin:"5px", width:"110px"}}>
Close
</Button.Ripple>
</div>
)
}
And the TicketNew code will look like this,
...
<CardHeader>
<PanelButton onClickCallback={this.clickClear.bind(this)} />
</CardHeader>
...

How can I get this React Bootstrap Modal Working properly?

I have a exercise I am working on/attempting to replicate and I am trying to add a modal button to the file. I have the button and the modal from React Bootstrap, however, I am unable to get the actual modal to show up. I was using the documentation from React-Bootstrap but getting the actual modal to come up is not working, I have tried to import the various modals but to no avail, am I missing something in my code?
import React from 'react';
import { Modal, Form, FormControl, Button, ButtonToolbar, InputGroup } from 'react-bootstrap';
import { connect } from 'react-redux';
import { addItem } from '../actions/itemActions';
function ItemModal(props) {
return (
<div>
<Button
variant="dark"
style={{marginBottom: '2em'}}
>Add Item
</Button>
<Modal
{...props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Add to Shopping List
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Label for="item">Item</Form.Label>
<InputGroup className="mb-3">
<FormControl
type="text"
name="name"
id="item"
aria-label="Add Shopping Item"
aria-describedby="basic-addon2"
/>
<InputGroup.Append>
<Button onClick={props.onHide} variant="outline-dark">Add</Button>
</InputGroup.Append>
</InputGroup>
</Form>
</Modal.Body>
</Modal>
</div>
);
}
function App() {
const [modalShow, setModalShow] = React.useState(false);
return (
<ButtonToolbar>
<Button variant="dark" onClick={() => setModalShow(true)}>
Add Item
</Button>
<ItemModal
show={modalShow}
onHide={() => setModalShow(false)}
/>
</ButtonToolbar>
);
}
export default connect()(ItemModal);
I do have this extra bit of code that I though would function to open the modal but I don't think it works with this version of Bootstrap?
state = {
modal: false,
name: ''
}
toggle = () => {
this.setState({
modal: !this.state.modal
});
};
onChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
From your code snippet, I found an issue.
You have 2 component's in a single file, App and ItemModal. From which App component is your base / parent component and ItemModal is your child component.
But you are exporting child compoennt,
export default connect()(ItemModal);
You should export the parent component,
export default connect()(App);

Would like a dialog window to open once IconFont is clicked

I am working with React and am very new to it. I have a page that has a bunch of FontIcons. I would like the user to click on an icon and have a dialog pop up. I found information on the dialog piece, http://www.material-ui.com/#/components/dialog. I have not found anything on how to make the onclick action render the dialog component.
I know I need to add something in here..
<a style={{position: 'absolute', bottom: 0, right: 0, cursor: 'pointer'}} onTouchTap={() => manageBookmark(parsedParams, this.props.documentRdxDoc.acm, this.props.documentRdxDoc.docTitle)}>
<Tooltip label='Manage Bookmark' position='right'>
<FontIcon className='material-icons' style={{color:
appConfig.globalFontColor}} tooltip="Notifications">star</FontIcon>
</Tooltip>
</a>
You need to create the dialog component itself and then show it when the FontIcon is clicked (using the onClick property).
The dialog state can be tracked using the component state object and modified via handler methods.
Here's an example based on the documentation site:
export default class DialogButtonSample extends React.Component {
state = {
open: false,
};
handleOpen = () => {
this.setState({open: true});
};
handleClose = () => {
this.setState({open: false});
};
render() {
const actions = [
<FlatButton
label="Cancel"
primary={true}
onClick={this.handleClose}
/>,
<FlatButton
label="Submit"
primary={true}
disabled={true}
onClick={this.handleClose}
/>,
];
return (
<div>
<a style={{position: 'absolute', bottom: 0, right: 0, cursor: 'pointer'}} onTouchTap={() => manageBookmark(parsedParams, this.props.documentRdxDoc.acm, this.props.documentRdxDoc.docTitle)}>
<Tooltip label='Manage Bookmark' position='right'>
<FontIcon className='material-icons' style={{color: appConfig.globalFontColor}} tooltip="Notifications" onClick={this.handleOpen}>star</FontIcon>
</Tooltip>
<Dialog
title="Dialog With Actions"
actions={actions}
modal={false}
open={this.state.open}
onRequestClose={this.handleClose}
>
</a>
</div>
);
}
}

Categories