编辑
2022-09-02
我当开发
00

目录

1. 升级TinyMCE
2. TinyMCE的参数
3. TinyMCE的插件
4. 核心实现 当然是JS
5. 后台
6. 源码
后记和问题

昨天设计发送邮件,需要设计邮件模板,将动态的字段放入模板里,使用了TinyMCE今天来分享一下;

测试环境: FineUICore 8.1 (前端的应该不区别FineUI版本) TinyMCE版本 5.10.0 (下面会写升级方法)

先上图

插入

1. 升级TinyMCE

FineUI自带的好像是4.X,升级我之前发过帖子,需要下载最新的包,覆盖就行了(\wwwroot\res\third-party\tinymce\)

不升级的话会有BUG,插入的字段会跑偏; 升级之后的话会有BUG,高度不会自适应,需要指定高度,这个倒是无所谓,等我修复了再放出来;

2. TinyMCE的参数

TinyMCE的参数通过 .Options( 去设置,参考 http://tinymce.ax-z.cn/ 就可以了, 比如设置中文

F.OptionItem().Key("language").Value("zh_CN").PersistOriginal(false),

PersistOriginal 表示是否原样输出,如果为false会当作字符串,比如输出 false ,就为true就好了,

完整配置和注释如下

.Options( //语言 F.OptionItem().Key("language").Value("zh_CN").PersistOriginal(false), //自定义css路径 F.OptionItem().Key("content_css").Value(Url.Content("~/res/css/FineUIOvereide.css")).PersistOriginal(false), //不要上面的菜单 F.OptionItem().Key("menubar").Value("false").PersistOriginal(true), //最小高度 F.OptionItem().Key("min_height").Value("500").PersistOriginal(true), //插件选择 F.OptionItem().Key("plugins").Value("['link','code','textcolor colorpicker ','noneditable importcss autoresize']").PersistOriginal(true), //工具条 F.OptionItem().Key("toolbar1").Value("bold italic underline strikethrough | numlist bullist | alignleft aligncenter alignright | link unlink | code"), //作为标签的class类 F.OptionItem().Key("noneditable_noneditable_class").Value("tag").PersistOriginal(false) )

3. TinyMCE的插件

要实现标签功能,需要用到 两个插件 noneditable不可编辑插件importcss引用css插件,放到plugins 最后就行了;这里我设置了 noneditable_noneditable_class ,就是这个css 将作为 不可编辑的标记;

如果没升级 TinyMCE 出现以下情况

插入

插入焦点会很奇怪;

4. 核心实现 当然是JS

直接上代码,看注释

//一个字段的合集 [{id,value},{id,value}] const fields = @Html.Raw(ViewBag.myFields); F.ready(function () { fields.forEach(item => { //Label let tag = new F.Label({ cls: "tag", hideLabel: true, value: item.value, renderTo: F.ui.field.bodyEl, }); //点击事件 tag.el.on("click", () => { //拼一个标签 把值塞进去 let span = `<span class="tag" id="${item.id}" style="height:20px;line-height:20px;margin:0px 5px;">${item.value}</span>`; //注意获取编辑控件的用法 F.ui.HtmlEditor1.getEditorInstance().insertContent(span); }); }) });

tag 是我自己写的样式,不放出来了,30RMB

到这就能插入了;

5. 后台

后台需要保存,发送邮件时需要替换标签,这里用的正则替换,也放出来

myFields.ForEach(item => { var v = ""; //如果有数据 if (data.ContainsKey(item.id)) { v = data[item.id].ToString(); } //正则替换模板 var regEx_style = $"<span[^>]*id=\"{item.id}\"[^>]*?>[\\s\\S]*?<\\/span>"; temp = Regex.Replace(temp, regEx_style, v); });

这里的span 要和前台的 span标签一致,否则找不到,属于约定,也可以用一个参数控制;

6. 源码

6.1 前台代码

@{ ViewBag.Title = "没想好"; var F = Html.F(); } @section head { } @section body { @( F.Panel().NoBorderAndHeader().Layout(LayoutType.HBox).IsViewPort(true) .Items( F.Panel().ID("field").BoxFlex(1).Title("字段").Toolbars(F.Toolbar().Items( F.Button().Text("测试").OnClick(Url.Action("test"), new Parameter("temp", "F.ui.HtmlEditor1.getValue()")) )), F.HtmlEditor().BoxFlex(3).ID("HtmlEditor1").Editor(Editor.TinyMCE).LabelAlign(LabelAlign.Top) .BasePath(Url.Content("~/res/third-party/tinymce/")).ToolbarSet(EditorToolbarSet.Full) //.Height(600) .Options( F.OptionItem().Key("language").Value("zh_CN").PersistOriginal(false), F.OptionItem().Key("content_css").Value(Url.Content("~/res/css/FineUIOvereide.css")).PersistOriginal(false), F.OptionItem().Key("menubar").Value("false").PersistOriginal(true), F.OptionItem().Key("min_height").Value("500").PersistOriginal(true), F.OptionItem().Key("plugins").Value("['link','code','textcolor colorpicker ','noneditable importcss autoresize']").PersistOriginal(true), F.OptionItem().Key("toolbar1").Value("bold italic underline strikethrough | numlist bullist | alignleft aligncenter alignright | link unlink | code"), F.OptionItem().Key("noneditable_noneditable_class").Value("tag").PersistOriginal(false) ) ) ) } @section script { <script> const fields = @Html.Raw(ViewBag.myFields); F.ready(function () { fields.forEach(item => { let tag = new F.Label({ cls: "tag", hideLabel: true, value: item.value, renderTo: F.ui.field.bodyEl, }); tag.el.on("click", () => { let span = `<span class="tag" id="${item.id}" style="height:20px;line-height:20px;margin:0px 5px;">${item.value}</span>`; F.ui.HtmlEditor1.getEditorInstance().insertContent(span); }); }) }); </script> }

6.2 后台代码

using FineUICore.EmptyProject.Controllers; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace FineUICoreEx.Demo.Areas.Other.Controllers { [Area("Other")] public class TinyMCETestController : BaseController { public IActionResult Index() { List<myField> myFields = GetmyFields(); ViewBag.myFields = JArray.FromObject(myFields).ToString(Formatting.None); return View(); } [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> test(string temp) { JObject data = new JObject(); GetData().ForEach(item => { data.Add(item.id, item.value); }); List<myField> myFields = GetmyFields(); myFields.ForEach(item => { var v = ""; if (data.ContainsKey(item.id)) { v = data[item.id].ToString(); } var regEx_style = $"<span[^>]*id=\"{item.id}\"[^>]*?>[\\s\\S]*?<\\/span>"; temp = Regex.Replace(temp, regEx_style, v); }); ShowAlert(temp); return FineUICore.UIHelper.Result(); } private List<myField> GetData() { return new List<myField>() { new myField() { id ="date",value=DateTime.Now.ToString("yyyy-MM-dd") }, new myField() { id ="name",value="我不是标题" }, new myField() { id ="content",value="内容22223423<br/>内容22223423" }, }; } public dynamic GetmyFields() { return new List<myField>() { new myField() { id ="date",value="日期" }, new myField() { id ="name",value="姓名" }, new myField() { id ="title",value="标题" }, new myField() { id ="content",value="内容" }, }; } } public class myField { public string id { get; set; } public string value { get; set; } } }

引用图

实际图


后记和问题

  • 问题1

目前遇到的问题是 F.ui.HtmlEditor2.getEditorInstance() 页面初始时会获取不到,需要延迟

  • 问题2

另外页面初始时回发,会有一个

n.beforeAjax(function () { t.oIlO0.initialized && t.oIlO0.save() })

这个会报错,不要回发或者延迟回发就好了 绝对是BUG

  • 代码断
let Editor = F.ui.HtmlEditor1.getEditorInstance(); Editor.on('focus', function () { ... }); Editor.on('change', ...);
F.HtmlEditor().ID("HtmlEditor1").Editor(Editor.TinyMCE) .Label("标题") .LabelAlign(LabelAlign.Top) .BasePath(Url.Content("~/res/third-party/tinymce/")) .ToolbarSet(EditorToolbarSet.Full)//好像影响menubar:false .Options( F.OptionItem().Key("language").Value("zh_CN").PersistOriginal(false), F.OptionItem().Key("toolbar").Value("false").PersistOriginal(true),//没工具条 F.OptionItem().Key("menubar").Value("false").PersistOriginal(true),//没菜单 F.OptionItem().Key("statusbar").Value("false").PersistOriginal(true),//没状态栏 F.OptionItem().Key("height").Value("58").PersistOriginal(true), F.OptionItem().Key("content_css").Value(Url.Content("~/res/css/FineUIOvereide.css")).PersistOriginal(false), F.OptionItem().Key("plugins") .Value("['noneditable importcss']").PersistOriginal(true), F.OptionItem().Key("noneditable_noneditable_class").Value("tag").PersistOriginal(false) ), F.HtmlEditor().ID("HtmlEditor2").Editor(Editor.TinyMCE) .Label("内容") .LabelAlign(LabelAlign.Top) .BasePath(Url.Content("~/res/third-party/tinymce/")) .Options( F.OptionItem().Key("language").Value("zh_CN").PersistOriginal(false), F.OptionItem().Key("plugins") .Value("['link','code','textcolor colorpicker ','noneditable importcss autoresize preview']").PersistOriginal(true),//插件 F.OptionItem().Key("min_height").Value("350").PersistOriginal(true),//最小高度 F.OptionItem().Key("toolbar1") .Value("fontselect fontsizeselect | bold italic underline strikethrough | numlist bullist | alignleft aligncenter alignright | link unlink | code preview wordcount"),//工具栏 F.OptionItem().Key("noneditable_noneditable_class").Value("tag").PersistOriginal(false), F.OptionItem().Key("content_css").Value(Url.Content("~/res/css/FineUIOvereide.css")).PersistOriginal(false),//引用css F.OptionItem().Key("menubar").Value("false").PersistOriginal(true),//没有菜单 F.OptionItem().Key("branding").Value("false").PersistOriginal(true),//没有logo F.OptionItem().Key("font_formats").Value("微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif").PersistOriginal(false)//字体 )
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:没想好

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!