Reputation: 728
I am trying to make a live search on div tags of an html page.
var val;
$(document).ready(function() {
$('#search').keyup(function() {
var value = document.getElementById('search').value;
val = $.trim(value).replace(/ +/g, ' ').toLowerCase();
$(".parent:contains('" + val + "')").show().children().show();
$(".parent:not(:contains('" + val + "'))").css("display", "none");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search" placeholder="Type to search" class="clearable" />
<div class="graph">
<span>graph</span>
<div class="parent">
<span>Personal Info1</span>
<div>
<fieldset>value1</fieldset>
<div class="child">
<span>Id </span>
<span>111</span>
</br>
<span>name </span>
<span>Jared</span>
</br>
</div>
<div class="child">
<span>Id</span>
<span>222</span>
</br>
<span>name</span>
<span>3rd name</span>
</br>
<span class="xtags">fathers name </span>
<span class="xtags" contenteditable="true">Padelk</span>
</div>
</div>
</div>
<div name="connections" class="parent">
<span class="xtags" type="connections">connections</span>
<div>
<div name="connection" class="child">
<div class="child" type="connection"><span>con1</span>
<span contenteditable="true">STH</span>
</br>
</div>
</div>
<div name="connection" class="child"><span class="child">con2</span>
<div class="child">
<span contenteditable="true">STH2</span>
</br>
</div>
</div>
</div>
</div>
</div>
The search should perform on every level of nested div tags. I want when the user types something contained in one of the parent tags, the related child tags be shown as well. Also, when written something contained in child tags, all child tags of that level be hidden except the related one.
Upvotes: 0
Views: 1507
Reputation: 31682
First of all put all the element you want to search through them inside a container (here I put them inside a div with the ID pool
). The every time the user type something in the textbox, hide all the element and loop through them to see if an element contain that text, if so show the whole branch starting from that element (inclusive) all the way to the container #pool
(exclusive) using jQuery.parentsUntil and jQuery.add. Like this (check the HTML to see where I added the container #pool
):
var val;
$(document).ready(function() {
$('#search').keyup(function() {
// the value of the textbox (use jQuery since you're already using it)
var value = $('#search').val();
// get all the elements inside #pool
var $pool = $("#pool *");
// hide all of them them
$pool.hide();
// loop through them
$pool.each(function() {
var $this = $(this);
// if the text is contained in them then show the whole branch until #pool (including the curent element this)
if ($this.text().toLowerCase().indexOf(value.toLowerCase()) != -1) {
$this.parentsUntil('#pool').add($this).show();
// if you want to show just the direct children of this element as well, then uncomment the following line
//$this.children().show();
// if you want to show it's whole subtree (children and children of children ...), then uncomment the following line and keep the previous line commented
// $this.find("*").show();
}
});
});
});
#pool, #pool * {
border: 1px solid black;
padding: 5px;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search" placeholder="Type to search" class="clearable" />
<div id="pool">
<div class="graph">
<span>graph</span>
<div class="parent">
<span>Personal Info1</span>
<div>
<fieldset>value1</fieldset>
<div class="child">
<span>Id </span>
<span>111</span>
</br>
<span>name </span>
<span>Jared</span>
</br>
</div>
<div class="child">
<span>Id</span>
<span>222</span>
</br>
<span>name</span>
<span>3rd name</span>
</br>
<span class="xtags">fathers name </span>
<span class="xtags" contenteditable="true">Padelk</span>
</div>
</div>
</div>
<div name="connections" class="parent">
<span class="xtags" type="connections">connections</span>
<div>
<div name="connection" class="child">
<div class="child" type="connection"><span>con1</span>
<span contenteditable="true">STH</span>
</br>
</div>
</div>
<div name="connection" class="child"><span class="child">con2</span>
<div class="child">
<span contenteditable="true">STH2</span>
</br>
</div>
</div>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 1155
I don't know if it can be easier but it works. I made everything case insensitive and select child to show.
// make case insensitive : https://css-tricks.com/snippets/jquery/make-jquery-contains-case-insensitive/
$.expr[":"].contains = $.expr.createPseudo(function(arg) {
return function( elem ) {
return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
};
});
var val;
$(document).ready(function() {
$('#search').keyup(function() {
var value = document.getElementById('search').value;
val = $.trim(value).replace(/ +/g, ' ').toLowerCase();
$(".parent:contains('" + val + "')").each(function( index, parent ) {
jParent = $(parent)
jParent.show();
var childs = jParent.find('.child');
var childsToHide = [];
childs.each(function(index, child){
var jChild = $(child);
if(child.outerText.toLowerCase().indexOf(val) === -1){
childsToHide.push(jChild);
} else {
jChild.show();
}
});
if(childsToHide.length < childs.length){
$.each(childsToHide, function(index, jChild){
jChild.hide();
})
}
});
$(".parent:not(:contains('" + val + "'))").css("display", "none");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search" placeholder="Type to search" class="clearable" />
<div class="graph">
<span>graph</span>
<div class="parent">
<span>Personal Info1</span>
<div>
<fieldset>value1</fieldset>
<div class="child">
<span>Id </span>
<span>111</span>
</br>
<span>name </span>
<span>Jared</span>
</br>
</div>
<div class="child">
<span>Id</span>
<span>222</span>
</br>
<span>name</span>
<span>3rd name</span>
</br>
<span class="xtags">fathers name </span>
<span class="xtags" contenteditable="true">Padelk</span>
</div>
</div>
</div>
<div name="connections" class="parent">
<span class="xtags" type="connections">connections</span>
<div>
<div name="connection" class="child">
<div class="child" type="connection"><span>con1</span>
<span contenteditable="true">STH</span>
</br>
</div>
</div>
<div name="connection" class="child"><span class="child">con2</span>
<div class="child">
<span contenteditable="true">STH2</span>
</br>
</div>
</div>
</div>
</div>
</div>
Upvotes: 1