How to hide parent element based on child's text value - javascript

What I want is to be able to search the DOM for a certain string. If the text is on the page hide certain elements and show others. The catch is the id's are given dynamically within a PHP foreach statement.
I've tried to search for an .exists() function specific to text. So far I've tried:
jQuery(document).ready(function($) {
var string1 = 'string1',
string2 = 'string2';
if ($('li').children().text() === string1) {
if ($('li').children().text() === string2) {
$(this).parent().show();
} else {
$(this).parent().hide();
}
} else {
if ($('li').children().text() === string2) {
$(this).parent().hide();
} else {
$(this).parent().show();
}
}
});
so what I'm looking for:
1) search page for string1.
2) if string1 exists on the page show the parent of the child element that contains string2 and hide any other string.
3) if it doesn't exists hide string1 and string2.
but that doesn't work. I'm not the greatest at Jquery/JS and in general I'm a beginner with it..

To see if a string contains another (sub)string you can use indexOf.
And check if it is not -1.
Using each() you can loop over all li elements. Taking your jsFiddle (provided in comment) into account, I got this result: http://jsfiddle.net/ub8c6smh/5/
jQuery(document).ready(function($) {
var string1 = 'string1',
string2 = 'string2';
var string1exists= $('li').text().indexOf( string1)!==-1;
console.log(string1exists);
$('li').each(function () {
if ($(this).text().indexOf( string2)!==-1 && string1exists==true) {
// this child contains string 2
$('li').hide(); //hide all others
$(this).show();
}
if ($(this).text().indexOf( string2)!==-1 && string1exists==false) {
// this child contains string 2
$(this).hide();
}
if ($(this).text().indexOf( string1)!==-1 && string1exists==false) {
// this child contains string 1
$(this).hide();
}
});
});

Related

How to search text and ignore spaces in text?

I have a following jQuery which searches text in table rows and it works fine. The issue is that I would like to ignore/remove spaces when searching some text e.g.: I want to find this in a table:
'John Smith'
but when I type in search bar: Johnsmith then record is not found. So I would like to remove spaces in my jQuery code to find any text ignoring spaces. Here is my jQuery with commented code which removes spaces but it doesn't work:
$('document').ready(function() {
$('#search').keyup(function() {
search_table($(this).val());
});
function search_table(value) {
$('table .rows').each(function() {
var found = 'false';
$(this).each(function () {
//if ($(this).text().replace(" ", "").toLowerCase().indexOf(value.toLowerCase()) >= 0) {
if ($(this).text().toLowerCase().indexOf(value.toLowerCase()) >= 0) {
found = 'true';
}
});
if (found == 'true') {
$(this).show();
} else {
$(this).hide();
}
});
}
});
use .replace(/ /g,"") to replace all spaces (groups of spaces)
if ($(this).text().toLowerCase().replace(/ +/g,"").indexOf(value.toLowerCase()) >= 0) {
found = 'true';
}

Search from a list and remove siblings when search result found

I am trying to add a search filter so that user can find results from this list of contracts while they are typing. E.g.: if a user types "IP", then the top 4 results should be displayed. Following is the function:
$('#doc_search').on('keyup', function(){
var inputtext = $(this).val().toLowerCase();
$('.subdoclist li a').each(function() {
if(inputtext ==''){
$('.subdoclist li').each(function(){
$(this).addClass('show');
});
console.log(inputtext);
} else if ($(this).text().toLowerCase() === inputtext) {
$('.subdoclist li').removeClass('show');
$(this).parent().addClass('show');
console.log(inputtext);
}
});
})
'#doc_search' is the search field on top
'.subdoclist li' are the list items that contain anchor tags with text
At the moment, I have to type exact text and only then the search works.
Fiddle link: Click here
Here it is with a couple of things fixed up, first I'm using indexOf > -1 to see if the input string is contained within each potential match, and instead of removing show on all of them per-match I do it before it performs the search.
$('#doc_search').on('keyup', function() {
var inputtext = $(this).val().toLowerCase();
if (inputtext != '') {
$('.subdoclist li').removeClass('show');
$('.subdoclist li a').each(function() {
if ($(this).text().toLowerCase().indexOf(inputtext) > -1) {
$(this).parent().addClass('show');
}
});
} else {
$('.subdoclist li').addClass('show');
}
});
If you want a simple search, you can check if the text entered is contained on the string like this:
How to check whether a string contains a substring in JavaScript?
You can check each word entered on the search, splitting the string with space delimiter and using a loop but that will take more effort if there too words or a lot if entries.
Short and case-sensitive variant:
$('#doc_search').on('keyup', function() {
var inputtext = $(this).val();
if (inputtext !== '') {
$('.subdoclist li').each(function() {
$(this).toggle($("a:contains('"+ inputtext +"')",$(this)).length > 0);
});
} else {
$('.subdoclist li').show();
}
});

Parent siblings not showing after hiding/showing

I have a simple in-page search function which shows only topics which contain words searched for.
Each section has a heading, a <h2> - I want the headings for the blocks which are not hidden, to show.
The problem: The h2 header does not always show after the search
This is a fiddle to test the issue
Fail/success examples:
One of the headings is Complaints and cancellations - sub section titled: How do I cancel
If you search for how do then you'll see the first block show, with header... the second block titled Guides disappears. This is correct.
If you search for I cancel - again, the second block disappears, which is correct, but, the heading for the first block hides too, which it shouldn't.
This is the javascript:
$("#faq_search").on("input", function () {
var v = $(this).val().toLowerCase();
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v != "" && eachPlace.search(v) == -1) {
$(this).parent().parent().parent().siblings('h2').hide();
$(this).fadeOut();
} else {
$(this).fadeIn('fast', function(){
$(this).parent().parent().parent().siblings('h2').show();
});
}
});
});
Is there a better way to do this?
The problem is that a hide of the h2 can occur after a show for the same section, depending on the order of matches in the section.
The quick solution is to do all the hides first, then the shows:
$("#faq_search").on("input", function () {
var v = $(this).val().toLowerCase();
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v != "" && eachPlace.search(v) == -1) {
$(this).closest('.vc_tta').siblings('h2').hide();
$(this).fadeOut();
}
});
$(".vc_tta-panel").each(function () {
var eachPlace = $(this).html().toLowerCase();
if (v == "" || eachPlace.search(v) > -1) {
$(this).fadeIn('fast', function(){
$(this).closest('.vc_tta').siblings('h2').show();
});
}
});
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/L0m3z98y/2/
Notes:
parent().parent().parent() is a not a maintainable solution. Any change to the DOM structure will break the code. Instead use closest() with an appropriate target selector. This is shorter and safer

Sorting List Items by First Letter

I am trying to sort list items by their first letter. I am filtering by the .list-title div and then showing the .list-item which holds all of the contents. The problem is, I am using the show method directly on the filter method which is causing nothing to show as it needs to show the .list-item (parent) for the returned results. I am not sure how to rewrite this in any other way. How can I show the list item for each item returned?
$(document).ready(function() {
function filterResults(letter){
$('.list-item').hide();
$('li.list-item .list-title').filter(function() {
return $(this).text().charAt(0).toUpperCase() === letter;
}).show();
};
filterResults('A');
$('a').on('click',function(){
var letter = $(this).text();
filterResults(letter);
});
});
var $listItem = $('.list-item')
$('a').addClass(function(){
var s = this.textContent;
return $listItem.filter(function(){
return this.textContent.charAt(0) === s
}).length ? '' : 'grey';
})
JS Fiddle:
http://jsfiddle.net/2ewgr2mt/2/
You hide .list-item at first which contains everything else.So, when you show .list-title it won't be shown because its parent (.list-item) is hidden. The correct code should be
$(document).ready(function() {
function filterResults(letter){
$('.list-item').hide();
$('.list-item').filter(function() {
return $(this).find('.list-title').text().charAt(0).toUpperCase() === letter;
}).show();
};
filterResults('A');
$('a').on('click',function(){
var letter = $(this).text();
filterResults(letter);
});
var $listItem = $('.list-item')
$('a').addClass(function(){
var s = this.textContent;
return $listItem.filter(function(){
return this.textContent.charAt(0) === s
}).length ? '' : 'grey';
});
});
P/s: Remember to put everything inside ready, and also be careful when using the selector, in your original code you missed . in front of the class name selectors

How to get link containing known text

A page contains a link with the text "Open Help". How to get the anchor containing that text with YUI?
YUI2 provides therefore the getElementsBy function. It has a filter methode attribute and with it you can check if the current element matches your purpose. Notice that you get an array with all matched elements. So you can pick the first if there was a hit.
http://developer.yahoo.com/yui/docs/YAHOO.util.Dom.html#method_getElementsBy
var elements,
searchText = "Open Help";
elements = YAHOO.util.Dom.getElementsBy(function (element) {
return (element.innerHTML === searchText) ? true : false;
}, "a", document);
if (elements.length > 0) {
//do something with elements[0]
}
On the other hand the YUI3 solution is in my opinion a cleaner way:
var searchText = "Open Help";
Y.all("a").each(function (el) {
if (el.getContent() === searchText) {
//do something with the el
}
});

Categories