Looking for a jquery method to narrow down an unordered list by user input. Each item on the list contains a first and last name. Purpose is to use both to narrow down the list, so if first letter is "x" all items without "x" in first name OR last name will be cleared. Additionally if list is narrowed down to 0 id like to fire a function (ajax call, but could be anything).
html:
<input id="listCheck">
<ul>
<li class="entry"><span class="nametext">alex crain</span></li>
<li class="entry"><span class="nametext">Bart Simpson</span></li>
<li class="entry"><span class="nametext">Jessica Alba</span></li>
<li class="entry"><span class="nametext">Will Farrell</span></li>
</ul>
js:
$("listCheck").keyup(function(){
var term = $(this).val();
});
I am assuming I need to transform the spans into an array with first and last names separated and then loop through them all. Fiddle
Like this
$('#listSearch').keyup(function(){
var valThis = $(this).val().toLowerCase();
$('.navList>li').each(function(){
var text = $(this).text().toLowerCase();
(text.indexOf(valThis) >= 0) ? $(this).show() : $(this).hide();
});
});
Demo Fiddle
//You can use if else in place of ternary operator.
Rather than using indexOf you can go about it with the :contains() selector. It won't be any faster, but the code will look cleaner:
$("li:contains(term)").show();
$("li:not(:contains(term))").hide();
and such. Here's a demo on your fiddle
try this :
$("#listCheck").keyup(function(){
var txt = $(this).val();
$('.nametext').each(function ()
{
if($(this).html().indexOf(txt) >= 0)
{
$(this).parent().show();
}
else
{
$(this).parent().hide();
//$(this).parent().remove();
}
});
});
here is the working example HERE
Related
I've created a small script that filters my ul with a nested ul inside of it. The only issue with my script is I want to hide the title of the nested ul if none of the li's contain the search term, but I am not sure how to go about checking the li's of each "group" as opposed to each li individually. The way it stands, it will display the title if it finds an li in the group matching the search term, but it will immediately turn around and hide the title if the same group contains an li that DOES NOT contain the search term. I know what I'm doing wrong, but I am not as skilled in jquery and cannot seem to visualize how to go about this.
Any help would be great. My code is below:
HTML:
<div id="sitemap">
<h3>Hospital Data Solutions Interactive Site Map</h3>
<hr/>
<p id="header"><input type="text" placeholder="Filter Site Map"> - Use this field filter our list of databases: Search by Topic or Topic Subgroup</p>
<ul id="toplist">
<li class="group">
<h3 class="sTitle">Available Beds - <a style="font-size:18px;">Go to Section</a></h3>
<ul class="sublist">
<li>General</li>
<li>ICU</li>
<li>CCU</li>
<li>BICU</li>
<li>SICU</li>
<li>Other</li>
<li>Hospice</li>
<li>Total</li>
</ul>
</li>
<hr/>
<li class="group">
<h3 class="sTitle">Discharges - <a style="font-size:18px;">Go to Section</a></h3>
<ul class="sublist">
<li>Medicare</li>
<li>Medicaid</li>
<li>Other</li>
<li>Total</li>
</ul>
</li>
</ul>
</div>
Jquery:
$(function(){
$('input[type="text"]').keyup(function(){
var searchText = $(this).val().toLowerCase();
$('.sublist>li').each(function(){
var currentLi = $(this).text().toLowerCase();
if(currentLi.search(searchText) != -1){
$(this).slideDown();
$(this).closest('.group').children('.sTitle').show();
} else { $(this).slideUp(); $(this).closest('.group').children('.sTitle').hide();}
});
});
});
First, select the .sublist elements instead of the lis.
Then iterate that collection using .each(), and use .children() to test each li like you currently are, except use .filter() instead of .each(). This will give you a collection as a result. If the collection is empty, there were no matches. If not, then there was a match.
$('input[type="text"]').keyup(function(){
var searchText = $(this).val().toLowerCase();
$('.sublist').each(function(i, sub){
var matches = $(sub).children().filter(function(i, li) {
return $(li).text().toLowerCase().search(searchText) != -1;
});
if (matches.length) {
$(sub).slideDown().prev().show();
} else {
$(sub).slideUp().prev().hide();
}
});
});
Now the slideDown/Up and show/hide are happening once per sublist instead of on every child li. And I just used .prev() to get back to the h3 element.
If you're going to be hiding those list items that don't match your search you're going to want to deal with them individually anyway, so I wouldn't abandon that approach. So you just need a way to check to see if the term was found somewhere in the search of the nested list. Here's what I might do to utilize what you already have.
After you capture the search term, loop through each of the sublists and set a flag to false; this will be where we capture whether there were any matches. Then loop through that sublist's items, and if you find a match set the flag to true, showing or hiding the item as necessary. Then, after you've checked all the items show or hide the heading based on that flag. It might look something like this:
$('.sublist').each(function(){
found = false;
$(this).children("li").each( function() {
var currentLi = $(this).text().toLowerCase();
if(currentLi.search(searchText) != -1){
$(this).slideDown();
found = true;
} else {
$(this).slideUp();
}
});
if(found) {
$(this).closest('.group').children('.sTitle').show();
} else {
$(this).closest('.group').css("list-style-type", "none");
$(this).closest('.group').children('.sTitle').hide();
}
});
I added a css line to show/hide the header's disc to avoid having that hanging there if everything else disappears. Hope this helps! Let me know if you have any questions.
Thanks to this idea
http://www.redotheweb.com/2013/05/15/client-side-full-text-search-in-css.html, I implemented a client side text search using CSS3 data attributes and JQuery.
This is an HTML example
<input type="text" id="search">
<a id="btn">Filter</a>
<ul>
<li data-index="A01658">A01658 and other stuff</li>
<li data-index="A09956">A09956 and other stuff</li>
<li data-index="B25628">B25628 and other stuff</li>
<li data-index="A01777">A01777 and other stuff</li>
</ul>
And this is the JS code (jQuery required)
$('#btn').click(function() {
$('ul > li:not([data-index=\"' + $('#search').val() + '\"])').hide();
});
It works. But only "full" text. I need to let the users to perform "partial" text search (a good example is LIKE operator in MySQL).
If "A01" is entered, both first and fourth box should remain visible.
If "995" is entered, only second box should remain visible.
In there any chance to do this?
Thank you
Try this, Here is http://api.jquery.com/attribute-contains-selector/
$('#btn').click(function() {
$('ul > li:not([data-index*=\"' + $('#search').val() + '\"])').hide();
});
Another one here. This would work as and when the user types in the search field and filter LI's accordingly. This is also case insensitive.
var items = $('ul > li');
var search = $('#search');
search.on("keyup", function() {
items.show().filter(function() {
return $(this).data("index").toLowerCase().indexOf(search.val().toLowerCase()) < 0
}).hide();
});
Demo#fiddle
Let's say I have some unordered lists with items, and one or many that has a class of 'active'
<ul id='list'>
<li class='row active'></li>
<li attrA='something active'></li>
<li attrB='active'></li>
</ul>
<ul id='otherList'>
<li class='row active'></li>
<li attrA='something active'></li>
<li attrB='active'></li>
</ul>
I want to get the item where class is "active" that is a child or element of the unordered list, "list".
I tried...
$("#list li[class~='active']")
$("#list > li[class~='active']")
But to no avail...
Here's a more detailed version of my problem. The code used to print this output is...
var listId = "typeahead-3-6260";
console.log( $("#"+listId+" li") );
console.log( $("#"+listId+" li[class~='active']") );
As you can see, line 2 had some results, but line 3 didn't.
$("#list li").filter(function(){return $(this).attr('name').indexOf("name") >= 0)
Use element.attributes to get the list of attributes and use nodeValue to get the value of attribute to check if it has active
Live Demo
$("#list li").each(function(){
for(i=0; i < this.attributes.length; i++)
if(this.attributes[i].nodeValue.indexOf('active') != -1)
$(this).text('has active attribute');
});
As you have mentioned that you need to check the 'class' attribute as 'active' here is the code that might help you
$(document).on('click','#list>li.active',function(){
alert('I am here');
});
JSFiddle
I have been looking all over the web for ideas on how to do this. I have a DrillDown menu that at some points goes six levels deep (not my choice this is what the customer wants) I have created an xml document that holds all of these items there are a total of 106 different options that a user can select just in the side menu alone (again its what the customer wants). I want to create a search box that would allow me to type in the name of one of the selections and the list would shrink to only show the options with the word(s) that the user inputs.
My question Is there a plugin that would allow this behavior?
If not How do you search a group of li elements for text?
To code it yourself would be fairly straightforward, the jQuery below takes a string from the input #inputString and will iterate through the list items "ul li" and show/hide depending if they match the input string.
You can modify the "ul li" selector to contain other lists if needed
jQuery("#inputString").keyup(function () {
var filter = jQuery(this).val();
jQuery("ul li").each(function () {
if (jQuery(this).text().search(new RegExp(filter, "i")) < 0) {
jQuery(this).hide();
} else {
jQuery(this).show()
}
});
});
I expect there are many plugins that do the same thing, give it a google!
You can try to filter by contains selector:
var matches = $( 'ul#myMenu' ).find( 'li:contains(search string) ' );
$( 'li', 'ul#myMenu' ).not( matches ).slideUp();
matches.slideDown();
See example on jsFiddle
How do you search a group of li elements for text?
var filteredLIS = $("li:contains('" + yourQuery + "')");
Reference: http://api.jquery.com/contains-selector/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
// Start here: Search Service area via jQuery
window.filter = function(element)
{
var value = $(element).val().toUpperCase();
$(".left_message > li").each(function()
{
if ($(this).text().toUpperCase().search(value) > -1){
$(this).show();
}
else {
$(this).hide();
}
});
}
});
</script>
<input type="text" placeholder="Enter text to search" onkeyup="filter(this);">
<ul role="tablist" class="left_message">
<li><span>Anupk Kumar</span></li>
<li><span>Pradeep Kumar</span></li>
<li><span>Zahid Gani</span></li>
<li><span>Amitabh</span></li>
<li><span>Chandan Gupta</span></li>
</ul>
Result : Search Zahid , they return following output
<ul role="tablist" class="left_message">`enter code here`
<li><span>Zahid Gani</span></li>
</ul>
Using the drilldown sample here:
http://www.designchemical.com/lab/jquery-drill-down-menu-plugin/getting-started/
This is my suggestion:
$('#drilldown').find("a:contains('Product')");
You can try using this concept:
$('.search').keyup(function(){
if( $(this).val().length > 0 ){
var foundin = $('#drilldown').find('li a:contains("'+$(this).val()+'")');
}
});
I would like to accomplish the following with jquery :
When I click on this link
Cars
I would like all divs like those
<div class="product">
<div class="category">Cars</div>
</div>
to do something.
You get the idea, I have a menu with a list of categories, and a list of products, each containing a div with the category name, and I would like to make them hide/show.
I am not sure if i fully understand your question, but if you want the div class="category" cars to appear when cars link is clicked, follow this:
$("#menu a").click(function() {
var value = $(this).html();
$.each($(".category"), function(i, item) {
if ($(item).html() == value) {
$(item).parent().hide();
}
});
});
if you want to hide the div just replace $(item).show(); with $(item).hide();
Assuming:
Cars
then:
$("a.highlight").click(function() {
$("div.category").removeClass("category")
.filter(":contains(" + $(this).text() + ")").addClass("highlight");
return false;
});
What this does is add the category class to any category dvis that contain the text of the link. This can be modified to modify the parent product div if you want to do it that way too.
It works by first removing the class highlight from all category divs and then adding it to the ones that require it.
DEMO: http://jsbin.com/ucewo3/11 SOURCE: http://jsbin.com/ucewo3/11/edit
$('a').click( function(e) {
var search_term = $.trim($(this).text()); //trim text
$('.category').each(function() {
($(this).text().search(new RegExp( search_term , 'i')) < 0 )//upper & lower
? $(this).parent().hide() : $(this).parent().show();
});
});
This keep the text inside the <a> tag and make a search into the <div class="category"> if the <a> text match with .category text it show the related .product content!
NOTE:
the script match both Uppercase and Lowercase chars
example match Cars as well as cars and CARS
also match spaced text like <a> cars </a> as well as <a>cars</a> and <a>cars </a>
match also tagged text like <div class="category"><span>cars</span></div>