We have a custom form developed using angular js in which we need to show a rich text box. For this we have used ckeditor.js. But the problem with ckeditor is when we try to insert image or document it asks for the url or link for the picture or document where as the user wants to upload the file from system.

I am aware of SPEditable() but this only works when the page is in edit mode which we do not want. Have also tried jQuery.spHtmlEditor as suggested at github but that's also not working

any help would be of great use. Thanks in advance

1 Answer 1


I did this in the past in an angular app, javascript only solution.

Major issue is that rich editor scripts (sp.ui.rte.js, etc.) don't load correctly, if you are trying to include them in to the page. Common solution is to use codebehind, but it doesn't work for javascript only.
I found a way to workaround it by including into the page hidden xslt web part.

So the key points (how I made it work for angular with javascript only):

  1. Create test list or use existing with a known url, say 'Lists/Test'
  2. Put xslt list view web part on your page and hide it with css:
<div style="display: none">
    <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="full" Title="loc:full">
        <WebPartPages:XsltListViewWebPart runat="server" ListUrl="Lists/Test" IsIncluded="True"
            NoDefaultStyle="TRUE" Title="XsltListView web part" PageType="PAGE_NORMALVIEW"
            Default="False" ViewContentTypeId="0x">
  1. Now you need two additional directives:
angular.module("myapp.directives").directive("spEditable", [
        function () {
            return {
                restrict: "A",
                scope: {},
                link: function ($scope, element) {
                    element.addClass("ms-rte-layoutszone-inner-editable ms-rtestate-write").attr("role", "textbox").attr("aria-haspopup", "true").attr("contentEditable", "true").attr("aria-autocomplete", "both").attr("aria-autocomplete", "both").attr("aria-multiline", "true");


angular.module("myapp.directives").directive("contenteditable", [
            function() {
                return {
                    require: "ngModel",
                    link: function($scope, element, attrs, ngModel) {
                        // view -> model
                        element.on("blur", function() {
                            $scope.$apply(function() {

                        // model -> view
                        ngModel.$render = function() {

  1. Now you can put following html and bind html content to your mymodel:
 <div sp-editable contenteditable ng-model="mymodel">

For further reference take a look at the real-life project (you can even install the app from the office store) - Faq Page All code samples taken from there

  • Hi Kai I tried your solution but it also shown the "Format Text" and "Insert" tab when the page is in edit mode. I have followed all the steps suggested by you above
    – SiD
    Commented Dec 1, 2016 at 8:56
  • Download and install the app from app store, you will see that the page is not in the edit mode. Probably you are doing something wrong Commented Dec 1, 2016 at 9:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.