I am using React-Select in my first React App and I am not sure how to handle multiple selects in one form.
Is there anyway to pass props into the ReactSelect.jsx file so that I can have multiple selects in one form, each with their own attributes/data?
What is the proper way to deal with this?
Ref: Experimental Popout
App.js
import React from 'react';
import ReactSelect from './ReactSelect'
function App() {
return (
<ReactSelect name="select1" placeholder="Select 1" label="Select 1" data={} />
<ReactSelect name="select2" placeholder="Select 2" label="Select 2" data={} />
<ReactSelect name="select3" placeholder="Select 3" label="Select 3" data={} />
);
}
export default App;
ReactSelect.jsx
/** #jsx jsx */
import { Component } from 'react';
import { jsx } from '#emotion/core';
import Button from '#atlaskit/button';
import CreatableSelect from 'react-select/creatable';
import { defaultTheme } from 'react-select';
const { colors } = defaultTheme;
const selectStyles = {
control: provided => ({ ...provided, minWidth: 240, margin: 8 }),
menu: () => ({ boxShadow: 'inset 0 1px 0 rgba(0, 0, 0, 0.1)' }),
};
const State = {
isOpen: false,
options: [{ [""]: "" }],
value: "",
isLoading: false,
};
const createOption = (label = "") => ({
value: label.toLowerCase().replace(/\W/g, ''),
label,
});
const groupStyles = {
width: '100%',
textAlign: 'left',
borderRadius: 4,
backgroundColor: 'white',
border: '1px solid #ced4da',
};
const options=[
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two' },
{ value: 'three', label: 'Three' },
];
export default class ReactSelect extends Component {
state = {
isOpen: false,
options: options,
value: undefined,
isLoading: false,
};
toggleOpen = () => {
this.setState(state => ({ isOpen: !state.isOpen }));
};
onSelectChange = value => {
this.toggleOpen();
this.setState({ value });
console.log(value.value);
};
handleCreate = (inputValue = "") => {
this.setState({ isLoading: true });
setTimeout(() => {
const { options } = this.state;
const newOption = createOption(inputValue);
const newOptions = [...options, newOption];
newOptions.sort((a, b) =>
a.value.localeCompare(b.value)
);
this.setState(state => ({
isOpen: false,
options: newOptions,
value: newOption
}));
this.setState({ isLoading: false });
}, 1000);
}
render() {
const { isOpen, options, value, isLoading } = this.state;
return (
<Dropdown
isOpen={isOpen}
onClose={this.toggleOpen}
target={
<Button
iconAfter={<ChevronDown />}
onClick={this.toggleOpen}
isSelected={isOpen}
style={groupStyles}>
{value ? `Location: ${value.label}` : 'Select a Location'}
</Button>
}>
<CreatableSelect
backspaceRemovesValue={false}
components={{ DropdownIndicator, IndicatorSeparator: null }}
controlShouldRenderValue={true}
hideSelectedOptions={false}
isClearable={true}
menuIsOpen
isLoading={isLoading}
isDisabled={isLoading}
onChange={this.onSelectChange}
onCreateOption={this.handleCreate}
options={options}
placeholder="Search..."
styles={selectStyles}
tabSelectsValue={false}
value={value} />
</Dropdown>
);
}
}
// styled components
const Menu = props => {
const shadow = 'hsla(218, 50%, 10%, 0.1)';
console.log(props);
return (
<div
css={{
backgroundColor: 'white',
borderRadius: 4,
boxShadow: `0 0 0 1px ${shadow}, 0 4px 11px ${shadow}`,
marginTop: 8,
position: 'absolute',
zIndex: 2,
width:'100%',
}}
{...props}
/>
);
};
const Blanket = props => (
<div
css={{
bottom: 0,
left: 0,
top: 0,
right: 0,
position: 'fixed',
zIndex: 1,
}}
{...props}
/>
);
const Dropdown = ({ children, isOpen, target, onClose }) => (
<div css={{ position: 'relative' }}>
{target}
{isOpen ? <Menu>{children}</Menu> : null}
{isOpen ? <Blanket onClick={onClose} /> : null}
</div>
);
The following seems to work for me...
this.props.name
this.props.placeholder
this.props.data
Example: To set the placeholder
{value ? `${this.props.placeholder} ${value.label}` : this.props.placeholder}
Related
I have created a dropdown menu in react using the react-select package, The dropdown menu is working as as expected, now I want to change the option value automatically after some seconds. After some seconds it should select another option from the option array, which option I want from the option array option.
import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import Select, { components } from "react-select";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faCircle, faMinusCircle } from "#fortawesome/fontawesome-free-solid";
import "./presence.css";
function Presence() {
const [presence, setPresence] = useState({
value: "unavailable",
label: "Offline",
icon: <FontAwesomeIcon icon={faCircle} color="gray" />,
});
console.log(presence);
const client = useSelector((state) => state.client.client);
const handleChange = (selectedOption) => {
setPresence(selectedOption.label);
console.log(`Option selected:`, selectedOption);
};
const { Option, SingleValue } = components;
const CustomSelectOption = (props) => (
<Option {...props}>
<div style={{ display: "inline-block", marginRight: "5%" }}>
{props.data.icon}{" "}
</div>
<div style={{ display: "inline-block" }}> {props.data.label}</div>
</Option>
);
const ValueOption = (props) => (
<SingleValue {...props}>
<span style={{ marginRight: "8%" }}> {props.data.icon}</span>
<span>{props.data.label}</span>
</SingleValue>
);
const options = [
{
value: "chat",
label: "Available",
icon: <FontAwesomeIcon icon={faCircle} color="#5cd068" />,
},
{
value: "xa",
label: "Appear Away",
icon: <FontAwesomeIcon icon={faCircle} color="orange" />,
},
{
value: "away",
label: "Be Right Back",
icon: <FontAwesomeIcon icon={faCircle} color="orange" />,
},
{
value: "dnd",
label: "Do not Disturb",
icon: <FontAwesomeIcon icon={faMinusCircle} color="red" />,
},
{
value: "unavailable",
label: "Offline",
icon: <FontAwesomeIcon icon={faCircle} color="gray" />,
},
];
const style = {
control: (base) => ({
...base,
border: 0,
boxShadow: "none",
}),
placeholder: (base) => ({
...base,
fontSize: "1em",
fontWeight: 600,
}),
};
const DropdownIndicator = (props) => {
return (
components.DropdownIndicator && (
<components.DropdownIndicator {...props}>
<FontAwesomeIcon
icon={props.selectProps.menuIsOpen ? "caret-up" : "caret-down"}
/>
</components.DropdownIndicator>
)
);
};
return (
<Select
styles={style}
name="presence"
clearable={false}
placeholder={"Choose"}
onChange={handleChange}
options={options}
classNamePrefix="select"
components={{
Option: CustomSelectOption,
SingleValue: ValueOption,
DropdownIndicator: DropdownIndicator,
IndicatorSeparator: () => null,
}}
/>
);
}
export default Presence;
If you want to execute some code after the first render only, use useEffect(() => {}, []) (notice the empty array), to execute once after 5 seconds, call the setTimeout in the callback like this:
useEffect(() => {
setTimeout(() => {
handlerChange(options.find(o => o.value === 'chat'));
}, 5000);
}, []);
You have no value defined on your <Select>
You have no getOptionValue or getOptionLabel defined (though it's probably using the defaults)
If presence were your value, all it would require is the selectedOption.value
Since presence appears to be defaulted to unavailable, then your initial value would never be away
You are rebuilding a lot of stuff on every rerender of Presence, which will force rerender your <Select> every time.
You are defaulting your presence to "unavailable", so it would never start as "away"
Maybe you're saying you will change the value by loading some record on component load. In that situation, you would put your window.setTimeout in that method. I put some notes on that in the comments below.
Refactored Presence.js:
import React, { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import Select, { components } from "react-select";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faCircle, faMinusCircle } from "#fortawesome/fontawesome-free-solid";
import "./presence.css";
const { Option, SingleValue, DropdownIndicator } = components;
const CustomSelectOption = (props) => {
const {
data: { icon: Icon, label }
} = props;
return (
<Option {...props}>
<div style={{ display: "inline-block", marginRight: "5%" }}>
<Icon />{" "}
</div>
<div style={{ display: "inline-block" }}> {label}</div>
</Option>
);
};
const ValueOption = (props) => {
const {
data: { icon: Icon, label }
} = props;
return (
<SingleValue {...props}>
<span style={{ marginRight: "8%" }}>
{" "}
<Icon />
</span>
<span>{label}</span>
</SingleValue>
);
};
const Indicator = (props) => {
const icon = props.selectProps.menuIsOpen ? "caret-up" : "caret-down";
return (
<DropdownIndicator {...props}>
<FontAwesomeIcon
icon={icon}
/>
</DropdownIndicator>
);
};
const Separator = () => null;
const options = [
{
value: "chat",
label: "Available",
icon: <FontAwesomeIcon icon={faCircle} color="#5cd068" />
},
{
value: "xa",
label: "Appear Away",
icon: <FontAwesomeIcon icon={faCircle} color="orange" />
},
{
value: "away",
label: "Be Right Back",
icon: <FontAwesomeIcon icon={faCircle} color="orange" />
},
{
value: "dnd",
label: "Do not Disturb",
icon: <FontAwesomeIcon icon={faMinusCircle} color="red" />
},
{
value: "unavailable",
label: "Offline",
icon: <FontAwesomeIcon icon={faCircle} color="gray" />
}
];
const style = {
control: (base) => ({
...base,
border: 0,
boxShadow: "none"
}),
placeholder: (base) => ({
...base,
fontSize: "1em",
fontWeight: 600
})
};
const getLabel = (option) => option.label;
const getValue = (option) => option.value;
function Presence() {
const [presence, setPresence] = useState("unavailable");
console.log(presence);
const client = useSelector((state) => state.client.client);
/**
* Let's say you include some other process to 'set' `presence`,
* like loading some record or something. The you could 'init'ialize
* your component by then adding your timeout. You can't really do
* this alone in a `useEffect`, as you defaulted the value, which
* would trigger your effect.
*
window.setTimeout(() => {
// make sure to check that current value again, in case
// someone changed it in that 5 seconds
setPresence(prev => prev === 'away' ? 'chat' : prev);
}, 5000);
*/
const handleChange = (selectedOption) => {
setPresence(selectedOption?.value);
console.log(`Option selected:`, selectedOption);
};
return (
<Select
styles={style}
name="presence"
isClearable={false}
placeholder={"Choose"}
onChange={handleChange}
options={options}
classNamePrefix="select"
components={{
Option: CustomSelectOption,
SingleValue: ValueOption,
DropdownIndicator: Indicator,
IndicatorSeparator: Separator
}}
getOptionLabel={getLabel}
getOptionValue={getValue}
value={presence}
/>
);
}
export default Presence;
I'm trying to convert EditableTabGroup to a functional component Tags however I can't seem to convert it correctly as I'm trying to remove this. .
EditableTabGroup is working correctly but when I render Tags in Taskform it does not work.
Also, how can I clear state Tags so that onCreate(submit) tags is an empty array?
class EditableTagGroup extends React.Component {
state = {
tags: [],
inputVisible: false,
inputValue: ""
};
handleClose = removedTag => {
const tags = this.state.tags.filter(tag => tag !== removedTag);
console.log(tags);
this.setState({ tags });
};
showInput = () => {
this.setState({ inputVisible: true }, () => this.input.focus());
};
handleInputChange = e => {
this.setState({ inputValue: e.target.value });
};
handleInputConfirm = () => {
const { inputValue } = this.state;
let { tags } = this.state;
if (inputValue && tags.indexOf(inputValue) === -1) {
tags = [...tags, inputValue];
}
console.log(tags);
this.setState({
tags,
inputVisible: false,
inputValue: ""
});
};
saveInputRef = input => (this.input = input);
forMap = tag => {
const tagElem = (
<Tag
closable
onClose={e => {
e.preventDefault();
this.handleClose(tag);
}}
>
{tag}
</Tag>
);
return (
<span key={tag} style={{ display: "inline-block" }}>
{tagElem}
</span>
);
};
render() {
const { tags, inputVisible, inputValue } = this.state;
const tagChild = tags.map(this.forMap);
const { getFieldDecorator } = this.props;
return (
<div>
<div style={{ marginBottom: 16 }}>
<TweenOneGroup
enter={{
scale: 0.8,
opacity: 0,
type: "from",
duration: 100,
onComplete: e => {
e.target.style = "";
}
}}
leave={{ opacity: 0, width: 0, scale: 0, duration: 200 }}
appear={false}
>
{tagChild}
</TweenOneGroup>
</div>
{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: this.state.tags
})(
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{ display: "none" }}
/>
)}
{!inputVisible && (
<Tag
onClick={this.showInput}
style={{ background: "#fff", borderStyle: "dashed" }}
>
<Icon type="plus" /> New Tag
</Tag>
)}
</div>
);
}
}
export default EditableTagGroup;
So, 2 things that I changed in order to make it work:
1) You didn't export Tags from its file. In this example I exported it as a named export, but you should probably just export it as default export (export default Tags).
2) The second problem was in this part of the code:
const handleInputConfirm = () => {
if (inputValue && state.indexOf(inputValue) === -1) {
let state = [...state, inputValue];
}
setState(state);
setInputVisible(false);
setInputValue("");
};
Inside the if condition, where you check current tags and the tag the user wants to add, you define a let "state". There are 2 problems here. The first one is that you're assigning a let inside an if block, which means that its not accessible from outside of the block, hence the line setState(state) is just setting the state to the same state (state refers to the state variable state, not to the new state you defined inside the if block).
The second problem is not really a problem, you just shouldn't assign new variables with names identical to variables in the upper scopes. It's bad practice as you probably understand now.
Read more about let and its scope rules here.
Here is the full working code of Tags:
import React, { useState } from "react";
import { Tag, Input, Icon } from "antd";
import { TweenOneGroup } from "rc-tween-one";
export const Tags = props => {
const [state, setState] = useState([]);
const [inputVisible, setInputVisible] = useState(false);
const [inputValue, setInputValue] = useState("");
const handleClose = removedTag => {
const tags = state.filter(tag => tag !== removedTag);
setState(tags);
};
const showInput = () => {
setInputVisible(true);
};
const handleInputChange = e => {
setInputValue(e.target.value);
};
const handleInputConfirm = () => {
if (inputValue && state.indexOf(inputValue) === -1) {
var newState = [...state, inputValue];
setState(newState);
}
setInputVisible(false);
setInputValue("");
};
const saveInputRef = input => (input = input);
const forMap = tag => {
const tagElem = (
<Tag
closable
onClose={e => {
e.preventDefault();
handleClose(tag);
}}
>
{tag}
</Tag>
);
return (
<span key={tag} style={{ display: "inline-block" }}>
{tagElem}
</span>
);
};
const tagChild = state.map(forMap);
const { getFieldDecorator } = props;
return (
<div>
<div style={{ marginBottom: 16 }}>
<TweenOneGroup
enter={{
scale: 0.8,
opacity: 0,
type: "from",
duration: 100,
onComplete: e => {
e.target.style = "";
}
}}
leave={{ opacity: 0, width: 0, scale: 0, duration: 200 }}
appear={false}
>
{tagChild}
</TweenOneGroup>
</div>
{inputVisible && (
<Input
ref={saveInputRef}
onChange={handleInputChange}
onPressEnter={handleInputConfirm}
value={inputValue}
onBlur={handleInputConfirm}
type="text"
size="small"
style={{ width: 78 }}
/>
)}
{getFieldDecorator("tags", {
initialValue: state.tags
})(
<Input
ref={saveInputRef}
type="text"
size="small"
style={{ display: "none" }}
/>
)}
{!inputVisible && (
<Tag
onClick={showInput}
style={{ background: "#fff", borderStyle: "dashed" }}
>
<Icon type="plus" /> New Tag
</Tag>
)}
</div>
);
};
As for resetting the tags, you can define the state state inside Taskform.js and pass it to Tags as props. That way you can reset the state (setState([])) on Taskform.js.
Taskform.js:
const [tags, setTags] = useState([]);
const handleCreate = () => {
form.validateFields((err, values) => {
if (err) {
return;
}
form.resetFields();
onCreate(values);
setTags([]);
});
};
...
<Tags
getFieldDecorator={getFieldDecorator}
state={tags}
setState={setTags}
/>
Tags.js:
...
const { state, setState } = props;
Of course you should also remove [state, setState] = useState([]) from Tags.js.
Hope it helps!
how can i set pagination arrows to be enabled even there is no data or even if i'll use a condition to switch disable/enablePagination Arrows
import React from 'react';
import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet';
import { NavLink } from 'react-router-dom';
import Truncate from 'react-truncate';
// Material-UI
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
import AddIcon from '#material-ui/icons/Add';
import EditIcon from '#material-ui/icons/Edit';
import MaterialTable, { MTableToolbar, TablePagination } from 'material-table';
import IconButton from '#material-ui/core/IconButton';
import Tooltip from '#material-ui/core/Tooltip';
import Typography from '#material-ui/core/Typography';
import Zoom from '#material-ui/core/Zoom';
// Components
import Entity from '~/Components/Entity';
import violationsStyles from './styles';
import Strings from '~/Services/Strings';
// Services
import Navigate from '~/Services/Navigate';
#withStyles(violationsStyles)
class Violations extends React.Component {
state = {
data : [],
pageIndex: 0,
pageSize: 1,
totalCount: 0
}
componentDidMount() {
this.get();
}
get() {
const { pageIndex, pageSize } = this.state;
this.entity.get({ pageIndex, pageSize });
}
get options() {
return {
actionsColumnIndex: -1,
pageSize: 10,
filtering: true,
columnsButton: true,
maxBodyHeight: 550,
doubleHorizontalScroll: true,
headerStyle: {
color: '#434343',
fontSize: 13
}
};
}
get localization() {
return {
header: {
actions: '',
},
body: {
emptyDataSourceMessage: Strings.listEmptyLabel,
},
pagination: {
labelRowsPerPage: Strings.rowsPerPageLabel,
labelDisplayedRows: `{from}-{to} ${Strings.fromText} {count}`,
},
toolbar: {
addRemoveColumns: Strings.addRemoveColumns,
showColumnsTitle: Strings.showColumnsTitle
},
};
}
get columns() {
const { classes } = this.props;
return [
{ title: Strings.violationReferenceNumber, field: 'referenceNumber', cellStyle: { width: 110 } },
{
title: Strings.violationDescription,
field: 'description',
render: rowData => (
<Typography>
<Truncate lines={1} ellipsis={<span>... </span>}>
{rowData.description}
</Truncate>
</Typography>
),
cellStyle: { paddingLeft: 0 }
},
{ title: Strings.violationPenalty,
field: 'penaltyTypeId',
lookup: {
1: Strings.inform,
2: Strings.alert,
3: Strings.suspension,
},
cellStyle: { width: '120px' }
},
{
title: Strings.violationStatus,
field: 'isArchived',
lookup: {
false: Strings.violationIsNotSettled,
true: Strings.violationIsSettled,
},
cellStyle: { width: '130px' },
defaultFilter: [ 'false' ]
},
{
title: Strings.listActionsLabel,
field: 'isArchived',
render: rowData => (
<div className={classes.iconWrapper}>
<Choose>
<When condition={rowData.isArchived === 'true'}>
<Tooltip TransitionComponent={Zoom} title={Strings.violationEditActionOn}>
<span>
<IconButton disabled={rowData.isArchived === 'true'}>
<EditIcon fontSize="default"/>
</IconButton>
</span>
</Tooltip>
</When>
<Otherwise>
<IconButton disabled={rowData.isArchived === 'true' ? true : false} onClick={() => Navigate.go(`/violations/editor/${rowData.id}`)}>
<Tooltip TransitionComponent={Zoom} title={Strings.violationListEditLabel}>
<EditIcon fontSize="default"/>
</Tooltip>
</IconButton>
</Otherwise>
</Choose>
</div>
),
filtering: false,
cellStyle: { paddingLeft: 35, paddingRight: 75, textAlign: 'left', justifyContent: 'flex-end', display: 'flex' },
headerStyle: { paddingLeft: 35, textAlign: 'left', }
},
];
}
get components() {
const { classes } = this.props;
return {
Toolbar: props => (
<div className={classes.toolbar}>
<MTableToolbar {...props} />
<div className={classes.customActionsBar}>
<Button component={NavLink} to={'/violations/editor'} variant={'outlined'} color={'primary'}>
<AddIcon className={classes.rightIcon} />
{Strings.addNewViolation}
</Button>
</div>
<div className={classes.tabelSecondHeader}>
<Typography variant='h6'>
{Strings.listOfViolations}
</Typography>
</div>
</div>
),
Pagination: props => (
<TablePagination {...props}
count={this.state.totalCount}
/>
),
};
}
onEntityReceived(data) {
const arr = data.result;
const mutableList = [];
if(arr && arr.length > 0) {
arr.map(item => {
mutableList.push({
...item,
isArchived: item.isArchived.toString()
});
});
this.setState({
data: mutableList,
totalCount: data.totalCount
});
}
}
render() {
const { data } = this.state;
return (
<React.Fragment>
<Helmet>
<title>
{Strings.violationsManegment}
</title>
</Helmet>
<Entity
storeId={'Supervision-Violations'}
entityRef={ref => { this.entity = ref; }}
onEntityPosted={() => this.onEntityPosted()}
onEntityReceived={data => this.onEntityReceived(data)}
render={store => (
<MaterialTable
title={Strings.violationsManegment}
data={data}
isLoading={store.loading}
options={this.options}
localization={this.localization}
columns={this.columns}
components={this.components}
onChangePage={pageIndex => this.setState({ pageIndex })}
onChangeRowsPerPage={pageSize => this.setState({ pageSize })}
/>
)}
/>
</React.Fragment>
);
}
}
Violations.propTypes = {
classes: PropTypes.object,
};
export default Violations;
i need to update the count of table because i'm getting the data from back-end and i'm using server side pagination technique and it appears that the total counts automatically be the total rows received unless i mutated it to be be total count that i received from endpoint because i receive some data per page
Use nextIconButtonProps={{disabled:false}} and backIconButtonProps={{disabled:false}}
could you try using the override that is explained here https://material-table.com/#/docs/features/component-overriding.
Use the code above to try to find a way of that you want. Right now there isnt a property that you can do that in a easy way.
components={{
Pagination: props => (
<TablePagination
{...props}
rowsPerPageOptions={[5, 10, 20, 30]}
rowsPerPage={this.state.numberRowPerPage}
count={this.state.totalRow}
page={
firstLoad
? this.state.pageNumber
: this.state.pageNumber - 1
}
onChangePage={(e, page) =>
this.handleChangePage(page + 1)
}
onChangeRowsPerPage={event => {
props.onChangeRowsPerPage(event);
this.handleChangeRowPerPage(event.target.value);
}}
/>
),
}}
I am creating timer component and implement with every task. So when I start my timer for a single task then other task timer will be disabled or hidden. I am trying to disable other timer component on start timer but it gives me only value for current component. So how can I update all components when I start a single timer?
DeveloperTasks.js
import { Mutation, Query } from "react-apollo";
import gql from "graphql-tag";
import React, { Component, Fragment } from "react";
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import TaskTimer from "./TaskTimer";
import Note from "./Note";
import getCDTime from "../util/commonfunc";
import Button from "#material-ui/core/Button";
import IconButton from "#material-ui/core/IconButton";
import Paper from "#material-ui/core/Paper";
import List from "#material-ui/core/List";
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
import CircularProgress from "#material-ui/core/CircularProgress";
import Avatar from "#material-ui/core/Avatar";
import FormControl from "#material-ui/core/FormControl";
import InputLabel from "#material-ui/core/InputLabel";
import Select from "#material-ui/core/Select";
import MenuItem from "#material-ui/core/MenuItem";
import TextField from "#material-ui/core/TextField";
import Dialog from "#material-ui/core/Dialog";
import MuiDialogTitle from "#material-ui/core/DialogTitle";
import MuiDialogContent from "#material-ui/core/DialogContent";
import MuiDialogActions from "#material-ui/core/DialogActions";
import Popover from "#material-ui/core/Popover";
import DeleteIcon from "#material-ui/icons/Delete";
import AssignmentIcon from "#material-ui/icons/Assignment";
import NotesIcon from "#material-ui/icons/EventNote";
import AssignmentInd from "#material-ui/icons/AssignmentInd";
import CheckCircleOutline from "#material-ui/icons/CheckCircleOutline";
import CheckCircle from "#material-ui/icons/CheckCircle";
import CloseIcon from "#material-ui/icons/Close";
import Typography from "#material-ui/core/Typography";
import EditIcon from "#material-ui/icons/Edit";
import DateFnsUtils from "#date-io/date-fns";
import {
MuiPickersUtilsProvider,
TimePicker,
DatePicker
} from "material-ui-pickers";
import UserList from "../components/UserList";
import emails from "../components/UserList";
import TodoInlineForm from "../components/TodoInlineForm";
const ms = require("pretty-ms");
//Kanban Quearies
export const tasksQuery = gql`
query Developertasklist($contact_id_c: String) {
Developertasklist(contact_id_c: $contact_id_c) {
id
name
due_date
dtask_start_time
time_tracking_flag
dtask_total_time
status
}
}
`;
//Delete Task Mutation
export const DELETE_TODO = gql`
mutation todo_operations($id: String, $deleted: String) {
todo_operations(id: $id, deleted: $deleted) {
id
}
}
`;
//Complete Task Mutation
const COMPLETE_TASK_OPERATIONS = gql`
mutation todo_operations(
$id: String
$status: String
$actual_due_date: String
) {
todo_operations(
id: $id
status: $status
actual_due_date: $actual_due_date
) {
id
}
}
`;
const styles = theme => ({
root: {
width: "100%",
marginTop: theme.spacing(3),
overflowX: "auto"
},
icon: {
margin: theme.spacing.unit,
fontSize: 20
},
button: {
margin: theme.spacing.unit
},
listroot: {
width: "100%",
minWidth: 900,
backgroundColor: theme.palette.background.paper
},
tasklist: {
marginTop: 30
},
taskwidth: {
width: "55%",
display: "inline-flex"
},
timerwidth: {
width: "25%"
},
width5: {
width: "5%"
},
margin: {
margin: theme.spacing.unit
},
input: {
display: "none"
},
datepadding: {
"padding-right": "10px;",
width: "17%"
},
formControl: {
minWidth: 120
},
elementpadding: {
"padding-right": "10px;"
},
completeIcon: {
color: "Green"
},
popover: {
pointerEvents: "none"
},
label: {
display: "inline",
padding: ".2em .6em .3em",
"font-size": "75%",
"font-weight": "700",
"line-height": 1,
color: "#fff",
"text-align": "center",
"white-space": "nowrap",
"vertical-align": "baseline",
"border-radius": ".25em"
},
labelcomplete: {
"background-color": "#5cb85c"
},
labelprogress: {
"background-color": "#5bc0de"
},
labelonhold: {
"background-color": "#d9534f"
},
labelqafail: {
"background-color": "#d9534f"
},
labelnotstated: {
"background-color": "#777"
},
labelqa: {
"background-color": "#337ab7"
},
labelqapassed: {
"background-color": "#777"
},
labeldefered: {
"background-color": "#f0ad4e"
},
hideelement: {
display: "none"
},
showelement: {
display: "block"
}
});
const DialogTitle = withStyles(theme => ({
root: {
borderBottom: `1px solid ${theme.palette.divider}`,
margin: 0,
padding: theme.spacing.unit * 2
},
closeButton: {
position: "absolute",
right: theme.spacing.unit,
top: theme.spacing.unit,
color: theme.palette.grey[500]
}
}))(props => {
const { children, classes, onClose } = props;
return (
<MuiDialogTitle disableTypography className={classes.root}>
<Typography variant="h6">{children}</Typography>
{onClose ? (
<IconButton
aria-label="Close"
className={classes.closeButton}
onClick={onClose}
>
<CloseIcon />
</IconButton>
) : null}
</MuiDialogTitle>
);
});
const DialogContent = withStyles(theme => ({
root: {
margin: 0,
padding: theme.spacing.unit * 2
}
}))(MuiDialogContent);
const DialogActions = withStyles(theme => ({
root: {
borderTop: `1px solid ${theme.palette.divider}`,
margin: 0,
padding: theme.spacing.unit
}
}))(MuiDialogActions);
class DeveloperTasks extends React.Component {
state = {
start_date: new Date(),
end_date: new Date(),
status: "",
task: "",
searchTerm: "",
open: false,
anchorEl: null,
selectedValue: emails[1],
openreport: false,
openTodoForm: false,
taskid: ""
};
constructor(props) {
super(props);
this.searchUpdated = this.searchUpdated.bind(this);
}
handleDateChange = name => date => {
this.setState({ [name]: date });
};
handleChange = name => event => {
this.setState({ [name]: event.target.value });
};
handleClickOpen = name => event => {
this.setState({
open: true
});
};
handleClose = () => {
this.setState({ open: false });
};
handleClickDialogOpen = () => {
this.setState({ openreport: true });
};
handleDialogClose = value => {
this.setState({ selectedValue: value, openreport: false });
};
searchUpdated(term) {
this.setState({ searchTerm: term });
}
handlePopoverOpen = event => {
this.setState({ anchorEl: event.currentTarget });
};
handlePopoverClose = () => {
this.setState({ anchorEl: null });
};
handleClickTodoOpen(taskid) {
this.setState({ taskid: taskid, openTodoForm: true });
}
componentWillReceiveProps(newProps) {
this.setState({ openTodoForm: newProps.open });
}
render() {
let todoinlineform = "";
const { classes, contact_id } = this.props;
const { anchorEl } = this.state;
const open = Boolean(anchorEl);
let currdatetime = getCDTime.getCurrentDateTime();
let shownbutton = {
display: "block"
};
if (
this.state.openTodoForm &&
this.state.openTodoForm === true &&
this.state.taskid != ""
) {
todoinlineform = (
<TodoInlineForm
open={this.state.openTodoForm}
taskid={this.state.taskid}
modaltitle="Edit Todo"
/>
);
}
return contact_id === "" ? (
""
) : (
<Query query={tasksQuery} variables={{ contact_id_c: contact_id }}>
{({ loading, error, data: { Developertasklist } }) => {
if (error) return <p>{error}</p>;
if (loading) return <CircularProgress className={classes.progress} />;
//Filter with task name
if (this.state.task && this.state.task != "") {
Developertasklist = Developertasklist.filter(
developertasklist =>
developertasklist.name
.toLowerCase()
.indexOf(this.state.task.toLowerCase()) != -1
);
}
//Task status wise filter
if (this.state.status && this.state.status != "") {
Developertasklist = Developertasklist.filter(
developertasklist => developertasklist.status == this.state.status
);
}
//Label array for apply class on status label
let labelcolor = [
{ status: "In Progress", class: classes.labelprogress },
{ status: "Completed", class: classes.labelcomplete },
{ status: "On Hold", class: classes.labelonhold },
{ status: "QA Fail", class: classes.labelqafail },
{ status: "Not Started", class: classes.labelnotstated },
{ status: "QA", class: classes.labelqa },
{ status: "QA Passed", class: classes.labelqapassed },
{ status: "Deferred", class: classes.labeldefered }
];
return (
<Fragment>
<br />
<div className={classes.tasklist}>
<div className="picker">
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<DatePicker
label="Start Date"
name="start_date"
value={this.state.start_date}
format="yyyy-MM-dd"
onChange={this.handleDateChange("start_date")}
className={classes.datepadding}
animateYearScrolling
/>
<DatePicker
label="End Date"
name="end_date"
value={this.state.end_date}
format="yyyy-MM-dd"
onChange={this.handleDateChange("end_date")}
className={classes.datepadding}
animateYearScrolling
/>
</MuiPickersUtilsProvider>
<Button
type="submit"
variant="contained"
color="primary"
className={classes.button}
>
Search
</Button>
<Button
variant="contained"
color="secondary"
className={classes.button}
>
Reset
</Button>
</div>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="status-simple">Status</InputLabel>
<Select
value={this.state.status}
onChange={this.handleChange("status")}
className={classes.elementpadding}
inputProps={{
name: "status",
id: "status"
}}
>
<MenuItem value="">
<em>Please Select</em>
</MenuItem>
<MenuItem value="Not Started">Not Started</MenuItem>
<MenuItem value="In Progress">In Progress</MenuItem>
<MenuItem value="On Hold">On Hold</MenuItem>
<MenuItem value="Deferred">Deferred</MenuItem>
<MenuItem value="Completed">Completed</MenuItem>
<MenuItem value="QA">QA</MenuItem>
<MenuItem value="QA Passed">QA Passed</MenuItem>
<MenuItem value="QA Fail">QA Fail</MenuItem>
</Select>
</FormControl>
<TextField
id="standard-name"
label="Task"
className={classes.textField}
value={this.state.task}
onChange={this.handleChange("task")}
/>
</div>
<div className={classes.tasklist}>
<Paper className={classes.listroot}>
<List className={classes.listroot}>
{Developertasklist.map((task, index) => {
let statusLabel = labelcolor.filter(
obj => obj.status == task.status
);
let completeStatusClass = classes.hideelement;
let pendingStatusClass = "";
let hidetimer = "";
if (task.status === "Completed") {
pendingStatusClass = classes.hideelement;
hidetimer = "hide";
completeStatusClass = "";
}
if (statusLabel.length > 0)
statusLabel = statusLabel[0].class;
return (
<ListItem key={index} divider="true">
<div className={classes.taskwidth}>
<Avatar>
<AssignmentIcon />
</Avatar>
<ListItemText
primary={
<React.Fragment>
{task.name} - {task.due_date}
</React.Fragment>
}
secondary={
<React.Fragment>
<Typography
component="span"
className={[classes.label, statusLabel]}
color="textPrimary"
>
{task.status}
</Typography>
</React.Fragment>
}
/>
</div>
<div className={classes.timerwidth}>
<div>
<TaskTimer
developerlist={task}
hidetimer={hidetimer}
/>
</div>
</div>
<div className={classes.width5}>
<EditIcon
onClick={event => {
this.handleClickTodoOpen(task.id);
}}
/>
</div>
<div className={classes.width5}>
<Mutation mutation={COMPLETE_TASK_OPERATIONS}>
{(todo_operations, { loading, error }) => (
<CheckCircleOutline
className={pendingStatusClass}
aria-owns={
open ? "mouse-over-popover" : undefined
}
aria-haspopup="true"
onMouseEnter={this.handlePopoverOpen}
onMouseLeave={this.handlePopoverClose}
onClick={event => {
todo_operations({
variables: {
id: task.id,
actual_due_date: currdatetime,
status: "Completed"
}
});
}}
/>
)}
</Mutation>
<Popover
id="mouse-over-popover"
className={classes.popover}
classes={{
paper: classes.paper
}}
open={open}
anchorEl={anchorEl}
anchorOrigin={{
vertical: "bottom",
horizontal: "left"
}}
transformOrigin={{
vertical: "top",
horizontal: "left"
}}
onClose={this.handlePopoverClose}
disableRestoreFocus
>
<Typography>Mark as completed.</Typography>
</Popover>
<CheckCircle
className={[
classes.completeIcon,
completeStatusClass
]}
/>
</div>
<div className={classes.width5}>
<div className={pendingStatusClass}>
{/* <Typography variant="subtitle1">
Selected: {this.state.selectedValue}
</Typography> */}
<AssignmentInd
onClick={this.handleClickDialogOpen}
/>
<UserList
selectedValue={this.state.selectedValue}
open={this.state.openreport}
onClose={this.handleDialogClose}
/>
</div>
</div>
<div className={classes.width5}>
<NotesIcon onClick={this.handleClickOpen()} />
<Dialog
onClose={this.handleClose}
aria-labelledby="customized-dialog-title"
open={this.state.open}
>
<DialogTitle
id="customized-dialog-title"
onClose={this.handleClose}
>
Notes
</DialogTitle>
<DialogContent>
<Note />
</DialogContent>
</Dialog>
</div>
<div className={classes.width5}>
<Mutation mutation={DELETE_TODO}>
{(todo_operations, { loading, error }) => (
<DeleteIcon
aria-label="Delete"
onClick={event => {
todo_operations({
variables: {
id: task.id,
deleted: "1"
}
});
}}
/>
)}
</Mutation>
</div>
</ListItem>
);
})}
</List>
</Paper>
</div>
{todoinlineform}
</Fragment>
);
}}
</Query>
);
}
}
export default withStyles(styles, { withTheme: true })(DeveloperTasks);
TaskTimer.js
import { Mutation, Query } from "react-apollo";
import gql from "graphql-tag";
const React = require("react");
const ms = require("pretty-ms");
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import StartIcon from "#material-ui/icons/PlayCircleFilled";
import StopIcon from "#material-ui/icons/Stop";
import getCDTime from "../util/commonfunc";
//Start timer mutation
const TODO_OPERATIONS = gql`
mutation todo_operations(
$id: String
$status: String
$dtask_start_time: String
$time_tracking_flag: String
$developer_daily_hours: String
$is_task_started: String
$actual_start_date: String
) {
todo_operations(
id: $id
status: $status
dtask_start_time: $dtask_start_time
time_tracking_flag: $time_tracking_flag
developer_daily_hours: $developer_daily_hours
is_task_started: $is_task_started
actual_start_date: $actual_start_date
) {
id
}
}
`;
//Stop timer mutation
const STOP_TIMER = gql`
mutation todo_operations(
$id: String
$dtask_stop_time: String
$dtask_total_time: String
$time_tracking_flag: String
) {
todo_operations(
id: $id
dtask_stop_time: $dtask_stop_time
dtask_total_time: $dtask_total_time
time_tracking_flag: $time_tracking_flag
) {
id
}
}
`;
const styles = theme => ({
button: {
margin: theme.spacing.unit
},
stopbutton: {
margin: theme.spacing.unit,
color: "Red"
},
input: {
display: "none"
},
clock: {
color: "Green",
fontWeight: "700",
fontSize: "15px"
},
hideelement: {
display: "none"
},
timerClass: {
display: "none"
}
});
class TaskTimer extends React.Component {
constructor(props) {
const total_time = !props.developerlist.dtask_total_time
? parseInt(0)
: parseInt(props.developerlist.dtask_total_time);
let statetime = total_time;
let stateison = false;
super(props);
if (props.developerlist.time_tracking_flag === "yes") {
let currentdatetime = new Date(getCDTime.getCurrentDateTime());
let start_time = new Date(props.developerlist.dtask_start_time);
let time_diff = Math.abs(currentdatetime - start_time) / 1000;
statetime = time_diff + total_time;
stateison = true;
this.state = {
time: statetime,
isOn: stateison
};
this.startTimer();
}
this.state = {
time: statetime,
isOn: stateison,
timerClass: "test"
};
this.startTimer = this.startTimer.bind(this);
this.stopTimer = this.stopTimer.bind(this);
}
startTimer(next) {
this.setState({
isOn: true,
time: this.state.time,
timerClass: "abc"
});
this.timer = setInterval(
() =>
this.setState({
time: parseInt(this.state.time + 1)
}),
1000
);
}
stopTimer() {
this.state.time = parseInt(this.state.time);
this.setState({ isOn: false });
clearInterval(this.timer);
}
render() {
let totalTaskTime = parseInt(this.state.time) * 1000;
const { classes, theme } = this.props;
let hideTimerClass =
this.props.hidetimer === "hide" ? classes.hideelement : "";
let currdatetime = getCDTime.getCurrentDateTime();
let start =
(this.state.time == 0 || this.state.time > 0) && this.state.isOn == 0 ? (
<Mutation mutation={TODO_OPERATIONS}>
{(todo_operations, { loading, error }) => (
<StartIcon
variant="contained"
color="primary"
className={[
classes.button,
hideTimerClass,
this.state.timerClass
]}
//className={this.state.timerClass}
onClick={event => {
this.startTimer();
todo_operations({
variables: {
id: this.props.developerlist.id,
status: "In Progress",
dtask_start_time: currdatetime,
time_tracking_flag: "yes",
developer_daily_hours: dailyhours,
is_task_started: "yes",
actual_start_date: currdatetime
}
});
}}
/>
)}
</Mutation>
) : null;
let stop =
this.state.isOn && this.state.isOn == 1 ? (
<Mutation mutation={STOP_TIMER}>
{(todo_operations, { loading, error }) => (
<StopIcon
variant="contained"
className={[classes.stopbutton, hideTimerClass]}
disabled={true}
onClick={event => {
this.stopTimer();
todo_operations({
variables: {
id: this.props.developerlist.id,
dtask_stop_time: currdatetime,
dtask_total_time: this.state.time,
time_tracking_flag: "stop"
}
});
}}
/>
)}
</Mutation>
) : null;
return (
<div>
<div className={classes.clock}>{ms(totalTaskTime)}</div>
{start}
{stop}
</div>
);
}
}
export default withStyles(styles, { withTheme: true })(TaskTimer);
if I'm understanding your problem correctly you are trying to cause an update in sister components when a certain event happens.
I believe that the best way to do this would be to have a state in your parent component (DeveloperTasks) that holds whether or not each timer should be disabled. Then pass a callback into each timer that would update the disabled list in the way that you're looking for.
The way I'm imagining such a callback would work is:
function getDisableOtherTimersCallback(timerNum) {
return timerNum => {
return this.state.setState({disabledList: disabledList.map((value, index) => index == timerNum)})
// this line just goes through and makes sure that the index corresponding to timerNum is the only one that's true
};
}
Then when you render your component for timer n you would pass in the timer you get for timer n.
<TaskTimer
developerlist={task}
hidetimer={this.state.disabledList[n]}
disableOtherTimersCallback={getDisableOtherTimersCallback(n)}
/>
Then whenever you want to disable the other timers you would call this method and your done!
(Also note that you can now use the disabledList to show or hide each timer!)
(Also also note that you need to add the disabledList to your state and initiate it in the way you are looking for)
Hope this helps!
I am trying to delete div section without using state, how to remove this? I tried by using unmountComponentAtNode but showing the error
unmountComponentAtNode(): The node you're attempting to unmount was rendered by React and is not a top-level container. Instead, have the parent component update its state and rerender in order to remove this component.
Code:
import 'rc-slider/assets/index.css';
import 'rc-tooltip/assets/bootstrap.css';
import React from 'react';
import Tooltip from 'rc-tooltip';
import Slider from 'rc-slider';
import { withStyles } from '#material-ui/core/styles';
import Icon from '#material-ui/core/Icon';
import { unmountComponentAtNode } from 'react-dom';
const createSliderWithTooltip = Slider.createSliderWithTooltip;
const Range = createSliderWithTooltip(Slider.Range);
const Handle = Slider.Handle;
const marks = {
0: <strong>0°C</strong>,
26: '26°C',
37: '37°C',
50: '50°C',
100: {
style: {
color: 'red',
},
label: <strong>100°C</strong>,
},
};
const handle = (props) => {
const { value, dragging, index, ...restProps } = props;
return (
<Tooltip
prefixCls="rc-slider-tooltip"
overlay={value}
visible={dragging}
placement="top"
key={index}
>
<Handle value={value} {...restProps} />
</Tooltip>
);
};
class StepSlider extends React.Component {
constructor(props) {
super(props);
this.state = { sliderValues: [80] };
this.onDelEvent = this.onDelEvent.bind(this)
}
handleChange = sliderValues => {
this.setState({ sliderValues });
};
onDelEvent = (e) => {
console(e)
var object = this.refs.slider;
unmountComponentAtNode(object);
document.body.removeChild(object);
}
render() {
const { classes } = this.props;
const { sliderValues } = this.state;
return (
<div className="row" style={{ margin: '50px' }} ref="slider" id="slider">
<div className="col-md-11">
<div className="box-header" style={{ textAlign: 'center', fontSize: '20px' }}><strong>Project NPV: $2.98M</strong></div>
<p style={{ position: 'absolute', color: 'pink' }}>kjh</p>
{/* <Slider min={0} max={100} marks={marks} defaultValue={sliderValues} onChange={this.handleChange} handle={handle} tipFormatter={value => `${value}%`}/> */}
<Slider
min={0} max={100} marks={marks} defaultValue={sliderValues} onChange={this.handleChange} handle={handle} tipFormatter={value => `${value}%`}
trackStyle={{ backgroundColor: 'blue', height: 15 }}
handleStyle={{
borderColor: 'red',
height: 35,
width: 35,
marginLeft: -14,
marginTop: -9,
backgroundColor: 'white',
}}
railStyle={{ backgroundColor: 'black', height: 15 }}
/>
</div>
<div className="col-md-1">
<Icon className={classes.icon} color="primary" onClick={this.onDelEvent.bind(this)} style={{ marginTop: '45px' }}>
remove_circle</Icon>
{/* <div style={wrapperStyle}>
<p>Range with custom handle</p>
<Range min={0} max={20} defaultValue={[3, 10]} tipFormatter={value => `${value}%`} />
</div> */}
</div>
</div>
)
}
}
export default withStyles({ withTheme: true })(StepSlider);
I suggest the following pattern for dynamic removal of sliders:
Slider.js
const Slider = ({ id, onRemove }) => (
<div className="slider">
<button onClick={() => onRemove(id)} />
</div>
);
export default Slider;
StepSlider.js
import Slider from './Slider';
class StepSlider extends React.Component {
state = {
sliders: [
{id: 1, value: ...},
{id: 2, value: ...},
...
]
}
handleRemoveSlider = id => {
this.setState(prevState => ({
sliders: [...prevState.sliders.filter(slider => slider.id !== id)]
}))
}
render() {
this.state.sliders.map(slider => (
<Slider id={slider.id} onRemove={this.handleRemoveSlider} />
))
}
}
import 'rc-slider/assets/index.css';
import 'rc-tooltip/assets/bootstrap.css';
import React from 'react';
import Tooltip from 'rc-tooltip';
import Slider from 'rc-slider';
import { withStyles } from '#material-ui/core/styles';
import Icon from '#material-ui/core/Icon';
const createSliderWithTooltip = Slider.createSliderWithTooltip;
const Range = createSliderWithTooltip(Slider.Range);
const Handle = Slider.Handle;
const marks = {
0: '5%',
10: '6%',
20: '7%',
30: '8%',
40: '9%',
50: '10%',
60: '11%',
70: '12%',
80: '13%',
90: '14%',
100: '15%'
};
const handle = (props) => {
const { value, dragging, index, ...restProps } = props;
return (
<Tooltip
prefixCls="rc-slider-tooltip"
overlay={value}
visible={dragging}
placement="top"
key={index}
>
<Handle value={value} {...restProps} />
</Tooltip>
);
};
const handleStyle = {
borderColor: 'red',
height: 28,
width: 28,
marginLeft: -14,
marginTop: -8,
backgroundColor: 'white',
}
class StepSlider extends React.Component {
constructor() {
super()
this.state = {
sliders: [
{ id: 1, title: 'Discount Rate', value: '5' },
{ id: 2, title: 'Total Volume', value: '10' },
{ id: 3, title: 'Avg Sales Rate', value: '50' }
]
}
this.handleRemoveSlider = this.handleRemoveSlider.bind(this);
this.onChange=this.onChange.bind(this)
}
onChange=(e)=>{
let inputValue = e;
let statusCopy = Object.assign({}, this.state);
statusCopy.value = inputValue;
this.setState(statusCopy);
}
handleRemoveSlider = id => {
this.setState(prevState => ({
sliders: [...prevState.sliders.filter(slider => slider.id !== id),
],
}))
}
render() {
return (
this.state.sliders.map(slider => (
<div>
<Button id={slider.id} onRemove={this.handleRemoveSlider} title={slider.title} value={slider.value} onChange={this.onChange}/>
</div>
))
)
}
}
export default StepSlider;
const Button = ({ id, onRemove, value, title,onChange }) => (
<div className="row" style={{ margin: '50px' }} id={id}>
<div className="col-md-1">
{title}
</div>
<div className="col-md-10">
<Slider min={0} max={100} handle={handle}
defaultValue={value} marks={marks}
tipFormatter={value => `${value}%`}
trackStyle={{ backgroundColor: 'blue', height: 15 }}
handleStyle={handleStyle}
railStyle={{ backgroundColor: 'black', height: 15 }}
onChange={onChange}
/>
</div>
<div className="col-md-1">
<button onClick={() => onRemove(id)} style={{ backgroundColor: '#1a237e', color: 'white' }}>X</button>
</div>
</div>
);
Actually this is working, i mean deleting slider by passing its respective id but state is not updating and i wanna update the particular slider value onchanging it. please check and help me