I have the below html table where the header on seperate table and content on another table. I have to sort the table when i click the header that are in another table.
I found so many javascript examples that are working only if the headers are in same table.Can any you guys give me with some examples related to my task?
<html>
<table >
<tr>
<th>Name</th>
<th>Salary</th>
</tr>
</table>
<table>
<tr>
<td>Fred</td>
<td>$12000.00</td>
</tr>
<tr>
<td>Kevin</td>
<td>$191200.00</td>
</tr>
</table>
</html>
If you add some classes to the columns so that the column cells and the associated header have the same class name, it's not too difficult to leverage those other existing JavaScript solutions.
As an example, I used this simple JQuery sorting function and created this JSFiddle demo.
I modified the HTML like this:
<html>
<table id="heading">
<tr>
<th class="name-col">Name</th>
<th class="salary-col">Salary</th>
</tr>
</table>
<table id="data">
<tr>
<td class="name-col">Fred</td>
<td class="salary-col">$12000.00</td>
</tr>
<tr>
<td class="name-col">Kevin</td>
<td class="salary-col">$191200.00</td>
</tr>
</table>
</html>
Notice that I game the header Name and all of the cells in that column the class name-col, and I did the same for the Salary header and cells with the class salary-col.
Then I used JQuery to add a click listener to the name-col header, which then triggered the sort function on the name-col cells:
$('th.name-col').click(function() {
$('td.name-col').sortElements(function(a, b){
return $(a).text() > $(b).text() ? 1 : -1;
}, function(){ return this.parentNode; });
});
$('th.salary-col').click(function() {
$('td.salary-col').sortElements(function(a, b){
return $(a).text() > $(b).text() ? 1 : -1;
}, function(){ return this.parentNode; });
});
In this example, sortElements is the function provided in the simple JQuery sorting function I linked above. I am not the author of it.
You will notice that this script will only sort once, however, since the direction of the comparator (>) is hard-coded. One quick-n-dirty way to implement logic to reverse this sort is like this:
var nameAsc = false;
var salaryAsc = false;
$('th.name-col').click(function() {
$('td.name-col').sortElements(function(a, b){
if (nameAsc) {
nameAsc = false;
return $(a).text() > $(b).text() ? 1 : -1;
} else {
nameAsc = true;
return $(a).text() < $(b).text() ? 1 : -1;
}
}, function(){ return this.parentNode; });
});
$('th.salary-col').click(function() {
$('td.salary-col').sortElements(function(a, b){
if(salaryAsc) {
salaryAsc = false;
return $(a).text() > $(b).text() ? 1 : -1;
} else {
salaryAsc = true;
return $(a).text() < $(b).text() ? 1 : -1;
}
}, function(){ return this.parentNode; });
});
Here the nameAsc and salaryAsc boolean variables are just a hackish way of allowing you to reverse the sort order. If it's ascending, it flips the boolean and the direction of the > in the comparator function. There's probably a more efficient way to do this, but I was just going for a quick-and-dirty example.
You're going to have a lot of problems with your two-table model, especially with sizing the columns. If you have longer data in the cells in the data table, your data columns will no longer line up with your header columns. I strongly suggest you use just a single table for both the header and the data.
use sorttable.js for sorting, it might give problem with column alignment while clicking on column head for sorting....
<script type="text/javascript" src="http://community.wikidot.com/local--files/howto:sortable-tables-js/sorttable.js"></script>
<style>
th, td{
padding: 3px;//important
}
</style>
<table class="sortable">
<tr><th>...</th></tr><tr><td>...</td</tr>
</table>
Related
I have a scenario to bind a html table using angular js. In my table i need to show an a tag based on another column value(Payment Status). If its fully paid no need to show the a tag, else need to show it for very next element. I am a new one in angular.
<table>
<thead>
<tr>
<th>Month</th>
<th>Installement</th>
<th>PaymentAmount</th>
<th>PaymentDate</th>
<th>Payment Status</th>
<th>Pay</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="row in rowCollection|orderBy:type:reverse|filter:searchKeyword|itemsPerPage:maxsize">
<td>{{row.Month}}</td>
<td>{{row.MonthlyInstallement}}</td>
<td>{{row.PaymentAmount}}</td>
<td>{{row.PaymentDate}}</td>
<td>{{row.PaymentStatus}}</td>
<td ng-if="row.PaymentStatus == 'UNPAID'">
Pay Online
</td>
<td ng-if="row.PaymentStatus == 'FULLY_PAID'">
</td>
</tr>
</tbody>
</table>
function bindFinanceDetails() {
var finUrl = baseurl + 'api/FinancialStatement/GetCarFinanceInfo';
var req = {
method: 'post',
data: {
LoginID: LoginID,
ContractNumber: 11170200669,
CustomerId: 2355898046
},
url: finUrl,
headers: {
RequestedPlatform: "Web",
RequestedLanguage: cookiePreferredLanguage,
Logintoken: $cookieStore.get('LoginToken'),
LoginId: LoginID
}
};
$http(req).then(function(response) {
var getData = response.data.FinanceList;
$scope.rowCollection = getData;
}, function(error) {
toastr.error($filter('translate')('Error Occured'));
});
}
A quite hacky solution will be something like the following (just showing you the needed change in the unpaid td element):
<td ng-if="row.PaymentStatus === 'UNPAID'" ng-show="$index === data.payOnlineIndex"
ng-init="data.payOnlineIndex = (!data.payOnlineIndex || (data.payOnlineIndex > $index)) ? $index : data.payOnlineIndex">
Pay Online
</td>
This way ng-init will run for all unpaid elements, setting the smallest index to the payOnlineIndex variable. ng-show will make sure to only show that one element that has the smallest index.
I encapsulate payOnlineIndex with a data object to keep a stable reference to it. This also requires the following addition to the controller code:
$scope.data = { payOnlineIndex: null };
See a working jsFiddle example here: https://jsfiddle.net/t3vktv0r/
Another option is running your filter and orderBy in the controller, searching for the first occurrence of an "unpaid" row, and marking that element for the "pay online" feature with some flag you can test with ng-if in your view.
I have a basic html table where i need to have all the rows initially highlighted when the table is created. Also, if the user clicks the row it un highlights and clicked again highlights.
I have the click on a row, and it highlights. If you click again it un highlights.
I just need to initially highlight all rows possibly by ng-repeat. It also needs to release the highlighting when the row is clicked again and then highlight back. userData is just a line of text for each row
HTML
<table class="superusertable" cellpadding="5" cellspacing="0">
<tbody class="table-font">
<tr ng-init="" ng-repeat="source in userData"
ng-model="source.fromSourceID"
ng-class="{'sourcesSelected': source.sourcesSelected}"
ng-click="select(source)">
<td width="290px">
<div class="action-checkbox"; width="290px">{{source.fromSourceID}}
</div>
</td>
</tr>
</tbody>
</table>
angular
$scope.select = function(item) {
item.sourcesSelected ? item.sourcesSelected = false : item.sourcesSelected = true;
};
You can just add a function to the ng-init attribute on your tr. Just pass in your item and set it to true. Then like Aluan said in a comment, you can just make your ng-click function simpler by doing item.sourcesSelected = !item.sourcesSelected.
html
<table class="superusertable" cellpadding="5" cellspacing="0">
<tbody class="table-font">
<tr ng-init="init(source)"
ng-repeat="source in userData"
ng-model="source.fromSourceID"
ng-class="{'sourcesSelected': source.sourcesSelected}"
ng-click="select(source)">
<td width="290px">
<div class="action-checkbox"; width="290px">{{source.fromSourceID}}</div>
</td>
</tr>
</tbody>
</table>
angular
$scope.select = function(item) {
item.sourcesSelected = !item.sourcesSelected;
};
$scope.init = function(item) {
item.sourcesSelected = true;
}
On a side note, you can completely eliminate the ng-init and init function by setting item.sourcesSelected = true when you are retrieving your data.
There are too many errors i can observe.
ng-init="" not required
ternary operator is wrong you should do something following:
item.sourcesSelected = item.sourcesSelected ? false : true;
Is there any way to fill the empty <td></td>, if data does not exist in this?
<table><tr><td></td><td>1</td><td></td></tr></table>
Change it to:
<table><tr><td>Not Data</td><td>1</td><td>No Data</td></tr></table>
Not with HTML itself.
Usually you would do this by generating the HTML using a data in a programming language and a template, with template logic used to insert a default value if none came from the data.
A little bit hackish, because it changes only visual aspect. You can do that with CSS:
table, td {border: 1px solid black; padding: 4px; border-collapse: collapse}
td:empty::before {content: "No Data"}
<table>
<tr>
<td></td>
<td>Real data</td>
<td></td>
</tr>
</table>
Won't really work just with html.
it depends on how you build your HTML-DOM. If it is just a pure HTML-file (*.html ) you could check for value by adding some JavaScrit/JQuery.
But if you are trying to do this, make sure to give your table/tr or td to give element-ids.
<table>
<tr id="1">
<td id="1_1"></td>
<td id="1_2">1</td>
<td id="1_3"></td>
</tr>
</table>
<script type="text">
/* For the amount of rows */
for(var outeri = 1; outeri <= 1; outeri++)
{
/* For the amount of columns */
for(var ineri = 1; ineri <= 3; ineri)
{
var innertd = String(outeri + '_' + ineri);
if(document.getElementById(inntertd).innerHTML == '')
{
document.getElementById(inntertd).innerHTML = 'No Data';
}
else {continue;}
}
}
</script>
This example is not very realistic and more likely not to be done unless your table is just static.
you can add an empty space:
This can be achieved in many ways, here are 2 (c# and jquery)
Solutions:
c#:
Use razor as in the following:
<table>
<thead>
<tr>
<td>Name</td>
<td>Date</td>
</tr>
</thead>
<tbody>
<tr>
#{
if(data)
{
<td>#data.name</td>
<td>#data.date</td>
}
else
{
<td colspan="2">NO DATA</td>
}
}
</tr>
</tbody>
</table>
jQuery:
Select the table and change the html depending on if there is any data
$(document).ready(function()
{
var table = $("table-selector");
var isData = $("data-selector").length;
if(!isData){
table.html("customize HTML right here, considering 'colspan' in case
there is a headers row as well")
}
});
I am working on an HTML web page where I have a table with some data in it and I am trying to control CSS for an entire column in the table based on the values in another column and same row
For example, In the following screenshot I have my data
In the above picture, I have Volume, Price and Type. Now, I want to control the color of Price column based on the corresponding value in Type Column. Like for Price=10 I have Type as Sell, so I want to make the value 10 to red color and similarly if type is Buy then Price value should be in Yellow.
I am trying to do that using following script
<td data-bind="text: Volume"></td>
<td data-bind="text: (typeof Price() === 'number') ? Price().toFixed(2) : '',css:{cclientType:Type=='Sell'}"></td>
<td data-bind="text: Type"></td>
But, that doesn't seem to be working.
Provided, the data is coming from a Knockout View model which in turn is pulling from SQL Server.
Is there a better way I could achieve this?
You could add a ko.computed function to each of your data items to help you determine the css:
self.volume = ko.observable(volume);
self.price = ko.observable(price);
self.type = ko.observable(type);
self.priceCss = ko.computed(function() {
if (self.type() == 'buy') {
return 'buy-class';
} else if (self.type() == 'sell') {
return 'sell-class';
} else return '';
});
This can then be added to your markup:
<tr>
<td data-bind="text:volume"></td>
<td data-bind="text:price, css: priceCss"></td>
<td data-bind="text:type"></td>
</tr>
A plunker demonstrating this can be seen here
Dev.
Please, try this! Works.
<td data-bind="text: volume"></td>
<td data-bind="text: (typeof price() === 'number') ? price().toFixed(2) : '',css:{ cclientType: type() == 'sell'}"></td>
<td data-bind="text: type"></td>
I would set styles on the <tr> based on the contents of type column (or any other column) and handle everything you need in CSS.
Eg.
<tr class="sell">
<td>100</td>
<td>10.00</td>
<td>Sell</td>
</tr>
tr.sell td:nth-of-type(2) {
color: red;
}
If you don't like using the nth-of-type selector, you can set a class on the <td> and then your CSS selector would be:
tr.sell td.price {
color: red;
}
I am working on developing a multi-column multi-word filtering search and have difficulties with two problems:
I am only able to partially filter the first column; partial because typing apple it shows apple and oranges in the first column.
I am struggling with finding a way to make this a multi-word search over both columns.
I found a table filtering techniques on SO and adjusted them in this fiddle. But this code will only filter over all the columns with one word. Typing more than one word to narrow the result (find A and B) does not work.
The code below is my attempt to perform a multi-column multi-word search in a single box see my fiddle.
How can I achieve filtering over multiple columns that combines the search phrases?
Meaning show only rows where searchphrase-1 and searchphrase-2 are present.
JS
var $orig_rows1 = $('#table tbody tr td[class = "col1"]');
var $orig_rows2 = $('#table tbody tr td[class = "col2"]');
$('#search').keyup(function() {
var $rows1 = $orig_rows1;
var $rows2 = $orig_rows2;
var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
reg = RegExp(val, 'i'),
text;
$("tr:hidden").show();
$rows1.show().filter(function() {
text = $(this).text().replace(/\s+/g, ' ');
return !reg.test(text);
}).parent("tr").hide();
});
HTML
<input type="text" id="search" placeholder="Type to search title 1">
<table class="table-striped" id="table">
<thead>
<th>Title 1</th>
<th>Title 2</th>
</thead>
<tbody>
<tr>
<td class="col1">Apple</td>
<td class="col2">Green</td>
</tr>
<tr>
<td class="col1">Grapes</td>
<td class="col2">Green</td>
</tr>
</tbody>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</table>
Any advice would be great.
Mistake in your code </tbody> is placed wrong, it must be
<tbody>
<tr>
<td class="col1">Apple</td>
<td class="col2">Green</td>
</tr>
<tr>
<td class="col1">Grapes</td>
<td class="col2">Green</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</tbody>
Not a perfect solution, suggestions would be greatly appreciated
Try this Demo Fiddle it has multiple words search capability made using Tag-it! plugin.
Update search for both AND and OR
Demo Fiddle with a check box to perform both operations
Edit: pieces of linked fiddle added
This is a part of the code from the linked fiddle
var search = function () {
if ($('.tagit-label').length) {
$("#table tbody tr").hide();
var toShow = [];
$('.tagit-label').each(function () {
filter = $(this).text();
$("#table tbody tr").each(function () {
if ($(this).text().search(new RegExp(filter, "i")) > 0) {
toShow.push($("#table tbody tr").index(this));
}
});
});
if ($('#chkBoth').prop("checked") && $('.tagit-label').length > 1) {
var filterShow = [];
var outputArray = [];
$(toShow).each(function (i, value) {
if (($.inArray(value, outputArray)) == -1) {
outputArray.push(value);
}
});
$(outputArray).each(function (i, value) {
var index = toShow.indexOf(value);
toShow.splice(index, 1);
});
}
$(toShow).each(function (i, value) {
$("#table tbody tr").eq(value).fadeIn();
});
} else {
$("#table tbody tr").fadeIn();
}
}
This is the result of my linked fiddle below:
Hope it helps..!!