Issue #481✓ ResueltoAbierto el 3 de noviembre de 2017por mathieukReacciones 17

Pregunta: ¿Arrastrar bloques a un bloque de texto?

Respuesta rápidapor artf10

¿Has comprobado API-Rich-Text-Editor? Puedes añadir una acción personalizada como esta '''js editor. RichTextEditor.add('custom-vars', { icono: '<select class="gjs-field"> <valor de opción="">- Seleccionar -</option> <valor de opción="[[nombre]]">Nombre</option> <valor de opción="[[apellido]]">Apellido</option> <valor...

Lee la respuesta completa abajo ↓

Pregunta

Esto no es un bug, sino una cuestión de implementación. Si este no es el lugar adecuado para hacer estas preguntas, por favor, házmelo saber.

Estamos trabajando en una implementación en la que queremos usar GrapesJS para permitir a los usuarios crear una plantilla de correo electrónico. Como parte de esta implementación estamos trabajando para crear funcionalidad de fusión de correo: hemos introducido el concepto de 'merge-fields' o 'placeholders' que reemplazaremos por los valores adecuados en el lado del servidor. Esto significa que enviamos la estructura JSON 'components' y la convertimos en HTML en el lado del servidor, reemplazando los valores a medida que avanzamos.

Por ejemplo, uno de nuestros usuarios podría introducir el text: 'Hello <username><>' y reemplazaremos ese campo de fusión '<<username>>' por el campo adecuado.

Pero aún no hemos podido implementar esto de esta manera porque no podemos arrastrar estos bloques a un bloque de texto. Solo podemos arrastrarlo a su alrededor. Así que, por ahora, estamos ampliando el RTE con un 'bloque en línea' de campo de fusión ( '<tipo de entrada=clase solo lectura de texto=mergeField data-isMergefield=1 />') y creando un bloque de campo de fusión con el mismo HTML en el gestor de bloques. Implementar un tipo DomComponent para reconocerlo ofrece un método para configurarlo. Pero parece subóptimo, nos gustaría poder arrastrar ese bloque de mergefield al lugar correcto del campo de texto.

Para permitir esto, imagino que GrapesJS tendría que poder coger el textNode y dividirlo en (al menos) dos textnodes y una etiqueta para el campo de fusión, pero no sé por dónde empezar con esto. ¿Podrías aconsejarme cómo podríamos implementar esto?

Respuestas (3)

👍 Muy útilartf6 de noviembre de 2017

¿Has comprobado API-Rich-Text-Editor? Puedes añadir una acción personalizada como esta '''js editor. RichTextEditor.add('custom-vars', { icono: '<select class="gjs-field"> <valor de opción="">- Seleccionar -</option> <valor de opción="[[nombre]]">Nombre</option> <valor de opción="[[apellido]]">Apellido</option> <valor de opción="[[age]]">Age</option> ',</select> Vincula el 'resultado' al oyente de 'cambio' evento: 'cambio', resultado: (rte, acción) => rte.insertHTML(acción.btn.firstChild.value), Restablece la selección al cambiar actualización: (rte, acción) => { action.btn.firstChild.value = "";} })

! [rte-acción](https://user-images.githubusercontent.com/11614725/32463242-810de0fc-c33c-11e7-81df-3524c0ad55ac.gif)
artf10 de abril de 2019

Probablemente en la próxima versión esta función estará disponible. ! disponible por mensaje

Así que 'textible' será solo otra propiedad, esto permitirá que cualquier componente se elimine dentro de los componentes de texto. Aquí está el código del componente del ejemplo anterior: '''js Define un componente con la propiedad 'textible' editor. DomComponents.addType('var-placeholder', { modelo: { Predeterminados: { Textible: 1, marcador de posición: 'VARIABLE-1', }, toHTML() { return '{{ ${this.get('placeholder')} }}'; }, }, La vista de abajo es solo un ejemplo de cómo crear una experiencia de usuario diferente Vista: { etiquetaNombre: 'span', eventos: { 'cambio': 'actualizaciónPlh', }, Actualiza el modelo una vez que se cambie la selección updatePlh(ev) { this.model.set({ placeholder: ev.target.value }); this.updateProps(); }, Cuando difuminamos desde un TextComponent, todos sus componentes hijos son aplanado mediante innerHTML y analizado por el editor. Así que mantener el estado de nuestros props sincronizados con el modelo, así que necesitamos exponer los props en el HTML updateProps() { const { el, model } = this; el.setAttribute('data-gjs-placeholder', model.get('placeholder')); }, onRender() { const { model, el } = this; const currentPlh = model.get('placeholder'); const select = document.createElement('select'); const options = [ 'VARIABLE-1', 'VARIABLE-2', 'VARIABLE-3' ]; select.innerHTML = options.map(element => '<valor de opción="${item}" ${elemento === currentPlh ? 'seleccionado' : ''}> ${item} ')</option>.unir(''); mientras que (el.primerNiño) el.removeChild(el.primerNiño); el.appendChild(select); select.setAttribute('style', 'addding: 5px; border-radius: 3px; border: none; -webkit-appearance: none;'); this.updateProps(); }, } });

Usar el componente en bloques editor. BlockManager.add('simple-block', { etiqueta: 'Bloque textible', Contenido: { Tipo: 'var-placeholder' }, });

mathieuk8 de noviembre de 2017

Sí, lo he usado y prácticamente lo he conseguido funcionar. La diferencia es que yo no estoy usando un marcador de texto como tú. De hecho, estoy insertando un bloque (con un 'tipo' correspondiente) para poder configurar aún más estos marcadores de posición (por ejemplo, un campo podría ser un campo de Fecha y Hora y mi usuario podría querer configurar el formato exacto de salida para esa fecha-hora). Usé HTML5 arrastrando y soltando para implementar esto y funciona bastante bien, pero qué...

Parece que se aleja de la interfaz de usuario esperada. Creo que debería poder arrastrar un campo de fusión desde los 'bloques' y colocarlo en la posición correcta. He estado probando con el Clasificador para que esto lo permita y estoy dispuesto a esto:

! imagen

Ahora tengo el problema de que el Clasificador quiere mucho bloques reales para alinearse, así que tengo que ajustar más. Por ahora, implementar esto ha requerido cambiar en la ComponentTextView (principalmente: no vaciar la barra de herramientas para 'mergefields') y en el Sorter (si estoy pasando el cursor por un mergefield sobre un bloque de texto, insertar HTML en el activeRTE en lugar de añadir un bloque).

Actualmente estoy trabajando para que el arrastre funcione de forma más fiable (por alguna razón, cada vez que arrastro derecha el campo se añade al nodo de texto en lugar de en la posición del cursor, funciona bien al arrastrar izquierda :)), haciendo que el ordenador ignore la idea de 'bloques' cuando está dentro de un campo de texto, mostrando el marcador de posición correcto en ese caso (querría ver el cursor real) y limpiando todo.

No estoy seguro de cómo abordar el tema del Clasificador en este momento, salvo especializar bloques de texto, así que si tienes alguna idea en ese ámbito me encantaría escucharla. Puedes ver parte del código improvisado que he hecho hasta ahora en https://github.com/mathieuk/grapesjs/commit/d58c5ee5306c358cd19509f6b8affe9bb60493ed .

Preguntas y respuestas relacionadas

Continúa investigando con debates sobre temas similares.

Plugins de pago que cumplen con este problema

Seleccionado por temas clave y relevancia de etiquetas para ayudarte a enviar más rápido.

Ver todos los plugins

Cargando recomendaciones de plugins de pago...

Opción gratuita

Consulta los plugins de código abierto de GrapesJS en GitHub O haz una búsqueda rápida en nuestro catálogo gratuito.

Explora plugins gratuitos →
Opción premium

Los plugins premium incluyen soporte, actualizaciones regulares y funciones listas para producción — ahorrando días de trabajo de integración.

Explora plugins premium →

Explorar categorías de plugins

Ve directamente a las páginas de categorías de plugins en el marketplace.