How can I call scrollIntoView on an ref in React - reactjs

When I call someFun, I want to make formRef visible on the screen(it is on the top of the page, I may have scrolled to the bottom when I call someFun), is there standart way to do that?
function List(props) {
const formRef = useRef(null);
const someFun = params => {
if (formRef && formRef.current) {
//error FormRef.current.scrollIntoView is not a function
formRef.current.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'start' });
}
}
}
This is the form component used in the above parent component:
it is a ant design form component:
the link is here
https://3x.ant.design/components/form/#header
import { Form, Icon, Input, Button, Checkbox } from 'antd';
class NormalLoginForm extends React.Component {
handleSubmit = e => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<Form onSubmit={this.handleSubmit} className="login-form">
<Form.Item>
{getFieldDecorator('username', {
rules: [{ required: true, message: 'Please input your username!' }],
})(
<Input
prefix={<Icon type="user" style={{ color: 'rgba(0,0,0,.25)' }} />}
placeholder="Username"
/>,
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('password', {
rules: [{ required: true, message: 'Please input your Password!' }],
})(
<Input
prefix={<Icon type="lock" style={{ color: 'rgba(0,0,0,.25)' }} />}
type="password"
placeholder="Password"
/>,
)}
</Form.Item>
<Form.Item>
{getFieldDecorator('remember', {
valuePropName: 'checked',
initialValue: true,
})(<Checkbox>Remember me</Checkbox>)}
<a className="login-form-forgot" href="">
Forgot password
</a>
<Button type="primary" htmlType="submit" className="login-form-button">
Log in
</Button>
Or register now!
</Form.Item>
</Form>
);
}
}
const WrappedNormalLoginForm = Form.create({ name: 'normal_login' })(NormalLoginForm);
ReactDOM.render(<WrappedNormalLoginForm />, mountNode);

This how you can pass the ref from your NormalLoginForm to your List component.
In your List component you need to use forwardRef because it gives the child component a reference to a DOM element created by its parent component
Example
App
import "./styles.css";
import List from "./List";
import { useRef } from "react";
export default function App() {
const targetElement = useRef();
const scrollingTop = (event) => {
const elmnt = targetElement;
elmnt.current.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "start"
});
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<p>lorem ipsum </p>
<div style={{ height: "200vh", backgroundColor: "orange" }}>
<h1>Example Form Tag </h1>
<button id="btnAppear" onClick={scrollingTop}>
Submit Scroll bottom
</button>
</div>
<List ref={targetElement} />
</div>
);
}
List
import { forwardRef } from "react";
const List = (ref) => {
return (
<div
style={{
backgroundColor: "purple",
paddingTop: "50px",
color: "white"
}}
ref={ref}
>
<h1>List View</h1>
</div>
);
};
export default forwardRef(List);
DEMO

Related

ReactJS Antd Table Rendering Old Data

Summary: I have a component that contains an Antd Table component. The Antd Table component is created initially based on the original userData that is generated using a fetch request. The data is loaded initially and set using setState(fetchedData) calling render() to display appropriately. This works.
Using the NiceModal library, I present a new modal component and pass in a doCompelte closure that will then setstate again with the updated data. From here, the render() method is called again. I log the updated userData in the render() method before the data is loaded and it shows the data is updated and it confirms that render() is called with the new data. But, the visual display never actually loads on the screen.
At this point, I stopped taking user input from the Modal and tried giving it direct values, as shown in EditModal.jsx. This still doesn't work and I'm unsure of why.
Question: Why is my component render() method called, new data printed correctly, but the React Antd Table is not loading the new data?
Note: I did try creating a local variable inside the render() method that accesses userData at that given time but this also doesn't update the table.
UPDATE 1: You can see that the first name is "Mrs." then it gets hardcode changed to "GPRLEJAF" inside the showEditModal() function which now does NOT show a modal, it just changes the value and sets the state.
You'll see that the re-rendering shows the update in the console but the table is never updated.
UserList.jsx
import React, { useEffect } from 'react';
import NiceModal, { useModal } from '#ebay/nice-modal-react';
import { Button, Table } from 'antd';
import { EditOutlined } from '#ant-design/icons';
import AddCircle from '../../../node_modules/material-jsx-icons/dist/icons/add_circle';
import { useLocation } from 'react-router-dom';
import AddModal from './AddModal'
import EditModal from './EditModal'
import "./Table.css";
import 'bootstrap/dist/css/bootstrap.min.css';
import data from '../../mock';
function search() {
}
function withMyHook(Component) {
return function WrappedComponent(props) {
const myHookValue = useLocation();
return <Component {...props} myHookValue={myHookValue} />;
}
}
class UserList extends React.Component {
constructor(props) {
super(props);
this.state = {
userData: [],
}
}
self = this;
columns = [
{
title: 'First Name',
dataIndex: 'First_Name',
width: '10%',
align: 'center',
},
{
title: 'Last Name',
dataIndex: 'Last_Name',
width: '10%',
align: 'center',
},
{
title: 'Address',
dataIndex: 'Address',
width: '20%',
align: 'center',
},
{
title: 'Billed',
dataIndex: 'Billed',
width: '5%',
align: 'center',
},
{
title: 'Work Date',
dataIndex: 'Work_Date',
width: '12%',
align: 'center',
},
{
title: 'Last Modified Date',
dataIndex: 'Table_Date',
width: '12%',
align: 'center',
},
{
title: 'Notes',
dataIndex: 'Notes',
width: '32%',
align: 'center',
},
{
title: 'Actions',
width: '5%',
align: 'center',
dataIndex: 'taco',
render: (_, value) => <Button type="link" icon={<EditOutlined />} onClick={() => this.showEditModal(value)}/>
},
];
showEditModal(value) {
/*
var index = this.userData.findIndex(item => item == value);
NiceModal.show(EditModal, { data: value, onEdit: (updatedUser) => {
this.userData[index] = updatedUser; // Update current user with updated data
this.setState([...this.userData]); // Re-Render with new data
}});
*/
this.userData[0].First_Name = "Random Name";
this.setState([this.userData]);
};
iconStyles = {
width: '25px',
fill: '#ffffff',
justifyContent: 'center',
alignItems: 'center',
float: 'left',
marginRight: '5px',
};
componentDidMount() {
console.log("Updating");
const token = this.props.myHookValue.state['token'];
console.log("Token", this.props.myHookValue.state['token']);
let response = fetch('https://x7n8z7pgo5.execute-api.us-east-1.amazonaws.com/dev', {
headers: {
"Authorization": token
}
})
.then(response => response.json())
.then(data => {
console.log("Retrieved Data", data);
this.userData = data["Items"];
console.log("User Data", this.userData);
this.setState([...data["Items"]]); //re-renders data
})
.catch(err => console.log(err));
}
showAddModal = () => {
NiceModal.show(AddModal, { component: this });;
};
render() {
const curData = this.userData;
console.log("Rerendering", curData);
return <div>
<div className="container-xl">
<div className="table-responsive">
<div className="table-wrapper">
<div className="table-title">
<div className="row">
<div className="col-sm-6">
<h2>Manage Clients</h2>
</div>
<div className="col-sm-6">
{<Button className="btn btn-success" type="primary" onClick={this.showAddModal}>
<AddCircle style={this.iconStyles}/> Add New Client
</Button>}
</div>
</div>
</div>
<input id="search" type="text" placeholder="Search..." onKeyUp={search}/>
<Table
size="small"
rowKey="id"
pagination={false}
columns={this.columns}
dataSource={curData}
style={{ marginTop: '20px' }}
/>
</div>
</div>
<div>
</div>
</div>
</div>
}
}
export default withMyHook(UserList);
EditModal.jsx
import { Modal } from 'antd';
import NiceModal, { useModal } from '#ebay/nice-modal-react';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogContentText from '#material-ui/core/DialogContentText';
import DialogTitle from '#material-ui/core/DialogTitle';
import { FilePicker, TextInput } from 'evergreen-ui';
import TextArea from 'antd/lib/input/TextArea';
import TextField from '#material-ui/core/TextField';
import { Button } from 'antd';
import React, { useState } from 'react';
function textInputStyles(height='40px') {
return {
width: '350px',
fontSize: '20px',
height: height,
}
}
export default NiceModal.create(({ data, onEdit }) => {
const user = data;
const [firstName, setFirstName] = useState(user.First_Name);
const [lastName, setLastName] = useState(user.Last_Name);
const [address, setAddress] = useState(user.Address);
const [billed, setBilled] = useState(user.Billed);
const [workDate, setWorkDate] = useState(user.Work_Date);
const [notes, setNotes] = useState(user.Notes);
const modal = useModal();
return (
<Dialog
open={modal.visible}
onClose={() => {
modal.hide();
}}
TransitionProps={{
onExited: () => modal.remove(),
}}
>
<DialogTitle id="edit">{"Edit Client"}</DialogTitle><hr></hr>
<DialogContent>
<DialogContentText id="edit_first_name">
First Name
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
defaultValue={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
</DialogContentText>
<DialogContentText id="edit_last_name">
Last Name
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
defaultValue={lastName}
onChange={(e) => setLastName(e.target.value)}
/>
</DialogContentText>
<DialogContentText id="edit_address">
Address
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
defaultValue={address}
onChange={(e) => setAddress(e)}
/>
</DialogContentText>
<DialogContentText id="edit_billed">
Billed
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
defaultValue={billed}
/>
</DialogContentText>
<DialogContentText id="edit_work_date">
Work Date
</DialogContentText>
<DialogContentText>
<TextField
id="date"
label=""
type="date"
InputLabelProps={{
shrink: true,
}}
defaultValue={new Date(workDate).toISOString().substring(0, 10)}
/>
</DialogContentText>
<DialogContentText id="edit_last_modified_date">
Today's Date
</DialogContentText>
<DialogContentText>
<TextInput
style={textInputStyles()}
value={new Date().toDateString().split(' ').slice(1).join(' ')}
editable={false}
/>
</DialogContentText>
<DialogContentText id="edit_notes">
Notes
</DialogContentText>
<DialogContentText>
<TextArea
style={textInputStyles(175)}
editable={false}
defaultValue={notes}
/>
</DialogContentText>
<DialogContentText>
Invoice
</DialogContentText>
<DialogContentText>
<FilePicker>
onClick={}
</FilePicker>
</DialogContentText>
</DialogContent>
<DialogActions style={{backgroundColor:'#D3D3D3', justifyContent: 'space-between'}}>
<Button onClick={() => modal.hide()} className="btn" style={{backgroundColor:'red', width: '25%'}}>
Cancel
</Button>
<Button onClick={() => {
modal.hide();
const updatedUser = {
'Address': 'asd',
'First_Name': 'asd',
'Billed': '123',
'Index': user.Index,
'Last_Name': 'fadsad',
'Notes': 'sdad',
'Table_Date': new Date(workDate).toISOString().substring(0, 10),
'Work_Date': workDate
};
onEdit(updatedUser);
}} className="btn" style={{backgroundColor: '#47b300', color:'white', width: '25%', float:'right'}}>
Add
</Button>
</DialogActions>
</Dialog>
);
});
Maybe here in componentDidMount and ShowEditModal (but we don't the server response format) in UserList component
componentDidMount() {
console.log("Updating");
const token = this.props.myHookValue.state['token'];
console.log("Token", this.props.myHookValue.state['token']);
let response = fetch('https://x7n8z7pgo5.execute-api.us-east-1.amazonaws.com/dev', {
headers: {
"Authorization": token
}
})
.then(response => response.json())
.then(data => {
console.log("Retrieved Data", data);
this.userData = data["Items"];
console.log("User Data", this.userData);
//this.setState([...data["Items"]]); //re-renders data
this.setState({userData: data["Items"]}); //re-renders data
//or
this.setState({...data["Items"]});
})
.catch(err => console.log(err));
}
showEditModal(value) {
var index = this.userData.findIndex(item => item == value);
NiceModal.show(EditModal, { data: value, onEdit: (updatedUser) => {
this.userData[index] = updatedUser; // Update current user with updated data
//this.setState([...this.userData]); // Re-Render with new data
this.setState({userData: this.userData});
//or
this.setState({...this.userData});
}});
};
Antd Tables require a copy of the data to be able to dynamically update the table.
render() {
if (typeof this.userData !== 'undefined') {
var copy = JSON.parse(JSON.stringify(this.userData));
console.log(copy);
return <div>
<div className="container-xl">
<div className="table-responsive">
<div className="table-wrapper">
<div className="table-title">
<div className="row">
<div className="col-sm-6">
<h2>Manage Clients</h2>
</div>
<div className="col-sm-6">
{<Button className="btn btn-success" type="primary" onClick={this.showAddModal}>
<AddCircle style={this.iconStyles}/> Add New Client
</Button>}
</div>
</div>
</div>
<input id="search" type="text" placeholder="Search..." onKeyUp={search}/>
<Table
size="small"
rowKey="id"
pagination={false}
columns={this.columns}
dataSource={copy}
style={{ marginTop: '20px' }}
/>
</div>
</div>
<div>
</div>
</div>
</div>
}
return <div>
Loading
</div>
}

Passing value of component in separate jsx file's value to event on Full-Calendar

I am new to React. I am trying to pass the value of a select box imported from a separate .jsx file to an event for full-calendar. I can't find anything on this or figure out how to do it for the life of me. This is my component for the select box in a separate file.
import React from 'react'
export const Dropdown = (props) => (
<div className="form-group">
<select
className="form-control"
name="partner"
onChange={props.onChange}
>
<option defaultValue>Select Partner</option>
{props.options.map((item, index) => (
<option key={index} value={item.value}>
{item.label}
</option>
))}
</select>
</div>
)
export default class DropdownList extends React.Component {
constructor() {
super()
this.state = {
list: [],
chosenValue: '',
}
}
componentDidMount() {
fetch('/calendar/users')
.then((response) => response.json())
.then((item) => this.setState({ list: item }))
}
onDropdownChange = (e) => {
this.setState({ chosenValue: e.target.value })
}
render() {
return (
<div className="form-group">
<Dropdown
name="partner"
id="partner"
options={this.state.list}
onDropdownChange={this.onDropdownChange}
/>
</div>
)
}
}
This is my modal that contains the form to pass through as an event to full-calendar
import React, {useState} from "react";
import Modal from "react-modal";
import DateTimePicker from "react-datetime-picker";
import 'bootstrap-icons/font/bootstrap-icons.css'
import DropdownList from "./SelectBox";
export default function ({ isOpen, onClose, onEventAdded }) {
const [title, setTitle] = useState("");
const [start, setStart] = useState(new Date());
const [end, setEnd] = useState(new Date());
const [selectValue] = useState(DropdownList);
const onSubmit = (event) => {
event.preventDefault();
onEventAdded({
title,
start,
partner: selectValue,
end
});
onClose()
};
return (
<Modal isOpen={isOpen}
onClose={onClose}
style={{
overlay: {
backgroundColor: 'rgba(0, 0, 0, 0.5)'
},
content: {
top: '50%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
transform: 'translate(-50%, -50%)',
border: '1px solid #ccc',
background: '#fff',
overflow: 'auto',
WebkitOverflowScrolling: 'touch',
borderRadius: '4px',
outline: 'none',
padding: '20px',
maxWidth: '1200px',
minHeight: '80%',
textAlign: 'center'
}
}}
>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch#4.5.2/dist/lux/bootstrap.min.css" />
<form onSubmit={onSubmit}>
<div className='form-group'>
<input className='form-control' placeholder="Title" value={title} onChange={e => setTitle(e.target.value)} />
</div>
<DropdownList />
<div className='form-group'>
<DateTimePicker name='start' value={start} onChange={date => setStart(date)} />
</div>
<div className='form-group'>
<DateTimePicker name='end' value={end} onChange={date =>setEnd(date)} />
</div>
<button className="btn btn-primary btn-block" type="submit">Add Event</button>
<button className="btn btn-danger btn-block" onClick={onClose}>Cancel</button>
</form>
</Modal>
)
}
I have tried DropdownList.value, redoing the onDropdownChange(e) function in the modal jsx file to no avail. I'm sure this is really simple and I'm getting a headache so thank you for your kindness ahead of time. I'm currently trying to use props but it's all coming up undefined.
Edit: tried to add to component in the modal file
const [partner, setPartner] = useState();
<DropdownList
ref={partnerRef}
onDropdownChange={e => setPartner(this.chosenValue = e.target.value)}
/>

React and Antd, form data destroys on fulllscreen drawer out of focus

I have tried to remove the destroy on close, use same form hook, different form hook, removed from hook, but nothing worked.
I have consoled logged the form data on show modal and close modal. Show modal has the form data but inside the log of close modal the data is reset to undefined. As soon as the modal opens the Data resets to null.
In the following code you can see the creation of Full screen modal which is made using AntDrawer:
import React, { useEffect, useState } from "react";
import FullscreenDialog from "Components/FullScreenDialog";
import Form from "Components/Form";
import { Input, Typography, Button, Space, Menu, Dropdown } from "antd";
import { PlusCircleOutlined, CloseOutlined, DownOutlined } from "#ant-design/icons";
import HeaderInput from "Components/Inputs/HeaderInput";
import Table from "Components/Table";
import styled from "styled-components";
import { Services } from "Utilities/network";
import DetailsModal from "./DetailsModal";
const RootWrapper = styled.div`
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
`;
const CreateVoucher = ({ visible, initalValue = {}, onSuccess = (e) => e, onClose = (e) => e }) => {
const [form] = Form.useForm();
const [voucherData, setVoucherData] = useState([]);
const [newModal, setNewModal] = useState(false);
const [formData, setFormData] = useState({});
const handleSubmit = async () => {
const { _id, name, header } = form.getFieldsValue(true);
if (name && header && voucherData) {
let resp = await Services.createVoucher({
_id,
name,
header,
voucherData,
});
if (resp.key) onSuccess();
}
};
if (initalValue) {
const { _id, name, header, voucherData } = initalValue;
form.setFieldsValue({
_id,
name,
header,
voucherData,
});
}
useEffect(() => {
const { voucherData } = initalValue;
if (voucherData && voucherData.length) setVoucherData(voucherData);
else setVoucherData([]);
}, [initalValue]);
const handleDelete = (index) => {
const tableData = voucherData.filter((data, dataIndex) => {
if (index !== dataIndex) return data;
return null;
});
setVoucherData(tableData);
};
return (
<>
<FullscreenDialog visible={visible} onClose={onClose}>
<FullscreenDialog.Paper>
<RootWrapper>
<Typography.Text strong style={{ fontSize: "30px" }}>
Generate Voucher
</Typography.Text>
<Form form={form}>
<Space direction="vertical" style={{ width: "100%" }}>
<Form.Item label="Voucher ID" name="name" rules={[{ required: true, message: "Please input ID" }]}>
<Input />
</Form.Item>
<HeaderInput
fieldProps={{
name: "header",
label: "Inoivce Header",
rules: [{ required: true, message: "Please select header" }],
}}
itemProps={{ placeholder: "Select Header for Voucher" }}
/>
<Space style={{ float: "right", marginTop: "20px" }}>
<Button
type="primary"
shape="round"
icon={<PlusCircleOutlined />}
onClick={() => {
setFormData(form.getFieldsValue(true));
setNewModal(true);
}}
>
Add Details
</Button>
</Space>
<Table
dataSource={voucherData}
count={voucherData?.length || 0}
columns={[
{
title: "Label",
key: "label",
dataIndex: "label",
render: (_, record) => record.label,
},
{
title: "Details",
key: "detail",
dataIndex: "detail",
render: (_, record) => record.detail,
},
{
align: "right",
render: (_, record, index) => {
return (
<Dropdown
trigger={["click"]}
overlay={
<Menu>
<Menu.Item
style={{ color: "red " }}
onClick={() => {
handleDelete(index);
}}
>
<CloseOutlined /> Delete
</Menu.Item>
</Menu>
}
>
<Button type="primary">
Edit
<DownOutlined />
</Button>
</Dropdown>
);
},
},
]}
/>
<Space style={{ float: "right", marginTop: "30px" }}>
<Button type="outline" onClick={onClose}>
Cancel
</Button>
<Button type="primary" htmlType="submit" onClick={handleSubmit}>
Submit
</Button>
</Space>
</Space>
</Form>
</RootWrapper>
</FullscreenDialog.Paper>
</FullscreenDialog>
<DetailsModal
visible={newModal}
onClose={() => {
setNewModal(false);
console.log(formData);
form.setFieldsValue({ name: "2222" });
console.log(form.getFieldsValue(true));
}}
onSuccess={(data) => {
setVoucherData([...voucherData, data]);
setNewModal(false);
form.setFieldsValue(formData);
}}
/>
</>
);
};
export default CreateVoucher;
Below is the code for modal to use another form:
import React from "react";
import { Modal, Space, Input, Button } from "antd";
import Form from "Components/Form";
import styled from "styled-components";
const RootWrapper = styled.div`
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
`;
const DetailsModal = ({ visible, onClose = (e) => e, onSuccess = (e) => e }) => {
const [form] = Form.useForm();
return (
<Modal
visible={visible}
destroyOnClose={true}
onClose={() => {
form.resetFields();
onClose();
}}
onCancel={() => {
form.resetFields();
onClose(false);
}}
title="Add Details"
footer={false}
>
<Form form={form}>
<Space direction="vertical" style={{ width: "100%" }}>
<RootWrapper>
<Form.Item name="label" label="Label" rules={[{ required: true, message: "Please input label" }]}>
<Input />
</Form.Item>
<Form.Item name="detail" label="Details" rules={[{ required: true, message: "Please input details" }]}>
<Input />
</Form.Item>
</RootWrapper>
<Space style={{ float: "right", marginTop: "20px" }}>
<Button
type="outline"
onClick={() => {
form.resetFields();
onClose();
}}
>
Cancel
</Button>
<Button
type="primary"
htmlType="submit"
onClick={() => {
const { detail, label } = form.getFieldsValue(true);
onSuccess({ detail, label });
}}
>
Submit
</Button>
</Space>
</Space>
</Form>
</Modal>
);
};
export default DetailsModal;

Menu items are not clickable after rendering Google Maps container

My semantic-ui-react Menu component is acting strange when I add my google maps component to be rendered. Before I added my MapContainer, the FilterSection was working pretty fine. But after I render the MapContainer my sections in my Menu are no longer clickable nor do they react to my mouse hover. What should I do?
Snippet of render:
return (
<div>
<Navbar/>
<FilterSection/>
<ChatWidget/>
<div className="map-and-cards">
<MapContainer/> // This line causes the problem
<div style={containerStyle} className="cards-container">
<div class="card-columns" style={{gridTemplateColumns: '350px 350px', display: 'grid', rowGap: '50px', columnGap: '18px'}}>
<Cards listingData={listingData}/>
</div>
</div>
</div>
</div>
)
and my MapContainer.js:
import React from 'react';
import { Map, GoogleApiWrapper } from 'google-maps-react';
const style = {
position: 'relative',
top: '65px',
width: '47.5%', // 47.5
height: '85%',
};
const defaultCenter = {
lat: 41.04137, lng: 28.979530
}
export class MapContainer extends React.Component<MapProps> {
render() {
return (
<Map
style = {style}
google={this.props.google}
centerAroundCurrentLocation={true}
zoom={12}
initialCenter={defaultCenter}
/>
);
}
}
export default GoogleApiWrapper({
apiKey: (0)
})(MapContainer)
FilterSection.js:
import React, { Component } from "react";
import { Menu, Dropdown, Input, Button } from "semantic-ui-react";
import 'semantic-ui-css/semantic.min.css'
export class Price extends Component {
state = { isOpen: false };
handleItemClick = (e, { name }) => this.setState({ activeItem: name });
render() {
const { activeItem } = this.state;
return (
<div style={{float: 'left'}}>
<Menu secondary >
<Menu.Item>
<Dropdown
text={"Price"}
className="item"
onClick={this.toggleOpen}
open={this.state.isOpen}
>
<Dropdown.Menu onClick={this.preventClosing}>
<Dropdown.Header icon="money" content={" Price Range"} />
<Dropdown.Divider />
<form
style = {{margin: '10px'}}
name="id"
type="number"
max={900}
action={<Button onClick={this.toggleOpen} content={"Send"} />}
>
<Input style={{zoom: '0.9'}} placeholder="min"/> — <Input style={{zoom: '0.9'}} placeholder="max"/>
</form>
</Dropdown.Menu>
</Dropdown>
</Menu.Item>
</Menu>
</div>
);
}
toggleOpen = () => this.setState({ isOpen: !this.state.isOpen });
preventClosing = e => e.stopPropagation();
}
export class BedsAndBaths extends Component {
state = { isOpen: false };
handleItemClick = (e, { name }) => this.setState({ activeItem: name });
render() {
const { activeItem } = this.state;
return (
<div style={{float: 'left'}}>
<Menu secondary>
<Menu.Item>
<Dropdown
text={"Bedrooms & Livingrooms"}
className="item"
onClick={this.toggleOpen}
open={this.state.isOpen}
>
<Dropdown.Menu onClick={this.preventClosing}>
<form
style = {{margin: '10px'}}
name="id"
type="number"
max={900}
action={<Button onClick={this.toggleOpen} content={"Send"} />}
>
<Input style={{zoom: '0.9'}} placeholder="3"/> + <Input style={{zoom: '0.9'}} placeholder="1"/>
</form>
</Dropdown.Menu>
</Dropdown>
</Menu.Item>
</Menu>
</div>
);
}
toggleOpen = () => this.setState({ isOpen: !this.state.isOpen });
preventClosing = e => e.stopPropagation();
}
export class More extends Component {
state = { isOpen: false };
handleItemClick = (e, { name }) => this.setState({ activeItem: name });
render() {
const { activeItem } = this.state;
return (
<div style={{float: 'left'}}>
<Menu secondary>
<Menu.Item>
<Dropdown
text={"More"}
className="item"
onClick={this.toggleOpen}
open={this.state.isOpen}
>
<Dropdown.Menu onClick={this.preventClosing}>
<Dropdown.Header icon="money" content={" Price Range"} />
<Dropdown.Divider />
<form
style = {{margin: '10px'}}
name="id"
type="number"
max={900}
action={<Button onClick={this.toggleOpen} content={"Send"} />}
>
<Input style={{zoom: '0.9'}} placeholder="min"/> — <Input style={{zoom: '0.9'}} placeholder="max"/>
</form>
</Dropdown.Menu>
</Dropdown>
</Menu.Item>
</Menu>
</div>
);
}
toggleOpen = () => this.setState({ isOpen: !this.state.isOpen });
preventClosing = e => e.stopPropagation();
}
export class Alert extends Component {
state = { isOpen: false };
handleItemClick = (e, { name }) => this.setState({ activeItem: name });
render() {
const { activeItem } = this.state;
return (
<div style={{float: 'left', position: 'relative', top: '11.5px', left: '15px', zoom: '0.9'}}>
<Menu secondary >
<button class="ui button ">
Create Alert
</button>
</Menu>
</div>
);
}
toggleOpen = () => this.setState({ isOpen: !this.state.isOpen });
preventClosing = e => e.stopPropagation();
}
export class Search extends Component {
state = { isOpen: false };
handleItemClick = (e, { name }) => this.setState({ activeItem: name });
render() {
const { activeItem } = this.state;
return (
<div style={{float: 'left', position: 'relative', top: '12px', right: '50px', zoom: '0.9'}}>
<Menu secondary >
<div style={{float: 'left', position: 'relative', right: '10px'}} class="ui input focus">
<input type="text" placeholder="Enter an adress, neigborhood, city, or ZIP code
" size="45"/>
</div>
<button class="ui button ">
Search
</button>
</Menu>
</div>
);
}
toggleOpen = () => this.setState({ isOpen: !this.state.isOpen });
preventClosing = e => e.stopPropagation();
}
export default function FilterSection(){
return (
<div style={{position: 'relative', left: '75px', bottom: '1px'}}><Search/><div style={{position: 'relative', right: '30px'}}><More/><BedsAndBaths/><Price/><Alert/></div></div>
)
}
As I said, only the MapContainer component is triggering the deactivation of the menu.
You can see the actual page at royaremlak.com/search

Antd Forms, get values from custom component?

I'm trying to add some custom components within getFieldDecorator and obtain the values onCreate added. Not sure how I can go about it since the state is found within the Custom components. Ideally, the custom component will handle all user input value but unsure about how to pass those values as part of the object onCreate.
import React from "react";
import { Icon, Modal, Form, Input } from "antd";
import Tags from "./EditableTagGroup";
const Taskform = Form.create({ name: "event_form" })(props => {
const { visible, onCancel, onCreate, form } = props;
const { getFieldDecorator } = form;
const handleCreate = () => {
form.validateFields((err, values) => {
if (err) {
return;
}
form.resetFields();
onCreate(values);
});
};
return (
<Modal
visible={visible}
title="Task"
closeIcon={
<Icon
type="close"
style={{ fontSize: "14px", fontWeight: "600", marginTop: "30px" }}
/>
}
okText="Create"
onCancel={onCancel}
onOk={handleCreate}
>
<Form layout="vertical">
<Form.Item label="Name">
{getFieldDecorator("name", {
rules: [
{
required: true,
message: "Please type the name of task!"
}
]
})(<Input placeholder="Write a task name" />)}
</Form.Item>
<Form.Item label="Description">
{getFieldDecorator("description")(
<Input.TextArea
style={{ minHeight: "60px" }}
autoSize={{ minRows: 3, maxRows: 6 }}
placeholder="Write a description"
/>
)}
</Form.Item>
<Form.Item>{getFieldDecorator("tags")(<Tags />)}</Form.Item>
</Form>
</Modal>
);
});
export default Taskform;
I have checked your code on sandbox. You may need to pass the props getFieldDecorator down to the EditableFormTag.js like below:
Step one: from the taskform.js
<Form.Item><Tags getFieldDecorator={getFieldDecorator} /></Form.Item>
Step two: Inside the EditableTagGroup.js
const { getFieldDecorator } = this.props;
{inputVisible &&
<Input
ref={this.saveInputRef}
onChange={this.handleInputChange}
onPressEnter={this.handleInputConfirm}
value={inputValue}
onBlur={this.handleInputConfirm}
type="text"
size="small"
style={{ width: 78 }}
/>
}
{getFieldDecorator("tags", {
initialValue: { tags }
})(
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{ display: "none" }}
/>
)
}
End result

Resources