table javascript pagination and sorting - javascript

How Can I search and paginate Table? Also, how to sort all cols ascending and descending? Now I can do it only in one way.
Table loads data from javascript.
const users = [
{
obec: 'Bratislava',
okres: 'Bratislava',
kraj: 'Bratislavský',
obyvatelov: 411228,
celkovo: 1,
eco: 1,
peo: 1,
gov: 131,
mob: 203,
env: 81,
liv: 3 }];
//LOAD DATA
let data = users.map(createRow);
$('tbody').html(data);
// SORT TABLE
$('table thead td').on('click', e => {
let $this = $(e.currentTarget);
// Hide / show caret
$('.fa-caret-down').hide();
$this.find('.fa-caret-down').show();
// Get type and sort data
let type = e.target.id;
let sorted = sort(users, type);
// Create rows and set table HTML
let data = sorted.map(createRow);
$('tbody').html(data);
});
function createRow(user) {
let row = `<tr>
<td>${user.obec}</td>
<td>${user.okres}</td>
<td>${user.kraj}</td>
<td>${user.obyvatelov}</td>
<td>${user.celkovo}</td>
<td>${user.eco}</td>
<td>${user.peo}</td>
<td>${user.gov}</td>
<td>${user.mob}</td>
<td>${user.env}</td>
<td>${user.liv}</td>
</tr>`;
return row;
}
function sort(obj, type) {
let sorted = obj.sort((b, a) =>
type === 'obyvatelov' ? b.obyvatelov - a.obyvatelov :
type === 'celkovo' ? b.celkovo - a.celkovo :
type === 'eco' ? b.eco - a.eco :
type === 'peo' ? b.peo - a.peo :
type === 'gov' ? b.gov - a.gov :
type === 'mob' ? b.mob - a.mob :
type === 'env' ? b.env - a.env :
type === 'liv' ? b.liv - a.liv :
a.obec.localeCompare(b.obec));
return sorted;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- partial:index.partial.html -->
<table class="table table-striped table-bordered" cellspacing="0" style="width:100%;">
<thead>
<tr>
<td id="obec">Obec <i class="fa fa-caret-down"></i></td>
<td id="okres">Okres</td>
<td id="kraj">Kraj</td>
<td id="obyvatelov">Počet obyvateľov <i class="fa fa-caret-down"></i></td>
<td id="celkovo">Celkové poradie<i class="fa fa-caret-down"></i></td>
<td id="eco">Economy <i class="fa fa-caret-down"></i></td>
<td id="peo">People <i class="fa fa-caret-down"></i></td>
<td id="gov">Governance <i class="fa fa-caret-down"></i></td>
<td id="mob">Mobility <i class="fa fa-caret-down"></i></td>
<td id="env">Environment <i class="fa fa-caret-down"></i></td>
<td id="liv">Living <i class="fa fa-caret-down"></i></td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script><script src="new.js"></script>
I am new in javascript and can not solve this. I red whole internet but no luck.
This is how I want to look it like.

Related

Bootstrap 4 - DataTable search not working on rows added by jQuery

I have a problem with the Bootstrap 4 search tool. If the rows are added manually in tbody the search works, but if I add a new row from jQuery then search doesn't see those rows.
This is the body of the table.
Below is the function that adds a new row to the table:
function addProduct(name, id, price, quantity = 1)
{
var template = $("#product-template").clone(true, true);
var existingRow = $("#product-table").find('#product' + id);
template.removeClass("disabled");
if (existingRow.length > 0)
{
var quantity = parseInt(existingRow.find('.prod-quantity').text()) + 1;
existingRow.find('.prod-quantity').text(quantity);
calculateTotalPrice(id);
return;
}
template.attr("unit-price", price);
template.attr("id", "product" + id);
template.find('.prod-name').attr("title", name);
template.attr("productID", id);
template.find('.prod-name').text(name);
template.find('.prod-quantity').text(quantity);
template.find('.total-price').text(price);
$(template).css("display", "table-row");
$("#product-table").append(template);
calculateTotalPrice(id);
orderTableData();
calculateTotalPayment();
}
<tbody id="product-table" class="prd">
<tr id="product-template" class="tr-prod disabled">
<td class="text-center nr-order" id=""></td>
<td class="prod-name" contenteditable="true" title="" style="background-color: white; color:black;">a</td>
<td class="prod-quantity text-center" contenteditable="true" style="background-color: white; color:black">1</td>
<td class="total-price text-center"></td>
<td class="col-sm-3 text-center " style="width: 25px!important;">
<i class="fas fa-minus-circle remove" title="Elimină" style="font-size:20px;color:#F08080;width:20px">
</i>
</td>
</tr>
<tr id="product-template-1" class="tr-prod disabled">
<td class="text-center nr-order" id=""></td>
<td class="prod-name" contenteditable="true" title="" style="background-color: white; color:black;">b</td>
<td class="prod-quantity text-center" contenteditable="true" style="background-color: white; color:black">1</td>
<td class="total-price text-center"></td>
<td class="col-sm-3 text-center " style="width: 25px!important;">
<i class="fas fa-minus-circle remove" title="Elimină" style="font-size:20px;color:#F08080;width:20px">
</i>
</td>
</tr>
</tbody>
I don't know why, but the rows added with the addProduct() function don't appear in the search, and not only that, but they disappear completely when I'm searching for something.
What am I missing, maybe I should update the table after I add a new row?
<script>
$(document).ready(function () {
var table = $('#product-table').DataTable();
$('.dataTables_length').addClass('bs-select');
function addProduct(name, id, price, quantity = 1)
//instead $("#product-table").append(template)
table.row.add([
'td 1',
'td 2',
'td 3',
...
'td n',
])
table.draw();
}
});
</script>

How to search a table that has multiple pages?

I have a table with pagination and a search function that searches the said table. At the moment the search function only searches for values on the table page I am on rather than the entire table. Is there any way I can amend the search function below to allow the entire table to be searched?
Please note I am searching by multiple TD elements of the table so hence the multiple TD variables.
TS File
searchTable(table) {
var input, filter, table, tr, td, td2, td3, td4, i, txtValue, txtValue2, txtValue3, txtValue4;
input = document.getElementById("searchInput");
filter = input.value.toUpperCase();
table = document.getElementById(table);
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
td2 = tr[i].getElementsByTagName("td")[1];
td3 = tr[i].getElementsByTagName("td")[2];
td4 = tr[i].getElementsByTagName("td")[3];
if (td || td2 || td3 || td4) {
txtValue = td.textContent || td.innerText;
txtValue2 = td2.textContent || td2.innerText;
txtValue3 = td3.textContent || td3.innerText;
txtValue4 = td4.textContent || td4.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1 || txtValue2.toUpperCase().indexOf(filter) > -1 || txtValue3.toUpperCase().indexOf(filter) > -1 || txtValue4.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
Table
<table class="table align-items-center table-flush" id="customersTable">
<thead class="thead-light">
<tr>
<th scope="col">Name</th>
<th scope="col">Contact Email</th>
<th scope="col">Package</th>
<th scope="col">Subscription</th>
<th scope="col">Active</th>
<th scope="col">Customer Since</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let cust of customers | slice: (page-1) * pageSize : (page-1) * pageSize + pageSize">
<td class="primaryColumn">
{{cust.name.S}}
</td>
<td>
{{cust.email.S}}
</td>
<td>
{{cust.package_name.S}}
</td>
<td>
{{cust.subscription_name.S}}
</td>
<td [ngClass]="{
'active' : cust.sub_status.BOOL == true,
'inactive' : cust.sub_status.BOOL == false
}">
{{cust.sub_status.BOOL}}
</td>
<td>
{{cust.date_created.S}}
</td>
<td class="text-right">
<div ngbDropdown placement="bottom-right">
<a class="btn btn-sm btn-icon-only text-light" ngbDropdownToggle>
<i class="fas fa-ellipsis-v"></i>
</a>
<div ngbDropdownMenu class=" dropdown-menu-right dropdown-menu-arrow">
<a class="dropdown-item" (click)="selectCustomer(cust);openForm(custUpdate)"><i class="fas fa-edit"></i><span class="menu-option">Edit</span></a>
<a class="dropdown-item" (click)="selectCustomer(cust);openForm(custDelete)"><i class="fas fa-trash"></i><span class="menu-option">Delete</span></a>
</div>
</div>
</td>
</tr>
</tbody>
</table>
HTML File
<div class="form-group has-search">
<span class="fa fa-search form-control-feedback"></span>
<input type="text" id="searchInput" class="form-control" placeholder="Search" (keyup)="searchTable('customersTable')">
</div>
Thanks all!
Since pagination is done on the front-end side and since, as someone also stated in the comments section, this is an Angular application, juggling with DOM is not the best practice.
What you can do is use a work variable that would hold the current state of the customers list at any time and hold the data set in a different variable.
Table filtering would mean filtering the complete data set and assigning the result to the work variable. Angular should then detect the change and update the DOM accordingly.

How do i load data to a table on dropdownchange using ajax

$("#sel_gram").change(function(){
var gramid = $(this).val();
$.ajax({
url: 'getBooth-details.php',
type: 'post',
data: {gram:gramid},
dataType: 'json',
success:function(response){
var len = response.length;
for( var i = 0; i<len; i++){
var id = response[i]['id'];
var name = response[i]['name'];
var booth_officer_name = response[i]['booth_officer_name'];
var booth_officer_contact = response[i]['booth_officer_contact'];
}
}
});
});
I want to add this to a table that I have designed below the select options.
I am getting all the data properly but I'm unable to use it in my table .
This is the table where i want to show the data.
<table class="table table-hover p-table">
<thead>
<tr>
<th>Booth Name</th>
<th>Booth Adhikari</th>
<th>Contact</th>
<th>Custom</th>
</tr>
</thead>
<tbody>
<tr>
<td class="p-name">
<h6 id="boothname">Name</h6>
</td>
<td class="p-team">
<h6 id="adhikariname"></h6>
</td>
<td>
<h6 id="adhikaricontact"></h6>
</td>
<td>
<i class="fa fa-folder"></i> View
<i class="fa fa-pencil"></i> Edit
<i class="fa fa-trash-o"></i> Delete
</td>
</tr>
</tbody>
</table>
This is where i want my data to be displayed.. where on click of view i want to take user to next page with id of the booth show that i can show further details
You can append every row using += in some variable and then use .html() to append same row inside your <tbody> .
Demo Code :
//your response
var response = [{
"id": "1",
"name": "Booth First",
"booth_officer_name": "First Adhikari",
"booth_officer_contact": "9827198271",
"gram_parshad_name": "Gram Officer One",
"gram_parshad_contact": "1231231231",
"gram_population": "10000",
"gram_house_count": "106",
"gram_voters_count": "8922",
"gram_polling_both_count": "20",
"zone_selected": "23",
"sector_selected": "14",
"panchayat_selected": "9",
"gram_selected": "6",
"zone_area": "dongargadh",
"zone_region": "rural"
}];
var len = response.length;
var data = "";
for (var i = 0; i < len; i++) {
//appeding each row inside <tr>
data += '<tr><td class="p-name"><h6 id="boothname">' + response[i]['name'] + '</h6> </td><td class="p-team"> <h6 id="adhikariname">' + response[i]['booth_officer_name'] + '</h6></td> <td><h6 id="adhikaricontact">' + response[i]['booth_officer_contact'] + '</h6></td><td><i class="fa fa-folder"></i> View <i class="fa fa-pencil"></i> Edit <i class="fa fa-trash-o"></i> Delete </td></tr>';
}
//appending data inside table <tbody>
$("#data").html(data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-hover p-table" border="1">
<thead>
<tr>
<th>Booth Name</th>
<th>Booth Adhikari</th>
<th>Contact</th>
<th>Custom</th>
</tr>
</thead>
<tbody id="data">
<!--data will come here-->
</tbody>
</table>

angular 2 table collapse not working properly while sorting

I am working on angular 2. I am creating collapsible using ngFor directive in html table and sorting the table column wise. Before sorting the child collapse row placed between the main rows and working as expected but after sorting the collapsible rows showing top of the all rows.
Using sort option is only for main row not for inner collapse row.
Couldn't add image for clear explanation.
stackblitz example https://stackblitz.com/edit/angular-zoytga?file=src%2Fapp%2Fapp.component.html
<tbody class="portfolio-tbody">
<ng-container *ngFor="let liveData of liveDatas let i=index">
<tr class="portfolio-tr">
<td class="portfolio-td">{{liveData.siteName}}
<img src="../../images/caret.svg" class="portfolio-table-caret" data-toggle="collapse" [attr.data-target]="'.' + i" (click)="expandDevice(liveData.siteName, $event)">
</td>
<td class="portfolio-td">{{liveData.address}}</td>
<td class="portfolio-td"><img src="../../images/{{liveData.ledHealth == 1 ? 'on_icon' : 'off_icon'}}.png"></td>
<td class="portfolio-td"><img src="../../images/{{liveData.lightStatus == 1 ? 'on_icon' : 'off_icon'}}.png"></td>
<td class="portfolio-td">{{liveData.SV}}</td>
<td class="portfolio-td">{{liveData.SC}}</td>
<td class="portfolio-td">{{liveData.BV}}</td>
<td class="portfolio-td">{{liveData.BC}}</td>
<td class="portfolio-td">{{liveData.ts | date:'dd-MM-yyyy HH:mm:ss'}}</td>
</tr>
<tr *ngFor="let thisSitsDevice of thisSitsDevices let ind=index">
<ng-container *ngIf="liveData.siteName==thisSitsDevice.siteName">
<td class="hiddenRow portfolio-td-devices">
<a [routerLink]="['/energy-index']">
<div class="collapse panel-collapse in" class={{i}}>{{thisSitsDevice.deviceName}}</div>
</a>
</td>
<td class="hiddenRow portfolio-td-devices">
<div class="collapse panel-collapse in" class={{i}}>{{thisSitsDevice.address}}</div>
</td>
<td class="hiddenRow portfolio-td-devices">
<div class="collapse panel-collapse in" class={{i}}>
<img src="../../images/{{thisSitsDevice.ledHealth == 1 ? 'on_icon' : 'off_icon'}}.png">
</div>
</td>
<td class="hiddenRow portfolio-td-devices">
<div class="collapse panel-collapse in" class={{i}}>
<img src="../../images/{{thisSitsDevice.lightStatus == 1 ? 'on_icon' : 'off_icon'}}.png">
</div>
</td>
<td class="hiddenRow portfolio-td-devices">
<div class="collapse panel-collapse in" class={{i}}>{{thisSitsDevice.SV}}</div>
</td>
<td class="hiddenRow portfolio-td-devices">
<div class="collapse panel-collapse in" class={{i}}>{{thisSitsDevice.SC}}</div>
</td>
<td class="hiddenRow portfolio-td-devices">
<div class="collapse panel-collapse in" class={{i}}>{{thisSitsDevice.BV}}</div>
</td>
<td class="hiddenRow portfolio-td-devices">
<div class="collapse panel-collapse in" class={{i}}>{{thisSitsDevice.BC}}</div>
</td>
<td class="hiddenRow portfolio-td-devices">
<div class="collapse panel-collapse in" class={{i}}>{{thisSitsDevice.ts | date:'dd-MM-yyyy HH:mm:ss'}}</div>
</td>
</ng-container>
</tr>
</ng-container>
<tr *ngIf=" !liveDatas || liveDatas.length == 0 ">
<td style="text-align: center;" colspan="9">No data to display....</td>
</tr>
<!-- <tr *ngIf=" liveDatas == undefined">
<td style="text-align: center;" colspan="9">Loading....</td>
</tr> -->
</tbody>
Sorting query:
sortTable(f: any, n: number, sortingOrder: string) {
var rows = $('#portfolio-table tbody .portfolio-[tr][1]').get();
rows.sort(function(a: any, b: any) {
var A = getVal(a);
var B = getVal(b);
if (sortingOrder == 'descending') {
if (A < B) {
return -1 * f;
}
}
if (sortingOrder == 'ascending') {
if (A > B) {
return 1 * f;
}
}
return 0;
});
function getVal(elm: any) {
var v = $(elm).children('td').eq(n).text().toUpperCase();
if ($.isNumeric(v)) {
v = parseInt(v, 10);
}
return v;
}
$.each(rows, function(index: any, row: any) {
$('#portfolio-table').children('tbody').append(row);
});
}
sorting(sortingOrder: string) {
this.f_sl *= -1;
var n = 1
this.sortTable(this.f_sl, n, sortingOrder);
}
And sorting also not working properly.
As far as I can tell, your problem is that you're still "thinking in jQuery".
You don't want to manipulate directly the dom, in Angular.
You want to manipulate the data that builds the Dom, so whenever you change it, Angular can do his magic.
In your code you read the dom and sort it, instead of simply working on your data.
First: use TypeScript at your advantage. liveDatas is not an any, at least can be a any[]. You could also define a typing for your record class, and get autocompletion for your liveDatas records.
Second: just sort your data, not the rows:
sortTable(f: number, n: number, sortingOrder: string) {
this.liveDatas.sort((a: any, b: any) => {
if (a.siteName > b.siteName) return f;
if (a.siteName < b.siteName) return -f;
return 0;
}
}
Third: allow Angular's ngFor to track your rows when sorting them, so the Dom elements are actually swapped, instead of destroyed. Probably it will not make a huge difference, but sometimes it will, and it's a good habit:
<!-- in your .html -->
<ng-container *ngFor="let liveData of liveDatas; let i=index; trackBy: trackByUniqueId">
And the body of the track by function
// in your .ts
trackByUniqueId(index: number, value: any): any {
return value.siteName + value.ts;
}
Hope it helps!

Jquery datatable fnFilter is not work in some conditions

In my code i use fnFilter function of Jquery datatable to search the data.
In some cases it search perfectly but in some cases it not.
if i try to search code = "BS" it will search perfectly.
But when i try to search using code = "AL" it will display all records. which is not correct.
This is my code for datatable search option.
$("div.dataTables_filter input").bind('keypress', function (e) {
var searchText = $(this).val().trim();
if (e.which == 13) {
$("#search-error-text").remove();
if (searchText.length > 0) {
var value = searchText;
oTable.fnFilter(value);
$("div.dataTables_filter input").val(searchText);
}
else {
var errorMessage = "Please Enter Data!";
$("div.dataTables_filter input").before("<span id='search-error-text' class='error-text'>" + errorMessage + "</span>");
return;
}
}
else {
return;
}
});
$("div.dataTables_filter #grid-search-button").click(function () {
$("#search-error-text").remove();
var searchText = $("div.dataTables_filter input").val().trim();
if (searchText.length > 0) {
var value = searchText;
oTable.fnFilter(value);
$("div.dataTables_filter input").val(searchText);
}
else {
var errorMessage = "Please Enter Data!";
$("div.dataTables_filter input").before("<span id='search-error-text' class='error-text'>" + errorMessage + "</span>");
return false;
}
});
Html code below table.
<div class="table-responsive">
<table id="datatable-sale" class="datatable">
<thead>
<tr>
<th class="table_heading table-head ">
Code
</th>
<th class="table_heading table-head">
Description
</th>
<th class="table_heading table-head">
Type
</th>
<th class="table_heading table-head cursorDefault">
Edit
</th>
<th class="table_heading table-head cursorDefault">
Status
</th>
<th class="table_heading table-head cursorDefault">
Delete
</th>
</tr>
</thead>
<tbody class="table-head">
#foreach (var item in ViewData["sale"] as IEnumerable<Sales_lut>)
{
<tr>
<td class="table_heading text-left table-head-maintenance Width-10">
#item.code
</td>
<td class="table_heading text-left">
#item.descrip
</td>
<td class="table_heading text-left table-head-maintenance Width-10">
#item.type1
</td>
<td class="table_heading">
<a id="edit_sale" href="#" class=" edit action-button permission-based-access" saleidval="#item.saleid" permission-key="#Permissions.Sale.GetText()" sale-code="#item.code">
<i class="icon-pencil input-icon success" title="Edit">
</i>
</a>
</td>
<td class="table_heading permission-based-access" permission-key="#Permissions.Sale.GetText()">
#if (item.status == 0)
{
<a class="active" href="" title="Change Status" active-id="#item.saleid" sale-code="#item.code" active-code="#item.code">
<img id="active" src="#Url.Content("~/Content/Images/tick.png")" />
</a>
}
else
{
<a class="in-active" href="" title="Change Status" in-active-id="#item.saleid" sale-code="#item.code" in-active-code="#item.code">
<img id="in-active" src="#Url.Content("~/Content/Images/bullet_cross.png")" />
</a>
}
</td>
<td class="table_heading">
<a id="delete_sale" class=" deletesale delete permission-based-access" permission-key="#Permissions.Sale.GetText()" href="#" sale-code="#item.code">
<i class="icon-trash" title="delete">
</i>
</a>
</td>
</tr>
}
</tbody>
</table>
</div>
Attach screenshot display an actual issue.Code "FZ" and "AM" does not contain any word as "AL" then also it display this records. and this happen for multiple search options. I need to apply search for whole data so i can't use single column search option.I just find out one issue that it search alternate rows means it search only odd rows in the grid. Any solution for it ???

Categories

Resources