ng-quill
Version:
Angular directive for rich text editor Quill
2 lines (1 loc) • 4.46 kB
JavaScript
(function(root,factory){if(typeof define==="function"&&define.amd){define(["quill"],factory)}else if(typeof exports==="object"){module.exports=factory(require("quill"))}else{root.Requester=factory(root.Quill)}})(this,function(Quill){"use strict";var app;app=angular.module("ngQuill",[]);app.provider("ngQuillConfig",function(){var config={modules:{toolbar:[["bold","italic","underline","strike"],["blockquote","code-block"],[{header:1},{header:2}],[{list:"ordered"},{list:"bullet"}],[{script:"sub"},{script:"super"}],[{indent:"-1"},{indent:"+1"}],[{direction:"rtl"}],[{size:["small",false,"large","huge"]}],[{header:[1,2,3,4,5,6,false]}],[{color:[]},{background:[]}],[{font:[]}],[{align:[]}],["clean"],["link","image","video"]]},theme:"snow",placeholder:"Insert text here ...",readOnly:false,bounds:document.body};this.set=function(customConf){customConf=customConf||{};if(customConf.modules){config.modules=customConf.modules}if(customConf.theme){config.theme=customConf.theme}if(customConf.placeholder!==null&&customConf.placeholder!==undefined){config.placeholder=customConf.placeholder.trim()}if(customConf.bounds){config.bounds=customConf.bounds}if(customConf.readOnly){config.readOnly=customConf.readOnly}if(customConf.formats){config.formats=customConf.formats}};this.$get=function(){return config}});app.component("ngQuillEditor",{bindings:{modules:"<modules",theme:"@?",readOnly:"<?",formats:"<?",placeholder:"@?",bounds:"<?",onEditorCreated:"&?",onContentChanged:"&?",onSelectionChanged:"&?",ngModel:"<",maxLength:"<",minLength:"<"},require:{ngModelCtrl:"ngModel"},transclude:{toolbar:"?ngQuillToolbar"},template:'<div class="ng-hide" ng-show="$ctrl.ready"><ng-transclude ng-transclude-slot="toolbar"></ng-transclude></div>',controller:["$scope","$element","$timeout","$transclude","ngQuillConfig",function($scope,$element,$timeout,$transclude,ngQuillConfig){var config={};var content;var editorElem;var modelChanged=false;var editorChanged=false;var editor;var placeholder=ngQuillConfig.placeholder;this.validate=function(text){if(this.maxLength){if(text.length>this.maxLength+1){this.ngModelCtrl.$setValidity("maxlength",false)}else{this.ngModelCtrl.$setValidity("maxlength",true)}}if(this.minLength>1){if(text.length<=this.minLength&&text.length>1){this.ngModelCtrl.$setValidity("minlength",false)}else{this.ngModelCtrl.$setValidity("minlength",true)}}};this.$onChanges=function(changes){if(changes.ngModel&&changes.ngModel.currentValue!==changes.ngModel.previousValue){content=changes.ngModel.currentValue;if(editor&&!editorChanged){modelChanged=true;if(content){editor.pasteHTML(content)}else{editor.setText("")}}editorChanged=false}if(editor&&changes.readOnly){editor.enable(!changes.readOnly.currentValue)}};this.$onInit=function(){if(this.placeholder!==null&&this.placeholder!==undefined){placeholder=this.placeholder.trim()}config={theme:this.theme||ngQuillConfig.theme,readOnly:this.readOnly||ngQuillConfig.readOnly,modules:this.modules||ngQuillConfig.modules,formats:this.formats||ngQuillConfig.formats,placeholder:placeholder,bounds:this.bounds||ngQuillConfig.bounds}};this.$postLink=function(){$timeout(function(){this._initEditor(editorElem)}.bind(this),0)};this._initEditor=function(editorElem){var $editorElem=angular.element("<div></div>");var container=$element.children();editorElem=$editorElem[0];if($transclude.isSlotFilled("toolbar")){config.modules.toolbar=container.find("ng-quill-toolbar").children()[0]}container.append($editorElem);editor=new Quill(editorElem,config);this.ready=true;editor.on("selection-change",function(range,oldRange,source){if(this.onSelectionChanged){this.onSelectionChanged({editor:editor,oldRange:oldRange,range:range,source:source})}if(range){return}$scope.$applyAsync(function(){this.ngModelCtrl.$setTouched()}.bind(this))}.bind(this));editor.on("text-change",function(delta,oldDelta,source){var html=editorElem.children[0].innerHTML;var text=editor.getText();if(html==="<p><br></p>"){html=null}this.validate(text);if(!modelChanged){$scope.$applyAsync(function(){editorChanged=true;this.ngModelCtrl.$setViewValue(html);if(this.onContentChanged){this.onContentChanged({editor:editor,html:html,text:text,delta:delta,oldDelta:oldDelta,source:source})}}.bind(this))}modelChanged=false}.bind(this));if(content){modelChanged=true;var contents=editor.clipboard.convert(content);editor.setContents(contents);editor.history.clear()}if(this.onEditorCreated){this.onEditorCreated({editor:editor})}}}]})});