1

I am experimenting with live preview of text inputs.

At the moment, users can preview their text as they type and can also select the input field by clicking on the live preview text. What I would like to do is allow users to click on the live preview text and have the cursor in the text field appear in the exact same location in the text as where they clicked on in the preview. (Any solution must work with multiple input fields.)

Previous posts show how to highlight a range or a particular word (see below), but I couldn't find any Javascript/JQuery for what I am trying to do. Any advice would be helpful!

Related Stack Overflow Question: Selecting Part of String inside an Input Box with jQuery

$( document ).ready(function() {
  $('.liveInput').keyup(function(){
    var $this = $(this);
    $('.'+$this.attr('id')+'').html($this.val());
  });

  $('.description').click(function(){
    $('#description').focus();
  });

  $(".description").hover(function () {
    $(this).toggleClass("preview-hover");
  });
});
.preview-hover {
  cursor:pointer;
  opacity: 0.5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="description" class="liveInput" name="description" cols="80" rows="8" style="width:100%; resize:vertical;" placeholder="POST CONTENT"></textarea>    

<div>
  <p class="description"></p>                   
</div>
Community
  • 1
  • 1
Ron
  • 69
  • 1
  • 10
  • There's a jquery plugin called `$.caret()` that can detect click position in form input/textarea fields, but not paragraphs. This help? http://codepen.io/anon/pen/MJByEo – Michael Coker Feb 06 '17 at 16:42

2 Answers2

0

The logic is simple:

  1. Wrap each character with span.
  2. On click on the .description get the exactly span and get its index by using .index() of jQuery.
  3. Move the cursor to that index with the code in this answer.

Let me know if something is not clear.

Also I'm guessing that in some point this code will be heavy so don't do this on a large text.

$( document ).ready(function() {
  $('.liveInput').keyup(function(){
    var $this = $(this);
    $('.'+$this.attr('id')+'').html(function() {
       return $this.val().split('').map(function(char) {
         return '<span>' + char + '</span>';
       }).join('');
    });
  });

  $('.description').click(function(e) {
    var span = $(e.target);
    var caretPos = $(this).find('span').index(span);
    //var caretPos
    var elem = $('#description')[0];
    if(elem.createTextRange) {
      var range = elem.createTextRange();
      range.move('character', caretPos);
      range.select();
    }
    else {
      if(elem.selectionStart) {
        elem.focus();
        elem.setSelectionRange(caretPos, caretPos);
      }
      else
        elem.focus();
    }
  });

  $(".description").hover(function () {
    $(this).toggleClass("preview-hover");
  });
});
.preview-hover {
  cursor:pointer;
  opacity: 0.5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="description" class="liveInput" name="description" cols="80" rows="8" style="width:100%; resize:vertical;" placeholder="POST CONTENT"></textarea>    

<div>
  <p class="description"></p>                   
</div>
Community
  • 1
  • 1
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • Sorry but this doesn't seem to working for me (Thanks for your help though!) Another guy posted something that works.) – Ron Feb 07 '17 at 13:45
  • The other answer even not working (When you click on the preview, nothing happen). What exactly not working in my answer? – Mosh Feu Feb 07 '17 at 15:21
0

I think this is what you are looking for.

$('.liveInput').keyup(function(){
     var $this = $(this);
     $('.'+$this.attr('id')+'').html($this.val());
});
 
$('.description').click(function(){
    s = window.getSelection();
         var range = s.getRangeAt(0);
         var node = s.anchorNode;

         $('.liveInput')[0].setSelectionRange(range.startOffset, range.startOffset);

 });
 
$(".description").hover(function () {
     $(this).toggleClass("preview-hover");
});
.preview-hover {
     cursor:text;
     opacity: 0.5;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="description" class="liveInput" name="description" cols="80" rows="8" style="width:100%; resize:vertical;" placeholder="POST CONTENT"></textarea>    

<div>
   <p class="description"></p>                   
</div>