[ASP.net MVC] ckeditor網頁編輯器 字型、圖片上傳功能的快速安裝筆記

[ASP.net MVC] ckeditor網頁編輯器 字型、圖片上傳功能的快速安裝筆記

前言

我已經連續兩次遇到客戶要求,ckeditor的工具列只要字型+圖片上傳功能就好,其他小工具拿掉

這設定有點囉嗦,只好記在部落格上,方便日後隨時查看

※本文的ckeditor 為4.x版

實作

先去ckeditor 官網 http://ckeditor.com/builder ,客製化需要的plugin打包下載

image

image

有熱心網友整理出plugin的中英文對照表↓

CKEditor 按鈕中英文對照表

image

image

image

下載到本機的壓縮檔,解壓後會是一個ckeditor名稱的資料夾,把它放入Web專案的Content資料夾下

image

簡單兩個步驟就可以把網頁編輯器叫出來

1.引用ckeditor.js

2:兩種方式挑一個做↓

  • <textarea> 標籤加入class=”ckeditor”並至少給一個name或id
  • <textarea> 標籤至少給一個name或id,然後在<script>區段寫下↓
  <script type="text/javascript">
        CKEDITOR.replace('<textarea>的name或id皆可');
    </script>

不過要注意,預設圖片上傳的頁籤不會出現

image

如果要讓圖片上傳頁籤出現的話,要在頁面底下加入


 <script type="text/javascript">

        
        CKEDITOR.replace('textarea的id或name'
    , { filebrowserImageUploadUrl: '上傳圖片的路徑' }
    );
        
    </script>

前端View完整代碼

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title> 
</head>
<body>
    <div>
        <!--textarea加上class="ckeditor"並給一個name="myText"-->
        @Html.TextArea("myText", new { @class="ckeditor"})
    </div>


   <!--引用ckeditor.js-->
    <script src="~/Content/ckeditor/ckeditor.js"></script> 
   <!--加入圖片上傳頁籤,放在</body>前面,若放在網頁head區段的話,會抓不到textarea DOM-->
    <script type="text/javascript">
 
        CKEDITOR.replace('myText'
    , { filebrowserImageUploadUrl: '/Home/UploadPicture' }
    );
        
    </script>
</body>
</html>

完整Controller.cs(含圖片上傳代碼)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplicationCkeditor.Controllers
{
    public class HomeController : Controller
    { 
        //顯示網頁
        public ActionResult Index()
        {
            return View();
        } 

        /// <summary>
        /// ckeditor上傳圖片
        /// </summary>
        /// <param name="upload">預設參數叫upload</param>
        /// <param name="CKEditorFuncNum"></param>
        /// <param name="CKEditor"></param>
        /// <param name="langCode"></param>
        /// <returns></returns>
       [HttpPost]
        public ActionResult UploadPicture(HttpPostedFileBase upload, string CKEditorFuncNum, string CKEditor, string langCode)
        {
            string result = "";
            if (upload!=null && upload.ContentLength>0)
            {
                //儲存圖片至Server
                upload.SaveAs(Server.MapPath("~/Images/" + upload.FileName));

                
                var imageUrl = Url.Content("~/Images/" + upload.FileName);

                var vMessage = string.Empty;

               result = @"<html><body><script>window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ", \"" + imageUrl + "\", \"" + vMessage + "\");</script></body></html>";

            }
       
            return Content(result);
        }

    }
}

執行結果:

image

補充

想要讓網頁編輯器有預設內容的話,以下幾個方法

1:單純Html Code

 <textarea name="myText" class="ckeditor">
  <b>CKEditor Demo</b> 
  </textarea>

2.ASP.net MVC的欄位

 @Html.TextArea("myText", "<a href='#'>CKEditor Demo</a>", new { @class= "ckeditor" })
   

3.ASP.net MVC ModelBinding用的欄位(m.myText為Html原始內容,沒有HtmlEncode過的)

@Html.TextAreaFor(m => m.myText, new { @class = "ckeditor" })

以上得留意,預設Html內容填什麼標籤tag,ckeditor的toolbar就必須設定支援該標籤,否則不會正常顯示。

2017.11.03 追記

如果表單↓直接提交的話,會出現黃底紅字錯誤畫面

<!DOCTYPE html> 
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>ckeditor 4.7.3 Demo</title>
</head>
<body>
   
   @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { name = "myForm" }))
   { 
       @Html.TextArea("myText",new { @class= "ckeditor" })
        
      <input type="submit" value="submit Form" />
   }
    
    <script src="~/Content/ckeditor_4.7.3/ckeditor.js"></script> 
</body>
</html>

因為ckeditor把網頁編輯器的html內容原封不動地塞回textarea然後表單提交,為了讓ckeditor能把Html內容塞回textarea前先做HtmlEncode

得在ckeditor目錄下的config.js,追加一行代碼:config.htmlEncodeOutput = true;

如此表單在提交時,<textarea>的資料便會自動經過HtmlEncode後再送到Server端,程式就不會出錯了

另外,如果透過jQuery Ajax來提交資料到Server端的話

JS得先執行以下代碼,再呼叫jQuery Ajax ※當然config.js的config.htmlEncodeOutput = true;仍然要設定,這樣textarea填入的值才會是HtmlEncode過的值

for (let key in CKEDITOR.instances)
{
    CKEDITOR.instances[key].updateElement();//把編輯器內容填回textarea
}//end for in    

View完整程式碼↓

<!DOCTYPE html> 
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>ckeditor 4.7.3 Demo</title>
</head>
<body> 
   @using (Html.BeginForm("", "", FormMethod.Post, new { name = "myForm" }))
   { 
       @Html.TextArea("myText",new { @class= "ckeditor" })
        
        <input type="button" value="click button" />
   } 

    <!--引用jQuery核心-->
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.js"></script>
    <!--引用ckeditor-->
    <script src="~/Content/ckeditor_4.7.3/ckeditor.js"></script> 
    <script type="text/javascript"> 
        $(function () {
            $("input:button").click(function () {
                for (let key in CKEDITOR.instances)
                {
                    CKEDITOR.instances[key].updateElement();//把編輯器內容填回textarea
                }//end for in    
                $.ajax({
                    url:"@Url.Action("Index","Home")",
                    method: "post",
                    data: $("form[name=myForm]").serialize()
                });//end ajax
            }); 
        });
    </script>
</body>
</html>

不管是jQuery Ajax送資料到Server端或表單提交到Server端

Controller再搭配以下代碼,便可取得使用者實際輸入資料

[HttpPost]
//[ValidateInput(false)]//建議別加這行
public ActionResult Index(string myText)
{ 
 //還原成原本的html tag資料
 HttpUtility.HtmlDecode(myText);
               
 return View();
}

※有些網路上文章為了解決黃底紅字問題,會建議在Action方法加上 [ValidateInput(false)]的Attribute,個人不建議這樣做,因為客戶若拿弱點掃描工具掃一掃會被掃出資安漏洞

2013.10.5追記

客戶要求,工具列上的「插入分頁符號」、「Iframe」按鈕需要隱藏

image

修改方法有兩種:一種是在頁面上寫Javascript語法呼叫CKEDITOR.replace()的方式

另一種是在config.js裡寫下要異動的參數(config.removeButtons)

改config.js是全網站的ckeditor都會套用,本文以config.js做說明

找到ckeditor的config.js檔案

image

加入這一行:config.removeButtons = 'Iframe,PageBreak';

注意有區分大小寫

image

要移除的Button名稱若不知道的話,可以看一下這篇官方文件:http://ckeditor.com/latest/samples/plugins/toolbar/toolbar.html

Button名稱都在items陣列裡,看下圖大概就能知道Button名稱對應

image

另外,如果查找官方文件說明config.removeButtons參數的話:http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-removeButtons

官方是建議勿使用過度,請改用config.removePlugins參數,這樣就可以減少載入Plugin

config.removePlugins可以用來移除一組Buttons,例如:config.removePlugins = "basicstyles";,可以把底下的Bold , Italic ,  Underline ...等Button都移除掉(※注意removePlugins參數都是小寫)

如果要移除的Plugin被其他Plugin參考使用到的話,則不能移除

但…講歸講

我找不到哪裡有列出ckeditor的plugin參數清單Orz…

只好用removeButtons參數將就一下

附上找到不錯的官方文件Sample:CKEditor Samples

其他推薦文章

[前端軍火庫]CKEditor - 最好用的Web版文字編輯器

神調校讓 CKEditor 更好用