استفاده از Froala WYSIWYG Editor در ASP.NET
نویسنده: وحید نصیری
تاریخ: ۱۳۹۳/۰۲/۱۸ ۱۵:۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="Content/font-awesome.css" rel="stylesheet" />
<link href="Content/froala_editor.css" rel="stylesheet" />
<script src="Scripts/jquery-1.10.2.min.js"></script>
<script src="Scripts/froala_editor.min.js"></script>
<script src="Scripts/langs/fa.js"></script>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</html> @{
ViewBag.Title = "Index";
}
<style type="text/css">
/*تنظیم فونت پیش فرض ادیتور*/
.froala-element {
}
</style>
@using (Html.BeginForm(actionName: "Index", controllerName: "Home"))
{
@Html.TextArea(name: "Editor1")
<input type="submit" value="ارسال" />
}
@section Scripts
{
<script type="text/javascript">
$(function () {
$('#Editor1').editable({
buttons: ["bold", "italic", "underline", "strikeThrough", "fontFamily",
"fontSize", "color", "formatBlock", "align", "insertOrderedList",
"insertUnorderedList", "outdent", "indent", "selectAll", "createLink",
"insertImage", "insertVideo", "undo", "redo", "html", "save", "inserthorizontalrule"],
inlineMode: false,
inverseSkin: true,
preloaderSrc: '@Url.Content("~/Content/img/preloader.gif")',
allowedImageTypes: ["jpeg", "jpg", "png"],
height: 300,
language: "fa",
direction: "rtl",
fontList: ["Tahoma, Geneva", "Arial, Helvetica", "Impact, Charcoal"],
autosave: true,
autosaveInterval: 2500,
saveURL: '@Url.Action("FroalaAutoSave", "Home")',
saveParams: { postId: "123" },
spellcheck: true,
plainPaste: true,
imageButtons: ["removeImage", "replaceImage", "linkImage"],
borderColor: '#00008b',
imageUploadURL: '@Url.Action("FroalaUploadImage", "Home")',
imageParams: { postId: "123" },
enableScript: false
});
});
</script>
} /// <summary>
/// ذخیره سازی خودکار
/// </summary>
[HttpPost]
[ValidateInput(false)]
public ActionResult FroalaAutoSave(string body, int? postId) // نام پارامتر بادی را تغییر ندهید
{
//todo: save body ...
return new EmptyResult();
} // todo: مسایل امنیتی آپلود را فراموش نکنید
/// <summary>
/// ذخیره سازی تصاویر ارسالی
/// </summary>
[HttpPost]
public ActionResult FroalaUploadImage(HttpPostedFileBase file, int? postId) // نام پارامتر فایل را تغییر ندهید
{
var fileName = Path.GetFileName(file.FileName);
var rootPath = Server.MapPath("~/images/");
file.SaveAs(Path.Combine(rootPath, fileName));
return Json(new { link = "images/" + fileName }, JsonRequestBehavior.AllowGet);
} <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"
ValidateRequest="false"
EnableEventValidation="false"
AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FroalaWebFormsTest.Default" %>
<%--اعتبارسنجی ورودی غیرفعال شده چون باید تگ ارسال شود--%>
<%--همچنین در وب کانفیگ هم تنظیم دیگری نیاز دارد--%>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<%--حالت کلاینت آی دی بهتر است تنظیم شود در اینجا--%>
<asp:TextBox ID="txtEditor" ClientIDMode="Static"
runat="server" Height="199px" TextMode="MultiLine" Width="447px"></asp:TextBox>
<br />
<asp:Button ID="btnSave" runat="server" OnClick="btnSave_Click" Text="ارسال" />
<style type="text/css">
/*تنظیم فونت پیش فرض ادیتور*/
.froala-element {
}
</style>
<script type="text/javascript">
$(function () {
$('#txtEditor').editable({
buttons: ["bold", "italic", "underline", "strikeThrough", "fontFamily",
"fontSize", "color", "formatBlock", "align", "insertOrderedList",
"insertUnorderedList", "outdent", "indent", "selectAll", "createLink",
"insertImage", "insertVideo", "undo", "redo", "html", "save", "inserthorizontalrule"],
inlineMode: false,
inverseSkin: true,
preloaderSrc: 'Content/img/preloader.gif',
allowedImageTypes: ["jpeg", "jpg", "png"],
height: 300,
language: "fa",
direction: "rtl",
fontList: ["Tahoma, Geneva", "Arial, Helvetica", "Impact, Charcoal"],
autosave: true,
autosaveInterval: 2500,
saveURL: 'FroalaHandler.ashx',
saveParams: { postId: "123" },
spellcheck: true,
plainPaste: true,
imageButtons: ["removeImage", "replaceImage", "linkImage"],
borderColor: '#00008b',
imageUploadURL: 'FroalaHandler.ashx',
imageParams: { postId: "123" },
enableScript: false
});
});
</script>
</asp:Content> using System.IO;
using System.Web;
using System.Web.Script.Serialization;
namespace FroalaWebFormsTest
{
public class FroalaHandler : IHttpHandler
{
//todo: برای اینکارها بهتر است از وب ای پی آی استفاده شود
//todo: یا دو هندلر مجزا یکی برای تصاویر و دیگری برای ذخیره سازی متن
public void ProcessRequest(HttpContext context)
{
var body = context.Request.Form["body"];
var postId = context.Request.Form["postId"];
if (!string.IsNullOrWhiteSpace(body) && !string.IsNullOrWhiteSpace(postId))
{
//todo: save changes
context.Response.ContentType = "text/plain";
context.Response.Write("");
context.Response.End();
}
var files = context.Request.Files;
if (files.Keys.Count > 0)
{
foreach (string fileKey in files)
{
var file = context.Request.Files[fileKey];
if (file == null || file.ContentLength == 0)
continue;
//todo: در اینجا مسایل امنیتی آپلود فراموش نشود
var fileName = Path.GetFileName(file.FileName);
var rootPath = context.Server.MapPath("~/images/");
file.SaveAs(Path.Combine(rootPath, fileName));
var json = new JavaScriptSerializer().Serialize(new { link = "images/" + fileName });
// البته اینجا یک فایل بیشتر ارسال نمیشود
context.Response.ContentType = "text/plain";
context.Response.Write(json);
context.Response.End();
}
}
context.Response.ContentType = "text/plain";
context.Response.Write("");
context.Response.End();
}
public bool IsReusable
{
get { return false; }
}
}
} <location path="upload">
<system.webServer>
<handlers accessPolicy="Read" />
</system.webServer>
</location>
buttons: [
// .... ,
"insertHTML" //custom button
],
customButtons: {
insertHTML: {
title: 'Insert Code',
icon: {
type: 'font',
value: 'fa fa-dollar' // Font Awesome icon class fa fa-*
},
callback: function (editor) {
editor.saveSelection();
var codeModal = $("<div>").addClass("froala-modal").appendTo("body");
var wrapper = $("<div>").addClass("f-modal-wrapper").appendTo(codeModal);
$("<h4>").append('<span data-text="true">Insert Code</span>')
.append($('<i class="fa fa-times" title="Cancel">')
.click(function () {
codeModal.remove();
}))
.appendTo(wrapper);
var dialog = "<textarea id='code_area' style='height: 211px; width: 538px;' /><br/><label>Language:</label><select id='code_lang'><option>CSharp</option><option>VB</option><option>JScript</option><option>Sql</option><option>XML</option><option>CSS</option><option>Java</option><option>Delphi</option></select> <input type='button' name='insert' id='insert_btn' value='Insert' /><br/>";
$(dialog).appendTo(wrapper);
$("#code_area").text(editor.text());
if (!editor.selectionInEditor()) {
editor.$element.focus();
}
$('#insert_btn').click(function () {
var lang = $("#code_lang").val();
var code = $("#code_area").val();
code = code.replace(/\s+$/, ""); // rtrim
code = $('<span/>').text(code).html(); // encode
var htmlCode = "<pre language='" + lang + "' name='code'>" + code + "</pre></div>";
var codeBlock = "<div align='left' dir='ltr'>" + htmlCode + "</div><br/>";
editor.restoreSelection();
editor.insertHTML(codeBlock);
editor.saveUndoStep();
codeModal.remove();
});
}
}
} var htmlCode = "<pre language='" + lang + "' name='code'>" + code + "</pre></div>";
var htmlCode = "<pre class='brush: " + lang + "' language='" + lang + "' name='code'>" + code + "</pre></div>";
SyntaxHighlighter.config.bloggerMode = true; SyntaxHighlighter.all();
insertHTML: {
title: 'Insert Code',
icon: {
type: 'font',
value: 'fa fa-dollar' // Font Awesome icon class fa fa-*
},
callback: function (editor) {
this.saveSelection();
var thisEditor = this;
var codeModal = $("<div>").addClass("froala-modal").appendTo("body");
var wrapper = $("<div>").addClass("f-modal-wrapper").appendTo(codeModal);
$("<h4>").append('<span data-text="true">Insert Code</span>')
.append($('<i class="fa fa-times" title="Cancel">')
.click(function () {
codeModal.remove();
}))
.appendTo(wrapper);
var dialog = "<textarea id='code_area' style='height: 211px; width: 538px;' /><label>Language:</label><select id='code_lang'><option>CSharp</option><option>VB</option><option>JScript</option><option>Sql</option><option>XML</option><option>CSS</option><option>Java</option><option>Delphi</option></select> <input type='button' name='insert' id='insert_btn' value='Insert' />";
$(dialog).appendTo(wrapper);
$("#code_area").text(this.text());
if (!this.selectionInEditor()) {
this.$element.focus();
}
$('#insert_btn').click(function () {
var lang = $("#code_lang").val();
var code = $("#code_area").val();
code = code.replace(/\s+$/, ""); // rtrim
code = $('<span/>').text(code).html(); // encode
var htmlCode = "<pre class='brush: " + lang.toLowerCase() + "' language='" + lang + "' name='code'>" + code + "</pre></div>"; // syntaxhighlighter با این کد هماهنگ است
//var htmlCode = "<pre language='" + lang + "' name='code'>" + code + "</pre></div>";
var codeBlock = "<div align='left' dir='ltr'>" + htmlCode + "</div>";
thisEditor.restoreSelection();
thisEditor.insertHTML(codeBlock);
thisEditor.saveUndoStep();
codeModal.remove();
});
}
} <system.webServer>
...
<staticContent>
<remove fileExtension=".woff" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
<mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
<mimeMap fileExtension=".otf" mimeType="font/otf" />
<mimeMap fileExtension=".svg" mimeType="images/svg+xml" />
<mimeMap fileExtension=".svgz" mimeType="images/svg+xml" />
</staticContent>
</system.webServer> fullscreen: {
title: 'FullScreen',
icon: {
type: 'font',
value: 'fa fa-external-link'
},
callback: function (editor) {
if (editor.$box.hasClass("froala-editor-full-screen")) {
editor.$box.removeClass("froala-editor-full-screen");
editor.$box.appendTo(editor.editorParent);
}
else {
if (editor.editorParent === undefined)
editor.editorParent = editor.$box.parent();
editor.$box.addClass("froala-editor-full-screen");
editor.$box.appendTo("body");
}
editor.focus();
}
}, .froala-editor-full-screen {
position: fixed !important;
z-index: 10000;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
}
.froala-editor-full-screen div.f-placeholder {
height: 100% !important;
} imageDeleteParams: { src: $img.attr('src') }
"<p><br></p>"
PM> Install-Package Microsoft.jQuery.Unobtrusive.Ajax
<script src="~/Scripts/jquery-1.10.2.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
return Json(new { link = "Content/Images/" + fileName }, JsonRequestBehavior.AllowGet); http://localhost:1455/Content/Images/a_sunny_days_end-wallpaper-1440x900.jpg
new UrlHelper(this.Request.RequestContext).Content("~/content/images/file.png") .on('froalaEditor.file.unlink', function (e, editor, link) {
$.ajax({
method: "POST",
url: "@Url.Action("FroalaDeleteFile", "YeChizis")",
data: {
src:link.href
}
})
.done(function (data) {
console.log('file was deleted');
})
.fail(function () {
console.log('file delete problem');
})
}) /// <summary>
/// حذف فایلهای ادیتور
/// </summary>
[HttpPost]
public void FroalaDeleteFile(string src)
{
string relativePath = new Uri(src).PathAndQuery;
string physicalFilePath = Server.MapPath(relativePath);
if (System.IO.File.Exists(physicalFilePath))
System.IO.File.Delete(physicalFilePath);
} .on('froalaEditor.image.removed', function (e, editor, $img) {
$.ajax({
// Request method.
method: "POST",
// Request URL.
url: "@Url.Action("FroalaDeleteImageAction", "ControllerName")",
// Request params.
data: {
src: $img.attr('src')
}
})
.done(function (data) {
console.log('image was deleted');
})
.fail(function () {
console.log('image delete problem');
})
}) /// <summary>
/// حذف عکسهای ادیتور
/// </summary>
[HttpPost]
public void FroalaDeleteImageAction(string src)
{
string physicalFilePath = Server.MapPath(src);
if (System.IO.File.Exists(physicalFilePath))
System.IO.File.Delete(physicalFilePath);
} $('.selector').froalaEditor({
toolbarButtons: ['bold', 'italic', 'underline'],
/*
(≥ 1200px)
Default ['fullscreen', 'print', 'bold', 'italic', 'underline', 'strikeThrough', 'subscript', 'superscript', 'fontFamily', 'fontSize', '|', 'specialCharacters', 'color', 'emoticons', 'inlineStyle', 'paragraphStyle', '|', 'paragraphFormat', 'align', 'formatOL', 'formatUL', 'outdent', 'indent', 'quote', 'insertHR', '-', 'insertLink', 'insertImage', 'insertVideo', 'insertFile', 'insertTable', 'undo', 'redo', 'clearFormatting', 'selectAll', 'html']
*/
toolbarButtonsMD: ['bold', 'italic', 'underline'],
/*
(≥ 992px)
Default ['fullscreen', 'bold', 'italic', 'underline', 'fontFamily', 'fontSize', 'color', 'paragraphStyle', 'paragraphFormat', 'align', 'formatOL', 'formatUL', 'outdent', 'indent', 'quote', 'insertHR', 'insertLink', 'insertImage', 'insertVideo', 'insertFile', 'insertTable', 'undo', 'redo', 'clearFormatting']
*/
toolbarButtonsSM: ['bold', 'italic', 'underline'],
/*
(≥ 768px)
Default ['fullscreen', 'bold', 'italic', 'underline', 'fontFamily', 'fontSize', 'insertLink', 'insertImage', 'insertTable', 'undo', 'redo']
*/
toolbarButtonsXS: ['bold', 'italic', 'underline'],
/*
(< 768px)
Default ['bold', 'italic', 'fontFamily', 'fontSize', 'undo', 'redo']
*/
});