How to add scroll bars to a dynamic table with multiple tbodys - css

I am facing a complicated table design. I need to create a table with possible multiple tbodys. just like this:
As you can see, each tbody is for a date. and I need to add as many row as I want by clicking '+' icon for EACH date. and also can remove each row by clicking '-' icon. Now this is what I have done, but the new requirement is I need to add scroll bar for EACH tbody! (not for all table) each date(tbody) will show a scroll bar if I create more than 3 rows. as you can see, if I click '+' icon for date 01/08/2016, the scroll will appear on the right side of that tbody(only for this date leave other days alone.) How can I do it.
Here is my html:
<table class="table expensetable">
<thead>
<tr>
<th ng-hide="lodging.roomSameForAllDays">Date</th>
<th>Expense Type</th>
<th>Amount</th>
<th>Reimbursement</th>
<th ng-hide="lodging.sameDescriptionForAll">Description</th>
<th></th>
</tr>
</thead>
<tbody ng-repeat="day in lodging.roomData" ng-class="{'scroll-bar':getExpenseLength(day)}">
<tr ng-repeat-start="expense in day" class="ecom-components" ng-repeat-end>
<td ng-show="!lodging.roomSameForAllDays && ($index == 0)"
rowspan="{{day.length + 1}}"
style="vertical-align: top;">{{indexToDate($parent.$index) | date : companyDateFormat}}</td>
<td>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle clearfix" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<span class="dropdown-label pull-left">{{expense.expenseType.expenseTypeName}}</span>
<span class="caret pull-right"></span>
</button>
<ul class="dropdown-menu">
<li ng-repeat="exp in roomRateTaxExpenseList | orderBy:'expenseTypeName'"><a href="javascript:void(0)"
ng-click="expense.expenseType = exp">{{exp.expenseTypeName}}</a></li>
<li></li>
</ul>
</div>
</td>
<td><input type="text" ecom-amount ng-model="expense.amount"></td>
<td>
<div class="dropdown" style="width:100%">
<button class="btn btn-default dropdown-toggle clearfix" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="dropdown-label pull-left">{{RNP_STATUSES[expense.rnp]}}</span>
<span class="caret pull-right"></span>
</button>
<ul class="dropdown-menu">
<li>Yes</li>
<li>No</li>
<li>Personal</li>
<li></li>
</ul>
</div>
</td>
<td ng-hide="lodging.sameDescriptionForAll"><input type="text" ng-model="expense.description"></td>
<td><span class="whitebutton remove" ng-click="deleteRow('roomData', $parent.$index, $index)"></span></td>
</tr>
<tr>
<td colspan="5"><span class="whitebutton add" ng-click="addRow('roomData', $index)"></span></td>
</tr>
</tbody>
</table>
Thanks in advance.
Here is what I have tried to, it is close but still didn't 100% match the requirement:
table.expensetable{
width:100%;
thead{
display:table;
width:100%;
}
tbody {
max-height:240px;
display:block;
tr{
display:table;
width:100%;
}
}
}
post js for more information:
$scope.getExpenseLength = function(day){
var isScroll = false;
if(day.length>3){
isScroll = true;
}else{
isScroll = false;
}
return isScroll;
}
As you can see, I can add scroll-bar to each tbody( which is cool) but the rowspan, doesn't work after scroll-bar appear or disappear. any update I need here?

We have done similar kind of thing in one of our project like below
var abc = $scope.$watch('grid.gridModel.data.data.items.length', function (newValue, oldValue) {
if (newValue > 4) { //grid should show a scrollbar after 3 rows
$scope.grid.gridOptions.autoheight = false;
if ($scope.grid.stateModel.gridObj) {
$($scope.grid.stateModel.gridObj.element).jqxGrid('height', '124px');
$($scope.grid.stateModel.gridObj.element).jqxGrid('refresh');
}
} else {
$scope.grid.gridOptions.autoheight = true;
if ($scope.grid.stateModel.gridObj) {
$($scope.grid.stateModel.gridObj.element).jqxGrid('height', 'auto');
$($scope.grid.stateModel.gridObj.element).jqxGrid('refresh');
}
}
});
Here what we are doing is, we are fixing the height of the grid if it contains more then 3 rows else it is of autoheight.
In your case if you can count number of rows in addRow( & deleteRow( function then you can also set height/max-height of the table. You might need to set overflow-y:auto while fixing the height.
Hope this helps.

Related

Materialize CSS dropdown inside ngFor Angular 8

I'm trying to add a Materialize dropdown inside a table generate with *ngFor and the dropdown didn't show.
If I put the dropdown code outside the table it works.
<p>Users enabled in this node: {{usersEnabled}}</p>
<p>Users in this node: {{users.length}}</p>
<table>
<thead>
<th>
Email
</th>
<th>
Enabled
</th>
<th>
Actions
</th>
</thead>
<tbody>
<tr *ngFor="let user of users">
<td>
{{user.username}}
</td>
<td class="isLink cursorIcon" (click)="enableDisableUser(user.apiKey)">
{{user.enabled}}
</td>
<td>
<!-- Dropdown Structure -->
<!-- <button class="btn" (click)="resetPassword(user)">Reset password</button> -->
<a class='dropdown-trigger btn' data-target='dropdown{{user.apiKey}}'>Drop Me!</a>
<ul id='dropdown{{user.apiKey}}' class='dropdown-content'>
<li>one</li>
<li>two</li>
<li class="divider" tabindex="-1"></li>
<li>three</li>
<li><i class="material-icons">view_module</i>four</li>
<li><i class="material-icons">cloud</i>five</li>
</ul>
</td>
</tr>
</tbody>
</table>
Typescript important methods
ngOnInit() {
this.getUsers();
}
private getUsers(): void {
this.userService.getUsersByNodeApiKey(this.nodeKey).subscribe(
res => {
this.usersEnabled = res.filter((user: User) => user.enabled).length;
this.users = res.sort((a, b) => a.enabled < b.enabled ? 1 : -1);
M.AutoInit();
var elems = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elems, {autoTrigger: true});
},
err => console.error(err)
);
}
I'm using Angular 8 and Materialize CSS 1.0
For that you need to add [innerHTML] which enables generated html inside your table like this
[innerHTML]="user.dropdown"
Where as user.dropdown may be an empty string defined in your .ts file or some value which you want to use in drop-down.
May be in your case user.apiKey can also be used.
Try rendering the table / row in the view once users scope has it's data by add a
<ng-container *ngIf="users.length">
<tr *ngFor="let user of users">
.
.
.
</tr>
</ng-container>
Hope this helps!
Hey #Marc Serret i Garcia... I have found a work around. Try if my provided solution works:-
<tbody>
<tr *ngFor="let user of users">
<td>
{{user.username}}
</td>
<td class="isLink cursorIcon" (click)="enableDisableUser(user.apiKey)">
{{user.enabled}}
</td>
<td>
<!-- Dropdown Structure -->
<!-- <button class="btn" (click)="resetPassword(user)">Reset password</button> -->
<a class='dropdown-trigger btn' [attr.data-target]='user.apiKey'>Drop Me!</a>
<ul [id]='user.apiKey' class='dropdown-content'>
<li>one</li>
<li>two</li>
<li class="divider" tabindex="-1"></li>
<li>three</li>
<li><i class="material-icons">view_module</i>four</li>
<li><i class="material-icons">cloud</i>five</li>
</ul>
</td>
</tr>
</tbody>
Look for the changes that I have made -
<a class='dropdown-trigger btn' [attr.data-target]='user.apiKey'>Drop Me!</a>
And the other for the id of dropdown - <ul [id]='user.apiKey' class='dropdown-content'>. It worked for me. Hope this helps.
Please look at my stackblitz:- https://stackblitz.com/edit/multipledropdown

Dropdown is getting cropped out when using the ui-scroll directive

When I go to the last row (no. 25) and click edit you will see that the dropdown it's cropped out. Can you figure out how to solve this issue?
https://plnkr.co/edit/22e9bo?p=preview
<div ui-scroll-viewport class="col-md-12" style="height: 500px; border: dashed 1px #ddd;">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>id</th>
<th>source</th>
<th>destination</th>
</tr>
</thead>
<tbody>
<tr ui-scroll="item in datasource">
<td>{{item.id}} <a ng-click="showDropdown(item.id)">edit</a></td>
<td>{{item.source}}</td>
<td ng-if="dropdowns.active !== item.id">{{item.destination}}</td>
<td ng-if="dropdowns.active === item.id">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{item.destination}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li>10.0.0.0</li>
<li>10.255.255.255</li>
<li>172.16.0.0</li>
<li>172.31.255.255</li>
<li>192.168.255.255</li>
<li role="separator" class="divider"></li>
<li>192.168.0.0</li>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</div>
Generally, this is not the ui-scroll issue, this is how the Bootstrap hosts it's dropdown menu in DOM. If the hoster element has overflow-y: scroll, then you'll get the situation you described in your question. As an angular-way solution I would suggest to use angular-ui wrapper for the Bootstrap: https://angular-ui.github.io/bootstrap/.
They have Dropdown directive which has dropdown-append-to and dropdown-append-to-body settings which allow you to append your Bootstrap dropdown to any element. This will solve the issue.

bootstrap searchbox and pagination are in the middle. I want them at the right

<?php
// include Database connection file
include("connectionfile.php");
// Design initial table header
$data = '<table class="table table-bordered table-striped table-hover" id="supplierTable" style="max-width: 1000px">
<thead>
<tr>
<th>No</th>
<th>Sym</th>
<th>Name</th>
<th>Tax</th>
<th>Address</th>
<th>Phone</th>
<th>Email</th>
<th>Products</th>
<th>Update</th>
<th>Delete</th>
</tr>
</thead>';
$query = "SELECT * FROM suppliers";
$result=mysqli_query($con,$query);
// $row=mysqli_fetch_array($result);
if (!$result) {
exit(mysqli_error());
}
// if query results contains rows then featch those rows
if(mysqli_num_rows($result) > 0)
{
$number = 1;
while($row = mysqli_fetch_array($result))
{
$data .= '<tr>
<td align="right"> '.$number.'</td>
<td align="center">'.$row['symbol'].'</td>
<td align="center">'.$row['companyname'].'</td>
<td align="center">'.$row['taxnumber'].'</td>
<td align="center">'.$row['address'].'</td>
<td align="center"> +'.$row['phone'].'</td>
<td align="center">'.$row['email'].'</td>
<td>
<button onclick="GetSupplierProducts('.$row['id'].')" class="btn btn-success text-center">All Products</button>
</td>
<td>
<button onclick="GetSupplierDetails('.$row['id'].')" class="btn btn-warning text-center">Update</button>
</td>
<td>
<button onclick="DeleteSupplier('.$row['id'].')" class="btn btn-danger text-center">Delete</button>
</td>
</tr>';
$number++;
}
}
else
{
// records now found
$data .= '<tr><td colspan="6">Records not found!</td></tr>';
}
$data .= '</table>';
echo $data;
?>
<script>
$(document).ready(function() {
$('#supplierTable').DataTable({
bJQueryUI: true,
sPaginationType: "full_numbers"
});
});
</script>
<script src="../bower_components/datatables/media/js/jquery.dataTables.min.js"></script>
<script src="../bower_components/datatables-plugins/integration/bootstrap/3/dataTables.bootstrap.min.js"></script>
<script src="../dist/js/sb-admin-2.js"></script>
This is my code it displays the search bar and pagination at the middle. I would like them to be at the right. any ideas? Here is a picture:
I would simply love to see my search box under add a new supplier.
thanks
Adding the three scripts at the end shows the search box, entries and pagination. well, I have the button in a main page:
<div class="pull-right">
<button class="btn btn-success" data-toggle="modal" data-target="#add_new_supplier_modal">Add A New Supplier</button>
</div>
I can't import your bower components but i can give you some idea of how things should be arranged.
The basic idea is that you need to place all of your 3 components and also the table in their appropriate boxes. And this boxes are separated in groups. Start simple in a separate file - fake static data.. After you have the bare bones css+html working, then you simply place it inside php and do rendering with real dynamic data..
This is the code:
<div class="parent_div" style="margin-top: 20px;"> ///everything goes in here including the table
<!--only the 3 components in here-->
<div class="the_3_components_you_have">
<!-- the button is first component, "text-right" is a bootstrap class you need to align stuff to right. Doesn't work on the button directly so we wrap it in a div -->
<div class="text-right" style="margin-right:50px;">
<button class="btn btn-success" >Add a New Suplier</button>
</div>
<!-- Display on the same row the pagination and search component. But again text-right only works on display:block so we need position relative on the pagination element-->
<div>
<div style="position: relative; top: 23px; left: 20px; ">Show pagination Component.</div>
<div class="text-right" style="margin-right: 50px; ">Search stuff: <input style="margin: 0px;" type="text"></div>
</div>
</div>
<!-- the table separately goes in here -->
<div>
Table goes here.
</div>
</div>
Instead my styles - you can create your own classes, tweak them as you like, and instead of text, you can place the script tags you have, and they will load appropriately in that box. Chrome Developer Tools will help you. Here is a preview:
Learn about Bootstrap clases and Bootstrap positioning here.
and you can find this code as a live example here: JsBin Link

Do not "line break" the arrow when using btn-group

How to do not allow the arrow to go to another line? This will happens if the screen did not have enough space, see the image:
JSFIDDLE
CODE:
<table class="table table-condensed table-hover table-striped">
<thead>
<tr>
<th class="shrink">COLUMN 1</th>
<th class="shrink">COLUMN 2</th>
<th class="expand">COLUMN 3</th>
<th class="expand">COLUMN 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="btn-group btn-block">
<span class="btn btn-danger btn-xs btn-block dropdown-toggle text-left" data-hover="dropdown" data-toggle="dropdown">Descrition of the item <span class="pull-right"><i class="fa fa-caret-down"></i></span></span>
<ul class="dropdown-menu">
<li><i class="fa fa-caret-right"></i>Option 1</li>
</ul>
</div>
</td>
<td>Some info here</td>
<td>Some more here</td>
<td>And here too</td>
</tr>
<tr>
<td>
<div class="btn-group btn-block">
<span class="btn btn-danger btn-xs btn-block dropdown-toggle text-left" data-hover="dropdown" data-toggle="dropdown">Descrition of the i asd adasdasdasdasdtem <span class="pull-right"><i class="fa fa-caret-down"></i></span></span>
<ul class="dropdown-menu">
<li><i class="fa fa-caret-right"></i>Option 1</li>
</ul>
</div>
</td>
<td>Some info here</td>
<td>Some more here</td>
<td>And here too</td>
</tr>
<tr>
<td>
<div class="btn-group btn-block">
<span class="btn btn-danger btn-xs btn-block dropdown-toggle text-left" data-hover="dropdown" data-toggle="dropdown">No item <span class="pull-right"><i class="fa fa-caret-down"></i></span></span>
<ul class="dropdown-menu">
<li><i class="fa fa-caret-right"></i>Option 0</li>
</ul>
</div>
</td>
<td>Some info here again</td>
<td>yay more info here too</td>
<td>ok, enough info now, that is enough</td>
</tr>
</tbody>
</table>
Tried some white-space: nowrap; but could not get the desired result. Any help will be great. The arrow must be in the right side, always.
Instead of floating the carets right, float the text left.
<span class="pull-left">Description... </span> <i class="fa fa-caret-down"></i>
Demo
span.pull-right floats the i.fa-caret-down to the right after your “Description of the item”, which means it’s placed on the next line. Try putting the float before the description. For example:
<span class="btn btn-danger btn-xs btn-block dropdown-toggle text-left"
data-hover="dropdown" data-toggle="dropdown">
<span class="pull-right"><i class="fa fa-caret-down"></i></span>
Description of the item
</span>
Sample, fixing the first caret.
Setting the white-space: nowrap property will not effect the dropdown icon as it's in a different flow due to the float: right; applied to it by the class .pull-right.
What you're describing sounds as though you want to set a position: absolute against the icon. This does fix the issue of the icon not being effected by the text, but it raises a further question of, how do you want to resolve too much text in a button which isn't sufficiently big?
As far as I can see, the only way to resolve this would be to also apply an overflow: hidden property to the buttons, to force the spacing to the right where the icon sits to be empty, and to apply an ellipsis on the text if any overflow does occur. You can see the combination of these selectors in this JSFiddle, I have forced the buttons to be smaller purely to demonstrate how this would work when they are forced to consume a space smaller that you would otherwise like:
.btn {
white-space: no-wrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 10px;
}
.fixed-right {
position: absolute;
right: 5px;
}

Twitter bootstrap TD no padding

For one of my projects I need to make one button full width/height of the TD. I tried setting the normal .btn-warning with -Xpx!important but didn't work.
Currently I have this:
But want to achieve to this:
I'm using the following code:
<tbody>
<tr>
<td class="td-btn"><span class="glyphicon glyphicon-ok"></span></td>
<td>Projectnaam</td>
</tr>
</tbody>
Does anyone know how to get this button full with/height with the TD without spacing?
Friend of mine helped out:
<td style="padding: 0px;">
<a href="#" class="btn-sm btn btn-success" style="height: 44px;padding: 12px 10px;">
<span class="glyphicon glyphicon-ok"></span>
</a>
</td>
It's almost what I want =). Thanks all.
.table-condensed>thead>tr>th,
.table-condensed>tbody>tr>th,
.table-condensed>tfoot>tr>th,
.table-condensed>thead>tr>td,
.table-condensed>tbody>tr>td,
.table-condensed>tfoot>tr>td {
padding: 5px;
}

Resources