1

After searching almost all question related on how to delete the text between character such as @ and carret position in contenteditable div, Am almost in conclusion that this question has become impossible to community. See the following question and non of them actually solved the deleting task. Contenteditable div get and delete word preceding caret, How to get range of characters between @ and caret in contenteditable, Remove last x characters before carret position, return the range object of the word before or upon carret position in contenteditable div


Am also stuck. What we are looking for is

  1. Create a content editable div and a button value="playing".
  2. Type anything in contenteditable div and begin with any character eg @
  3. Example Assuming | symbol represent the carret in a sentence "I am @sch|ool with friends",
  4. since the carret is upon the word school, replace the word @school with playing. Remember @ symbol will no longer exist too.
  5. If possible, set the carret after the word playing.
  6. Final expected result is sentence "I am playing with friends".


Some of us are not familiar with range and selection and we are hereby requesting for help. Meanwhile, let me try a creating a fiddle. Thanks

function replace_with_playing(){
  var sel='';
  if(window.getSelection){//webkits plus firefox
  var sel=document.getSelection();
 sel.modify("extend","backword","word");
 range=sel.getRangeAt( 0);
 range.deleteContents();
 var el=document.createElement('span');
 el.innerHTML='Playing';
 $(el).attr('contenteditable','false');
 var frag=document.createDocumentFragment(),node;
 while(node=el.firstChild){
  frag.appendChild(node);
 }
 range.insertNode(frag);
 range.collapse();
  //this code is appending the word playing but not deleting the word @school
  }
  else if(document.selection){//IE
  //i dont know code for IE
  }
}


$(document).on('click','.bt',function(){
var el=document.getElementById('editable_div');
replace_with_playing();
});
.parent_container{
 position:relative;
}

.editable_div{
 width:200px;
 padding:5px 10px;
 min-height:50px;
 border: 1px #DCDCDC solid;
}
.bt{
width:70px;
border:1px #000 solid;
position:absolute;
left:100px;
bottom:-30px;
background:#ffff00;
padding:2px 8px;
}
.description{
margin-top:10px;
}
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>

<div class="parent_container">
 <button class="bt">playing</button>
 <div class="editable_div"id="editable_div"contenteditable>
  
  </div>
  <div class="description">Type am "@school" such that the carret is after school then click playing</div>
 
</div>
phi lo czar
  • 349
  • 2
  • 12
  • 1
    Rather than creating a fiddle, hit Ctrl+M or click the `<>` button on the editor of the question, to bring up the on site snippet tool. Make your example there, on site. – Taplar Nov 05 '18 at 15:40
  • @Taplar hope you understand what am looking for. Am currently creating a snippet – phi lo czar Nov 05 '18 at 15:45
  • I believe I understand what you are asking for, but am waiting for the snippet. Without the snippet, the question is, in my opinion, leaning towards the "too broad" side. You seem to be asking about quite a few things in your question. – Taplar Nov 05 '18 at 15:47
  • yeah, i know its quite a broad topic but hold on a minute i show you what i got – phi lo czar Nov 05 '18 at 15:51
  • As you can see, in the snippet i have just provided, the word playing is being appended after school. I would like to delete the word @school before appending the word playing – phi lo czar Nov 05 '18 at 16:25
  • What if the caret isn't in a word beginning with "@"? What should happen? – skyline3000 Nov 05 '18 at 16:35
  • @skyline3000 if the carret is not in word beggining with "@" the word playing should hide.I can do that but if you can do it the better.What i want right now is to replace the word school with playing given that the carret position is before or upon school. – phi lo czar Nov 05 '18 at 16:49
  • i hope @Taplar is watching this too – phi lo czar Nov 05 '18 at 16:50

2 Answers2

1

Hello I may have misunderstood your issue, or you have some constraints in the way you have to do it. But an easy way to do it it's to the string.replace() method;

$(document).ready(function() {
  $(".bt").click(function() {
    let str = $("#editable_div p").html();
    str = replaceSchool(str, "playing");
    $("#editable_div p").html(str);
  });

  function replaceSchool(content, word) {
    return content.replace("@school", word); // you can use a regExp to catch the word starting with @
  };
})
.parent_container {
  position: relative;
}

.editable_div {
  width: 200px;
  padding: 5px 10px;
  min-height: 50px;
  border: 1px #DCDCDC solid;
}

.bt {
  width: 70px;
  border: 1px #000 solid;
  position: absolute;
  left: 100px;
  bottom: -30px;
  background: #ffff00;
  padding: 2px 8px;
}

.description {
  margin-top: 10px;
}
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<div class="parent_container">
  <button class="bt">playing</button>
  <div class="editable_div" id="editable_div" contenteditable>
    <p>Im @school with Paulo</p>
  </div>
  <div class="description">Type am "@school" such that the carret is after school then click playing</div>

</div>
Nico
  • 518
  • 2
  • 11
  • According to what i needed, your code is helpful though i might need to check if there is any error doing what i needed. Thanks i will comment later – phi lo czar Nov 05 '18 at 18:17
1

If I understand correctly then your issue is not impossible to solve. You can try an approach like I did below. Basically you want to check the input string provided by the user for your target character ("@" in this case). If you find the target in the string then split out the input string to an array. Once you have that array, you can use the Array.prototype.map method on it to create a new array. Your map callback should check if the current element contains the target - if it does, simply replace it with your desired replacement string, otherwise just leave the input as it is:

const divEditable = document.getElementById('editable_div');

document.getElementById('btnPlaying').addEventListener('click', function() {
  var input = divEditable.innerHTML;
  var target = '@';
  if (input.length && input.indexOf(target) > -1) {
    divEditable.innerHTML = doReplace(input, target, 'playing');
  }
});

function doReplace(input, target, replacement) {
  var words = input.split(' ').map(function(word) {
    if (word.indexOf(target) > -1) {
      return replacement;
    }
    return word;
  });
  return words.join(' ');
}
<div id="editable_div" style="height: 75px; border-style: groove;" class="editable_div" contenteditable>
</div>

<div class="description">Type am "@school" such that the carret is after school then click playing</div>

<button id="btnPlaying">playing</button>
Tom O.
  • 5,730
  • 2
  • 21
  • 35
  • 1
    your code is Ok to what i wanted, let me see if it affects the nodes in contenteditable div after replacing.I will comment after. – phi lo czar Nov 05 '18 at 18:16