Work with the text selected by the user [duplicated]

2

Good morning,

I still have a theme that is making my head break, but I do not hit the key. In a text editor like the one I am writing now, I have some icons, which when touched, are added some labels in the textarea. But I have a series of problems:

  • The labels are put in order as I press, this a priori well, but it is not practical or functional, since the normal thing is often to write a paragraph and then select the text you want to put in bold.

  • Even if you select a piece of text, the labels appear at the ends of ALL the text.

I have searched for information and in principle you can work with window.getSelection() , I have tried some script, but it has not just given me any results.

Just as I have the code now, when you click on a button, the text is bold, for example, a script is executed, which receives 3 parameters, one of them is the text, but not the selected text , but the text of all the textarea, I think here is the problem, that I have to send only the selected text.

HTML Code:

                <form class="hilo_wrapper" action="crear_hilo.php?foro=<?php echo str_replace(" ", "%",$foro) ?>&subforo=<?php echo $subforo ?>"  method="post">
                <div class="data_hilo">
                    <input type="text" name="asunto" placeholder="Asunto:">
                </div>


                <div class="botones_crear_hilo">
                    <button type="button" accesskey="b" data-code="[b]" data-close="[/b]" onclick="insertText('txt1', '[b]','[/b]');" title="Negrita: [b]texto[/b] (Alt+B)">
                        <i class="fa fa-bold fa-fw"></i>
                    </button>
                    <button type="button" accesskey="i" data-code="[i]" data-close="[/i]" onclick="insertText('txt1', '[i][/i]');" title="Cursiva: [i]texto[/i] (Alt+I)">
                        <i class="fa fa-italic fa-fw"></i>
                    </button>
                    <button type="button" accesskey="u" data-code="[u]" data-close="[/u]" onclick="insertText('txt1', '[u][/u]');" title="Subrayado: [u]texto[/u] (Alt+U)">
                        <i class="fa fa-underline fa-fw"></i>
                    </button>
                    <button type="button" accesskey="q" data-code="[quote]" data-close="[/quote]" onclick="insertText('txt1', '[quote][/quote]');" title="Cita: [quote]texto[/quote] (Alt+Q)">
                        <i class="fa fa-quote-right fa-fw"></i>
                    </button>
                    <button type="button" accesskey="c" data-code="[code]" data-close="[/code]" onclick="insertText('txt1', '[code][/code]');" title="Código: [code]texto[/code] (Alt+C)">
                        <i class="fa fa-code fa-fw"></i>
                    </button>
                    <button type="button" name="img" accesskey="p" onclick="insertText('txt1', '[img][/img]');" title="Imagen: [img]http://www.ejemplo.com/imagen.jpg[/img] (Alt+P)">
                        <i class="fa fa-picture-o fa-fw"></i>
                    </button>
                    <button type="button" name="url" accesskey="w" onclick="insertText('txt1', '[url][/url]');" title="URL: [url]http://www.ejemplo.com[/url] o [url=http://www.ejemplo.com]texto[/url] (Alt+W)">
                        <i class="fa fa-link fa-fw"></i>
                    </button>
                    <button type="button" accesskey="s" data-code="[spoiler]" data-close="[/spoiler]" onclick="insertText('txt1', '[spoiler][/spoiler]');" title="Spoiler: [spoiler]texto[/spoiler]">
                        <i class="fa fa-list-alt fa-fw"></i>
                    </button>
                    <button type="button" name="mention" title="Mención">
                        <span class="fa-fw" onclick="insertText('txt1', '@');" style="display: inline-block">@</span>
                    </button>
                </div>
                <div class="col-100">
                    <textarea  id="txt1" name="texto_hilo" placeholder="Texto:"><?php if (isset($_POST['vista_previa'])) { echo $vista_previa;} ?></textarea>

                    <div class="col-emoticonos-enviar">
                        <input type="submit" name="vista_previa" value="Vista previa">
                        <input type="submit" name="guardar_borrador" value="Guardar borrador">
                        <input type="submit" name="crear_hilo" value="Crear hilo">
                    </div>
                </div>


            </form>

Javascript Code:

        <script type="text/javascript">
        function insertText(elemID, first, second) {
         var elem = document.getElementById(elemID);
         elem.value = second ? first + elem.value + second : first + elem.value;
     }
    </script>

I would appreciate any help.

    
asked by JetLagFox 22.03.2017 в 15:27
source

2 answers

0

I have finally searched for the answer, after researching and adapting the code to what I wanted to obtain. It is the part of <script> that I had to modify and after several tests, it works correctly for me.

    <script type="text/javascript">
    function getSel(first,second) // javascript
    {

        // obtiene todo el contenido del <textarea>
        var txtarea = document.getElementById("txt1");
        // Posición inicial del texto que tenemos seleccionado
        var start = txtarea.selectionStart;
        // Posición final del texto que tenemos seleccionado
        var finish = txtarea.selectionEnd;
        // extraemos el texto seleccionado
        var sel = txtarea.value.substring(start, finish);
        // agregamos las etiquetas al texto seleccionado
        var sel = second ? first+sel+second : first+sel;
        // nos devolvería todo
        txtarea.value = txtarea.value.substring(0, start)+sel+txtarea.value.substring(finish, txtarea.length);
    }
    </script>
    
answered by 22.03.2017 в 18:36
0

I put a variation of your answer, giving more order to the code; Let's see what you think.

// diccionario de estilos (pseudo-enum)
// https://stijndewitt.com/2014/01/26/enums-in-javascript/
var Estilos = {
  NEGRAS: 0,
  ITALICAS: 1,
  SUBRAYAR: 2,
  CITA: 3,
  MENCION: 4,
  tags: {
    0: { tag1: '[b]', tag2: '[/b]', nombre: 'Negritas' },
    1: { tag1: '[i]', tag2: '[/i]', nombre: 'Itálicas' },
    2: { tag1: '[u]', tag2: '[/u]', nombre: 'Subrayar' },
    3: { tag1: '[quote]', tag2: '[/quote]', nombre: 'Cita' },
    4: { tag1: '@', nombre: 'Mención' }
  }
};

// función principal
function aplicarEstilo(tipo) {
  var el = document.getElementById('editor');

  if (typeof(tipo) !== 'number' || el.selectionStart === undefined) {
    console.log('error: imposible procesar');
    return;
  }

  insertarTags(el, Estilos.tags[tipo].tag1, Estilos.tags[tipo].tag2);
}

// insertar los tags del estilo especificado
function insertarTags(el, tag1, tag2) {
  var ini = el.selectionStart;
  var fin = el.selectionEnd;
  var sel = el.value.substring(ini, fin);
  sel = tag2 ? tag1 + sel + tag2 : tag1 + sel;
  el.value = el.value.substring(0, ini) + sel + el.value.substring(fin, el.length);
  el.selectionStart = el.selectionEnd = ini + sel.length;
  el.focus();
}

Using the above code, you could change the HTML code of your buttons in the following way (I do not put styles or other attributes, just the button code):

<button id="btnBold" onclick="aplicarEstilo(Estilos.NEGRAS);">Negritas</button>

and you only have to vary the attribute of the style to be applied by said button ( Estilos.NEGRAS in this case); that's the interesting part of this variation: with the use of the Estilos object you can keep the tags or other properties (I added a nombre property as an example) in a centralized way and your handlers onclick they will be, in my opinion, cleaner. Here you can see the running example.

It is interesting what you try with your code and this could evolve into a JavaScript plugin that you add to your page and that allows you to initialize all this infrastructure with a few lines of code. I give an example of such infrastructure (without going into so many details):

In the HTML:

<button id="btnBold"></button>

In the JavaScript code of the page:

editor = document.getElementById('editor');
btn = document.getElementById('btnBold');

// inicializar el botón para agregar etiquetas de negritas [b][/b]
var btnNegritas = new PluginEstilos({
  button: btn,
  textArea: editor,
  estilo: Estilos.NEGRAS,
  titulo: 'Negrita: [b]texto[/b] (Alt+B)',
  icon: 'fa-bold',
  acceso: 'b'
});

In the plugin's JavaScript code:

// PluginEstilos (v1.0)
// Permite asociar botones HTML con la acción de insertar tags de estilos.
(function() {
  // Método constructor
  this.PluginEstilos = function() {
    ...
  }

  // Métodos públicos
  PluginEstilos.prototype.desactivar = function() {
    ...
  }

  // Métodos privados
  function funcionHelperPrivada() {
    ...
  }
}());

This plugin would completely configure the HTML element ( <button> ) in addition to the required events for the required functionality.

If you are interested in this technique, you can read this article (in English) where develop the idea of JavaScript plugins.

    
answered by 22.03.2017 в 20:23