Get shaded text from a div and apply styles on that text, with Jquey

1

I am creating a content editor, similar to this stack editor where we write our questions, with almost the same options to insert images, links, option to put bold text, italics, centered, aligned to the left or right, between Other options. Within my editor there will be these html elements: h1, h3, p, a, that is, the user will be able to insert title with h1 and h3, insert paragraph with p and links in tag a. I have each element separately and I add them dynamically. When the user clicks on the h1 button, an h1 element is automatically inserted. The user can edit it by double clicking on it, then if the user writes text there and then wants to select a fragment of that text and put it bold or italic, How could he do it? That I detected the selected text and click on the bold button, I applied, maybe I enclose that selected text for example in a or with css make a font-weight ... Something similar, the idea is that is only the selected text.

If this is not optimal. What other option would you recommend to achieve this? What I want is to have the option of being able to put part of the text in bold or italic, or increase the font size, or change the font.

Here I leave an example code:

$(document).ready(function(){

      $("#btnAddTitle").click(function(){

        var contador = $("#contador").val();

        var id = parseInt(contador) + 1;

        $("#contenedor").append("<h1 contenteditable='true' id='titulo-"+ id +"'>Titulo 1</h1>");

      });

      $("#btnAddSubtitle").click(function(){

        var contador = $("#contador").val();

        var id = parseInt(contador) + 1;

        $("#contenedor").append("<h3 contenteditable='true' id='subtitulo-"+ id +"'>Titulo 3</h3>");

      });

      $("#btnAddText").click(function(){

        var contador = $("#contador").val();

        var id = parseInt(contador) + 1;

        $("#contenedor").append("<p contenteditable='true' id='p-"+ id +"'>Parrafo</p>");

      });

      $("#btnAddLink").click(function(){

        var contador = $("#contador").val();

        var id = parseInt(contador) + 1;

        $("#contenedor").append("<a contenteditable='true' id='a-"+ id +"'>Link</a>");

      });

  });
.Toolbar-container
    {
      border: 1px solid grey;
      width: 90%;
      display: block;
      padding-left: 30px;
      padding-right: 30px;
      padding-top: 10px;
      padding-bottom: 10px;
    }

    .Text-container
    {
     width: 90%;
     display: block;
     border: 1px solid grey;
     padding: 30px;
    }

    .btn
    {
      border: none;
      background-color: transparent;
      text-align: center;
      font-size: 16px;
    }

    select
    {
      border: none;
      font-size: 16px;
      font-family:'FontAwesome';
      width: 150px;
    }

    #font-size-title
    {
      border: none;
      width: 40px;
      font-size: 16px;

    }

    #color-title
    {
      width: 20px;
    }

    #height-img, #width-img
    {
    border-radius: 5px;
    text-align: center;
    }

    #img-sizes
    {
      margin-left: 5px;
    }

    #btnAddTitle, #btnAddSubtitle, #btnAddText
    {
      font-family: 'Times New Roman', Times, serif;
    }

    .tooltip
      {display:none;
      position:absolute;
      background:white;
      border:1px black solid; 
      border-radius:8px;
      padding:8px;}
    .tooltip img{float:left;margin:0 8px 8px 0;}
     a:hover+.tooltip,.tooltip:hover{display:block;}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.12/css/all.css" integrity="sha384-G0fIWCsCzJIMAVNQPfjH08cyYaUtMwjJwqiRKxxE/rx96Uroj1BtIQ6MLJuheaO9" crossorigin="anonymous">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>


<div class="Toolbar-container">
  <span>
    
    <span>
      <button id="btnAddTitle" class="btn"><b>H1</b></button>
    </span>
    
    <span>
      <button id="btnAddSubtitle" class="btn">H3</button>
    </span>
    
    <span>
      <button id="btnAddText" class="btn"><i class="fa fa-file-text-o"></i> Text</button>
    </span>

    <span>
      <button id="btnAddImg" class="btn"><i class="fa fa-picture-o"></i></button>
    </span>

    <span>
      <button id="btnAddLink" class="btn"><i class="fa fa-link"></i></button>
    </span>

  </span>
  <span class="divider">|</span>
  
  <span>
    <span>
    <select class="font-familys" title="Fonts" id="font-family-title">
      <option value="" selected>&#xf031; Fonts</option>

      <option value="Arial, Helvetica, sans-serif">Arial Helvetica</option>
      <option value="‘Arial Black’, Gadget, sans-serif">Arial Black Gadget</option>
      <option value="‘Bookman Old Style’, serif">Bookman Old Style</option>
      <option value="Garamond, serif">Garamond</option>
      <option value="Georgia, serif">Georgia</option>
      <option value="‘Comic Sans MS’, cursive">Comic Sans MS cursive</option>
      <option value="Courier, monospace">Courier monospace</option>
                                    <option value="‘Courier New’, Courier, monospace">Courier New Courier monospace</option>
                                    <option value="Impact, Charcoal, sans-serif">Impact Charcoal</option>
                                    <option value="‘Lucida Console’, Monaco, monospace">Lucida Console Monaco monospace</option>
                                    <option value="‘Lucida Sans Unicode’, ‘Lucida Grande’, sans-serif">Lucida Sans Unicode</option>
                                    <option value="‘MS Sans Serif’, Geneva, sans-serif">MS Sans Serif Geneva</option>
                                    <option value="‘MS Serif’, ‘New York’, sans-serif">MS Serif New York</option>
                                    <option value="‘Palatino Linotype’, ‘Book Antiqua’, Palatino, serif">Palatino Linotype</option>
                                    <option value="Symbol, sans-serif"> Symbol, sans-serif</option>
                                    <option value="Tahoma, Geneva, sans-serif"> Tahoma Geneva</option>
                                    <option value="‘Times New Roman’, Times, serif">Times New Roman</option>
                                    <option value="‘Trebuchet MS’, Helvetica, sans-serif">Trebuchet MS Helvetica</option>
                                    <option value="Verdana, Geneva, sans-serif">Verdana Geneva</option>
                                    <option value="Webdings, sans-serif">Webdings</option>
                                    <option value="Wingdings, ‘Zapf Dingbats’, sans-serif">Wingdings Zapf Dingbats</option>
      
    </select>
    </span>

    <span>
    <input type="number" id="font-size-title" min="14" max="100" value="34">
    </span>
    </span>

  <span class="divider">|</span>
  
  <span>
    <span>
      <button id="font-weight-title" class="btn"><i class="fa fa-bold"></i></button>
      <input type="hidden" id="valueB" value="inactive">
    </span>
    <span>
      <button id="font-style-title" class="btn"><i class="fa fa-italic"></i></button>
      <input type="hidden" id="valueI" value="inactive">
    </span>
    <span>
      <button id="subline" class="btn"><i class="fa fa-underline"></i></button>
      <input type="hidden" id="valueS" value="inactive">
    </span>
    <span>
      <input type="color" id="color-title" class="btn" value="#000002"><i class="fa fa-font" id="colo_icons"></i>
      <input type="hidden" id="valueA" value="inactive">
    </span>
    <span>
      <button id="left-aligne" class="btn"><i class="fa fa-align-left"></i></button>
      <input type="hidden" id="valueLL" value="inactive">
    </span>
    <span>
      <button id="center-aligne" class="btn"> <i class="fa fa-align-center"></i></button>
      <input type="hidden" id="valueLC" value="inactive">
    </span>
    <span>
      <button id="right-aligne" class="btn"><i class="fa fa-align-right"></i></button>
      <input type="hidden" id="valueLR" value="inactive">
    </span>
    <span>
      <button id="justify-aligne" class="btn"><i class="fa fa-align-justify"></i></button>
      <input type="hidden" id="valueLJ" value="inactive">
    </span>
  </span>
  <span class="divider">|</span>
  <span id="img-sizes">
    <span>
     <i class="fa fa-text-width"></i> <input type="number" id="width-img" min="20" max="2000" value="200">
    </span>

     <span>
     <i class="fa fa-text-height"></i> <input type="number" id="height-img" min="20" max="2000" value="200">
    </span>
  </span>
    
</div>

<input type="hidden" id="contador" value="0">
<div class="Text-container" id="contenedor">

 
<p id="text-1">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras faucibus, metus a placerat facilisis, nibh quam scelerisque felis, quis auctor ipsum metus vitae tellus. Pellentesque et ipsum hendrerit lacus consectetur aliquet et sed tortor. Sed tincidunt pulvinar condimentum. Proin condimentum lectus eu tortor tempor vehicula. Proin fermentum porta metus, a pharetra tellus bibendum vel. Etiam nec leo felis. Nulla et libero vel nunc consectetur suscipit vitae eu diam. Curabitur magna erat, feugiat non mattis dictum, interdum non est. Donec purus urna, venenatis a scelerisque ac, iaculis adipiscing augue. Aliquam pharetra, lorem non condimentum luctus, odio magna lacinia nunc, eget gravida magna est at purus. Nunc volutpat elementum velit eget aliquet. Integer aliquet, ipsum in interdum consequat, tortor felis dictum lorem, nec congue quam lacus a lacus. Sed sed tellus nibh, sed porta quam. Nulla pulvinar neque non leo sodales eu tempus mi vulputate.</p>
<br>
 
</div>
    
asked by Marcos Schmell 25.12.2018 в 16:16
source

1 answer

1

Below is a basic example. First you select a part of the text within <textarea> , then click on the button. At this time you retrieve the position of the selected text ( desde hasta ) and insert the closing of a label </strong> at the position hasta . Then insert <strong> in the% position% co_ You finally replace the desde of innerHTML with the #resultado . I hope it's useful.

resultado.innerHTML = Texto.value;

function seleccionarTexto() {
  let desde = Texto.selectionStart; 
  let hasta = Texto.selectionEnd;
  let elTexto = Texto.value;
  let sel = elTexto.substring(desde, hasta);
  if (sel.length > 0) {// si hay algo seleccionado
  // primero inserta el cierre de la etiqueta strong en la posición hasta
    let nuevoTexto  = [elTexto.slice(0, hasta), "</strong>", elTexto.slice(hasta)].join('');
  // después abres le etiqueta strong en la posición desde  
    let nuevoTexto1  = [nuevoTexto.slice(0, desde), "<strong>", nuevoTexto.slice(desde)].join('');
    resultado.innerHTML = nuevoTexto1;
  }
}

b.addEventListener("click",seleccionarTexto);
#Texto{width:95vw}
<textarea id="Texto" rows="12"> Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</textarea>
<p><button id="b">ponlo en negrita</button></p>


<p id="resultado"></p>

update

A way still better , this time using the nuevoTexto1 method:

resultado.innerHTML = Texto.value;

function seleccionarTexto() {
  let desde = Texto.selectionStart; 
  let hasta = Texto.selectionEnd;
  let elTexto = Texto.value;
  let sel = elTexto.substring(desde, hasta);
  if (sel.length > 0) {// si hay algo seleccionado
    Texto.setRangeText('<strong>${sel}</strong>',desde,hasta,'select')
    resultado.innerHTML = Texto.value;
  }
}

b.addEventListener("click",seleccionarTexto);
#Texto{width:90vw}
<textarea id="Texto" rows="12"> Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</textarea>
<p><button id="b">ponlo en negrita</button></p>


<p id="resultado"></p>

update 2

The OP comments that this does not work with setRangeText tags

You probably have not done it properly. If you want to put part of the text in a <h1> you have to close the <h1> first and only then open the <p> . In the same way you first close the <h1> and then open the </h1> . So <p> is again <strong>${sel}</strong>

resultado.innerHTML = Texto.value;

function etiquetar() {
  let desde = Texto.selectionStart; 
  let hasta = Texto.selectionEnd;
  let elTexto = Texto.value;
  let sel = elTexto.substring(desde, hasta);
  if (sel.length > 0) {// si hay algo seleccionado
    Texto.setRangeText('</p><h1>${sel}</h1><p>',desde,hasta,'select');
    resultado.innerHTML = Texto.value;
  }
}

b.addEventListener("click",etiquetar);
#Texto{width:90vw}
<textarea id="Texto" rows="12"> Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</textarea>
<p><button id="b">h1</button></p>


<p id="resultado"></p>
    
answered by 25.12.2018 в 20:58