react js + reactstrap + bootstrap-select - reactjs

I'm trying to use the react + bootstrap + bootstrap-select. I've successfully changed the select dropdown to bootstrap-select but the click event's aren't getting triggered.
import React, { useEffect, useRef, createRef,forwardRef } from 'react';
import { Modal, ModalHeader, ModalBody, ModalFooter, Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap';
import $ from 'jquery';
import 'bootstrap-select/dist/js/bootstrap-select.min.js';
import 'bootstrap-select/dist/css/bootstrap-select.min.css';
const AddPModal = ({ addPModalShow, hideModal }) => {
const handleSelectPicker = ()=>{
console.log($('#add_tag').selectpicker());
}
return (
<Modal size="lg" isOpen={addPModalShow} centered={true} onOpened={handleSelectPicker}>
<ModalHeader>Add New Prospect</ModalHeader>
<ModalBody>
<Form>
<Row form>
<Col md={6}>
<FormGroup>
<Label for="add_tag">tag</Label>
<select name="tag" id="add_tag" className="form-control">
<option>1</option>
<option>2</option><option>3</option>
</select>
</FormGroup>
</Col>
</Row>
</Form>
</ModalBody>
<ModalFooter>
<Button color="primary">Save</Button>
<Button color="secondary" onClick={hideModal}>Cancel</Button>
</ModalFooter>
</Modal>
);
}
export default AddPModal;

...
<select name="tag" id="add_tag" className="form-control selectpicker">
<option>1</option>
<option>2</option><option>3</option>
</select>
...
Add selectpicker class to your select elements to auto-initialize bootstrap-select.
For more info click here

Even you can use:
useEffect(() => {
$("#mySelect").selectpicker("refresh");
}, []);
To initialize your selectpicker element (it will render properly) - it will not work as the jquery event handlers are not called (required for all functionality.
Best is to avoid jquery in your react project.

Related

how to use draftjs editor in function based components in react?

I want to work with rich text editor but I cannot find any informative documentation to use in react function base components.I used the wysiwyg editor by draftjs the text editor is shown as enter image description here
the code of the react file is
import React, { useContext, useEffect, useState } from 'react'
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import { Editor } from 'react-draft-wysiwyg';
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
import cityContext from "../context/cities/CityContext"
export default function CreatePost(props) {
// const [editorState,setState] = useState(EditorState.createEmpty());
const cities = useContext(cityContext);
let editorState = useState("");
const onEditorStateChange = () => {
// alert("here");
console.log(editorState);
}
return (
<div>
<Modal className="text-center"
{...props}
size="lg"
centered
>
<Modal.Body >
<input type="text" className="form-control my-2 p-3" placeholder='Enter title of the text'></input>
<input type="file" className="form-control my-2 p-3" placeholder='Enter title of the text'></input>
<select name="" id="" className="form-control cityField p-3 my-2" placeholder='select city'>
<option className='cityField' value="">--select city for the article--</option>
{cities.map(cityObj => <option key={cityObj.city} value="" className='cityField' >
{cityObj.city}</option>)}
</select>
<Editor className="editor"
onChange={onEditorStateChange}
/>
</Modal.Body>
<Modal.Footer>
<Button className="btn btn-danger form-control" onClick={props.onHide}>cancel</Button>
<Button className="btn btn-success form-control" onClick={props.onHide}>submit</Button>
</Modal.Footer>
</Modal>
</div>
)
}
I cannot find any solution that How I can handle the input data and how to store the input data in any variable to store the data in database.
react-draft-wysiwyg is using draft-js as core of the package and you can use this link to achieve what you want:
https://draftjs.org/docs/quickstart-api-basics#controlling-rich-text
Keep in mind that you have to create the initial state of editorState with EditorState.createEmpty()
EditorState should be available to import from react-draft-wysiwyg.

react-hook-form Controller issues

Hi im trying to do one form with react-hook-form and material-ui. I don't want to write Controller every time for all TextFields. Because of that i declare it in another file and call it in my form but its not working i didn't understand why, because in some videos that i watched is working. What is the problem and how i can fix it ?
Form Field
import React from 'react'
import { TextField, Grid } from '#material-ui/core'
import { useForm, Controller, useFormContext } from 'react-hook-form'
const FormField = ({name, label}) => {
const { control } = useForm()
return (
<Grid item xs={12} sm={6} >
<Controller
render = {({field}) =>
<TextField
{...field}
label={label} required
/>}
name={name}
control = {control}
defaultValue=""
/>
</Grid>
)
}
export default FormField
Adress Form
import React from 'react'
import { InputLabel, Select, MenuItem, Button, Grid, Typography, TextField } from '#material-ui/core'
import { useForm, FormProvider, Controller } from 'react-hook-form'
import FormField from './FormField'
import { Link } from 'react-router-dom'
const AdressForm = ({next}) => {
const {handleSubmit, control} = useForm()
return (
<>
<Typography variant="h6" gutterBottom>Shipping Address </Typography>
<form onSubmit={handleSubmit((data) => console.log(data) )}>
<Grid container spacing={3}>
<FormField name='firstName' label='First Name' required='required'/>
<FormField name='lastName' label='Last Name' />
<FormField name='email' label='Email' />
<FormField name='phoneNumber' label='Phone Number' />
</Grid>
<br/>
<div style={{ display: 'flex', justifyContent: 'space-between'}}>
<Button component={Link} to="/cart" variant="outlined">Back to Cart</Button>
<Button type="submit" variant="contained" color="primary">Next</Button>
</div>
</form>
</>
)
}
export default AdressForm
You must use one useForm hook for each form, in your code, you call useForm in every Field components, creating multiple independent form states, which leads to unexpected result.
What you need to do is to call useForm in the parent element and pass the dependencies (register, formState, error...) down the child components, so your form can have one unified state. If you have a deeply nested components, you can use useFormContext to pass the form context to the nested children easily:
import React from "react";
import { useForm, FormProvider, useFormContext } from "react-hook-form";
export default function App() {
const methods = useForm();
const onSubmit = data => console.log(data);
return (
<FormProvider {...methods} > // pass all methods into the context
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NestedInput />
<input type="submit" />
</form>
</FormProvider>
);
}
function NestedInput() {
const { register } = useFormContext(); // retrieve all hook methods
return <input {...register("test")} />;
}

How to hide a Button, Only if Value is there in Input tag in React

I am working on a React project, In my project I have one button If I click that button one
model is appearing. In that Model I have two Input tags and three buttons.
Here comes the login, In UI If Input tags have a Value then I have to hide Blue button in UI.
And If In UI If Input tags have no Value then I have to hide Red Buuton in UI this time I have
to show Blue button.
This is App.js
import React, { useState } from 'react';
import './App.css';
import Form from './Form/Form';
function App() {
const [show, setShow] = useState(false)
return (
<div className="App">
<button className='btn btn-danger'
onClick={() => setShow(true)}>Click here</button>
{ show && <Form></Form>}
</div>
);
}
export default App;
This is Form.js
import React, { useState } from 'react';
import './Form.css';
import {
Row,
Col,
Button,
ButtonGroup,
Card,
CardHeader,
CardSubtitle,
CardBody,
CardText,
Container,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
FormGroup,
Label,
Input,
UncontrolledButtonDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem
} from 'reactstrap';
const Form = () => {
const fun = () => {
}
return (
<div>
<Row>
<Col md="6" sm="6" xs="6">
<Modal
isOpen>
<ModalHeader >Add Role</ModalHeader>
<ModalBody>
<FormGroup>
<Label for="exampleName">Name</Label>
<Input
type="text"
name="name"
placeholder="Enter Your Name"
value='Tom'
/>
</FormGroup>
<FormGroup>
<Label for="exampleEmail">Description</Label>
<Input
type="textarea"
name="description"
placeholder="Enter Description"
value='React developer'
/>
</FormGroup>
</ModalBody>
<ModalFooter>
<Button color="secondary">
Cancel
</Button>
<Button className='one' color="primary">
Blue
</Button>
<Button color='danger'>Red</Button>
</ModalFooter>
</Modal>
</Col>
</Row>
</div>
)
}
export default Form
If you feel I am not clear with my doubt please put a comment.
you can check truthy value. If input has value, show 1 button and hide the other
const Form = () => {
const [value1, setValue1] = useState('');
const [value2, setValue2] = useState('');
return (
<div>
<Input
type="text"
name="name"
placeholder="Enter Your Name"
value={value1}
onChange={e => setValue1(e.target.value)}
/>
<Input
type="text"
name="value2"
placeholder="Enter Your Email"
value={value2}
onChange={e => setValue2(e.target.value)}
/>
{(!value1 || !value2) && <Button>Blue</Button>} // Show button if there is some value
{(value1 && value2) && <Button>Rad</Button>} // Show button if field is empty
</div>
);
}

How do I use component state as props in another non-child component?

I have a form inside of a component that adds items to an array when submitted using useState. I want to use these array values as options in a select input of another component. The problem is that there's not a parent-child relationship. What would be the best way to go about this?
The component generating processes array:
import React, {useState, useEffect} from 'react';
import {useForm} from 'react-hook-form';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
function AddProcessForm () {
const {register, handleSubmit, watch, errors} = useForm();
const [processes, setProcesses] = useState([]);
const onSubmit = data => {
setProcesses(processes => [...processes, data])
console.log(data)
document.getElementById("process-entry-form").reset();
}
useEffect(() =>{
console.log(processes);
})
return (
<Form id="process-entry-form" onSubmit={handleSubmit(onSubmit)}>
<Form.Group controlId="" className="mx-2">
<Form.Label>Add Process</Form.Label>
<Form.Control name="processname" type="text" placeholder="Enter Process Name" ref={register}/>
</Form.Group>
<Button variant="primary" type="submit" className="mb-2">
Submit
</Button>
</Form>
)
}
export default AddProcessForm;
The component that needs to use processes as select options:
import React from 'react';
import Form from 'react-bootstrap/Form';
function ActivitytoProcessInput () {
return (
<Form.Group controlId="" className="mx-2">
<Form.Label>Belongs to Process</Form.Label>
<Form.Control as="select">
<option value="" selected>Select a Process</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Form.Control>
</Form.Group>
)
}
export default ActivitytoProcessInput;

React - Form submit button in parent Modal

I have a Semantic UI Form:
import {Form} from 'semantic-ui-react';
<MyForm>
<Form onSubmit={_handleSubmit}>
<Form.Input name="myInput" label="My Label" value="" />
<Form.Group>
<Form.Button>Submit</Form.Button>
</Form.Group>
</Form>
</MyForm>
This form can be displayed inside a modal, or directly in a standard view in my app
My modal looks like this:
import {Button, Modal} from 'semantic-ui-react';
<Modal open={true} size="large" centered>
<Modal.Header>My Label</Modal.Header>
<Modal.Content>
<MyForm />
</Modal.Content>
<Modal.Actions>
<Button className="close-button">Cancel</Button>
{/* Insert submit button here*/}
</Modal.Actions>
</Modal>
This simple approach is working.
What I would like to do, is to have the submit button inside the Modal.Actions section when it's displayed in a modal, and keep it right after the input otherwise.
I don't know how to tell my form that the submit button is somewhere in its parent.
I finally managed to do it using a ref.
The idea is to create a ref in the form, pointing to the submit function and having a function in props to transmit this ref to my modal.
Modal:
import {Button, Modal} from 'semantic-ui-react';
const [submitFunc, setSubmitFunc] = useState();
const submitForm = () => {
if (submitFunc) {
submitFunc.current();
}
};
<Modal open={true} size="large" centered>
<Modal.Header>My Label</Modal.Header>
<Modal.Content>
<MyForm setSubmitFunc={setSubmitFunc} />
</Modal.Content>
<Modal.Actions>
<Button>Cancel</Button>
<Button onClick={submitForm}>Submit</Button>
</Modal.Actions>
</Modal>
Form:
function EditRecordForm({setSubmitFunc}) {
const submitRef = useRef(null);
useEffect(() => {
if (!!setSubmitFunc) {
setSubmitFunc(submitRef);
}
});
const handleSubmit = () => {
// Do whatever you need to retrieve form values and submit it
}
submitRef.current = handleSubmit;
return (
<MyForm>
<Form onSubmit={_handleSubmit}>
<Form.Input name="myInput" label="My Label" value="" />
<Form.Group>
<Form.Button>Submit</Form.Button>
</Form.Group>
</Form>
</MyForm>
)
}
What you can do is, you can associate the form with the button in the modal actions using a form id. Here is how you do it :-
Form:
<MyForm>
<Form id={'my-form'} onSubmit={_handleSubmit}>
{/*Form Elements}
</Form>
</MyForm>
Modal:
<Modal.Actions>
<Button>Cancel</Button>
<Button type={'submit'} form={'my-form'}>Submit</Button>
</Modal.Actions>
Following link is the tweet by the creator of chakr-ui telling the same method to join the form in a side drawer which needs to be connected to the button in the drawer footer.
https://twitter.com/thesegunadebayo/status/1330866834636201987?lang=en

Resources