I have a table whose items I render through a list. The idea is that, on clicking the name of a row, a modal will open and that will print certain values retrieved from the backend server.
Initially, for the modal, my data-target was the ID of my modal. After looking at this answer I realised that I might be doing something wrong and changed that data-target to the ID of the row. Now the problem is that the modal is not opening at all.
Edit: I realised I was doing something wrong when ID of my modal was fixed because irrespective of whichever name I clicked, the same information was loading. Through console.log I could see that the right values were being passed but only was being displayed.
What am I doing wrong here?
The rendered code for the table is as follows:-
<table className="table">
<thead>
<tr>
<th>S. NO.</th>
<th>NAME</th>
<th>ADDRESS</th>
<th>TELEPHONE</th>
<th>EMAIL</th>
<th>AGE</th>
<th></th>
</tr>
</thead>
<tbody>
{this.state.personData.map((pRow, idx) => (
<>
<PersonModal id={pRow.id} />
<tr key={pRow.id}>
<td>{idx + 1}</td>
<td data-toggle="modal" data-target={pRow.id}>{pRow.name}</td>
<td>{pRow.address}</td>
<td>{pRow.phone}</td>
<td>{pRow.email}</td>
<td>{pRow.age}</td>
<td>
{" "}
<DeleteButton id={pRow.id} onDelete={this.onDelete} />{" "}
</td>
</tr>
</>
</tbody>
</table>
This is the rendered code for the modal:-
render() {
console.log("Component rendered");
return (
<React.Fragment>
<div className="modal" id={this.props.id}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-body">
{this.props.id}
</div>
<div className="modal-footer">
<button type="button" className="btn optionsButton" data-dismiss="modal">CLOSE</button>
</div>
</div>
</div>
</div>
</React.Fragment>
);
}
Related
I need to align the "Products" and a "Show filter" button on one line and space between them. I need to add classNames because it's a crud app built with react and using bootstrap. And when I press "show filter" it should change to "hide filter" and show us input values filtering the table by products and price range.
For the Header and the button, I created a new div but I think it must be done in another way.
How can I fix it and then make the filter button functional?
``` return(
<div className='container'>
<h1 className='block'>Products</h1>
<button className='btn btn-light block'>Show Filter</button>
<table className="table">
<thead>
<tr className='bg-dark text-white'>
<th scope="col">#</th>
<th scope="col">Product Name</th>
<th scope="col">Product Number</th>
<th scope="col">Color</th>
<th scope="col">List Price</th>
<th scope="col">Modified Date</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>{products.map((product,index)=>(
<tr key={product.id}>
<th scope="row">{index + 1}</th>
<td>{product.name}</td>
<td>{product.number}</td>
<td>{product.color}</td>
<td>{product.price}</td>
<td>{product.date}</td>
<td>
{/* <Link className='btn btn-primary m-2'><i className="fa fa-eye" aria-hidden="true"></i></ Link> */}
<Link className='btn btn-secondary m-2' to={`/product/edit/${product.id}`}>Edit</Link>
<Link className='btn btn-danger m-2' onClick={()=>{deleteUSer()}}>Delete</Link>
</td>
</tr>
))}
</tbody>
</table>
<Link className='btn btn-outline-dark w-25' to='/product/add'>
Add Product
</Link>
</div>
);
}
export default Products; ```
I have a component, called Bucket, each bucket can have multiple challenges, it looks like this,
The code I have is like this, (much-simplified version)
class CLL_Bucket extends Component {
constructor(props) {
super(props);
this.state = {};
this.state = {
…
bucketChallengesIdx: 0, // to track the index of challegnes
bucketChallenges: this.props.bucket.bucketChallenges || [],
…
};
…
this.onBucketChallengeAdd = this.onBucketChallengeAdd.bind(this);
this.onBucketChallengeIDChanged = this.onBucketChallengeIDChanged.bind(this);
this.onBucketChallengeWeightChanged = this.onBucketChallengeWeightChanged.bind(this);
}
render() {
const bucketIdx = this.props.idx;
return (
<div style={styles.container}>
<div key={bucketIdx} className="row" style={styles.bucketStyle}>
<div className="col-md-2">
…
</div>
<div key={bucketIdx} className="col-md-4">
<div>
<label>
<span className="text-center">Challenges<span>
</label>
<button type="button" className="btn btn-success btn-sm" onClick={() => this.onBucketChallengeAdd()}>Add Challenge</button>
</div>
<table className="table table-bordered table-striped show">
<thead>
<tr>
<th>Challenge ID</th>
<th>Weight</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.bucketChallenges.map(this.renderBucketChallenges.bind(this))}
</tbody>
</table>
</div>
…
</div>
</div>
);
}
renderBucketChallenges(bucketIdx, idx){
return (
<tr key={idx}>
<td className="col-xs-3 input-group-sm">
<Select
options={challengeIDOptions}
defaultValue={challengeIDOptions[0]}
onChange={this.onBucketChallengeIDChanged.bind(this, idx)}
value={this.state.bucketChallengesID}
isSearchable={true}
/>
</td>
<td className="col-xs-1 input-group-sm">
<input type="text" className="form-control" value={this.state.bucketChallengesWeight}
onChange={(e) => this.onBucketChallengeWeightChanged(idx, e)} disabled={this.props.readOnly}>
</input>
</td>
<td className="col-xs-1 input-group-sm">
…
</td>
<td className="col-xs-1 input-group-sm">
<input className="btn btn-danger btn-sm" id="deleteButton" type="button" value="Delete" onClick={() => this.onDeleteChallenge.bind(this, bucketIdx, idx)} />
</td>
</tr>
);
}
onBucketChallengeAdd(){
var newChallengeIndex = this.state.bucketChallengesIdx + 1;
console.log("onBucketChallengeAdd(): " + newChallengeIndex);
this.setState({bucketChallengesIdx: newChallengeIndex});
this.props.onAddChallenge(this.props.idx, newChallengeIndex);
}
The problem I’m having is, when I click the “Add Challenge” button, I can see from the React developer tool that a new challenge is being added, even though the UI is not updated. When I go to a different tab of my app and come back, the UI is added (a new row for the added challenge is there). Why? Any suggestion on how to fix this? Thanks!
The bigger question is, am I on the right track to make this happen? or i should extract challenge portion to a different component?
I have a dynamic table whose items I render through a list. The idea is that, on clicking the name of a row, a modal will open and that will print certain values retrieved from the backend server.
When I click on a specific person's name, the modal loads for all elements in the table. How do I fix this?
The rendered code for the table is as follows:-
<table className="table">
<thead>
<tr>
<th>S. NO.</th>
<th>NAME</th>
<th>ADDRESS</th>
<th>TELEPHONE</th>
<th>EMAIL</th>
<th>AGE</th>
<th></th>
</tr>
</thead>
<tbody>
{this.state.personData.map((pRow, idx) => (
<>
<PopUp hideModal={this.hideModal} show={this.state.show} id={siteRow.id} />
<tr key={pRow.id}>
<td>{idx + 1}</td>
<td> <a onClick={this.showModal}> {pRow.name} </a> </td>
<td>{pRow.address}</td>
<td>{pRow.phone}</td>
<td>{pRow.email}</td>
<td>{pRow.age}</td>
<td>
{" "}
<DeleteButton id={pRow.id} onDelete={this.onDelete} />{" "}
</td>
</tr>
</>
</tbody>
</table>
In the code for the table, the placement of the PopUp component is such because I want to pass the ID of the particular site to the modal.
This is the rendered code for the modal:-
showModal(e) {
this.setState({
show: true
});
}
hideModal(e) {
this.setState({
show:false
});
this.props.hideModal && this.props.hideModal(e);
}
render() {
if(!this.props.show){
return null;
}
return (
<>
<div>
The ID of the person is: {this.props.id}
<button type="button" className="btn theButton" onClick={this.hideModal}>CLOSE</button>
</div>
</>
);
}
This is very rudimentary code and I haven't added much CSS so this just opens up in the table itself. I want to change this but given the placement of the PopUp component and the fact that I want to pass the ID to the component, I'm not sure how to go about it.
The problem is that you have a series of Popups, but only a variable controlling their visibility. Consider replacing the show state as a simple visibility with a showId one, meant as the "id" of the Popup to be shown.
showModal(id) {
this.setState({
showId: id
});
}
hideModal(e) {
this.setState({
showId: null
});
this.props.hideModal && this.props.hideModal(e);
}
Then:
<table className="table">
<thead>
<tr>
<th>S. NO.</th>
<th>NAME</th>
<th>ADDRESS</th>
<th>TELEPHONE</th>
<th>EMAIL</th>
<th>AGE</th>
<th></th>
</tr>
</thead>
<tbody>
{this.state.personData.map((pRow, idx) => (
<>
<PopUp hideModal={this.hideModal} show={this.state.showId === pRow.id} id={siteRow.id} />
<tr key={pRow.id}>
<td>{idx + 1}</td>
<td> <a onClick={() => this.showModal(pRow.id)}> {pRow.name} </a> </td>
<td>{pRow.address}</td>
<td>{pRow.phone}</td>
<td>{pRow.email}</td>
<td>{pRow.age}</td>
<td>
{" "}
<DeleteButton id={pRow.id} onDelete={this.onDelete} />{" "}
</td>
</tr>
</>
</tbody>
</table>
I did not try the code, but I think it should work.
I'm trying to figure out why my header and body rows aren't in sync. I'm using semantic ui for the css. Is it because my body rows are rendered in a different component? I tried moving them all to 1 and it didn't make any difference.
<table className="ui celled table" border="1">
<thead>
<tr>
<th >Status</th>
<th >Service Date of Visit</th>
<th >Claim ID</th>
<th >Insurance Plan</th>
</tr>
</thead>
<tbody>
{this.state.claims.map ( claim => <ClaimRow claim= { claim } /> ) }
</tbody>
and inside the component.
const ClaimRow = ( {claim} =this.props ) => (
<Form.Field>
<tr >
<td >
<input type="radio" name={claim._id} label="That Was Me" value="valid" checked={claim.status === 'valid'} />
Valid? <br />
<input type="radio" name={claim._id} label="Looks Like Fraud" value="fraud" checked={claim.status === 'fraud'} />
Fraud? <br />
<input type="radio" name={claim._id} label="Looks Like Fraud" value="notselected" checked={!claim.status && "defaultchecked"} />
Not Yet Sure
</td>
<td > {claim.claimDate} {claim.status}</td>
<td > {claim.claimID} </td>
<td > {claim.carrier} </td>
</tr>
</Form.Field>
);
ClaimRow.propTypes = {
claim: PropTypes.string.isRequired
};
export default
and the table footer
<tfoot className="full-width">
<tr>
<th colspan="4">
<div className="ui small button">
Approve
</div>
<div className="ui small button">
Approve All
</div>
<div className="ui right floated button" >
Next
<i class="right arrow icon"> </i>
</div>
<div className="ui right floated button" >
<i class="left arrow icon"></i>
Prev
</div>
</th>
</tr>
</tfoot>
</table>
Rows should be returning a <tr> at the top level, not a <Form.Field>.
for me adding this class worked.
.ReactTable .rt-tbody .rt-td{
margin-left: 0;
}
I'm using the following code to generate a simple UI, and I'm trying to convert it to use Bootstrap.
This is my original code (using Skeleton);
render:function(){
return (
<div className="grocery-item row">
<div className="six columns">
<h4 className={this.props.item.purchased ? "strikethrough" : "" }>
{this.props.item.name}
</h4>
</div>
<form onSubmit={this.togglePurchased} className="three columns">
<button className={this.props.item.purchased ? "btn btn-danger" : "button-primary"}>{this.props.item.purchased ? "unbuy" : "buy"}</button>
</form>
<form className="three columns" onSubmit={this.delete}>
<button>×</button>
</form>
</div>
)
}
I tried doing something like this;
render:function(){
return (
<table class="table table-striped">
<thead>
<tr>
<th>Column 1</th>
<th>Columan 2</th>
<th>Columan 3</th>
</tr>
</thead>
<tbody>
<tr>
<h4 className={this.props.item.purchased ? "strikethrough" : "" }>{this.props.item.name}</h4>
<form onSubmit={this.togglePurchased} className="three columns">
<button className={this.props.item.purchased ? "btn btn-danger" : "button-primary"}>{this.props.item.purchased ? "unbuy" : "buy"}</button>
</form>
<form className="three columns" onSubmit={this.delete}>
<button>×</button>
</form>
</tr>
</tbody>
</table>
)
}
But it's not working like I expect. I'm using react-express-examplar as my starting point.
How can I get Bootstrap tables working in my React app?
I think you'll have an easier time if you start your app using create-react-app. They even give instructions on how to use Bootstrap with React.
You said you're new to React. There are a lot of moving parts that can be overwhelming to figure out at first. Using create-react-app will take out a lot of the learning curve and make it a lot easier for you to get started with as little friction as possible.
Good luck!
From my understanding, you want the name and buy/unbuy buttons to come as a row , under respective columns.
In the tr tag, give each html part as a td tag
Please refer below html snippet:
<td>
<h4 class="strikethrough">
name
</h4>
</td>
<td>
<form class="three columns">
<button class="btn btn-info">buy</button>
</form>
</td>
<td>
<form class="three columns">
<button>×</button>
</form>
</td>
Please try to modify the html in your component render method, similarly.
You added table to wrong Component. It must be on GroceryItemList.jsx
Caution: Form is not allowed inside table. I'm just providing the structure and UI and code is not tested.
::: structure should something like-
GroceryItemList.jsx Component::::
render:function(){
return (
<div>
<table className="table">
<thead>
<tr>
<th>Column 1</th>
<th>Columan 2</th>
<th>Columan 3</th>
</tr>
</thead>
<tbody>
{this.props.items.map((item,index)=>{
return (
<GroceryItem item={item} key={"item"+index} />
)
})}
<GroceryListAddItem />
</tbody>
</table>
</div>
)
}
GroceryItem.jsx Component::::
render:function(){
return (
<tr>
<td>
<h4 className={this.props.item.purchased ? "strikethrough" : "" }>
{this.props.item.name}
</h4>
</td>
<td>
<form onSubmit={this.togglePurchased}>
<button className={this.props.item.purchased ? "" : "button-primary"}>{this.props.item.purchased ? "unbuy" : "buy"}</button>
</form>
</td>
<td>
<form onSubmit={this.delete}>
<button>×</button>
</form>
</td>
</tr>
)
}