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
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>
);
}
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/>
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 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');
}
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.