JQuery table filter - AND condition - javascript

I have a very large table I want to filter with more than 5000 rows
the table has 5 columns
hitting the FILTER button top right transforms the headers into input fields
that works ... well partially ... with this code I found on the web:
/*
Please consider that the JS part isn't production ready at all, I just code it to show the concept of merging filters and titles together !
V1.3 By Prakhar Srivastava
*/
function checkval() {
1 == $("tbody tr:visible").length && "No result found" == $("tbody tr:visible td").html() ? $("#rowcount").html("0") : $("#rowcount").html($("tr:visible").length - 1)
}
$(document).ready(function() {
$("#rowcount").html($(".filterable tr").length - 1), $(".filterable .btn-filter").click(function() {
var t = $(this).parents(".filterable"),
e = t.find(".filters input"),
l = t.find(".table tbody");
1 == e.prop("disabled") ? (e.prop("disabled", !1), e.first().focus()) : (e.val("").prop("disabled", !0), l.find(".no-result").remove(), l.find("tr").show()), $("#rowcount").html($(".filterable tr").length - 1)
}), $(".filterable .filters input").keyup(function(t) {
if ("9" != (t.keyCode || t.which)) {
var e = $(this),
l = e.val().toLowerCase(),
n = e.parents(".filterable"),
i = n.find(".filters th").index(e.parents("th")),
r = n.find(".table"),
o = r.find("tbody tr"),
d = o.filter(function() {
return -1 === $(this).find("td").eq(i).text().toLowerCase().indexOf(l)
});
r.find("tbody .no-result").remove(), o.show(), d.hide(), d.length === o.length && r.find("tbody").prepend($('<tr class="no-result text-center"><td colspan="' + r.find(".filters th").length + '">Keine Ergebnisse gefunden.</td></tr>'))
}
$("#rowcount").html($("tr:visible").length - 1), checkval()
})
});
the html looks like this
<div class="filterable">
<p>Anzahl Bilder: <span id="rowcount"></span></p>
<button class="btn btn-default btn-filter"><i class=""></i>FILTER</button>
<div class="table-responsive">
<table class="table table-bordered nobottommargin">
<thead>
<tr class="filters">
<th><input type="text" class="form-control" placeholder="Name" disabled></th>
<th><input type="text" class="form-control" placeholder="Größe" disabled></th>
<th><input type="text" class="form-control" placeholder="Wochentag" disabled></th>
<th><input type="text" class="form-control" placeholder="Datum" disabled></th>
<th><input type="text" class="form-control" placeholder="Uhrzeit" disabled></th>
</tr>
</thead>
<tbody>
<tr class="data">
<td>
Bild_20210102-235000.jpg
</td>
<td style="text-align:right;">
81 kb
</td>
<td style="text-align:right;">
Samstag
</td>
<td>
02.01.2021
</td>
<td>
23:50:03
</td>
</tr>
</tbody>
</table>
</div>
</div>
it filters the table by the last filter entered and than the whole list gets the filter of the last column-filter applied/changed.
but I cannot figure out how to include an AND condition for at least the columns 2-5, so that only rows are shown, that match ALL filter values entered/applied.

Related

Why the text generated from the previous table row of number cannot be displayed in the next table row?

Here's another problem encountered with js/html code. I typed some numbers at the top of the page, then after I pressed the button First Line, it will display the numbers I inputted in the first table row accordingly. If I press the button Last Line, I'd like it to display some numbers after getting done with some arithmetics, which is in the btn2 part in the js file, in the last table row of the page. I'd like to find out if it is the problem of innerHTML or valueAsNumber in the if statements, or the variables declared in the for loop not applicable in the later if statements, that caused the numbers in the last row cannot be displayed eventually.
The for loop and the if statement is intended for the page to scan the numbers inputted in the first row, do some arithmetics with them, and display them in the last row, in each respective cell. Is there any other way out to do so?
Thank you very much!
const tab = document.getElementById("tab");
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
var R1 = [R1C1, R1C2, R1C3, R1C4, R1C5, R1C6, R1C7, R1C8,
R1C9, R1C10, R1C11, R1C12, R1C13, R1C14, R1C15, R1C16];
var R2 = [R2C1, R2C2, R2C3, R2C4, R2C5, R2C6, R2C7, R2C8,
R2C9, R2C10, R2C11, R2C12, R2C13, R2C14, R2C15, R2C16];
btn1.addEventListener('click', () => {
for (var i = 0; i <= 15; i++) {
let row = tab.rows[1];
let c = row.cells[i];
let inpId = 'inp' + (i + 1);
let inpEl = document.getElementById(inpId);
c.innerHTML = inpEl.value;
}
});
btn2.addEventListener('click', () => {
for (var i = 0; i <= 15; i++) {
var r1c = R1[i].id;
var r2c = R2[i].id;
var r1El = document.getElementById(r1c);
var r2El = document.getElementById(r2c);
}
if (r1El.innerHTML > 0) {
var choices = [0, (r1El.valueAsNumber) % 7, (r1El.valueAsNumber + 2) % 7, (r1El.valueAsNumber - 2) % 7];
var x = Math.floor(Math.random() * choices.length);
if (choices[x] == choices.at(0)) {
r2El.innerHTML = choices[x];
} else if (choices[x] <= 0) {
r2El.innerHTML = choices[x] + 7;
}
}
});
th,
tr,
td {
border: 1px solid black;
padding: 5px;
width: 40px;
text-align: center;
}
<div class="container">
<div id="data">
<table id="inpdata">
<tr>
<td id="inpb1">Group 1</td>
<td id="inpb2">Group 2</td>
<td id="inpb3">Group 3</td>
<td id="inpb4">Group 4</td>
</tr>
<tr>
<td>
<input type="number" id="inp1" title="inp1">
<input type="number" id="inp2" title="inp2">
<input type="number" id="inp3" title="inp3">
<input type="number" id="inp4" title="inp4">
</td>
<td>
<input type="number" id="inp5" title="inp5">
<input type="number" id="inp6" title="inp6">
<input type="number" id="inp7" title="inp7">
<input type="number" id="inp8" title="inp8">
</td>
<td>
<input type="number" id="inp9" title="inp9">
<input type="number" id="inp10" title="inp10">
<input type="number" id="inp11" title="inp11">
<input type="number" id="inp12" title="inp12">
</td>
<td>
<input type="number" id="inp13" title="inp13">
<input type="number" id="inp14" title="inp14">
<input type="number" id="inp15" title="inp15">
<input type="number" id="inp16" title="inp16">
</td>
</tr>
</table>
<br>
<button id="btn1">First line</button>
<button id="btn2">Last line</button>
</div>
<div id="tables">
<table id="tab">
<tr>
<th colspan="4">Group 1</th>
<th colspan="4">Group 2</th>
<th colspan="4">Group 3</th>
<th colspan="4">Group 4</th>
</tr>
<tr>
<td id="R1C1"></td>
<td id="R1C2"></td>
<td id="R1C3"></td>
<td id="R1C4"></td>
<td id="R1C5"></td>
<td id="R1C6"></td>
<td id="R1C7"></td>
<td id="R1C8"></td>
<td id="R1C9"></td>
<td id="R1C10"></td>
<td id="R1C11"></td>
<td id="R1C12"></td>
<td id="R1C13"></td>
<td id="R1C14"></td>
<td id="R1C15"></td>
<td id="R1C16"></td>
</tr>
<tr>
<td id="R2C1"></td>
<td id="R2C2"></td>
<td id="R2C3"></td>
<td id="R2C4"></td>
<td id="R2C5"></td>
<td id="R2C6"></td>
<td id="R2C7"></td>
<td id="R2C8"></td>
<td id="R2C9"></td>
<td id="R2C10"></td>
<td id="R2C11"></td>
<td id="R2C12"></td>
<td id="R2C13"></td>
<td id="R2C14"></td>
<td id="R2C15"></td>
<td id="R2C16"></td>
</tr>
</table>
</div>
So you can Iterate the td by iterating the elements HTMLCollection property of the tr. Iterate two Iterables by using the index from one.
const tab = document.getElementById("tab");
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
const firstRow = tab.firstElementChild.children[1].children;
const secondRow = tab.firstElementChild.children[2].children;
btn1.addEventListener('click', () => {
for (var i = 0; i <= 7 /* <- This is a magic value - avoid these */; i++) {
let row = tab.rows[1];
let c = row.cells[i];
let inpId = 'inp' + (i + 1);
let inpEl = document.getElementById(inpId);
c.innerHTML = inpEl.value;
}
});
btn2.addEventListener('click', () => {
[...secondRow].forEach((el,index)=>{
//let group = Math.floor(index / 4);
let inp = parseInt(firstRow[index].innerText, 10);
if (!inp) return;
let choices = [0, inp, (inp + 2), (inp - 2)];
let x = (Math.floor(Math.random() * choices.length) + 7) % 7;
el.innerText = x;
})
});
th,
tr,
td {
border: 1px solid black;
padding: 5px;
width: 40px;
height: 1.5em;
text-align: center;
}
<div class="container">
<div id="data">
<table id="inpdata">
<tr>
<td id="inpb1">Group 1</td>
<td id="inpb2">Group 2</td>
</tr>
<tr>
<td>
<input type="number" id="inp1" title="inp1">
<input type="number" id="inp2" title="inp2">
<input type="number" id="inp3" title="inp3">
<input type="number" id="inp4" title="inp4">
</td>
<td>
<input type="number" id="inp5" title="inp5">
<input type="number" id="inp6" title="inp6">
<input type="number" id="inp7" title="inp7">
<input type="number" id="inp8" title="inp8">
</td>
</tr>
</table>
<br>
<button id="btn1">First line</button>
<button id="btn2">Last line</button>
</div>
<div id="tables">
<table id="tab">
<tr>
<th colspan="4">Group 1</th>
<th colspan="4">Group 2</th>
</tr>
<tr>
<td></td><td></td><td></td><td></td>
<td></td><td></td><td></td><td></td>
</tr>
<tr>
<td></td><td></td><td></td><td></td>
<td></td><td></td><td></td><td></td>
</tr>
</table>
</div>
Some additional advice:
I couldn't be bothered to clean up all of your code, next time please provide a Minimal Example, tree fields would have been plenty to ask the question.
Further please avoid magic numbers, like you use in your loops. Get the size of what you are iterating when you use it. This makes your code more flexible and reusable.
In the same vein: Please do not throw ids everywhere. They just beg to break your code if you ever try to reuse it somehow.

division work and sum in jquery not work?

i have a datatable with checkbox and a button add, i want when i click on button add, console display salaire and prime and sold which calculate like that sold = (salaire / 24) + prime.
index.php
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div id="form2">
<table class="table table-bordered" id="mytable">
<tr>
<th><input type="checkbox" id="check_all"></th>
<th>nom</th>
<th>salaire</th>
<th>adresse</th>
<th>prime</th>
</tr>
<tr>
<td><input type="checkbox" class="checkbox"></td>
<td>najib</td>
<td>5000</td>
<td>tihit</td>
<td><input type="text" name="prime" class="form-control prime" value="0"></td>
</tr>
<tr>
<td><input type="checkbox" class="checkbox"></td>
<td>adil</td>
<td>4000</td>
<td>tagmast</td>
<td><input type="text" name="prime" class="form-control prime" value="0"></td>
</tr>
</table>
<div class="form-group col-md-offset-5 ">
<button class="btn btn-success " type="submit" id="add">Pointage men</button>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#add").click(function(){
var items = [];
$("tr").each(function(i,r){
let salaire = r.cells[2].innerText;
let prime = $(r).find(".prime").val();
let sold = ((salaire)/24) + prime;
if ( i > 0 && $(r).find("input").first().prop("checked")){
items.push({ "salaire" : salaire , "prime" : prime , "sold" : sold });
}
})
console.log(items);
})
})
</script>
This happens since variables salaire and prime are actually returned in code as string and thus when you do this:
console.log( ('5000'/24) + '100' )
then answer is also returned as a string like "208.33333333333334100"
So, you just need to convert them to integer first and it should work fine like:
let salaire = '5000'
let prime = '100'
let sold = ((+salaire) / 24) + +prime;
console.log(sold)

Multiple Table Filters

I want to filter more than once in this table at the same time. It happens when I enter the $table.find('tbody tr:visible'); code, but it gets corrupted when I use the backspace in the filtering part because it only searches within the visible TR. (Original: $table.find('tbody tr');)
How can I solve this problem?
$(document).ready(function() {
$('.filterable .btn-filter').click(function() {
var $panel = $(this).parents('.filterable'),
$filters = $panel.find('.filters input'),
$tbody = $panel.find('.table tbody');
if ($filters.prop('disabled') == true) {
$filters.prop('disabled', false);
$filters.first().focus();
} else {
$filters.val('').prop('disabled', true);
$tbody.find('.no-result').remove();
$tbody.find('tr').show();
}
});
$('.filterable .filters input').keyup(function(e) {
/* Ignore tab key */
var code = e.keyCode || e.which;
if (code == '9') return;
/* Useful DOM data and selectors */
var $input = $(this),
inputContent = $input.val().toLowerCase(),
$panel = $input.parents('.filterable'),
column = $panel.find('.filters th').index($input.parents('th')),
$table = $panel.find('.table'),
$rows = $table.find('tbody tr');
/* Dirtiest filter function ever ;) */
var $filteredRows = $rows.filter(function() {
var value = $(this).find('td').eq(column).text().toLowerCase();
return value.indexOf(inputContent) === -1;
});
/* Clean previous no-result if exist */
$table.find('tbody .no-result').remove();
/* Show all rows, hide filtered ones (never do that outside of a demo ! xD) */
$rows.show();
$filteredRows.hide();
/* Prepend no-result row if all rows are filtered */
if ($filteredRows.length === $rows.length) {
$table.find('tbody').prepend($('<tr class="no-result text-center"><td colspan="' + $table.find('.filters th').length + '">No result found</td></tr>'));
}
});
});
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<div class="container">
<h3>The columns titles are merged with the filters inputs thanks to the placeholders attributes</h3>
<hr>
<p>Inspired by this snippet</p>
<div class="row">
<div class="panel panel-primary filterable">
<div class="panel-heading">
<h3 class="panel-title">Users</h3>
<div class="pull-right">
<button class="btn btn-default btn-xs btn-filter"><span class="glyphicon glyphicon-filter"></span> Filter</button>
</div>
</div>
<table class="table">
<thead>
<tr class="filters">
<th><input type="text" class="form-control" placeholder="#" disabled></th>
<th><input type="text" class="form-control" placeholder="First Name" disabled></th>
<th><input type="text" class="form-control" placeholder="Last Name" disabled></th>
<th><input type="text" class="form-control" placeholder="Username" disabled></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Markos</td>
<td>Ottoass</td>
<td>#mdo</td>
</tr>
<tr>
<td>2</td>
<td>Jacobos</td>
<td>Thorntonass</td>
<td>#fat</td>
</tr>
<tr>
<td>3</td>
<td>Larry</td>
<td>the Bird</td>
<td>#twitter</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
https://jsfiddle.net/b0vj6p4n/
jquery.Datatables could be used, it has various features related to searching, sorting and loading data.
The site has quite a few examples to get started with loading data and setting up a table:
https://datatables.net/examples/basic_init/zero_configuration.html
The following snippet could be used to configure a table as datatable:
$(document).ready(function() {
$('#example').DataTable();
} );

How to calculate to variable in javascript and print them in the html page

I try to get result from html table witch excepted only numbers i check them throw if statement if variable 1 bigger than variable 2 print content and that works good.
Now i am trying in the if statement to print variable 1 - variable 2 but it doesn't wanna work.
Here is the snippet:
$(document).ready(function() {
var vastInkomen = 0;
$('.txtBox').keyup(function() {
vastInkomen = 0;
$('.txtBox').each(function() {
var txtBoxVal = $(this).val();
vastInkomen += Number(txtBoxVal);
});
$('#vastInkomen').val(vastInkomen);
writeResult();
});
var vastLasten = 0;
$('.vast_lasten').keyup(function() {
vastLasten = 0;
$('.vast_lasten').each(function() {
var vastLastenVal = $(this).val();
vastLasten += Number(vastLastenVal);
});
$('#vastLasten').val(vastLasten);
writeResult();
});
function writeResult() {
if (vastInkomen !== 0 && vastLasten !== 0) {
if (vastInkomen > vastLasten) {
$('#result').text("Some text and work good!") +
vastLasten - vastInkomen;
} else if (vastInkomen < vastLasten) {
//$('#result-amount').console(vastInkomen -vastLasten);
$('#result').text("some text and work good.");
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>content1</td>
<td><input class="txtBox" type="number" name="content2" />
</td>
</tr>
<tr>
<td>content3</td>
<td><input class="txtBox" type="number" name="content3" />
</td>
</tr>
<tr>
<td>content4</td>
<td>
<input class="txtBox" type="number" name="content4" />
</td>
</tr>
</table>
<table>
<tr>
<td>content</td>
<td><input class="vast_lasten" type="number" name="content" /></td>
</tr>
<tr>
<td>content1</td>
<td><input class="vast_lasten" type="number" name="content1" /></td>
</tr>
<tr>
<td>content2</td>
<td><input class="vast_lasten" type="texnumber" name="content2" /></td>
</tr>
</table>
<div class="col">
<h3>Het resultaat is:</h3>
<p id="result"></p>
</div>
This will work:
var result = vastLasten - vastInkomen;
$('#result').text("Some text and work good!" + result);
You can use .text() to set the content of an element, but everything should be within the parenthesis.
I added an extra variable result because you cannot use + and - both here; it will result in NaN as it will try to sum the values.
This works as well:
$('#result').text("Some text and work good!" + (vastLasten - vastInkomen));

How to convert javascript fill table to fill form

My script calculates the price and shows the results in the table. I want to see that in the form which I can submit. Here is JavaScript code
<script type="text/javascript">
function update(){
var sum = 0;
$("#calculator > tbody > tr").each(function(){
var amount = parseFloat($(this).find("td").eq(1).find('input').val());
var value = $(this).find("td:eq(2)");
var price = $(this).find("td:eq(0)");
if (amount > 0 && amount < 501) {
price.text(0.37);
} else
if (amount > 500 && amount < 3001) {
price.text(0.32);
} else
if (amount > 3000 && amount < 6001) {
price.text(0.25);
} else
if (amount > 6000 && amount < 10001) {
price.text(0.21);
} else
if (amount > 10000) {
price.text(parseFloat(0.20).toFixed(2));
}
var _price = parseFloat(price.text());
if (amount > 0 && amount !== undefined ) {
value.text(parseFloat(_price*amount).toFixed(2));
sum += _price*amount;
} else {
value.text(0);
}
});
$("#summary").text(parseFloat(sum).toFixed(2));
}
$(document).ready(function(){
update();
$("#calculator input").keyup(function(){
update();
});
});
</script>
And this is the table code in html
<table id="calculator" class="table table-striped table-hover">
<thead>
<tr>
<th><p align="right">Price</p></th>
<th><p align="center">Amount</p></th>
<th><p align="left">Value</p></th>
</tr>
</thead>
<tbody>
<tr>
<td align="right"></td>
<td align="center"><input style="width:50px;" type="text" /></td>
<td align="left"></td>
</tr>
</tbody>
</table>
After fill Amount the script counts Value using price with rules. Please help me with convert that to do it not in the table but in the form.
<form id="transfer">
<input class="text" id="price" type="text" value="" />
<input class="text" id="amount" type="text" value="" />
<input class="text" id="value" type="text" value="" />
</form>

Categories