I'm in need of some help.
I have a datasource on my antd table in my React.Component. On that table i've set the attribute expandedRowRender:
<Table
bordered
size="small"
columns={columns}
rowKey={record => record.id}
expandedRowRender={record => (
<ProductDetailView
record={record}
onChange={this.OnCoverageProductNumberChanged()}
/>
)}
dataSource={products}
pagination={this.state.pagination}
loading={this.props.isProductsLoading}
onChange={this.handleChange}
/>
which is currently sending a record to ProductDetailView which is a react.component. I would like to know how I can send the row index to the onChange event as well, so I can track on which row I am looking at.
I hope this is enough information, basically I just need to know how to send the row index to my onChange event.
Thank you in advance.
The second variable of
expandedRowRender={(record, i) => <p>{i}</p>}
is the row index
you can pass it like this
expandedRowRender={(record, i) =>
<ProductDetailView
record={record}
onChange={() => this.OnCoverageProductNumberChanged(i)}
/>
}
Related
I'm having trouble identifying selected rows with a checkbox in prime React. the structure of the table is as follows: (the column with the checkbox most be "Visible?").
<div className="col-12">
<DataTable value={variableOptions} editMode = "cell" className="editable-cells-table"
dataKey="_id" paginator rows={10} rowsPerPageOptions={[5, 10, 25]}
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products" header={"Variables"} responsiveLayout="scroll">
<Column field="name" header="Nombre" sortable />
<Column field="units" header="Unidad" sortable />
<Column field="isPrincipal" header="Gerarquia" sortable />
<Column field="isVisible" header="Visible?" sortable onClick={(e) => bodyCheckBoxVisible(e)}/>
</div>
and the function where i have return the checkbox
const bodyCheckBoxVisible = (e) => {
return ( <Checkbox inputId="binary" checked={checked} onChange={e => setChecked(e.checked)} />)
}
The problem is that the function does not return the checkbox inside the table row.
How to solve this?
once the checkbox is shown I must be able to select more than one row because more than one variable can be visible or not, I don't know how to do this function either.
each row has a name and id that identify them, once identified making the change is not difficult I imagine
Your "bodyCheckBoxVisible" method is returning a component, but you are doing nothing with it.
Instead you could create a state named "checkboxVisible", update it on click, and displaying or not your data according to it, something like this :
const [bodyVisible, setBodyVisible] = useState(false);
return (
......
<Column field="isVisible" header="Visible?" sortable onClick={(e) => setBodyVisible(!bodyVisible)}/>
......
{bodyVisible && myElementToDisplay}
......
)
I hope it helped !
I am stuck on this issue with onChange handler being fired on a wrong element after .map function. I have a component, which I use to display mapped values, which looks like this:
const Step: React.FC<StepProps> = ({ status, title, text, onClick, onChange }) => {
return (
<button disabled={status === CompletionStatus.Completed} className={Styles.item} onClick={onClick}>
<mui.IconButton css={css.completionIcon} disabled={status === CompletionStatus.Completed}>
{status === CompletionStatus.Completed ? <muiIcons.Check /> : <Plus />}
</mui.IconButton>
<div className={Styles.content}>
<span className={status === CompletionStatus.Completed ? Styles.titleCompleted : Styles.title}>{title}</span>
<span className={status === CompletionStatus.Completed ? Styles.textCompleted : Styles.text}>{text}</span>
</div>
{onChange && (
<>
<label htmlFor="file-button" className={Styles.inputLabel} />
<input id="file-button" className={Styles.input} type={'file'} onChange={onChange} />
</>
)}
</button>
);
};
So, some of the mapped elements are being used with onClick, and two use onChange to gain photos from the user.
The issue is, that every time I trigger the onChange event on any of those inputs, only the first ones fires, e.g (I added this onChange function to test the name of the element that is being fired, and every time only the first one in the list is being console.logged)
onChange={(event: any)=> {
console.log(event, step);
event.target.value = null;
}}
So, I have figured out the issue here, maybe someone finds this helpful.
Having input with type file only having one id (file-button) was causing only the first such input to work
<label htmlFor="file-button" className={Styles.inputLabel} />
<input id="file-button" className={Styles.input} type={'file'} onChange={onChange} />
The way I fixed this, was basically having that id property unique, so I passed an index to the component and changed the id to
id={`file-button-${index}`}
Sounds like you may not have set a key for each item in your mapping function.
{yourData.map((item, index) => <Component key={`item-${index}`} item={item} />)}
I am currently working on an update form (put request) on ReactJS. I have the form data stored as this.state that I want to use to prepopulate, however, I am not sure how to implement it into the dynamic field, as I would want the prepopulated data to still hold on to the 'remove' function to remove that row of fields from the form. Also, I would want the rows to be rendered automatically when the form is rendered. Meaning, if there are two rows of the dynamic field, those two rows has to be shown without pressing the 'add' button. Below is the snippet of the code and a screenshot of the form.
<Form.List name={addon.model} key={addon.model}>
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field, index) => (
<Row key={field.key}>
{addon.fields.map((a) => (
<Col key={'c' + a.key}>
<Input placeholder={a.label} name={a.key} key={'i' + a.key}
onChange={(e) => this.onChangeAddOn(e, index, addon.model)} />
</Col>
))}
<Col flex="none">
<MinusCircleOutlined
className="dynamic-delete-button"
onClick={() => {
remove(field.name);
}}
/>
</Col>
</Row>
))
}
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
<PlusOutlined /> Add POCs
</Button>
</div>
);
}}
</Form.List>
screenshot (the '-' button is the remove button, and i am free to add more fields if i press the 'Add POC' button, but the main point is that the two rows of data must be rendered at the start together with the form => data stored in this.state)
All help is appreciated and welcomed, please do help to point me in the right direction as I am still new to ReactJS! I did take a look at render props and Form.List, but I am not sure how to implement it still.
I am displaying cards with data mapped with a price and location
return data.map( FD1 => (
<Row>
<Card className="card">
<Card body className="text-center">
<CardTitle data-es-label="location"> Location:
{FD1.Departure}
</CardTitle>
<CardText data-es-label="Price">Price
{FD1.price}
</CardText>
<label>
<Checkbox
id={FD1.FlightID}
name={FD1.FlightID}
checked={this.state.checked === FD1.FlightID}
onChange={this.handleCheckboxChange}/>
<span>Select</span>
</label>
<CardActions>'
Each card has a check box and my idea was when the check box is selected and submitted - the information mapped to that card will be sent to be 'booked'.
Is it possible to filter data from the mapped data. Each 'card' with the data has a unique id. How do I filter the data by card and send to a booking page with the details?
At the moment when I select a checked box they all select.
handleCheckboxChange = event =>
this.setState({ checked: event.target.checked });
EDIT: attempt - this is what I have tried
handleCheckboxChange = event =>
this.setState({ checked: event.target.checked });
Select(FD) {
this.state={checked:FD.FlightID};
return(
<label>
<Checkbox id={FD.FlightID}
name={FD.FlightID}
checked={this.state.checked}
onChange={this.handleCheckboxChange}
/>
<span>Select</span>
</label>
)
}
Do you know where I have gone wrong?
into the checked state save the FD1.FlightID instead of true/false and you will know exactly which card had been checked.
and then on submit you can send the appropriate data using this.state.checked (the id of checked card)
In the code inside your "map" function, "this" is still referring to the parent component. So you only have one checked state. That's why all your checkboxes show the same behaviour.
A cleaner solution would be to define a new stateful component "CardRow" that has everything inside the map plus it's own state and handleCheckboxChange function.
I have a string , in certain places I need to insert input tags with values. Everything displays fine , but I can't delete or edit values in input. What is wrong with that input?
editModalText() {
let modalMessage="Hello, my name is /# Ann #/. I'm working for /# IStaff #/, could you please call me back"
return (
<div>
{modalMessage
.split("/")
.map((text, idx) =>
text.includes("#") ? this.replaceCharacter(idx, text) : text,
)}
</div>
)
}
replaceCharacter(idx, text) {
let formattedText = text.replace(/#/g, " ")
return (
<input
key={idx}
value={formattedText}
onChange={e => this.setState({input:e.target.value})}
/>
)
}
replace value={formattedText} with defaultValue={formattedText}
this way input will be editable. it will show default value on first render and as you type you'll store that value in your state.
you can read more about controlled and uncontrolled components in the docs
I think you need to bind the input value and the state together. I am not sure how you're currently calling replaceCharacter but I would do something like this :
replaceCharacter(idx) {
return (
<input
key={idx}
value={this.state.input.replace(/#/g, " ")}
onChange={e => this.setState({input:e.target.value})}
/>
)
}
This way when you update your state with the onChange event the value of the state will be populated in the input.