I have the following table in html:
<div class="col-lg-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h4 class="card-title" id="section-title">
{{$inventory_name}} - {{ $category_name }}
</h4>
<div class="table-responsive">
<table class="table table-striped" id="medstable">
<thead>
<tr class="header">
<th>
Nume
</th>
#if ($inventory_id == 1 || $inventory_id == 2)
<th>Cantitate Totala</th>
#endif
</tr>
</thead>
<tbody>
#if( !empty($items) )
#php
$i = 0;
#endphp
#foreach ($items as $item)
<tr data-count="{{ $loop->index }}">
<td> {{$item->name}}</td>
#if ($inventory_id == 1)
<td>150 / {{$minimum_quantities_farm[$i]->quantity ?? 0}}</td>
#php
$i++;
#endphp
#endif
#if ($inventory_id == 2)
<td>150 / {{$minimum_quantities_stoc3[$i]->quantity ?? 0}}</td>
#php
$i++;
#endphp
#endif
</tr>
<tr class="treeview tr-{{ $loop->index }}">
<td colspan="100%">
<table>
<thead>
<tr>
#if ($item->category_id == 1)
<th>Cod CIM</th>
#endif
<th>Cod Produs</th>
<th>Cantitate</th>
<th>Termen Valab</th>
<th>Lot</th>
<th>UM</th>
<th>Pret Unitar</th>
<th>TVA</th>
<th>Pret TVA</th>
</tr>
</thead>
<tbody>
#if( !empty($item_stock[$item->name]))
#foreach($item_stock[$item->name] as $inItem)
#if($inItem['quantity'] > 0)
<tr>
#if ( $inItem['category_id'] == 1)
<td>{{$inItem['cim_code']}}</td>
#endif
<td>{{$inItem['product_code']}}</td>
<td>{{$inItem['quantity']}}</td>
#if ((new \DateTime($inItem['exp_date']))->format('Y-m-d') > (new \DateTime())->format('Y-m-d'))
<td>{{$newDate = date("d-m-Y", strtotime($inItem['exp_date'])); }}</td>
#else
<td style="color:red; font-weight: bold;">EXPIRED</td>
#endif
<td>{{$inItem['lot']}}</td>
<td>{{$inItem['m_name']}}</td>
<td>{{$inItem['price']}}</td>
<td>{{$inItem['tva']}}</td>
<td>{{$inItem['tva_price']}}</td>
</tr>
#endif
#endforeach
#endif
</tbody>
</table>
</td>
</tr>
#endforeach
#endif
</tbody>
</table>
</div>
</div>
</div>
</div>
I also have this input bar in which I can search through the table's items:
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search..">
Below is the JavaScript myFunction() function:
function myFunction() {
let input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("medstable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
The thing is, whenever I click on a row, the row should expand and display the values that are basically hidden (until I press on a row). It works fine, but for example, if I search for an item and I find it, if I click on it, the row will not expand anymore. How can I solve this? I also have this JavaScript function that basically expands the row:
function treeviewDisplay() {
jQuery('#medstable tbody tr:not(.treeview)').click(function() {
const treeview = jQuery('#medstable tbody tr.treeview.tr-' + jQuery(this).data('count'));
if( treeview.hasClass('active') ) {
treeview.removeClass('active');
} else {
jQuery('#medstable tbody tr.treeview').removeClass('active');
treeview.addClass('active');
}
});
}
And the css:
tr.treeview {
display:none;
transition: 0.5 all;
}
tr.treeview.active{
display: table-row;
}
tr.treeview table{
width: 100%;
}
P.S: I left the embedded php in the table, maybe it will help. If not, I can change to some hardcoded data
EDIT: I read the question again and I thought I should explain in better. So, if I don't search for anything, on any item I would click, the row expands with the data. However, if I search for the second item for example, the table is gonna show only the second item. And if I click on it, it won't expand. The rows only expand when you don't search for anything. I want them to expand even if I search for something
Related
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();
} );
I have a function that works perfectly
But the need arose, to add another field to the research, I do not know how to solve. It has a checkbox in the form, if it is filled, it fetches the data true in the table, if not the data false, how to add in the code below? I'm in doubt, if at all possible.
function myFunction2() {
var input, filter, table, tr, td, i, filtro;
input = document.getElementById("busca2");
filter = input.value.toUpperCase();
table = document.getElementById("tablepesquisa2");
tr = table.getElementsByTagName("tr");
filtro = document.getElementById("filtroPesquisa2").value;
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[filtro];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
<div class="form-group">
<div class="col-sm-3">
<select id="filtroPesquisa2" class="form-control">
<option value="0">Código</option>
<option value="1">Descrição</option>
</select>
</div>
<div class="col-sm-7">
<input type="text" id="busca2" placeholder="Pesquisa.." onkeyup="myFunction2();" class="form-control" />
</div>
</div>
<div class="modal-body">
<div class="table-overflow col-sm-12">
<table class="table table-responsive table-hover" id="tablepesquisa2">
<thead>
<tr>
<th>Código</th>
<th>Nome</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Produto) {
<tr>
<td>#item.Codigo</td>
<td>#item.nome</td>
<td align="right">
<i class="fa fa-check-circle fa-lg"></i>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="col-sm-3" style="text-align:left;">
<input type="checkbox" asp-for="Produtos" name="Produtos" id="Produtos"/>
<label asp-for="Produtos" class="control-label"></label>
<span asp-validation-for="Produtos" class="text-danger"></span>
</div>
<div class="col-sm-3" style="text-align:left;">
<input type="checkbox" asp-for="Servico" name="Servico" id="Servico"/>
<label asp-for="Servico" class="control-label"></label>
<span asp-validation-for="Servico" class="text-danger"></span>
</div>
In this table, have these two fields, then need to be filtered if they are marked or not, if product is marked, have to bring only the fields where product = true, and if it is the other, only the fields that the other is true
EDIT
I managed to solve, just by selecting the correct column and comparing to true
I solved the problem by doing this way:
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[filtro];
td1 = tr[i].getElementsByTagName("td")[4];
td2 = tr[i].getElementsByTagName("td")[3];
var tbBoolean = ($(td2).text() == "True" ? true : false);
if ($('#Venda').prop("checked") == true) {
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1 && $(td1).text() == idEmpresa || $(td1).text() == "") {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
else {
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1 && tbBoolean == false) {
if ($(td1).text() == idEmpresa || $(td1).text() == "") {
tr[i].style.display = "";
}
} else {
tr[i].style.display = "none";
}
}
}
}
I have this function to do a filter by jquery, and it is returning this error:
Cannot read property 'getElementById' of undefined
function VerificaCheck() {
var input, filter, table, tr, td, i, filtro;
input = document.getElementById("busca2");
filter = input.value.toUpperCase();
table = document.getElementById("tablepesquisa2");
tr = table.getElementsByTagName("tr");
filtro = document.getElementById("filtroPesquisa2").value;
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[filtro];
var tipoProduto = tr[i].getElementById("tipoProduto").value;
if (td) {
if (tipoProduto == $('#Produtos').prop("checked")) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
This is the HTML of my table, and the checkbox. If the checkbox is checked it should look for in the table the fields of typeProduct that are true
<div class="form-group">
<div class="col-sm-3">
<select id="filtroPesquisa2" class="form-control">
<option value="0">Código</option>
<option value="1">Descrição</option>
</select>
</div>
<div class="col-sm-7">
<input type="text" id="busca2" placeholder="Pesquisa.." onkeyup="myFunction2();" class="form-control" />
</div>
</div>
<div class="modal-body">
<div class="table-overflow col-sm-12">
<table class="table table-responsive table-hover" id="tablepesquisa2">
<thead>
<tr>
<th>Código</th>
<th>Nome</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Produto)
{
<tr>
<td>#item.Codigo</td>
<td>#item.nome</td>
<td align="right">
<i class="fa fa-check-circle fa-lg"></i>
</td>
<td id="tipoProduto" value="#item.TipoProduto">#item.TipoProduto</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<input type="checkbox" asp-for="Produtos" onclick="checkProduto();" name="Produtos" id="Produtos"/>
getElementById is available on the document, not on tr.
Documentation
change the following line to
var tipoProduto = document.getElementById("tipoProduto").value;
However, this may not get what you want, based on my guesses that you have multiple elements by this id in your table. Post your html and what you are trying to do, may be there's another way to do this.
UPDATE:
As suspected, your td repeats in the loop, so you multiple td with same id. I'd suggest to remove id from it.
Since the value you are looking is the last td, what you can possibly do to get the value you are looking for is (one way that is):
td[td.length-1].innerHTML
So the loop would look more like:
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[filtro];
if (td) {
var tipoProduto = td[td.length-1].innerHtml;
if (tipoProduto == $('#Produtos').prop("checked")) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
I have made a table that outputs data from a database. I added a searchbar that works for 1 column, but my goal is to make it work for two columns in the table: The 'Locatie' column and the 'Nr.' column. Besides that (but less important) I would like the thead to stay visible when something is searched. Right now it disappears and only shows the data that is searched for.
My code is as following:
<script>
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("p")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
<div class="titel-top">
<div class="col-xs-10">
<div class="input-group">
<input type="text" class="form-control" id="myInput" placeholder="Zoeken naar locatie..." onkeyup="myFunction()">
<!--<span class="input-group-btn">
<button class="btn btn-secondary" type="button">Zoeken</button>
</span>-->
</div>
</div>
</div>
<?php
$page_title = "Sensors";
?>
<div class="row">
<table class="table" id="myTable">
<thead>
<tr>
<th><p class="text-14">Status</p></th>
<th><p class="text-14">Locatie</p></th>
<th><p class="text-14">Nr.</p></th>
<th><p class="text-14">Sensors</p></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><div id="status"></div></td>
<td><p class="text-12"><?php echo $locatie ?></p></td>
<td><p class="text-12"><?php echo $huisnummer ?></p></td>
<td><p class="text-12">5</p></td>
<td class="meer-informatie-verhuurder"><svg class="chev-forward" viewBox="0 0 24 24">
<path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
</svg></td>
</tr>
</tbody>
</table>
</div>
<?php
//bekijkt of één van de waardes rood is.
if($co2 >1000 OR $humidity >80 OR $temperature >25 OR $temperature <9 OR $humidity <30) {
?>
<script>
document.getElementById("status").style.backgroundColor = "#ff1744";
</script>
<?php
//bekijkt of één van de waardes oranje is.
}
elseif ($co2 >800 OR $humidity >60 OR $temperature >20 OR $temperature >9 OR $humidity >30) {
?>
<script>
document.getElementById("status").style.backgroundColor = "#dc9b10";
</script>
<?php
//Als er geen rode of oranje status is wordt de status groen.
}else { //maakt status groen.
?>
<script>
document.getElementById("status").style.backgroundColor = "#51c53f";
</script>
<?php
}
?>
The table can be found on the website: http://st359450.cmd17c.cmi.hanze.nl/senz/verhuurder-sensors.php
You will need to log in: username '1' and password 'Hallo'
I include the header, footer etc. at the top and bottom of the page, I didn't think they would be relevant for this question. I hope you guys can help me.
td = tr[i].getElementsByTagName("p")[0];
In this line, as you access the element at index 0 in the returned list of <p> elements, you are incidentally getting the values from "Locatie" column.
A quick fix would be to read the value from element at index 1 as well, and show the tr element if either of them contain given word:
var paragraphsInRow = tr[i].getElementsByTagName("p");
var locatie = paragraphsInRow[0];
var nr = paragraphsInRow[1];
if (locatie || nr) {
if (locatie.innerHTML.toUpperCase().indexOf(filter) > -1
|| nr.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
Possible improvements:
Don't filter using innerHTML. As evident from the name, it returns the HTML content of the paragraph element. Currently that paragraph element may not contain HTML elements, but in future it might. So it is best to use innerText for filtering data - which only contains the visible text within the element.
Instead of identifying data through tr[i].getElementsByTagName("p")[0], use a better CSS selector. I would suggest setting a CSS class in the HTML, and then using a descendant selector like tr[i].querySelector("p.locatie"). Your HTML should then look like:
<tr>
<td><div id="status"></div></td>
<!-- Notice the CSS class added here. -->
<td><p class="text-12 locatie"><?php echo $locatie ?></p></td>
<td><p class="text-12"><?php echo $huisnummer ?></p></td>
<td><p class="text-12">5</p></td>
<td class="meer-informatie-verhuurder"><svg class="chev-forward" viewBox="0 0 24 24">
<path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
</svg></td>
</tr>
Doing so would make it easier to change the markup in future. For instance, if you add another column between "Status" and "Locatie", an index based selector would give incorrect results.
I have a table and using javascript I give the user the option to remove table rows from the table by putting the display style to none.
If the user wants to see the rows again, I need to put the display style away from none and my problem is that I don't know what style to use. I thought table-row-group is the most sensible, but it messes up the rows...
I created a fiddle here and copied the code below
https://jsfiddle.net/b2s3dpo5/#&togetherjs=7EwfsBJIfw
<fieldset style="display: inline-block;">
<div style="display: inline-block;">
<input type="checkbox" name="{{ category.name }}" id="category" checked> remove rows
</div>
</fieldset>
<div class="panel panel-default col-xs-12">
<table class="table table-striped">
<thead>
<tr>
<th><strong>ID</strong></th>
<th><strong>test test test</strong></th>
<th><strong>Institute/Organisation</strong></th>
<th><strong>test deadline test</strong></th>
</tr>
</thead>
<tbody>
<tr class="category">
<th class="col-xs-1" scope="row">
test
</th>
<td class="col-xs-5">
test
</td>
<td class="col-xs-4">
test
</td>
<td class="col-xs-2">
test
</td>
</tr>
</tbody>
</table>
</div>
and the necessary javascript
document.getElementById('category').onclick = function() {
toggleSub_by_class(this, 'category');
};
function toggleSub_by_class(box, select_class) {
// get reference to related content to display/hide
var el = document.getElementsByClassName(select_class);
var flag;
if (box.checked) {
for (var i = 0, j = el.length; i < j; i++) {
el[i].style.display = 'table-row-group';
}
} else {
for (var i = 0, j = el.length; i < j; i++) {
var classList = el[i].className.split(' ')
flag = 0
for (var h = 0, k = classList.length; h < k; h++) {
if (document.getElementById(classList[h])) {
if (document.getElementById(classList[h]).checked) {
flag = 1
}
}
}
if (flag == 0) {
el[i].style.display = 'none';
}
}
}
}
Try visibility:hidden or height:0px or both.
I figured it out myself... the correct display style is empty
el[i].style.display = '';
that works fine for me
carl
First off, for readability purposes, try to create more concise headers when you share it with the rest of the community (although I understand that this is not a big deal).
I would try
visibility:hidden