Redux-form: how can I mutate field by onSubmit - reactjs

I have to clear the Account field if I change the Partner field. How can I do this with the onSubmit event using Redux-form?
Example code:
<form onSubmit={handleSubmit}>
<BoxBlock>
<Row>
<Col md={3}>
<Field
name={FORM_FILTER_NAMES.PARTNER}
label="Partner"
placeholder="Choose a partner"
/>
</Col>
<Col md={3}>
<Field
component={MultiSelect}
name={FORM_FILTER_NAMES.ACCOUNT}
label="Account"
options={sortedAccounts}
placeholderOption="Choose account"
loaded={accountsLoaded}
isSearchable
/>
</Col>
</Row>
<div className="d-flex justify-content-between">
<Button
className="pull-right"
bsStyle="primary"
type="submit"
disabled={submitting || pristine}
>
Filter
</Button>
</div>
</BoxBlock>
</form>

Related

Antd dynamic form - how can I change form elements based on current values?

I have a dynamic Antd form where I can enter menu elements. The user can add, remove and reorder menu elements. The dynamic fields work fine, but I have a radio button for each dynamic element indicating that the corresponding menu element is an external URL or an internal page. I need to display different input elements if the user chooses URL or internal page. I tried the method listed in the Antd documentation, but it is for static fields and it doesn't seem to be working for dynamic elements.
My code so far is:
<Form.List name={"menuTree"}>
{(fields, { add, remove }) => (
<>
{fields.map((field, index) => (
<Row id={"menu-row-" + index} key={index}>
<Col span={8}>
<Form.Item label="Title" name={[field.name, "title"]} key={"title" + index + Math.random()}>
<Input />
</Form.Item>
</Col>
<Col span={4}>
<Form.Item label="Type" name={[field.name, "type"]}>
<Radio.Group>
<Radio value={"link"}>URL</Radio>
<Radio value={"page"}>Page</Radio>
</Radio.Group>
</Form.Item>
</Col>
<Col span={9}>
<Form.Item
// label="URL"
// name={[field.name, "url"]}
noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.type !== currentValues.type}>
{({ getFieldValue }) => {
return getFieldValue("type") === "link" ? (
<Form.Item name={[field.name, "url"]} label="URL">
<Input />
</Form.Item>
) : (
<Form.Item name={[field.name, "page"]} label="Page">
<Input />
</Form.Item>
)
}}
<Input />
</Form.Item>
</Col>
<Col span={2}>
<Form.Item>
<Button htmlType="button" onClick={() => moveUp(index)}>
<CaretUpOutlined />
</Button>
<Button htmlType="button" onClick={() => moveDown(index)}>
<CaretDownOutlined />
</Button>
</Form.Item>
</Col>
<Col span={1}>
<Button htmlType="button" onClick={() => removeMenuItem(index)}>
<MinusOutlined />
</Button>
</Col>
</Row>
))}
<Button type="dashed" onClick={() => addMenuItem()} block icon={<PlusOutlined />}>
Add menu item
</Button>
</>
)}
</Form.List>
How can I achieve to change the input on a per line basis whenever the user changes the value of the radio button?
You are trying to get type value with wrong name path. getFieldValue expects the complete path when you want to get any value.
You form list name is menuTree. Since it's a list, your namepath will look like this:
getFieldValue(['menuTree', field.name, 'type'])
<Form>
<Form.List name={'menuTree'}>
{(fields, { add, remove }) => (
<>
{fields.map((field, index) => (
<Row id={'menu-row-' + index} key={index}>
<Col span={8}>
<Form.Item label='Title' name={[field.name, 'title']} key={'title' + index + Math.random()}>
<Input />
</Form.Item>
</Col>
<Col span={4}>
<Form.Item label='Type' name={[field.name, 'type']}>
<Radio.Group>
<Radio value={'link'}>URL</Radio>
<Radio value={'page'}>Page</Radio>
</Radio.Group>
</Form.Item>
</Col>
<Col span={9}>
<Form.Item
noStyle
shouldUpdate={(prevValues, currentValues) =>
prevValues?.menuTree?.[field.name]?.type !== currentValues?.menuTree?.[field.name]?.type
}
>
{({ getFieldValue }) => {
return (
<>
{getFieldValue(['menuTree', field.name, 'type']) === 'link' ? (
<Form.Item name={[field.name, 'url']} label='URL'>
<Input />
</Form.Item>
) : (
<Form.Item name={[field.name, 'page']} label='Page'>
<Input />
</Form.Item>
)}
</>
);
}}
</Form.Item>
</Col>
<Col span={2}>
<Form.Item>
<Button htmlType='button' onClick={() => {}}>
<CaretUpOutlined />
</Button>
<Button htmlType='button' onClick={() => {}}>
<CaretDownOutlined />
</Button>
</Form.Item>
</Col>
<Col span={1}>
<Button htmlType='button' onClick={() => remove(field.name)}>
<MinusOutlined />
</Button>
</Col>
</Row>
))}
<Button type='dashed' onClick={() => add()} block icon={<PlusOutlined />}>
Add menu item
</Button>
</>
)}
</Form.List>
</Form>

How i can download a component or div on PDF with react JS?

I wanna download in PDF all my code inside my div in PDF . I tried a few possibilities but i always have a problem to do it .
This is what i need to download :
<div id="qrCodePdf" ref={ref}>
<Row className="backgroundTicket">
<Col>
<Row className="rowCode">
<Col>
<p className="titleName">
{localStorage.getItem("propsRestaurant")}
</p>
</Col>
<Col>
<div id="qrCodeDiv2" />
</Col>
<Col>
<img
src="/image/tipourboirePhrase.png"
className="tipPicture"
/>
</Col>
</Row>
</Col>
<Col>
<Row className="rowCode2">
<Col className="col2">
{" "}
<img src="/image/logoCode.png" className="tipPicture" />
</Col>
<Col className="col2">
<p>Juste pour un merci</p>
</Col>
</Row>
</Col>
</Row>
</div>
For the moment i used js pdf and HTML2Canvas but i always have error like ×
TypeError: Cannot read properties of null (reading 'toDataURL')
also my button
<button
className="buttonQrCode"
onClick={() => {
const canvas = document.querySelector("qrCodePdf canvas");
const image = canvas.toDataURL();
const element = document.createElement("a");
element.setAttribute("href", image);
element.setAttribute("download", "canvas.pdf");
document.body.appendChild(element);
element.click();
}}>
Télécharger le QR Code Ticket
</button>
import { exportComponentAsPDF } from "react-component-export-image";
<div id="qrCodePdf" ref={ref}>
<Row className="backgroundTicket">
<Col>
<Row className="rowCode">
<Col>
<p className="titleName">
{localStorage.getItem("propsRestaurant")}
</p>
</Col>
<Col>
<div id="qrCodeDiv2" />
</Col>
<Col>
<img
src="/image/tipourboirePhrase.png"
className="tipPicture"
/>
</Col>
</Row>
</Col>
<Col>
<Row className="rowCode2">
<Col className="col2">
{" "}
<img src="/image/logoCode.png" className="tipPicture" />
</Col>
<Col className="col2">
<p>Juste pour un merci</p>
</Col>
</Row>
</Col>
</Row>
</div>
<button
className="buttonQrCode"
onClick={() => {()=>exportComponentAsPDF(ref, { fileName: "FileName" })}>
Télécharger le QR Code Ticket
</button>

Avoid form being reset

I am trying react-hook-forms. Is there anyway to not reset the form when submitting? Everytime I click submit form is reset.
import React from "react";
import { useForm } from "react-hook-form";
import {
Row,
Col,
Card,
CardHeader,
CardBody,
Form,
FormGroup,
Label,
Input,
Button
} from "reactstrap";
const Insights = props => {
const { register, handleSubmit, watch } = useForm();
const GetSearchForm = () => {
const timePickerStyle = { width: 96, important: "true" };
const onSearch = data => {
console.log(data);
};
return (
<Form onSubmit={handleSubmit(onSearch)}>
<Row>
<Col>
<FormGroup>
<Label for="exampleEmail">Account Id</Label>
<Input
type="number"
name="account"
id="account"
placeholder="AccountId"
innerRef={register}
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Label for="examplePassword">Email</Label>
<Input
type="email"
name="email"
id="email"
placeholder="Email"
innerRef={register}
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Label for="exampleEmail">xPage Id</Label>
<Input
type="number"
name="xpageid"
id="xpage"
placeholder="xPage Id"
innerRef={register}
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Label for="examplePassword">Content Devider Id</Label>
<Input
type="number"
name="contentdevider"
id="contentdeviderid"
placeholder="Content Devider Id"
innerRef={register}
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Label for="examplePassword">Custom Page Id</Label>
<Input
type="number"
name="custompage"
id="custompageid"
placeholder="Custom Page Id"
innerRef={register}
/>
</FormGroup>
</Col>
<Col>
<FormGroup>
<Label for="examplePassword">Service</Label>
<Input
type="text"
name="servicename"
id="servicename"
placeholder="Custom Page Id"
innerRef={register}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col xs="4">
<FormGroup>
<Label for="exampleDate">Date</Label>
<Row>
<Col xs="8">
<Input
type="date"
name="date"
id="exampleDate"
placeholder="date placeholder"
innerRef={register}
/>
</Col>
<Col xs="3">
<Input
style={timePickerStyle}
type="time"
name="time"
id="exampleTime"
placeholder="time placeholder"
innerRef={register}
/>
</Col>
</Row>
</FormGroup>
</Col>
<Col xs="4">
<FormGroup>
<Label for="exampleDate">Date</Label>
<Row>
<Col xs="8">
<Input
type="date"
name="date"
id="exampleDate"
placeholder="date placeholder"
innerRef={register}
/>
</Col>
<Col xs="3">
<Input
style={timePickerStyle}
type="time"
name="time"
id="exampleTime"
placeholder="time placeholder"
innerRef={register}
/>
</Col>
</Row>
</FormGroup>
</Col>
</Row>
<Button>Submit</Button>
</Form>
);
};
return (
<Row>
<Col xs="12" lg="12">
<Card>
<CardHeader>
<i className="fa fa-align-justify"></i> Insights
</CardHeader>
<CardBody>
<GetSearchForm></GetSearchForm>
</CardBody>
</Card>
</Col>
</Row>
);
};
export default Insights;
Because GetSearchForm is its own component, it gets created every time Insights is being rerendered.
You call the register function with the innerRef, but since the Input changed, and it is not the same component (newly created), its getting newly registered, which resets the state.
You either can move the useForm to the GetSearchForm and pass the data back up on submit or inline the whole form in Insights.

Reactstrap InputGroup resposive Issue in mobile view

I'm using InputGroup component from reactstrap inside a modal. In Desktop view it looks fine but Mobile view Like this:
Code:
<Row>
<Col xs='2'>
<span>Price(s)</span>
</Col>
<Col xs='10'>
<PriceInput
cats={this.state.cats}
/>
</Col>
</Row>
price input and description fields are add as another component , so i can add more than one price to it
PriceInput Code
<Row>
<Col xs='3'>
<InputGroup
className={'form-group'}>
<InputGroupAddon addonType="prepend">{props.symbol}
</InputGroupAddon>
<Input
type="text"
placeholder='0.00'/>
</InputGroup>
</Col>
<Col xs='7'>
<Input
type="text"
placeholder='description'/>
</Col>
<Col xs='2'>
<Button >
<i color={'red'}
className='zmdi zmdi-delete'>
</i>
</Button>
</Col>
</Row>
How can i set Price and Price symbol wrap together?
change your xs props to xl it will work

How to pass information from a form into a function in react

I have a login model with the following login function:
login() {
console.log("Hello. It's Me")
axios.post('https://crossorigin.me/http://requestb.in/w21igbw2', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
//this.setState({ showModal: false });
})
.catch(function (error) {
console.log(error);
});
}
this is working fine, so how I do change this to send the actual data from the login form instead of just the hardcoded info in the function. The input in the login model this is what the full form looks like:
<form>
<FormGroup >
<Row>
<Col md={12}>
<input className="col-md-10 col-md-offset-1 top-space fat-input" placeholder="Email"/>
<input className="col-md-10 col-md-offset-1 top-space fat-input" placeholder="Password"/>
</Col>
</Row>
<Row className='top-space'>
<Col md={5} mdOffset={1}>
<Checkbox className="checkbox-login"> Remember Me </Checkbox>
</Col>
<Col md={6} className='forgot-password'>
Forgot Password
</Col>
</Row>
<Row className='top-space'>
<Col md={10} mdOffset={1}>
<Button onClick={this.login} bsStyle="btn btn-black btn-block">Login</Button>
</Col>
</Row>
</FormGroup>
</form>
You can keep track of inputs in you state and when you fire API read the values from the state.
constructor(){
super()
this.state = {
email : null,
password : null,
}
onChangeEmail(){
this.setState({email: e.target.value});
}
onChangePassword(){
this.setState({password: e.target.value});
}
login(){
//api call with state values for id and pass
}
render(){
<form>
<FormGroup >
<Row>
<Col md={12}>
<input className="col-md-10 col-md-offset-1 top-space fat-input" placeholder="Email" onChange={this.onChangeEmail}/>
<input className="col-md-10 col-md-offset-1 top-space fat-input" placeholder="Password" onChange={this.onChangePassword}/>
</Col>
</Row>
<Row className='top-space'>
<Col md={5} mdOffset={1}>
<Checkbox className="checkbox-login"> Remember Me </Checkbox>
</Col>
<Col md={6} className='forgot-password'>
Forgot Password
</Col>
</Row>
<Row className='top-space'>
<Col md={10} mdOffset={1}>
<Button onClick={this.login} bsStyle="btn btn-black btn-block">Login</Button>
</Col>
</Row>
</FormGroup>
</form>
}
}
P.S: I would strongly suggest using redux with react and using redux-form to handle you forms. It has been the best way I have found till now to handle forms in react-redux app. You can check it out here.

Resources