2015-10-16 27 views
10

Cercando di implementare un componente textarea con supporto di emoticon mentre scrittura.Supporto di emoticon per area di testo o contentedabile div

voglio potere a sostegno testo originale (solo caratteri ASCII) presentando il risultato filtrato html/generata (con un emoticons angolare filtrano) su un div.

La mia soluzione iniziale è quello di

<textarea ng-model="text" ng-change="..." ng-focus="..."></textarea> 
<div ng-bind-html="text | myEmoticonsFilter"></div> 

ma sto avendo difficoltà a raggiungere la parte di utilizzo di una textarea nascosta. Inoltre, con questo non sarei in grado di selezionare il testo del mouse ed eliminare o copiare/incollare in modo sicuro.

Ho anche pensato di utilizzare un <div contenteditable="true"> ma ng-focus e ng-change non verranno gestiti.

Qualcuno ha qualche suggerimento su come continuare questo?

Modifica 1: ecco un jsfiddle con un tentativo su quello che sto facendo. Fino ad ora, in grado di sostituire la prima occorrenza, ma il comportamento rimane irregolare da quello. Sto usando una direttiva contenteditable per l'associazione dati a 2 vie e per filtrare il modello di emoticon.

Edit 2: per quanto riguarda la mia dichiarazione dicendo che ng-focus e ng-change non sarà gestita, che non è vero - ng-focus funziona in modo nativo su <div contenteditable="true"> e ng-change funzionerà fino a quando una direttiva viene dichiarato utilizzando il ngModel e l'impostazione del appropriato $modelValue e $viewValue (un esempio è fornito nello jsfiddle in Modifica 1).

+0

Non ho la risposta alla domanda, ma è possibile aggiungere eventi di modifica/messa a fuoco a contenteditable utilizzando il codice fornito in [questo esempio] (https: // docs.angularjs.org/api/ng/type/ngModel.NgModelController # custom-control-example) dalla documentazione angolare ufficiale – pasine

+0

Credo che la soluzione si intrometterà direttamente con gli oggetti 'window.getSelection' e' Range' quando un nodo viene fisicamente alterato nel 'contenteditable' – nuno

+0

E riguardo l'uso della dipendenza di bower https://github.com/globaldev/angular-emoji-filter Non è lo stesso mathod che si desidera utilizzare, ma d'altra parte è una soluzione semplice e anche potente. Se hai bisogno di icone personalizzate di quelle che ritieni di considerare diverse. – Miha2255

risposta

5

L'unico modo per eseguire questa operazione in modo coerente tra browser è utilizzare un campo WYSIWYG che converta le emoji in immagini.

C'è un plug-in jQuery jquery-emojiarea che fa ciò che ti serve, quindi devi solo creare una direttiva che avvolge questo plugin e sei fuori per le gare. Dal momento che viene immesso in una textarea nascosta con la sintassi emoji :smile: l'angolare non dovrebbe avere difficoltà a legarsi.

Ecco una direttiva di lavoro che ho creato. http://jsfiddle.net/dboskovic/g8x8xs2t/

var app = angular.module('app', []); 
app.controller('BaseController', function ($scope) { 
    $scope.text = 'This is pretty awesome. :smile: :laughing:'; 
}); 
app.directive('emojiInput', function ($timeout) { 
    return { 
     restrict: 'A', 
     require: 'ngModel', 
     link: function ($scope, $el, $attr, ngModel) { 
      $.emojiarea.path = 'https://s3-us-west-1.amazonaws.com/dboskovic/jquery-emojiarea-master/packs/basic'; 
      $.emojiarea.icons = { 
       ':smile:': 'smile.png', 
       ':angry:': 'angry.png', 
       ':flushed:': 'flushed.png', 
       ':neckbeard:': 'neckbeard.png', 
       ':laughing:': 'laughing.png' 
      }; 
      var options = $scope.$eval($attr.emojiInput); 
      var $wysiwyg = $($el[0]).emojiarea(options); 
      $wysiwyg.on('change', function() { 
       ngModel.$setViewValue($wysiwyg.val()); 
       $scope.$apply(); 
      }); 
      ngModel.$formatters.push(function (data) { 
       // emojiarea doesn't have a proper destroy :(so we have to remove and rebuild 
       $wysiwyg.siblings('.emoji-wysiwyg-editor, .emoji-button').remove(); 
       $timeout(function() { 
        $wysiwyg.emojiarea(options); 
       }, 0); 
       return data; 
      }); 
     } 
    }; 
}); 

e di utilizzo:

<textarea ng-model="text" emoji-input="{buttonLabel:'Insert Emoji',wysiwyg:true}"></textarea> 

Se si desidera che il campo modificabile per convertire il testo come :(durante la digitazione dovrete sborsare quel plugin jQuery e modificarlo leggermente per analizzare il testo di input sul cambiamento e su init. (come un paio di righe di codice)

+0

Grazie David, in realtà sono andato in questo modo usando ['jquery-emojiarea'] (https://github.com/diy/jquery-emojiarea) e basandomi su alcune delle mie decisioni in [angular-emoji-popup] (https : //github.com/Coraza/angular-emoji-popup), che a sua volta usa 'jquery-emojiarea' – nuno

+0

Tuttavia ho dovuto implementare il mio codice perché voglio emoji personalizzati e menu. Per quanto riguarda le modifiche * durante la digitazione, ho dovuto implementare i gestori di eventi in 'keyup' per elaborare le parole dei dintorni per la posizione attuale del cursore con [' Range API'] (https://developer.mozilla.org/en-US/docs/Web/API/Range) – nuno

+1

Interessante! @nuno se vuoi collaborare per trasformarlo in una direttiva angolare per il resto del mondo, sarei felice di aiutarti! –