is there a way how to define that only "data" greater than * should be added to my columns in data grid?
I have tried add filter, but it support only exact value.
In my example i want to add only columns which has "combinationId" greater than 100.
class App extends React.Component {
constructor(props) {
super(props);
this.state = this.getCleanState();
this.reload();
}
getCleanState() {
return {
columns:[
{ name: 'combinationId', title: 'ID kombinace'},
{ name: 'name', title: 'Název kombinace'},
],
defaultColumnWidths: [
{ columnName: 'combinationId', width: 160 },
{ columnName: 'name', width: 200 },
],
rows:[]
};
}
reload() {
axios.get('http://private-anon-27979f8bb8-bulgur.apiary-mock.com/api/v1/combinationInfo').then((response) => {
this.loading = false;
var newState = {columns: this.state.columns, rows: response.data
.map(x => x.combinations)
.reduce((a, b) => a.concat(b))};
this.setState(newState);
}, (error) => {
this.loading = false;
})
}
render() {
const { columns, rows, defaultColumnWidths, integratedFilteringColumnExtensions } = this.state;
return (
<div>
{/* <button onClick={() => this.reload()}>Load</button>*/}
<div className="grids">
<div className="patient-container">
<Grid
rows={rows}
columns={columns}>
<Table />
<TableColumnResizing defaultColumnWidths={defaultColumnWidths} />
<TableHeaderRow />
</Grid>
</div>
<div className="patient-container2">
<Grid
rows={rows}
columns={columns}>
<FilteringState defaultFilters={[{ columnName: 'combinationId', value: 100 }]} /> <IntegratedFiltering />
<Table />
<TableColumnResizing defaultColumnWidths={defaultColumnWidths} />
<TableHeaderRow />
</Grid>
</div>
</div>
</div>)
}
}
Thanks for answers. I wish you great day.
does it have to be dynamic filtering? else you could just filter it before returning
render() {
const { columns, rows, ... } = this.state;
const filteredRows = rows.map(row => row.combinationId >= 100);
return ( ...
Related
can someone help me to understand why the filter with the multiselect in the cinema field does not give results .. I have a problem understanding how the filter callback works ..
if i select a cinema in cinema column's i don't have result. I think the the issues is about the callback in options.filterCallback(e.value) but im not sure.. i didn't found a clear docmentation about on prime react site..
const App = () => {
const [filters1, setFilters1] = useState(null);
const [globalFilterValue1, setGlobalFilterValue1] = useState("");
const cinemas = [
{ name: "nola", cinema: "nola" },
{ name: "parco" },
{ name: "guidonia" },
{ name: "vicenza" },
{ name: "limena" }
];
const items = [
{ id: "nla-1", cinema: "nola" },
{ id: "prc-1", cinema: "parco" }
];
useEffect(() => {
/* dispatch(getItems({ cinemas })); */
initFilters1();
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const clearFilter1 = () => {
initFilters1();
};
const onGlobalFilterChange1 = (e) => {
const value = e.target.value;
let _filters1 = { ...filters1 };
_filters1["global"].value = value;
setFilters1(_filters1);
setGlobalFilterValue1(value);
};
const initFilters1 = () => {
setFilters1({
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
cinema: { value: null, matchMode: FilterMatchMode.IN }
});
setGlobalFilterValue1("");
};
const renderHeader1 = () => {
return (
<div className="flex justify-content-between">
<Button
type="button"
icon="pi pi-filter-slash"
label="Clear"
className="p-button-outlined"
onClick={clearFilter1}
/>
<span className="p-input-icon-left">
<i className="pi pi-search" />
<InputText
value={globalFilterValue1}
onChange={onGlobalFilterChange1}
placeholder="Keyword Search"
/>
</span>
</div>
);
};
const representativeBodyTemplate = (rowData) => {
return (
<React.Fragment>
<span className="image-text">{rowData.cinema}</span>
</React.Fragment>
);
};
const representativeFilterTemplate = (options) => {
console.log("opt", options);
return (
<MultiSelect
value={options.value}
options={cinemas}
itemTemplate={representativesItemTemplate}
onChange={(e) => options.filterCallback(e.value)}
placeholder="Any"
className="p-column-filter"
/>
);
};
const representativesItemTemplate = (option) => {
console.log("opt cit", option);
return (
<div className="p-multiselect-representative-option">
<span className="image-text">{option.name}</span>
</div>
);
};
const header1 = renderHeader1();
return (
<div className="datatable-filter-demo">
<div className="card">
<h5>Filter Menu</h5>
<p>Filters are displayed in an overlay.</p>
<DataTable
value={items}
paginator
className="p-datatable-customers"
showGridlines
rows={10}
dataKey="id"
filters={filters1}
filterDisplay="menu"
responsiveLayout="scroll"
globalFilterFields={["id", "cinema"]}
header={header1}
emptyMessage="No customers found."
>
<Column
field="id"
header="id"
filter
filterPlaceholder="Search by name"
style={{ minWidth: "12rem" }}
/>
<Column
header="cinema"
field="cinema"
options={cinemas}
sortable
filterField="cinema"
showFilterMatchModes={false}
filterMenuStyle={{ width: "14rem" }}
style={{ minWidth: "14rem" }}
body={representativeBodyTemplate}
filter
filterElement={representativeFilterTemplate}
/>
</DataTable>
</div>
</div>
);
};
export default App;
Thank evryboby and have a good day!!!
how to create chart taking input from the user from a form in reactjs
I made a form and pie chart not getting an idea of how to access data from a form
chartData:{
datasets:[{
data:[10,20,30,40,50]
}]
}
i want the chart to be created by the inputs form the form
export default class App extends Component {
state = {
dataPie: {
datasets: [{
data: [10, 20, 30]
}],
},
first: "",
second: "",
}
handleSubmit = () => {
const { dataPie } = this.state;
this.setState({
dataPie: {
...dataPie,
datasets: [{
...dataPie.datasets,
data: [...dataPie.datasets[0].data,
this.state.first, this.state.second]
}]
}
})
}
handleChange = (evt) => {
let a = parseInt(evt.target.value)
this.setState({
[evt.target.name]: a,
})
}
render() {
const { data, dataPie } = this.state;
console.log(dataPie);
return (
<React.Fragment>
<input type="number"
value={this.state.first}
name="first"
onChange={(evt) => this.handleChange(evt)} />
<input type="number"
value={this.state.second}
name="second" onChange={(evt) => this.handleChange(evt)} />
<button onClick={() => this.handleSubmit()}>add data to chart</button>
<h1>pie chart</h1>
<Pie data={dataPie} />
</React.Fragment>
)
}
}
Use the following code will generate a dynamic chart
import React, { Component } from "react";
import { Pie } from "react-chartjs-2";
export default class App extends Component {
state = {
dataPie: {
datasets: [{
data: [10, 20, 30]
}],
},
first: "",
second: "",
}
handleSubmit = () => {
const { dataPie } = this.state;
this.setState({
dataPie: {
...dataPie,
datasets: [{
...dataPie.datasets,
data: [
this.state.first,
this.state.second
]
}]
}
})
}
handleChange = (evt) => {
let a = parseInt(evt.target.value)
this.setState({
[evt.target.name]: a,
})
}
render() {
const { data, dataPie } = this.state;
console.log(dataPie);
return (
<React.Fragment>
<input type="number"
value={this.state.first}
name="first"
onChange={(evt) => this.handleChange(evt)} />
<input type="number"
value={this.state.second}
name="second" onChange={(evt) => this.handleChange(evt)} />
<button onClick={() => this.handleSubmit()}>add data to chart</button>
<h1>pie chart</h1>
<Pie data={dataPie} />
</React.Fragment>
)
}
}
data: [...dataPie.datasets[0].data, this.state.first, this.state.second] }]change this to data: [ this.state.first, this.state.second] }]
I'm using material-ui to list group of violations to the user to select one or multiple violations, then during the selection i extract from each violation it's id and update the state so as a result i'll have an array of ids to send it to backend
here is my code
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import get from 'lodash/get';
// Material-UI
import MaterialTable, { MTableToolbar } from 'material-table';
import { withStyles } from '#material-ui/core/styles';
import Grid from '#material-ui/core/Grid';
import Paper from '#material-ui/core/Paper';
import Button from '#material-ui/core/Button';
import SaveIcon from '#material-ui/icons/Save';
import CancelIcon from '#material-ui/icons/Cancel';
// Forms
import Entity from '~/Components/Entity';
import { BaseFormComponent, Form, FormContainer, FormItem } from '~/Components/FormComponent';
import { LabelAndValue, LookupString } from '~/Components/FormComponent/Controls';
import {
isRequired,
minNumbers,
maxNumbers,
onlyNumbers,
noEnglish
} from '~/Services/Validators';
import Navigate from '~/Services/Navigate';
import Notifications from '~/Services/Notifications';
import Message from '~/Components/Message';
import Strings from '~/Services/Strings';
import styles from './styles';
#withStyles(styles)
class violationEditorScreen extends BaseFormComponent {
constructor(props) {
super(props);
this.initState({
error: false,
errorMsg: '',
requestId: null,
complaintId: null,
penalityTypeId: null,
violations: [],
inistitutionsData: [],
selectedViolationsId: [],
form: {
id: {
type: this.types.number,
value: 0,
},
districtId: {
type: this.types.number,
value: 1,
UIOnly: true
},
cityId: {
type: this.types.number,
value: 1,
UIOnly: true
},
institutionTypeId: {
type: this.types.number,
value: 2,
UIOnly: true
},
complaintTitle: {
type: this.types.string,
validators: [ isRequired(), noEnglish() ],
},
complaintDescription: {
type: this.types.string,
validators: [ isRequired(), noEnglish() ],
},
institutionId: {
type: this.types.number,
validators: [ isRequired() ],
},
}
});
}
componentDidMount() {
super.componentDidMount();
// const id = get(this, 'props.match.params.id', null);
// if (id) {
// this.addFormFields({
// });
// }
this.getInstitutionsList();
}
getInstitutionsList() {
const { form } = this.state;
this.getInstitutionsEntity.get({
cityId: form.cityId.value,
districtId: form.districtId.value,
institutionTypeId: form.institutionTypeId.value
});
}
// On Institution Change
onHandleInstitutionChange(institutionId) {
this.getRequestIdEntity.post({ institutionId });
}
getRequestIdEntityPosted(data) {
const requestId = data.requestId;
const complaintId = data.id;
this.setState({
requestId,
complaintId
}, () => {
this.getViolationsEntity.get({
complaintId
});
});
}
onViolationsEntityReceived(data) {
const violations = [];
if(data && data.length > 0) {
data.map(item => {
violations.push({ ...item });
});
this.setState({ violations });
}
this.setState({ violations });
}
onInstitutionEntityReceived(data) {
if(data && data.licensingInstitutionsModel && data.licensingInstitutionsModel.length > 0) {
const arr = [];
data.licensingInstitutionsModel.map(item => {
arr.push({
id: item.institutionId,
nameAr: item.fullName
});
});
this.setState({ inistitutionsData: arr });
}
}
onEntityPosted(data) {
const requestId = data.requestId;
Notifications.notify('success', Strings.complaintHasBeenSuccessfullyPublished);
this.getViolationsEntity.post({ requestId });
}
onSubmit() {
const id = get(this, 'props.match.params.id', null);
const { selectedViolationsId, requestId } = this.state;
if (this.isFormValid) {
if(selectedViolationsId.length === 0) {
this.setState({
error: true,
errorMsg: Strings.addAtLeastOneViolation
});
}else {
const payload = {
...this.formValues,
selectedViolationsId,
requestId,
id: id ? id : 0
};
this.entity.post(payload);
}
} else {
this.showFormErrors();
}
}
handleSelectedRows(rows) {
const selectedViolationsId = [];
const penalityTypeIds = [];
if(rows.length > 0) {
rows.map(row => {
selectedViolationsId.push(row.id);
penalityTypeIds.push(row.penaltyTypeId);
});
this.setState({ selectedViolationsId }, () => {
if(penalityTypeIds.length > 0) {
const validators= [
isRequired(),
minNumbers(1),
onlyNumbers()
];
const penalityTypeId = penalityTypeIds.sort((a, b) => {
if(a > b) return -1;
if(b > a) return 1;
})[0];
if(penalityTypeId === 1 || penalityTypeId === 2) {
validators.push(maxNumbers(30));
} else {
validators.push(maxNumbers(60));
}
this.addFormFields({
settlementPeriodInDays: {
type: this.types.number,
validators
},
});
this.setState({ penalityTypeId });
} else {
this.setState({ penalityTypeId: null });
}
});
} else {
this.setState({
selectedViolationsId: [],
penalityTypeId: null
});
}
}
get localization() {
return {
header: {
actions: Strings.listActionsLabel,
},
body: {
emptyDataSourceMessage: Strings.listEmptyLabel,
},
pagination: {
labelRowsPerPage: Strings.rowsPerPageLabel,
labelDisplayedRows: `{from}-{to} ${Strings.fromText} {count}`,
},
toolbar: {
nRowsSelected: `${Strings.nSelected} {0} ${Strings.selectedViolations}`
}
};
}
get options() {
return {
actionsColumnIndex: -1,
pageSize: 10,
selection: true,
filtering: true,
columnsButton: true,
maxBodyHeight: 600,
pageSizeOptions: [ 5, 10 ] ,
doubleHorizontalScroll: true,
rowStyle: row => {
if ( row.tableData.id % 2 ) {
return { backgroundColor: '#f2f2f2' };
}
}
};
}
get columns() {
return [
{ title: Strings.violationReferenceNumber, field: 'referenceNumber', cellStyle: { width: 120 } },
{ title: Strings.violationDescription, field: 'description' },
];
}
get components() {
const { classes } = this.props;
return {
Toolbar: props => (
<div className={classes.toolbar}>
<MTableToolbar {...props} />
</div>
),
};
}
render() {
const { form, error, errorMsg, inistitutionsData, violations, penalityTypeId } = this.state;
const { classes } = this.props;
const {
TextField,
LookupSelectField,
SelectAutocompleteField,
} = this;
return (
<React.Fragment>
<Entity
storeId={'Supervision-Complaints-Editor'}
entityRef={ref => { this.entity = ref; }}
onEntityReceived={data => this.onEntityReceived(data)}
onEntityPosted={data => this.onEntityPosted(data)}
onEntityPostedError={data => this.onEntityPostedError(data)}
render={store => (
<React.Fragment>
<If condition={error}>
<Grid item xs={12}>
<Message variant={'error'} text={errorMsg} />
</Grid>
</If>
<Form loading={store.loading}>
<Grid container spacing={24}>
<Grid item xs={9}>
<Paper elevation={1} className={classes.box1}>
<fieldset className={classes.fieldSet}>
<legend>{Strings.complaintDetails}</legend>
<FormContainer>
<FormItem lg={4}>
<LookupSelectField
name={'districtId'}
label={Strings.selectDistrictToSearch}
lookup={'Districts'}
onChange={() => this.getInstitutionsList()}
autocomplete
/>
</FormItem>
<FormItem lg={4}>
<LookupSelectField
name={'cityId'}
label={Strings.selectCityToSearch}
lookup={`City/LookupItemsByParentId/${form.districtId.value}`}
onChange={() => this.getInstitutionsList()}
autocomplete
/>
</FormItem>
<FormItem lg={4}>
<LookupSelectField
name={'institutionTypeId'}
label={Strings.selectInstitutionTypeToSearch}
lookup={'InstitutionTypes'}
onChange={() => this.getInstitutionsList()}
/>
</FormItem>
<FormItem lg={4}>
<div className={classnames(classes.placeholder, {})}>
<SelectAutocompleteField
name={'institutionId'}
label={Strings.assignmentInstitutionName}
emptyString={Strings.searchByNameAndLicense}
data={inistitutionsData}
onChange={field => this.onHandleInstitutionChange(field.value)}
/>
</div>
</FormItem>
<FormItem lg={4}>
<TextField
name={'complaintTitle'}
label={Strings.complaintTitle}
setBorder={false}
/>
</FormItem>
<If condition={penalityTypeId}>
<FormItem lg={4}>
<TextField
name={'settlementPeriodInDays'}
label={Strings.insertSettlementPeriodInDays}
setBorder={false}
/>
</FormItem>
</If>
<FormItem fullWidth>
<TextField
multiline
name={'complaintDescription'}
label={Strings.complaintDescription}
/>
</FormItem>
</FormContainer>
</fieldset>
</Paper>
<Paper elevation={1} className={classes.box}>
<fieldset className={classes.fieldSet}>
<legend>{Strings.complaintAttachments}</legend>
<FormContainer>
</FormContainer>
</fieldset>
{/* Attachment Here */}
</Paper>
<If condition={violations.length > 0}>
<Paper elevation={1} className={classes.box}>
<MaterialTable
title={Strings.complaintsAddViolationList}
data={violations}
options={this.options}
localization={this.localization}
columns={this.columns}
components={this.components}
onSelectionChange={rows => this.handleSelectedRows(rows)}
/>
</Paper>
</If>
</Grid>
<Grid item xs={3}>
{/* =========== Sidebar ============= */}
<If condition={penalityTypeId}>
<Paper elevation={1} className={classes.box}>
<FormItem fullWidth style={{ marginBottom: 10 }}>
<LabelAndValue
label={Strings.earnedPenality}
className={classes.deservedPenality}
value={(<LookupString
lookup={'PenaltyType'}
value={penalityTypeId}
/>)}
/>
</FormItem>
</Paper>
</If>
<Paper elevation={1} className={classes.box}>
<FormItem fullWidth style={{ marginBottom: 10 }}>
<Button
fullWidth
size={'large'}
color={'primary'}
variant={'contained'}
className={classes.submitButton}
onClick={() => this.onSubmit()}
>
<SaveIcon className={classes.rightIcon} />
{Strings.saveText}
</Button>
<Button
fullWidth
size={'large'}
color={'secondary'}
variant={'contained'}
className={classes.cancelButton}
onClick={() => Navigate.goBack()}
>
<CancelIcon className={classes.rightIcon} />
{Strings.cancelText}
</Button>
</FormItem>
</Paper>
</Grid>
</Grid>
</Form>
</React.Fragment>
)}
/>
{/* Get Institutions */}
<Entity
storeId={'Supervision-PlannedVisit-Schedule-List'}
entityRef={ref => { this.getInstitutionsEntity = ref; }}
onEntityReceived={data => this.onInstitutionEntityReceived(data)}
/>
{/* Get Request Id */}
<Entity
storeId={'Supervision-Complaints-GetRequestId'}
entityRef={ref => { this.getRequestIdEntity = ref; }}
onEntityPosted={data => this.getRequestIdEntityPosted(data)}
/>
{/* Get Violation By Request Id --- And Initiate Request in Admin Screens */}
<Entity
storeId={'Supervision-Complaints-Violations-By-ComplaintId'}
entityRef={ref => { this.getViolationsEntity = ref; }}
onEntityReceived={data => this.onViolationsEntityReceived(data)}
onEntityPosted={data => Navigate.goBack()}
/>
</React.Fragment>
);
}
}
violationEditorScreen.propTypes = {
classes: PropTypes.object,
};
export default violationEditorScreen;
componentDidMount() {
if(id) {
// grap the data from back end and upadte the table with checked rows that matches the ids that i got from Back-End
}
}
i expect receive array of Ids then mark each row that it's id is in the array Of Ids to let the user knows What he selected before.
Thx in Advance.
if I understand you correct, you want change the style of the row if it selected, so could you check this url and see the last example in order to modify it to adapt to your situation?
https://material-table.com/#/docs/features/styling
I am getting the checkboxes based on table columns. If I select check box I am getting only one checked value. I want to get multiple checked values.
How do I achieve that?
class StudentTable extends React.Component {
state = {
columns: [
{
title: "StudentID",
dataIndex: "studentid",
key: "studentid"
},
{
title: "Name",
dataIndex: "name",
key: "name"
}
]
};
onChange = e => {
alert(JSON.stringify(e));
console.log(`checked = ${e.target.checked}`);
console.log(`checked = ${e.target.name}`);
this.setState({
[e.target.name]: e.target.value
});
if (e.target.checked === true) {
let filterData = this.state.columns.filter(columnData => {
return e.target.name === columnData.dataIndex;
});
CsvData.push(filterData[0].dataIndex);
console.log("After Filter", filterData[0].dataIndex);
}
};
render() {
return (
<div>
{this.state.columns.map(columData => {
return (
<div key={columData.key}>
<Checkbox name={columData.dataIndex} onChange={this.onChange}>
{columData.dataIndex}
</Checkbox>
</div>
);
})}
<CSVLink data={CsvData}>Download me</CSVLink>;<h2>Student Data</h2>
<Table
dataSource={data}
columns={this.state.columns}
pagination={{ pageSize: 5 }}
rowKey={record => record.id}
onChange={this.handleChange}
/>
</div>
);
}
}
Use checkbox group instead of checkbox
<Checkbox.Group
options={this.state.columns.map(column => ({label:column.dataIndex, value: column.dataIndex}))}
onChange={this.onChange}
/>
I hope this would help
Antd's Checkbox Group https://ant.design/components/checkbox/#components-checkbox-demo-group
Reactjs displays users info serially going up irrespective of the user clicked.
I have 5 users in the array.
The code below was meant to display each Person Id and Name uniquely on their various popup box when their corresponding name
in the list button is clicked.
Here is my problem:
My issue is that if I click for instance on user 1, instead of getting content of user 1 displayed on its own popup box
it will display content of user 5.
If I pick another user randomly for example user 3 from the list, instead of getting the content of user 3 displayed on its
own popup box, it will display content of user 4 and next click of any user will display content of user 3 and so on going up to user 1.
Is this problem caused from person.id alignment or from serial alignment of users info in the array list?. can someone help me out
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import axios from 'axios';
class App extends Component {
constructor() {
super();
this.state = {
showBox: false,
data: [
{ id: "1", name: "user 1" },
{ id: "2", name: "user 2"},
{ id: "3", name: "user 3"},
{ id: "4", name: "user 4"},
{ id: "5", name: "user 5"},
],
};
this.showBox = this.showBox.bind(this);
this.closeBox = this.closeBox.bind(this);
}
showBox = (pid, name) => {
this.setState({ person_id: pid });
const dataSet = this.state.data;
alert(dataSet);
if ($.inArray(pid, dataSet) != -1)
{
dataSet.splice($.inArray(pid, this.state.data), 1);
}
dataSet.unshift(pid);
var s = 270 ; // start position
var j = 260; //next position
$.each(dataSet, function( index, value ) {
if(index < 4){
$('[rel="'+value+'"]').css("right",s);
$('[rel="'+value+'"]').show();
s = s+j;
}
else{
$('[rel="'+value+'"]').hide();
}
});
//event.preventDefault();
//event.preventDefault();
this.setState({ showBox: true }, () => {
document.addEventListener('click', this.closeBox);
});
}
closeBox(event) {
if (this.cBox.contains(event.target)) {
this.setState({ showBox: false }, () => {
document.removeEventListener('click', this.closeBox);
});
}
}
render() {
return (
<div >
<ul style={{float: "right"}}>
{this.state.data.map((person) => (
<div className="chat-sidebar" key={person.id}>
<button onClick={ () => this.showBox(person.id, person.name)}>
{person.name} </button>
{this.state.showBox
? (
<div rel={person.id} className="msg_box" style={{right: '270px',position: 'fixed', bottom:'-5px', width:'250px',background: 'white',borderRadius:'5px 5px 0px 0px', height: '200px'}}>
<div> <div style={{background: 'red',height: '150px'}}>
<div ref={(element) => {this.cBox = element;}} style={{color: 'blue'}}>Close</div>
Each Users info will appear here below.<br />
(person Id: {person.id})<br />
(person Name: {person.name})<br />
</div>
</div>
</div>
): (
null
)}
</div>
))}
</ul>
</div>
);
}
}
Screenshot updates
Updated Code as Requested by Sir Win
import React, { Component, Fragment } from "react";
import { render } from "react-dom";
import axios from 'axios';
class User extends React.Component {
open = () => this.props.open(this.props.data.id, this.props.data.name);
render() {
return (
<React.Fragment>
<div key={this.props.data.id}>
<button onClick={() => this.open(this.props.data.id,this.props.data.name)}>{this.props.data.name}</button>
</div>
</React.Fragment>
);
}
}
class OpenedUser extends React.Component {
close = () => this.props.close(this.props.data.id);
render() {
return (
<div style={{ display: 'inline-block' }}>
<div onClick={this.toggle} className="msg_head">
(<b style={{ color: 'orange' }}>
Minimize
</b>)
<button onClick={this.close}>close</button>
<div>user {this.props.data.id}</div>
<div>name {this.props.data.name}</div>
<div className="msg_wrap"><div className="msg_body">Message will appear here</div></div>
</div>
</div>
)
}
}
class ChatReact extends React.Component {
constructor() {
super();
this.state = {
shownToggle: true,
activeIds: [],
data: [
{ id: 1, name: "user 1" },
{ id: 2, name: "user 2" },
{ id: 3, name: "user 3" },
{ id: 4, name: "user 4" },
{ id: 5, name: "user 5" }
]
};
}
open = (id,name) => {
alert(name);
alert(id);
this.setState((prevState) => ({
activeIds: prevState.activeIds.find((user) => user === id)
? prevState.activeIds
: [...prevState.activeIds, id]
}));
}
close = id => {
this.setState((prevState) => ({
activeIds: prevState.activeIds.filter((user) => user !== id),
}));
};
renderUser = (id) => {
const user = this.state.data.find((user) => user.id === id);
if (!user) {
return null;
}
return (
<OpenedUser data={user} close={this.close}/>
)
}
renderActiveUser = () => {
return (
<div style={{ position: "fixed", bottom: 0, right: 0 }}>
{this.state.activeIds.map((id) => this.renderUser(id)) }
</div>
);
};
render() {
var hidden = {
display: this.state.shownToggle ? "block" : "none"
}
return (
<div>
{this.state.data.map(person => (
<User key={person.id} data={person} open={this.open} />
))}
{this.state.activeIds.length !== 0 && this.renderActiveUser()}
</div>
);
}
}
Welcome to StackOverflow. To get around this problem, I would use .find instead of $.inArray so that we can filter down the data into one result so that we can use it to display the information in the info box.
Avoid using document.addEventListener and document.removeEventListener and rely purely on state. If you're trying to achieve something not listed in the question, then please explain.
Also, try and avoid using jQuery with React.
Here's an example:
class User extends React.Component {
open = () => this.props.open(this.props.data.id);
render() {
return (
<React.Fragment>
<div key={this.props.data.id}>
<button onClick={this.open}>{this.props.data.name}</button>
</div>
</React.Fragment>
);
}
}
class OpenedUser extends React.Component {
close = () => this.props.close(this.props.data.id);
render() {
return (
<div style={{ display: 'inline-block' }}>
<button onClick={this.close}>close</button>
<div>user {this.props.data.id}</div>
<div>name {this.props.data.name}</div>
</div>
)
}
}
class App extends React.Component {
constructor() {
super();
this.state = {
activeIds: [],
data: [
{ id: 1, name: "user 1" },
{ id: 2, name: "user 2" },
{ id: 3, name: "user 3" },
{ id: 4, name: "user 4" },
{ id: 5, name: "user 5" }
]
};
}
open = id => {
this.setState((prevState) => ({
activeIds: prevState.activeIds.find((user) => user === id)
? prevState.activeIds
: [...prevState.activeIds, id]
}));
}
close = id => {
this.setState((prevState) => ({
activeIds: prevState.activeIds.filter((user) => user !== id),
}));
};
renderUser = (id) => {
const user = this.state.data.find((user) => user.id === id);
if (!user) {
return null;
}
return (
<OpenedUser data={user} close={this.close}/>
)
}
renderActiveUser = () => {
return (
<div style={{ position: "fixed", bottom: 0, right: 0 }}>
{this.state.activeIds.map((id) => this.renderUser(id)) }
</div>
);
};
render() {
return (
<div>
{this.state.data.map(person => (
<User key={person.id} data={person} open={this.open} />
))}
{this.state.activeIds.length !== 0 && this.renderActiveUser()}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>