简体   繁体   中英

Matching and highlighting tags/words (changing color and font-weight) inside textarea using jQuery

I've textarea where I just start typing when I add tags which I define in array so based on my condition it should say in array but it is saying not in array here is my example code

 $(document).ready(function() { var tagsArray = new Array("{full_name}", "{email}", "{company}", "{reg_no}", "{address}", "{city}", "{mobile}", "{rec1_full_name}", "{rec1_email}", "{rec2_full_name}", "{rec2_email}"); var txtArea = $("textarea#txtarea").val(); $(document).on("keyup", "#txtarea", function() { if ($.inArray(txtArea, tagsArray) != -1) { console.log("in array"); } else { console.log("not in array"); } }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <textarea id="txtarea" name="txtarea" rows="10" cols="50"></textarea> 

I just start typing this text This is not what we want {email} {rec1_full_name} although my email tag is typed in textarea but it is showing message not in array so how to match my tags during typing and after match the tags I have to change its color to blue and its font to bold.

1) Your code doesn't work since you read the value of textarea once and this variable is not changing while you are typing;

2) Using $.inArray(txtArea, tagsArray) you are trying to if the full string is contained in the array which is not correct. Using RegExp for this would be much better:

 $(document).ready(function() { var tagsArray = new Array("{full_name}", "{email}", "{company}"); $('textarea#txtarea').on('keyup', function() { var val = $(this).val(); var searchExp = new RegExp(tagsArray.join("|"),"gi"); if(searchExp.test(val)) { console.log("in array"); } else { console.log("not in array"); } }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <textarea id="txtarea" name="txtarea" rows="10" cols="50"></textarea> </div> 

3) You can't apply styling to the separate words withing the textarea. See this question . Probably you will need to have some other approach, for example something like this - the idea here is to have a div element as background and sync content between this element and textarea .

UPDATE: 4) You can try to use contenteditable="true" on the div element and this will the inner content editable, so your div could behave like a rich text editor. Here is a quick example on how this could be achieved. Hope this idea will help you (I'm not going to write the full functionality for you, just want to illustrate the concept and what options do you have with your issue).

 $(document).ready(function() { var tagsArray = new Array("{full_name}", "{email}", "{company}"); $('div#txtarea').on('keyup', function() { var $this = $(this); //remember position of cursor before changing the content of the div element var restoreCursorPosition = saveCaretPosition(this); var val = $this.text(); //highlight tags $this.html(val.replace(new RegExp(tagsArray.join("|"), "gi"), "<mark>$&</mark>")); //resore cursor position restoreCursorPosition(); }); function saveCaretPosition(context){ var selection = window.getSelection(); var range = selection.getRangeAt(0); range.setStart(context, 0 ); var len = range.toString().length; return function restore(){ var pos = getTextNodeAtPosition(context, len); selection.removeAllRanges(); var range = new Range(); range.setStart(pos.node ,pos.position); selection.addRange(range); } } function getTextNodeAtPosition(root, index){ var lastNode = null; var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT,function next(elem) { if(index > elem.textContent.length){ index -= elem.textContent.length; lastNode = elem; return NodeFilter.FILTER_REJECT } return NodeFilter.FILTER_ACCEPT; }); var c = treeWalker.nextNode(); return { node: c? c: root, position: c? index: 0 }; } }); 
 div#txtarea { width: 150px; height: 150px; border: 1px solid black; overflow: auto; } mark { color: blue; font-weight: bold; background: transparent } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <div id="txtarea" name="txtarea" contenteditable="true"> Test input! </div> </div> 

I have a solution for you. Hope this will help.

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>

<textarea id="txtarea" name="txtarea" rows="10" cols="50"></textarea>
<button id="submitBtn">Submit</button>
<div id="displayContainer"></div>

<style type="text/css">
  .bold-blue{
    color: blue;
    font-weight: bold;
  }
</style>
<script src="https://code.jquery.com/jquery-3.2.1.js"
        integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
        crossorigin="anonymous"></script>

<script type="text/javascript">
  function inArray(needle, haystack) {
    var length = haystack.length;
    for(var i = 0; i < length; i++) {
        if(haystack[i] == needle) return true;
    }
    return false;
}

$(document).ready(function() {
    var tagsArray = new Array("{full_name}", "{email}", "{company}", "{reg_no}", "{address}", "{city}", "{mobile}", "{rec1_full_name}", "{rec1_email}", "{rec2_full_name}", "{rec2_email}");

   $("#txtarea").on('keyup', function(e) {

      var tags = $("#txtarea").val().match("{(.*)}");

   //check whether the entered tag is valid
      for (tag in tags){
         if(!inArray(tags[tag], tagsArray)){
            if(tags[tag][0] == "{" && tags[tag][tags[tag].length-1] == "}"){
               //alert the user that he entered an invalid tag
               alert(tags[tag]+" is not a valid tag.");
            }
         }
      }
    });
   //render the tags blue and bold
     $("#submitBtn").on("click", function(){
      var tags = $("#txtarea").val().match("{(.*)}");
        var text = $("#txtarea").val();
        for (tag in tags){
          if(tags[tag][0] == "{" && tags[tag][tags[tag].length-1] == "}"){
           var newText = text.replace( tags[tag], '<span class="bold-blue">'+tags[tag]+'</span>');
          }
        }
        $("#displayContainer").html( newText );

     });

});
</script>
</body>
</html>

 $(document).on('keyup', function(e) { var yourstring =$("P").html().match("{(.*)}") for (i=0; i< yourstring.length; i++){ $('p:contains('+yourstring[i]+')', document.body).each(function(){ $(this).html($(this).html().replace( new RegExp(yourstring[i], 'g'), '<span class=someclass>'+yourstring[i]+'</span>' )); }); } }); 
 .someclass { color: blue; font-weight: bold; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> <p> Lorem Ipsum is simply {email} {rec1_email} dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's printer took a galley of type and scrambled it to make a type specimen book. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, printe book. </p> <div> 

Using keyup you can apply styles whatever you want and onfocus() your

tag will be editable

  $(document).ready(function () { $('P').on("click", function () { $('P').attr("contenteditable", "true"); }); }); $(document).on('keyup', function (e) { if (e.keyCode == 38) { var str = $('P').html(); $('P').attr("contenteditable", false); var words = ["{full_name}", "{email}", "{company}", "{reg_no}", "{address}", "{city}", "{mobile}", "{rec1_email}"] var reg = RegExp(words.join('|'), 'gi') var p = document.createElement('p') p.innerText = str $('P').html($('P').html().replace(reg, '<b style="color:blue">$&</b>')); } else { $('P').attr("contenteditable", true); } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> <p> Lorem Ipsum is simply {email} {rec1_email} dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's printer took a galley of type and scrambled it to make a type specimen book. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, printe book. </p> <div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM