Nested Row with Table Row with Bootstrap 4 / ReactJS - reactjs

I am trying to create a dropdown/collapse area within a table row that is the full width of the table with Bootstrap 4 and React JS. I haven't been able to find a visual of what I want, I just remember using it somewhere before (maybe on AWS?), but I haven't been able to locate it again.
EDIT: Desired action has been found (https://i.imgur.com/Pcg1JgI.png). Once the chevron is clicked, the below rows open.
This is my current code:
import React from "react";
import { API, graphqlOperation } from 'aws-amplify';
import { listTrackerItems } from '../graphql/queries';
class TrackerGeneralPage extends React.Component {
state = {
id: '',
active: [],
completed: [],
completedDateNow: '',
newStatus: 'Complete'
};
async componentDidMount() {
const result = await API.graphql(graphqlOperation(listTrackerItems))
let data = result.data.listTrackerItems.items
let General = data.filter(t=>t.department === 'General');
const activeGeneral = General.filter(t=>t.status === 'Active');
const completedGeneral = General.filter(t=>t.status === 'Completed');
const date = new Date();
const month = date.getUTCMonth() + 1;
const day = date.getUTCDate();
const year = date.getUTCFullYear();
const timeNow = month + "/" + day + "/" + year;
this.setState({active: activeGeneral, completed: completedGeneral, completedDateNow: timeNow });
}
render() {
const { active } = this.state
return (
<>
<div>
<div class="container">
<div class="row">
<div class="col-sm">
</div>
<div class="col-sm">
<div className="mx-auto" align="center">
<h1>General</h1>
</div>
</div>
<div class="col-sm">
<div className="mx-auto mt-2" align="center">
{/* <!-- Button trigger modal --> */}
<a role="button" className="btn btn-dark" href="/tracker/nwa/lab/add" >
Add Tracker
</a>
</div>
</div>
</div>
</div>
{/* Active Trackers */}
<div id="toggle-active" className="">
<div className="my-4">
<table className="table table-hover table-bordered mb-3">
<thead className="thead-dark">
<tr>
<th scope="col">Actions</th>
<th scope="col">Name</th>
<th scope="col">Regulation</th>
{/* <th scope="col">Occurrence</th> */}
<th scope="col">Due On</th>
<th scope="col">Assigned</th>
<th scope="col">Status</th>
{/* <th scope="col">Completer</th>
<th scope="col">Date Completed</th>
<th scope="col">Description</th> */}
</tr>
</thead>
<tbody>
{active.map(item => (
<tr key={item.id}>
<th scope="row" className="dropdown">
<a class="btn" data-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample"><img src="https://icon.now.sh/chevronDown" width="25" height="25" className="d-inline-block align-top" alt="Open Row" /></a>
</th>
<td>{item.name}</td>
<td>{item.reg}</td>
<td>{item.dateDue}</td>
<td>{item.assigned}</td>
<td>{item.status}</td>
<div class="collapse" id="collapseExample">
<div class="card card-body">
<td>{item.occurrence}</td>
<td>{item.completer}</td> */}
<td>{item.dateCompleted}</td>
<td>{item.description}</td>
</div>
</div>
</tr>
))}
</tbody>
</table>
</div> {/* End Table Section */}
</div> {/* End Active Toggle */}
</div> {/* End Container */}
</>
)
}
}
export default TrackerGeneralPage;
If I currently click the dropdown arrow, it places it to the right side of the table: visual on imgur.
If I move this:
<div class="collapse" id="collapseExample">
<div class="card card-body">
<td>{item.occurrence}</td>
<td>{item.completer}</td> */}
<td>{item.dateCompleted}</td>
<td>{item.description}</td>
</div>
</div>
into the <th> where the dropdown/collapse button is located, it places it all into that specific column only: visual on imgur.
I would like the button to open the dropdown/collapse area directly under the table row, as if its attached, (pushing the row beneath further down) and be full width of the table/row.
Each button would need to only open that specific rows dropdown/collapse area as well, and right now if I click any button, it opens all of the rows dropdown/collapse areas.
How is this accomplished/what is this called?

Take this as an idea. Simply add collapse to your <td> and overwrite bootstrap <td> padding;
You can pass value to replace the data-target with unique id for each row like fd1, fd2or other id name that can avoid collision via your map function.
/*overwrite bootstrap table padding*/
.hiddenRow {
padding: 0 !important;
}
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<table class="table table-hover">
<thead>
<th></th><th>1</th><th>2</th><th>3</th>
</thead>
<tbody>
<tr data-toggle="collapse" data-target="#folder1">
<td class="text-center"><span>+</span></td>
<td>Cell 1.1</td>
<td>Cell 1.2</td>
<td>Cell 1.3</td>
</tr>
<tr>
<td colspan="4" class="hiddenRow">
<div id='folder1' class="collapse">
row1
</div>
</td>
</tr>
<tr data-toggle="collapse" data-target="#folder2">
<td class="text-center"><span>+</span></td>
<td>Cell 2.1</td>
<td>Cell 2.2</td>
<td>Cell 2.3</td>
</tr>
<tr style="background:lightyellow">
<td colspan="4" class="hiddenRow">
<div id="folder2" class="collapse">
row2
</div>
</td>
</tr>
</tbody>
</table>

Related

Bootstrap modal in React is not opening

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>
);
}

Rendering table's data header in reactjs

I could render the herader's table users through for exemple: {user[name]}. But I couldn't render the header itself who is the [name] for example rendering: name of Leanne Graham. Can anyone help me with this?
import React from 'react'
const Users= ({ users}) => {
return (
<div>
{users.map((user,index) => (
<div key={index}>
<div className="container smcontainer d-flex justify-content-start">
<div className="row">
<div className="col-md-12">
<table className="table table-striped">
<thead>
</thead>
<tbody>
<tr>
<td className=""> {user['id']} </td>
<td className=""> {user['name']} </td>
<td className=""> {user['username']} </td>
<td className=""> {user['email']} </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
))}
</div>
)}
export default Products
This is the App component
class App extends Component {
constructor(props){
super(props)
this.state= {
users: [],
}
}
async componentDidMount() {
const url = ('https://jsonplaceholder.typicode.com/users')
const response = await fetch (url)
const data = await response.json()
this.setState({users: data.itemsList})
console.log({users: data.itemsList})
}
render() {
return (
<Users users = {this.state.users} />
)
}
}
export default App;
When you map over an array, whatever you return is returned each time for every element in the array. This code will create a whole new table for each user.
I think what you want to do is define your column headers separately from your map call and then map over the array to generate the rows:
const columns = ["ID", "Name", "Username", "Email"];
...
<div>
<div className="container smcontainer d-flex justify-content-start">
<div className="row">
<div className="col-md-12">
<table className="table table-striped">
<thead>
{columns.map(c => <th>{c}</th>)}
</thead>
<tbody>
{users.map((user, index) => (
<tr>
<td className=""> {user['id']} </td>
<td className=""> {user['name']} </td>
<td className=""> {user['username']} </td>
<td className=""> {user['email']} </td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
I made a Codepen demonstrating both ways, but to me the first one makes much more sense.
That should give you what you want.
<thead>
{user['name']}
<thead/>
If you want to take the first name of Leanne Graham, you can do:
<thead>
{user['name'].split(" ")[0]}
<thead/>

React table misaligns table header columns with table row columns

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;
}

How to switch from one tab to another in angularjs?

How do i switch from one tab to another tab in angular js? I am using multiple divs for creating tabs. I want to switch from one tab to another by click on button.
This is part of my code -
<div ng-controller="MyController">
<div class="tabgroup" ng-init="tab=1">
<div class="tab" ng-class="{selected: tab==1}" ng-click="tab = 1">Home</div>
<div class="tab" ng-class="{selected: tab==2}" ng-click="tab = 2">Display Records</div>
<div class="tab" ng-class="{selected: tab==3}" ng-click="tab = 3">Add Records</div>
<div class="tab" ng-class="{selected: tab==4}" ng-click="tab = 4">Remove Records</div>
</div>
<div class="otherContainer">
<div class="tabcontents">
<div ng-show="tab == 1">
This application shows employee details registered for this site. You can add your records by clicking on add button. Also you can update and delete records.
</div>
<div ng-show="tab == 2">
<table border=1>
<thead>
<th>Id</th>
<th>Name</th>
<th>Birthdate</th>
<th>Address</th>
<th>Contact</th>
<th>Email</th>
</thead>
<tr data-ng-repeat="Emp in EmpList">
<td ng-bind="Emp.Id"></td>
<td ng-bind="Emp.Name"></td>
<td ng-bind="Emp.Birthdate"></td>
<td ng-bind="Emp.Address"></td>
<td ng-bind="Emp.Contact"></td>
<td ng-bind="Emp.Email"></td>
<th><input type="button" ng-click="removeItem()" value="Remove" /></th>
<th><input type="button" ng-click="editItem(i)" value="Edit" /></th>
</tr>
</table>
</div>
You can refer the following sample
//in your controller
// code to switch you views based on tabs
$scope.onep = true; // sets bydefault true on div
$scope.one = function() {
$scope.onep = true;
$scope.twop = false;
$scope.threep = false;
}
//follow as above for funcions two() and three()
//your tabs
<div ng-click=one()>
//div content
</div>
<div ng-click=two()>
//div content
</div>
<div ng-click=three()>
//div content
</div>
<p ng-show=onep></p>
<p ng-show=twop></p>
<p ng-show=threep></p>
Using JavaScript for this problem will easily solve the problem.
<div class="tab" data-target="#tab1" ng-class="{selected: tab==1}" ng-click="goToTab(1)">Home</div>
In your controller
$scope.goToTab = function(tabIndex) {
$scope.tab = tabIndex;
angular.element('[data-target="#tab'+tabIndex+'"]').tab('show');
}

Infinite Scroll in angular UI Modal

I am trying to use infinite scroll in a angular UI modal and the modal is defined in ng-template as shown below
<script type="text/ng-template" id="someID" >
<div infinite-scroll="loadMoreEmployees()" infinite-scroll-distance="1">
<div class="modal-header">
<div class="vertical-margin row">
<div class="col-lg-12">
<h2 class="help-block">Departments assign</h2>
</div>
</div>
</div>
<div class="modal-body">
<div class="content-container">
<div class="col-lg-12 col-md-12 simple-data-table-content">
<table data-ng-if="vm.employees!=null || vm.employees.length!=0" class="table table-condensed text-center clear-bottom">
<tbody>
<tr>
<th>Employee No</th>
<th>Employee Name</th>
<th>Email</th>
<th data-ng-repeat="DeptType in vm.DeptTypes track by $index">{{DeptType.name}}</th>
<th></th>
</tr>
<tr data-ng-if="vm.employees==null || vm.employees.length==0"><td colspan="{{vm.DeptTypes.length + 4}}"></td></tr>
<tr data-ng-repeat="employee in vm.employees | limitTo:vm.loadEmployeeLimitCount" data-ng-if="vm.employees!=null && vm.employees.length > 0">
<td class="">{{employee.employeeNumber}}</td>
<td class="">{{employee.name}}</td>
<td class="">{{employee.email}}</td>
<td class="" data-ng-repeat="DeptType in vm.DeptTypes">
<input type="text" only-digits data-ng-model="employee.DeptSummary[DeptType.id]" style="width:50px;" min="1" />
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
But infinite scroll as does not respond to scroll action, please point out where I am wrong.

Resources