jQuery how to count elements that are hidden - javascript

I created a manual search functionality that displays the results as the user types. Here is the fiddle: https://jsfiddle.net/rtq4jfuq/1/
Here is the HTML
<script src='https://code.jquery.com/jquery-3.2.1.min.js'></script>
<input style='width: 300px;' placeholder='search' id='search'>
<table border='1'>
<tr>
<th>Name</th>
</tr>
<tr class='names'>
<td>Bob</td>
</tr>
<tr class='names'>
<td>Ted</td>
</tr>
<tr class='names'>
<td>Steve</td>
</tr>
<tr class='names'>
<td>Sven</td>
</tr>
<tr class='names'>
<td>Magnus</td>
</tr>
</table>
Here is the script
$(document).ready(function() {
$("#search").keyup(function(){
var query = $(this).val();
$(".names").each(function(){
var n = $(this).children("td").html();
if (n.toUpperCase().includes(query.toUpperCase())) {
$(this).css("display", "");
}
else {
$(this).css("display", "none");
}
});
});
});
I want to display a message once there are no rows displayed but how do I check if there are no rows displayed?

Use the :visible filter so see if you've hidden all results:
$(document).ready(function() {
$("#search").keyup(function() {
var query = $(this).val();
$(".names").each(function() {
var n = $(this).children("td").html();
if (n.toUpperCase().includes(query.toUpperCase())) {
$(this).css("display", "");
} else {
$(this).css("display", "none");
// Check to see if all elements have been hidden
if (!$(".names:visible").length) {
// All element hidden, do something here
alert("no results");
}
}
});
});
});
EDIT
FYI - your code can be greatly simplified. This is a quick and dirty example - I'm sure that there's room for further improvement:
$(document).ready(function() {
$("#search").keyup(function() {
var query = $(this).val();
var matches = $(".names").filter(function() {
return $(this).children("td").html().toUpperCase().includes(query.toUpperCase())
}).show();
$(".names").not($(matches)).hide();
if (!$(".names:visible").length) {
$("#myTable").append("<tr class='noRecords'><td>No records found</td></tr>");
} else {
$(".noRecords").remove();
}
});
});
Here's a working fiddle.

I will suggest you that instead of adding/removing an inline CSS add/remove a class with display none, so you can find how much elements has that class and compare it againist of how much cells you have, if number matches you will know that is not displaying any cell

Related

ignore spaces and dashes in javascript search code

I've got a search box where as I type, table data gets filtered through and only matching results get shown. It works great; however, I want to make it better.
I want the code to ignore spaces and dashes. I'd prefer make it easy to add additional characters I want it to ignore as well in the future..
For instance...
Product Table
FH-54
TDN 256
TDN25678
FH54
In the search box, if I type FH54, I'd like both the FH-54 and the FH54 to show up. If I type in FH-54 I'd also like the FH54 and the FH-54 to show up and so on to include FH 54 as well.
If I type in TDN2 or TDN 2 in the search box, I'd like TDN 256 and TDN25678 to show up.
<b>Product Search</b><br /><form class="formatted">
<input id="Search" data-class="search_product" type="text" /></form>
<script type="text/javascript">
$('#Search').on('keyup', function(e) {
$("#noData").remove();
var value = $(this).val();
value = value.replace(/\\/g, '');
var patt = new RegExp(value, "i");
var sw = 0;
var counter = 0;
$('#Data tbody').find('tr').each(function() {
counter++;
if (!($(this).find('td').text().search(patt) >= 0)) {
$(this).not('#header').hide();
sw++;
} else if (($(this).find('td').text().search(patt) >= 0)) {
$(this).show();
}
});
if (sw == counter) {
$("#Data tbody").append(`<tr id="noData">
<td colspan="3">No data</td>
</tr>`);
} else {
$("#noData").remove();
}
});
</script>
I've tried to reconstruct your scenario the best I could and made a working example.
As per your requirement to ignore all spaces and dashes: How about removing spaces and dashes from search string and from your values within the columns?
$('#Search').on('keyup', function(e) {
$("#noData").remove();
var value = $(this).val();
var spacesAndDashes = /\s|-/g;
value = value.replace(spacesAndDashes, "");
var patt = new RegExp(value, "i");
var sw = 0;
var counter = 0;
$('#Data tbody').find('tr').each(function() {
counter++;
if (!($(this).find('td').text().replace(spacesAndDashes, "").search(patt) >= 0)) {
$(this).not('#header').hide();
sw++;
} else if (($(this).find('td').text().replace(spacesAndDashes, "").search(patt) >= 0)) {
$(this).show();
}
});
if (sw == counter) {
$("#Data tbody").append(`<tr id="noData">
<td colspan="3">No data</td>
</tr>`);
} else {
$("#noData").remove();
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<b>Product Search</b>
<br />
<form class="formatted">
<input id="Search" data-class="search_product" type="text" />
</form>
<table id="Data">
<thead>
<tr>
<th>Product Table</th>
</tr>
</thead>
<tbody>
<tr>
<td>FH-54</td>
</tr>
<tr>
<td>TDN 256</td>
</tr>
<tr>
<td>FH54</td>
</tr>
<tr>
<td>FH 54</td>
</tr>
<tr>
<td>TDN25678</td>
</tr>
</tbody>
</table>

checked all/ unchecked all but limit row for check

I have
<thead>
<tr>
<th>Num</th>
<th>name</th>
<th>date</th>
<th><input type="checkbox" name="m_check" id="m_check" /></th>
</tr>
</thead>
<tbody>
<!-- i have loop for get data -->
<tr>
<td>$Num</td>
<td>$name</td>
<td>$date</td>
<td><input type="checkbox" name="e_check[]" value="<?php echo $companys->data[$i]['com_id'] ?>" class ="e_check" id="e_check_<?php echo $companys->data[$i]['com_id'] ?>" /></td>
</tr>
<!-- end loop for get data -->
</tbody>
this is my script
$('#m_check').change('change',function() {
if ($(this).is(':checked')) {
$('input[name="e_check[]"]:checkbox').attr('checked', true);
$('#ib_email').removeAttr("disabled");
} else {
$('input[name="e_check[]"]:checkbox').attr('checked', false);
$('#ib_email').attr("disabled", "disabled");
}
});
my problem is i need when user checked on m_check it's check element of e_check but check only 10, if my e_check more than 10 also.
please help me to correct my js
I also see this but i still can not custom my code :(
**Confirm my code is not wrong for user checked all, it's checked element row all, unchecked and it's unchecked all element row but i need when user checked all button it's checked element row limit 10 row top and other is still not check
There are a few mistakes in the jQuery. Prop should be used instead of attributes for the checked prop. Also ':checkbox' is not necessary when name="e_check[]" is already a unique identifier. Lastly, checkout the snippet at the bottom to grab the number. With it, you can set the checking behavior to reflect the number grabbed.
$('#m_check').change('change', function () {
if ($(this).is(':checked')) {
$('[name="e_check[]"]').prop('checked', true);
$('#ib_email').removeAttr("disabled");
} else {
$('[name="e_check[]"]').prop('checked', false);
$('#ib_email').attr("disabled", "disabled");
}
var $num = $(this).closest('table').find('td:first');
$num = parseInt($num);
});
You should do it like
$(document).on('change', '#m_check', function() {
$('#m_check').click(function () {
if ($(this).is(':checked')) {
$('input[type=checkbox].e_check').map(function (_, el) {
$(el).prop('checked', true);
});
} else {
$('input[type=checkbox].e_check').map(function (_, el) {
$(el).prop('checked', false);
});
}
});
});
or
$('#m_check').change(function() {
});
Edited:
Now when you will click on <input type="checkbox" name="m_check" id="m_check" /> All of your records will be checked.
you can do in this way.
I am assuming there is class tablecheckbox attachewd to tbody to
uniquely identify the checkbox.
$('#m_check').on('change',function() {
if ($(this).is(':checked')) {
if( $(".tablecheckbox tr input[type='checkbox']").length > 10){
$(".tablecheckbox tr input[type='checkbox']").slice(0,10).prop('checked',true)
}else{
$(".tablecheckbox tr input[type='checkbox']").prop('checked',true)
}
$('#ib_email').removeAttr("disabled");
} else {
$(".tablecheckbox tr input[type='checkbox']").slice(0,10).prop('checked',false)
$('#ib_email').attr("disabled", "disabled");
}
});

Jquery. Find all <tr> containing text from selected <option>

I try to show all lines contaning selected text from option after click on button, this is my code:
<select>
<option>text1</option>
<option>text2</option>
<option>text3</option>
<option>text4</option>
</select>
<button class="show"></button>
<button class="hide"></button>
<table>
<tr>
<td>text1</td><td>....</td>
</tr>
<tr>
<td>text2</td><td>....</td>
</tr>
<tr>
<td>text3</td><td>....</td>
</tr>
<tr>
<td>text1</td><td>....</td>
</tr>
</table>
I try to do something like this but it doesnt work:
$(function(){
b = $("tr");
$(".show").on("click", function(){
var a = $("select option:selected").text();
$(b).hide();
if ($("tr:contains('"+a+"')").length)
$(this).closest(tr).show();
});
$(".hide").on("click", function(){
$(b).show();
});
});
Can someone help me, pls :)
You need something like this. Don't pollute global space and use proper selectors. And there is no need to wrap a jQuery object again.
$(function() {
var b = $("table");
$(".show").on("click", function() {
var a = $("select option:selected").text();
b.find("tr").hide().end().find("td:contains('" + a + "')").parent().show();
});
$(".hide").on("click", function() {
b.find("tr").show();
});
});
Try this : You can use each to check each tr for selected option text and make it visible. No need to use closest('tr') as $(this) itself is a TR.
$(function(){
b = $("tr");
$(".show").on("click", function(){
var a = $("select option:selected").text();
b.hide();
//if ($("tr:contains('"+a+"')").length)
// $(this).closest(tr).show();
b.each(function(){
if($(this).text().indexOf(a)!=-1)
{
$(this).show();
}
});
});
$(".hide").on("click", function(){
b.show();
});
});
You can't use contains cause match any element that simple contains test(Select all elements that contain the specified text). Bu you can use each and match any td with same text and show parent(tr) like:
b = $("tr");
$(".show").on("click", function() {
var a = $("select option:selected").text();
$(b).hide();
$("td").each(function() {
if ($(this).text() == a) {
$(this).parents("tr").show();
}
});
});
$(".hide").on("click", function() {
$(b).show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option>text1</option>
<option>text2</option>
<option>text3</option>
<option>text4</option>
</select>
<button class="show">show</button>
<button class="hide">hide</button>
<table>
<tr>
<td>text1</td>
<td>....</td>
</tr>
<tr>
<td>text2</td>
<td>....</td>
</tr>
<tr>
<td>text3</td>
<td>....</td>
</tr>
<tr>
<td>text1</td>
<td>....</td>
</tr>
</table>
Make your buttons run functions directly here.
function show() {
var needle = $("select option:selected").text();
$('#myTable td').each(function() {
if ($(this).text() === needle) $(this).show();
});
}
function hide() {
var needle = $("select option:selected").text();
$('#myTable td').each(function() {
if ($(this).text() === needle) $(this).hide();
});
}
Take a look at this (jsFiddle).

Looping through table and changing <tr> background depending on which checkboxes are checked

I have a table with table rows, which contain 2 checkboxes in them, one is under the class of student_late, and the other is under the class of student_present.
I want it to do the following:
If the student_present checkbox only is checked, make the tablerow green by adding the class "success".
If the student_present checkbox is checked as well as the student_late checkbox, make the tablerow yellow by adding the class "info".
If no checkbox is checked, make the tablerow red by adding the class "danger".
This is my current CoffeScript:
$(document).ready ->
return $("tr .student_present").each(->
if #checked
$(this).closest("tr").addClass "success"
else
$(this).closest("tr").addClass "danger"
)
$("tr .student_late").each ->
$(this).closest("tr").addClass "info" if #checked
Or for those who prefer JS:
$(document).ready(function() {
return $("tr .student_present").each(function() {
if (this.checked) {
return $(this).closest("tr").addClass("success");
} else {
return $(this).closest("tr").addClass("danger");
}
});
return $("tr .student_late").each(function() {
if (this.checked) {
return $(this).closest("tr").addClass("info");
}
});
});
You do not need to use return for document ready. Here is the code that you could use.
$(function() {
$('table tbody tr').each(function() {
var $row = $(this);
var late = $row.find('.student_late')[0].checked;
var present = $row.find('.student_present')[0].checked;
if(present && !late) {
$row.addClass('success');
} else if(present && late) {
$row.addClass('info');
} else if(!present && !late) {
$row.addClass('danger');
}
});
});
$(function() is just a shorthand for $(document).ready(function() . Here is JSfiddle of the code working. http://jsfiddle.net/5DUwr/
If you want it to update when you click a checkbox. Use this code
$(function() {
$('table tbody tr').each(function() {
var $row = $(this);
updateRow($row);
});
$('table tbody tr input[type="checkbox"]').click(function() {
var $row = $(this).parents('tr');
updateRow($row);
});
});
function updateRow($row) {
$row.removeClass('success danger info');
var late = $row.find('.student_late')[0].checked;
var present = $row.find('.student_present')[0].checked;
if(present && !late) {
$row.addClass('success');
} else if(present && late) {
$row.addClass('info');
} else if(!present && !late) {
$row.addClass('danger');
}
}
Here is the fiddle http://jsfiddle.net/5DUwr/4/
Not 100% sure what the problem is here, I've just replicated your code and it seems to work fine (obviously I don't have your HTML, though)... http://jsfiddle.net/VWcXW/
<table>
<tr>
<td><input type="checkbox" class="student_present"></input></td>
</tr>
<tr>
<td><input type="checkbox" class="student_present" checked="checked"></input></td>
</tr>
</table>
$(document).ready(function() {
return $("tr .student_present").each(function() {
if (this.checked) {
return $(this).closest("tr").addClass("success");
} else {
return $(this).closest("tr").addClass("error");
}
});
return $("tr .student_late").each(function() {
if (this.checked) {
return $(this).closest("tr").addClass("info");
}
});
});
It works fine for me:
http://jsfiddle.net/Ba5qg/
I mean, it's executed once !
It's not binding click event to change the background-color...
That you could change with:
$("tr .student_present").on('click', function () {
if ($(this).is(':checked')) {
$(this).closest('tr').addClass('success');
[...]
}
});
Fiddle code:
HTML
<table>
<tr>
<td>Paul</td>
<td><input type='checkbox' name='student_present' class='student_present' checked /></td>
<td><input type='checkbox' name='student_late' class='student_late' /></td>
</tr>
<tr>
<td>John</td>
<td><input type='checkbox' name='student_present' class='student_present' /></td>
<td><input type='checkbox' name='student_late' class='student_late' checked /></td>
</tr>
</table>
CSS
.success {
background: green;
}
.error {
background: red;
}
.info {
background: yellow;
}
JS
You can remove your return statement here !
$(document).ready(function() {
$("tr .student_present").each(function() {
if (this.checked) {
return $(this).closest("tr").addClass("success");
} else {
return $(this).closest("tr").addClass("error");
}
});
$("tr .student_late").each(function() {
if (this.checked) {
return $(this).closest("tr").addClass("info");
}
});
});
you can add unique ids for your checkboxes i.e. 'chk_001' and eqivalent numbers in the ids of the tr/td tags.
Then looping through the checkboxes your can grab the rows you want to change.
When you use the same numbers in the tr/td ids (like tr_001 or td_001) you can set the desired classes/styles using getElementById wherever you find the checkbox checked.
I think this could be achieved easier(Working fiddle):
HTML
<table>
<tr>
<td><input class="student_present" type="checkbox" checked="checked">Present</td>
<td><input class="student_late" type="checkbox">Late</td>
</tr>
<tr>
<td><input class="student_present" type="checkbox">Present</td>
<td><input class="student_late" type="checkbox" checked="checked">Late</td>
</tr>
</table>
CSS
.success {
background: green;
}
.error {
background: red;
}
.info{
background: yellow;
}
JS
$(document).ready(function() {
$(".student_present").closest('tr').addClass('error');
$(".student_present:checked").closest('tr').toggleClass('success error');
$(".student_late:checked").closest('tr').addClass(function() {
if($('.student_present', $(this).closest('tr')).is(':checked')) return 'info';
else return '';
});
});

How to hide any row in a table whose third cell value does not match a given string in JQuery

If i have a table:
<table id="myTable">
<tr>
<td>1</td><td>2</td><td>NoMatch</td><td>4</td>
</tr>
<tr>
<td>1</td><td>2</td><td>Match</td><td>4</td>
</tr>
</table>
I have been trying:
$(document).ready(function () {
$('input#myInput').keyup(function (val) {
// for each third td of each row, if this value does not contain: this.val() then hide it
});
});
Something like this:
var $cells = $('#myTable tr td:nth-child(3)'),
$hidden = $();
$('#myInput').keyup(function () {
var search = this.value;
var $to_hide = $cells.filter(function() {
return $(this).text() !== search;
}).parent();
$hidden.not($to_hide.get()).show();
$hidden = $to_hide.hide();
});
I assumed that when you say contains, you mean that the text has to be equal to the provided input (otherwise NoMatch and Match would not make sense). But if the content of cell just has to contain the search string as substring, you can use .indexOf() [docs].
DEMO
There are other things you have to consider, like what should happen when the search string is empty, but this is for you to play around ;)
Use "this" in your key up event handler to get the value of the input.
$(document).ready(function () {
$('input#myInput').keyup(function () {
//add if statement
alert($(this).val());
});
});
Not quite sure what you are trying to do with the table. There is not enough information.
Try this:
jsfiddle
HTML
<table id="myTable">
<tr>
<td>1</td><td>2</td><td>NoMatch</td><td>4</td>
</tr>
<tr>
<td>1</td><td>2</td><td>Match</td><td>4</td>
</tr>
</table>
<input id="myInput"/>
Javascript/Jquery
$('#myInput').keyup(function () {
var me = $(this);
var val = me.val();
$("#myTable tr").each(function() {
var tr = $(this);
var td = tr.find("td:eq(2)");
if(td.text().substring(0, val.length) === val) {
tr.show();
} else {
tr.hide();
}
});
});

Categories