Currently I search within a div within an html file and remove the hideMe class if a result is found inside it, to reveal the found hymn. I'm wondering if I can search the hymn without punctuation (removing punctuation from both input and output), while also excluding the info class from the search.
<div id="himnario">
<div id="1" class="song hideMe">
<div class="info">I don't want this info to be searched</div>
<div class="tuneName">This tune should be searched</div>
<ol>
<li>Verse 1</li>
<li>Verse 2</li>
</ol>
</div>
<div id="2" class="song hideMe">...</div>
</div>
My search code presently is:
$("#himnario div.song:Contains("+item+")").removeClass('hideMe').highlight(item);
isHighlighted = true; //check if highlighted later and unhighlight, for better performance
(extending jquery with "Contains" as follows)
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
Also, I am using a jquery plugin for highlighting the results, so I suppose this would complicate things. If need be, the highlight could be disfunctional for those places where punctuation gets in the way.
Of course, the more efficient the better since this will be part of a mobile app... If removing the info class from the search takes a lot of time, I will have to just delete it from the file because it isn't absolutely essential.
I found the following code from here that might help, which is supposed to strip invalid characters, but not sure how to incorporate it into the custom Contains function properly with my limited coding ability.
Return Regex.Replace(strIn, "[^\w\.@-]", "")
Thanks so much in advance for your help.
Edit: Here is the preferred solution thanks to @Nick:
$('#himnario').children().addClass('hideMe'); // hide all hymns
//http://stackoverflow.com/questions/12152098/jquery-search-contains-without-punctuation-excluding-specific-class
// Get rid of punctuation in your search item - this only allows alphanumeric
item2 = item.toUpperCase().replace(/<(.|\n)*?>|[^a-z0-9\s]/gi, '');
// Loop though each song
$('#himnario').children().each(function() {
var $this_song = $(this);
// Examine the song title & the ordered list, but not the hidden info (first child)
$this_song.children('.tuneName, ol').each(function() {
// Get the html, strip the punctuation and check if it contains the item
if ($(this).html().toUpperCase().replace(/<(.|\n)*?>|[^a-z0-9\s]/gi, '').indexOf(item2) !== -1) {
// If item is contained, change song class
$this_song.removeClass('hideMe').highlight(item); //original search phrase
isHighlighted = true; //check later, for better performance
return false; // Prevents examination of song lines if the title contains the item
}
});
});
Highlight function:
/*
highlight v3
Highlights arbitrary terms.
<http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html>
MIT license.
Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>
*/
jQuery.fn.highlight = function(pat) {
function innerHighlight(node, pat) {
var skip = 0;
if (node.nodeType == 3) {
var pos = node.data.toUpperCase().indexOf(pat);
if (pos >= 0) {
var spannode = document.createElement('span');
spannode.className = 'highlight';
var middlebit = node.splitText(pos);
var endbit = middlebit.splitText(pat.length);
var middleclone = middlebit.cloneNode(true);
spannode.appendChild(middleclone);
middlebit.parentNode.replaceChild(spannode, middlebit);
skip = 1;
}
}
else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) {
for (var i = 0; i < node.childNodes.length; ++i) {
i += innerHighlight(node.childNodes[i], pat);
}
}
return skip;
}
return this.each(function() {
innerHighlight(this, pat.toUpperCase());
});
};
jQuery.fn.removeHighlight = function() {
return this.find("span.highlight").each(function() {
this.parentNode.firstChild.nodeName;
with (this.parentNode) {
replaceChild(this.firstChild, this);
normalize();
}
}).end();
};