0

My requirement is : Thers's an input field. When user is going to filled it, on runtime i searched for #tag and make text bold. And wants to separate both groups of #tags

For Example: "I am more #FromSide #FromSide and would like to speak with someone more #ToSide" Group1: #FromSide #FromSide Group2: #ToSide

Here's my code:

 `$('#custm-field').keyup(function(){`
            `let str = $(this).val();`
            `let arr = str.split(" ");`
            `$(arr).each((i,e)=>{`
                `if(e=="#")`
                `{ // $(e).css('font-weight','bold');`
                    `arr[i].replace(e,"<strong>"+e+"</strong>");}
                    `let newStr = arr.join(" ");`
            `$('#custm-field').val(newStr)`
            `});`

2 Answers2

0

This can be achieved using RegEx:

$('#custm-field').keyup(function(){
  let str = $(this).val();
  str = str.replace(/#(.+?)\s/, '<strong>$1</strong>');
  $('#custm-field').val(str);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="custm-field"></input>

However, the bold effect won't be displayed in input fields, you need a contenteditable element for this.

Henryc17
  • 851
  • 4
  • 16
0

I've constructed a solution for you,

First of all, you can't add HTML tags inside the value of an input tag. So you have to make use of contenteditable HTML attribute, by setting it to true contenteditable="true" on any element you can start to edit the content of it (write inside it).

NOTE: I added a background-color to make it visible when its empty

<div contentEditable="true" id="text" style="background-color: #eee;"></div>

Your JavaScript (JQuery) would look like this:

Note that your code had many errors I had to fix.

$('#text').keyup(function(){
            // get the div element
            let e = document.querySelector('#text');
            // get only the text inside the element (without the HTML tags)
            let str = e.innerText;
            e.innerHTML = '';
            // create a new element to contain our text because you cant add HTML text inside a DOM element directly
            let tag = document.createElement('div');
            let arr = str.split(" ");
            // this string will contain our HTML and text 
            let newStr = ``;
            $(arr).each((i,e)=>{
                if(e[0]=="#")
                { 
                    newStr += `<strong>${e}</strong>`;
                }
                else{
                    newStr += `${e}`
                }
                newStr += ` `;
            })
            // add the string to the inner HTML of the element we created
            tag.innerHTML = newStr;
            // append the newly created element inside the div
            e.append(tag);

            // based on Vito Gentile answer
            // this is to move the cursor to the end of the text we added, other wise the cursor would be at start of the text
            cursorManager.setEndOfContenteditable(e);
        });

I made use of the code of this answer, this is where this line cursorManager.setEndOfContenteditable(e); came from. Here is their code for convenience.

(function( cursorManager ) {

            //From: http://www.w3.org/TR/html-markup/syntax.html#syntax-elements
            var voidNodeTags = ['AREA', 'BASE', 'BR', 'COL', 'EMBED', 'HR', 'IMG', 'INPUT', 'KEYGEN', 'LINK', 'MENUITEM', 'META', 'PARAM', 'SOURCE', 'TRACK', 'WBR', 'BASEFONT', 'BGSOUND', 'FRAME', 'ISINDEX'];

            //From: https://stackoverflow.com/questions/237104/array-containsobj-in-javascript
            Array.prototype.contains = function(obj) {
                var i = this.length;
                while (i--) {
                    if (this[i] === obj) {
                        return true;
                    }
                }
                return false;
            }

            //Basic idea from: https://stackoverflow.com/questions/19790442/test-if-an-element-can-contain-text
            function canContainText(node) {
                if(node.nodeType == 1) { //is an element node
                    return !voidNodeTags.contains(node.nodeName);
                } else { //is not an element node
                    return false;
                }
            };

            function getLastChildElement(el){
                var lc = el.lastChild;
                while(lc && lc.nodeType != 1) {
                    if(lc.previousSibling)
                        lc = lc.previousSibling;
                    else
                        break;
                }
                return lc;
            }

            //Based on Nico Burns's answer
            cursorManager.setEndOfContenteditable = function(contentEditableElement)
            {

                while(getLastChildElement(contentEditableElement) &&
                    canContainText(getLastChildElement(contentEditableElement))) {
                    contentEditableElement = getLastChildElement(contentEditableElement);
                }

                var range,selection;
                if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
                {    
                    range = document.createRange();//Create a range (a range is a like the selection but invisible)
                    range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
                    range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
                    selection = window.getSelection();//get the selection object (allows you to change selection)
                    selection.removeAllRanges();//remove any selections already made
                    selection.addRange(range);//make the range you have just created the visible selection
                }
                else if(document.selection)//IE 8 and lower
                { 
                    range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
                    range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
                    range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
                    range.select();//Select the range (make it the visible selection
                }
            }

}( window.cursorManager = window.cursorManager || {}));

Hopefully this works like what you want.