Increment function in another jQuery function

Asked

Viewed 96 times

-2

The code below helps the user to find terms and highlight them(hightlights) within any HTML element, is functional but the code does not highlight words when typed without accentuation, if highlight the accented words even typed without accent the feature would have an even better use.

The jQuery code that searches and highlights the words in yellow:

<script type="text/javascript">
    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() {
        function newNormalize(node) {
            for (var i = 0, children = node.childNodes, nodeCount = children.length; i < nodeCount; i++) {
                var child = children[i];
                if (child.nodeType == 1) {
                    newNormalize(child);
                    continue;
                }
                if (child.nodeType != 3) { continue; }
                var next = child.nextSibling;
                if (next == null || next.nodeType != 3) { continue; }
                var combined_text = child.nodeValue + next.nodeValue;
                new_node = node.ownerDocument.createTextNode(combined_text);
                node.insertBefore(new_node, child);
                node.removeChild(child);
                node.removeChild(next);
                i--;
                nodeCount--;
            }
        }
        return this.find("span.highlight").each(function() {
            var thisParent = this.parentNode;
            thisParent.replaceChild(this.firstChild, this);
            newNormalize(thisParent);
        }).end();
    };
    $(function() {
        $('#text-search').bind('keyup change', function(ev) {
            var searchTerm = $(this).val();
            $('.categorias').removeHighlight();
            if ( searchTerm ) {
                 $('.categorias').highlight( searchTerm );
            }
        });
    });
</script>

Here the input that receives the term entry to highlight:

<div class="input-group">
    <div class="input-group addon addon-destaca-termos">
        <span class="input-group-addon"><i class="fas fa-search"></i></span>
        <input placeholder="Destaque termos da lista" type="text" class="input-destaca-termos form-control input-sm" id="text-search">
    </div>
</div>

Element that was referenced in #text-search Handler:

<div class='categorias'>
    <ul>
        <li>xyz abc wotf</li>
        <li>xyz abc wotf</li>
        <li>xyz abc wotf</li>
        <li>xyz abc wotf</li>
    </ul>
</div>

The function takes accents I have but I don’t know how to integrate:

<script>
    function tiraAcentos(i){
      var i = i.toLowerCase().trim();
      var acentos = "ãáàâäéèêëíìîïõóòôöúùûüç";
      var sem_acentos = "aaaaaeeeeiiiiooooouuuuc";
      for(var x=0; x<i.length; x++){
         var str_pos = acentos.indexOf(i.substr(x,1));
         if(str_pos != -1){
            i = i.replace(acentos.charAt(str_pos),sem_acentos.charAt(str_pos));
         }
      }
      return i;
    }
</script>

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() {
        function newNormalize(node) {
            for (var i = 0, children = node.childNodes, nodeCount = children.length; i < nodeCount; i++) {
                var child = children[i];
                if (child.nodeType == 1) {
                    newNormalize(child);
                    continue;
                }
                if (child.nodeType != 3) { continue; }
                var next = child.nextSibling;
                if (next == null || next.nodeType != 3) { continue; }
                var combined_text = child.nodeValue + next.nodeValue;
                new_node = node.ownerDocument.createTextNode(combined_text);
                node.insertBefore(new_node, child);
                node.removeChild(child);
                node.removeChild(next);
                i--;
                nodeCount--;
            }
        }
        return this.find("span.highlight").each(function() {
            var thisParent = this.parentNode;
            thisParent.replaceChild(this.firstChild, this);
            newNormalize(thisParent);
        }).end();
    };
    $(function() {
        $('#text-search').bind('keyup change', function(ev) {
            var searchTerm = $(this).val();
            $('.categorias').removeHighlight();
            if ( searchTerm ) {
                 $('.categorias').highlight( searchTerm );
            }
        });
    });
.categorias .highlight {
	background-color: #fff34d;
	-moz-border-radius: 5px;
	-webkit-border-radius: 5px;
	border-radius: 5px;
	-moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
	-webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);
}
.categorias .highlight {
	 padding:1px 4px;
	 margin:0 -4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="input-group">
    <div class="input-group addon addon-destaca-termos">
        <span class="input-group-addon"><i class="fas fa-search"></i></span>
        <input placeholder="Destaque termos da lista" type="text" class="input-destaca-termos form-control input-sm" id="text-search">
    </div>
</div>
<div class='categorias'>
    <ul>
        <li>xyz abc wotf</li>
        <li>xyz abc wotf</li>
        <li>xyz abc wotf</li>
        <li>xyz abc wotf</li>
    </ul>
</div>

  • You can create a Jsfiddle to be easier to help?

  • @iamdlm done, check.

2 answers

2

Maybe the String.prototype.normalize() solve the problem, it works like this:

var string = "Ça été Mičić. ÀÉÏÓÛ";
console.log(string);

var string_norm = string.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
console.log(string_norm);

It has the advantage that it does not need to maintain a function (tiraAcentos) to deal with it.

  • Thank you for your wisdom, I will memorize this answer, but the function I already use for other purposes so I thought I’d reuse it in this.

  • 1

    Sure, keep that reference for the future.

1


@Eliseu just needs a simple change in function jQuery.fn.highlight

It’s like this:

var pos = node.data.toUpperCase().indexOf(pat);

Change it to look like this:

var pos = tiraAcentos(node.data).indexOf(tiraAcentos(pat));

Browser other questions tagged

You are not signed in. Login or sign up in order to post.