I'm trying to write a jQuery function to apply filters to multiple columns.
Example:
html
<table id="myTable" class="table table-sm">
<thead class="thead-light">
<tr>
<th scope="col">Address</th>
<th scope="col">Name</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" class="form-control search" onkeyup="filterTable('#myTable', $(this).val().toLowerCase(), 0);"></td>
<td><input type="text" class="form-control search" onkeyup="filterTable('#myTable', $(this).val().toLowerCase(), 1);"></td>
<td><input type="text" class="form-control search" onkeyup="filterTable('#myTable', $(this).val().toLowerCase(), 2);"></td>
</tr>
<?php while ($row = $res->fetchArray()) { ?>
<tr>
<td><?php echo "{$row["address"]}"?></td>
<td><?php echo "{$row["name"]}"?></td>
<td><?php echo "{$row["description"]}"?></td>
</tr>
<?php } ?>
</tbody>
</table>
js
function filterTable(table, text, col) {
$(table + " > tbody > tr").not(':first').find("td").eq(col).filter(function() {
$(this).closest("tr").toggle($(this).text().toLowerCase().indexOf(text) > -1)
});
}
When the keyup event is fired a call the filterTable function passing the id of the table to be filtered, the text inserted by the user and the index of the column.
The goal is to hide the rows whose target column doesn't contain the text. I skip the first row because it contains the filter input textboxes.
I also want to let the user to enter multiple filters on different columns.
Even typing something in only one input textbox the behavior is not correct: when I type something that doesn't match all the rows hide.
I searched for similar questions (i.e. jQuery column filters) but the answers don't seem to work - when applying another filter the previous one is removed.
UPDATE
This is the actual html code generated:
<table id="tableParameters" class="table table-sm">
<thead class="thead-light">
<tr>
<th scope="col">Address</th>
<th scope="col">Name</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" class="form-control search" onkeyup="filterTable('#tableParameters', $(this).val().toLowerCase(), 0);"></td>
<td><input type="text" class="form-control search" onkeyup="filterTable('#tableParameters', $(this).val().toLowerCase(), 1);"></td>
<td><input type="text" class="form-control search" onkeyup="filterTable('#tableParameters', $(this).val().toLowerCase(), 2);"></td>
</tr>
<tr>
<td>1000</td>
<td>Date</td>
<td>Date of the event</td>
</tr>
<tr>
<td>1001</td>
<td>Time</td>
<td>Time of the event</td>
</tr>
<tr>
<td>1002</td>
<td>Code</td>
<td>Requested code</td>
</tr>
</tbody>
</table>
You are not doing it right, the filterTable function must be like this:
function filterTable(table) {
var filterColumn1Value = $(table + " > tbody > tr:first-child").find('td').eq(0).find('input').first().val().toLowerCase();
var filterColumn2Value = $(table + " > tbody > tr:first-child").find('td').eq(1).find('input').first().val().toLowerCase();
var filterColumn3Value = $(table + " > tbody > tr:first-child").find('td').eq(2).find('input').first().val().toLowerCase();
$(table + " > tbody > tr").not(':first').filter(function() {
var column1Value = $(this).find("td").eq(0).text().toLowerCase();
var column2Value = $(this).find("td").eq(1).text().toLowerCase();
var column3Value = $(this).find("td").eq(2).text().toLowerCase();
$(this).toggle(column1Value.indexOf(filterColumn1Value) > -1 &&
column2Value.indexOf(filterColumn2Value) > -1 &&
column3Value.indexOf(filterColumn3Value) > -1)
});
}
And the calling of the function should be just:
filterTable('#tableParameters');
Related
I have a big table with multiple table heads. I have a simple js function to filter table data, but I need to make it so that it shows the table head section too. I added tbody and tr tags to my function but now it searches data in table but shows every thead section. How can I get that it shows only the specific thead section which contains searched tr element?
My code:
$(document).ready(function() {
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tbody tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
<div class="col-md d-inline">
<input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" placeholder="Meklēt.." id="myInput">
</div>
<table id="myTable" class="table table-sm table-bordered table-hover">
<thead class="bg-primary">
<tr>
<th colspan="3">Information about department</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name - It</td>
<td>Phone - 1111111</td>
<td>E-mail - mail#mail.com</td>
</tr>
</tbody>
<thead class="bg-primary">
<tr>
<th colspan="3">Information about department 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name - Finance</td>
<td>Phone - 1111112</td>
<td>E-mail - finance#mail.com</td>
</tr>
<tr>
<td>Name - Finance2</td>
<td>Phone - 1111113</td>
<td>E-mail - finance2#mail.com</td>
</tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You can try the below approach with data attribute data-group to group thead and tbody into separate groups. That would help to recognize element sections and find string matches in groups easily.
$(document).ready(function() {
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase().trim();
$("#myTable thead").each(function() {
var group = $(this).data("group")
var isTheadMatched = $(this).text().toLowerCase().indexOf(value) > -1
var selector = `tbody[data-group='${group}'] tr`
var allRows = $('#myTable').find(selector);
var isAnyRowMatched = false;
for (var row of $(allRows)) {
const isRowMatched = isTheadMatched || $(row).text().toLowerCase().indexOf(value) > -1
$(row).toggle(isRowMatched);
if ($(row).text().toLowerCase().indexOf(value) > -1) {
isAnyRowMatched = true;
}
}
$(this).toggle(isTheadMatched || isAnyRowMatched)
});
});
});
<div class="col-md d-inline">
<input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" placeholder="Meklēt.." id="myInput">
</div>
<table id="myTable" class="table table-sm table-bordered table-hover">
<thead class="bg-primary" data-group="1">
<tr>
<th colspan="3">Information about department</th>
</tr>
</thead>
<tbody data-group="1">
<tr>
<td>Name - It</td>
<td>Phone - 1111111</td>
<td>E-mail - mail#mail.com</td>
</tr>
</tbody>
<thead class="bg-primary" data-group="2">
<tr>
<th colspan="3">Information about department 2</th>
</tr>
</thead>
<tbody data-group="2">
<tr>
<td>Name - Finance</td>
<td>Phone - 1111112</td>
<td>E-mail - finance#mail.com</td>
</tr>
<tr>
<td>Name - Finance2</td>
<td>Phone - 1111113</td>
<td>E-mail - finance2#mail.com</td>
</tr>
</tbody>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I need to create textfield dynamically when I click checkbox in table. In table I have around 500 data. Each data has check box and user can search and select parameters. As below image, If user click Testing 1 checkbox from table, Same Testing1 value should present in Parameter name text field.
If the user selects Testing 2 checkbox, dynamically Textfield needs be added and Testing 2 value should be present in created textfield. If user uncheck checkbox, textfield has to be removed from table. I have attached snapshot for reference.
Below code for TextField which resides in table.
<div class="tab-content">
<div id="protocol" class="tab-pane fade in active">
<div class="span3 border-0" style="overflow: scroll">
<table id="addParamTable" class="table table-bordered">
<thead>
<tr class="info">
<th>Parameter Name</th>
<th>Data Type</th>
<th>Expected Set Value</th>
</tr>
</thead>
<tbody class="parameter_table">
<tr>
<td>
<input type="text" id="parameterName" class="parameterName" name="parameter_name">
</td>
<td>
<input type="text" class="parameterDscription" name="parameter_description">
</td>
<td>
<input type="text" class="expectedValue" name="expected_value">
</td>
</tr>
</tbody>
</table>
You can do it like this:
$("#paramTable input[type='checkbox']").on("click", function() {
if ($(this).is(":checked")) {
let name = $(this).parent("td").next("td").text();
let newname = name.replace(" ", "_");
let newrow = $("<tr>");
let newcell = $("<td>");
let newinput = $("<input type='text' class='parameterName' name='" + newname + "' id='" + newname + "' value='" + name + "'/>");
newcell.append(newinput);
newrow.append(newcell);
let newcells = $("<td><input type='text' class='parameterDscription' name='parameter_description'></td><td><input type='text' class='expectedValue' name='expected_value'></td>")
newrow.append(newcells);
$("tbody.parameter_table").append(newrow);
} else {
let name = $(this).parent("td").next("td").text();
let newname = name.replace(" ", "_");
$("#addParamTable").find("#" + newname).closest("tr").remove();
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="paramTable">
<tr>
<td><input type="checkbox"/></td>
<td>Testing 1</td>
<td>1, 4, 6, 5, 9</td>
</tr>
<tr>
<td><input type="checkbox"/></td>
<td>Testing 2</td>
<td>1, 4, 3, 5</td>
</tr>
</table>
<div class="tab-content">
<div id="protocol" class="tab-pane fade in active">
<div class="span3 border-0" style="overflow: scroll">
<table id="addParamTable" class="table table-bordered">
<thead>
<tr class="info">
<th>Parameter Name</th>
<th>Data Type</th>
<th>Expected Set Value</th>
</tr>
</thead>
<tbody class="parameter_table">
<tr>
<td>
<input type="text" id="parameterName" class="parameterName" name="parameter_name">
</td>
<td>
<input type="text" class="parameterDscription" name="parameter_description">
</td>
<td>
<input type="text" class="expectedValue" name="expected_value">
</td>
</tr>
</tbody>
</table>
I have a Bootstrap table in the following format
<div class="col-sm-8">
<div class="tablecontainer">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Instances</th>
<th scope="col">Chains</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type='checkbox' id='[0]' class='jmolInline'>1</td>
<td>4LF8|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[1]' class='jmolInline'>2</td>
<td>4LF7|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[2]' class='jmolInline'>1</td>
<td>4B3W|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[3]' class='jmolInline'>2</td>
<td>4AA4|1|A</td>
</tr>
</tbody>
</table>
</div>
I would like to get the ids of the checkboxes as they are being checked using d3. I've tried the following but it doesn't seem to work. What would be the best way to get the checked ids stored in an array using d3?
var checked = []
var boxes = d3.selectAll("input.jmolInline:checked");
boxes.each(function() {
checked.push(this.id)
});
console.log(checked)
use this code to get the job done
var inputs = d3.selectAll('input[type="checkbox"]')._groups[0];
document.getElementById('submit').addEventListener('click', function() {
var checked = [];
for (i = 0; i < inputs.length; i++) {
if (inputs[i].checked) {
checked.push(inputs[i].id);
}
}
document.getElementById('result').innerHTML = 'Array of ids selected ' + checked;
console.log(checked);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div class="col-sm-8">
<div class="tablecontainer">
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Instances</th>
<th scope="col">Chains</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type='checkbox' id='[0]' class='jmolInline'>1</td>
<td>4LF8|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[1]' class='jmolInline'>2</td>
<td>4LF7|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[2]' class='jmolInline'>1</td>
<td>4B3W|1|A</td>
</tr>
<tr>
<td><input type='checkbox' id='[3]' class='jmolInline'>2</td>
<td>4AA4|1|A</td>
</tr>
</tbody>
</table>
<button id="submit">get Id</button>
<div id="result"></div>
</div>
what I'm making is a Laravel project. That web page I need to add a table when user insert number in column 1 and column 2 the table should multiply the numbers and should display in column 3.
Controller code
public function makeTable(Request $request){
$items = $request->get('values');
$output = '<table class="table table-sm">
<thead>
<tr>
<th scope="col">Item ID</th>
<th scope="col">Food Item</th>
<th scope="col">Unit Price</th>
<th scope="col">Amount</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>';
foreach ($items as $item){
$itemId = FoodItem::where('itemName','like','%'.$item.'%')->value('id');
$output .= '<tr>
<th scope="row">'.$itemId.'</th>
<td>'.$item.'</td>
<td><input type="text" class="form-control"></td>
<td><input type="text" class="form-control"></td>
<td></td>
</tr>';
}
$output .= '</tbody>
</table>';
echo $output;
}
What I want is when user input unit price and amount the price should be display automatically by multiplying unit price and amount.
The user should be able to do this row by row.
The code below does what you would like.
I've add some classes so that it is easier to determine what each input and td is for.
I've also added the event triggers in a manner that means dynamically added rows will continue to work (click on the add button to see this in action).
Update changed the cost per row to an input as requested and added a sum function for the value of all rows.
Demo
// Add event trigger to inputs with class auto-calc
$(document).on("keyup change paste", "td > input.auto-calc", function() {
// Determine parent row
row = $(this).closest("tr");
// Get first and second input values
first = row.find("td input.unit-price").val();
second = row.find("td input.amount").val();
// Print input values to output cell
row.find(".total-cost").val(first * second);
// Update total invoice value
var sum = 0;
// Cycle through each input with class total-cost
$("input.total-cost").each(function() {
// Add value to sum
sum += +$(this).val();
});
// Assign sum to text of #total-invoice
// Using the id here as there is only one of these
$("#total-invoice").text(sum);
});
// Add dynamic row to demonstrate works in this case
$(document).on("click", "#add", function() {
$("tbody").append('<tr><th scope="row">ITEM003</th><td>KNIFE</td><td><input type="text" class="auto-calc unit-price form-control"></td><td><input type="text" class="auto-calc amount form-control"></td><td><input type="text" class="total-cost amount form-control"></td></tr>');
$(this).remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Item ID</th>
<th scope="col">Food Item</th>
<th scope="col">Unit Price</th>
<th scope="col">Amount</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">ITEM001</th>
<td>PLATE</td>
<td><input type="text" class="auto-calc unit-price form-control"></td>
<td><input type="text" class="auto-calc amount form-control"></td>
<td><input type="text" class="total-cost form-control"></td>
</tr>
<tr>
<th scope="row">ITEM002</th>
<td>SPOON</td>
<td><input type="text" class="auto-calc unit-price form-control"></td>
<td><input type="text" class="auto-calc amount form-control"></td>
<td><input type="text" class="total-cost form-control"></td>
</tr>
</tbody>
</table>
<p>Total invoice amount: <span id="total-invoice">0</span>.
<p>
<button id="add">Add row</button>
I found the answer but this only works if there is only one row. But in my case it have many rows.
<input type="text" name="input1" id="input1" value="5">
<input type="text" name="input2" id="input2" value=""> <a href="javascript: void(0)"
onClick="calc()">Calculate</a>
<input type="text" name="output" id="output" value="">
And in javascript
$("#input2,#input1").keyup(function () {
$('#output').val($('#input1').val() * $('#input2').val());
});
This will simply multiply columns.
I've a following HTML code for table:
<table id="blacklistgrid_1" class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th style="vertical-align:middle">Products</th>
<th style="vertical-align:middle">Pack Of</th>
<th style="vertical-align:middle">Quantity</th>
<th style="vertical-align:middle">Volume</th>
<th style="vertical-align:middle">Unit</th>
<th style="vertical-align:middle">Rebate Amount</th>
</tr>
</thead>
<tbody class="apnd-test">
<tr id="reb1_1">
<td><input type="text" name="pack[1]" id="pack_1" value="" class="form-control" size="8"/></td>
<td><input type="text" name="quantity[1]" id="quantity_1" value="" class="form-control" size="8"/></td>
<td><input type="text" name="volume[1]" id="volume_1" value="" class="form-control" size="8"/></td>
</tr>
</tbody>
<tfoot>
<tr id="reb1_2">
<td><button style="float:right; margin-bottom: 20px" class="products" type="button" class="btn btn-default" onclick=""> Add</button></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
And I've following jQuery code on above table:
$(document).ready(function() {
$('.products').click(function () {
var new_row = $('#reb1').clone();
/*Here I want to use the id as #blacklistgrid_1. As the there may be more than one tables present the ids could be #blacklistgrid_2, #blacklistgrid_3, and so on. So it should be dynamic not static for value 1*/
var tbody = $('tbody', '#blacklistgrid');
/*And in this line too, I want to access the tr and t body of that table with specific id only*/
var n = $('tr', tbody).length + 1;
new_row.attr('id', 'reb' + n);
$(':input', new_row).not('.prod_list').remove();
//new_row.find("td:eq(1)").html();
$('<button style="color:#C00; opacity: 2;" type="button" class="close delete" data-dismiss="alert" aria-hidden="true">×</button>').appendTo( $(new_row.find('td:first')) );
tbody.append(new_row);
$('.delete').on('click', deleteRow);
});
});
I've written my requirement in form of commentin above code. So someone please help me in achieving this. Thank you.
You can do make your code, id starts with blacklistgrid
$('[id^= blacklistgrid_]') // here you can access all elements whose id starts
// with backlistgrid_
and for accessing their specific children
$('[id^= blacklistgrid_]>td')
What others tried to explain in comments,
Here using class selector, you're going to access their id
$.each('.table', function () { // iterate all the table elements
var id = $(this).prop('id');
if (id === "blacklistgrid_1") { // check for the ids
//Perform ToDos
var tds = $(this).find('td');
// using tds perform its ToDos
}
});