Skip to content

Commit b0622bc

Browse files
authored
Merge pull request #4627 from syncfusion-content/988174-core-mvc-add
988174: Rich Text Editor Missing topics Are Added
2 parents 0a48e08 + b906f97 commit b0622bc

File tree

46 files changed

+1620
-17
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1620
-17
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class HomeController : Controller
2+
{
3+
4+
public ActionResult Index()
5+
{
6+
ViewBag.value = @"<p>This is paragraph one.</p><p>This is paragraph two.</p>"
7+
return View();
8+
}
9+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
<button class="e-btn" style="margin-bottom: 20px;" onclick="selectCell()">
3+
Select Paragraph
4+
</button>
5+
6+
@Html.EJS().RichTextEditor("cellSelectionRTE").Value(ViewBag.value).Render()
7+
8+
<script>
9+
function selectCell() {
10+
const panel = document.getElementById("cellSelectionRTE").ej2_instances[0].contentModule.getEditPanel();
11+
const cells = panel.querySelectorAll('td');
12+
13+
if (cells.length > 2) {
14+
const cell = cells[2]; // Third cell
15+
const range = document.createRange();
16+
range.selectNode(cell);
17+
18+
const selection = window.getSelection();
19+
if (selection) {
20+
selection.removeAllRanges();
21+
selection.addRange(range);
22+
}
23+
24+
cell.style.backgroundColor = '#cce5ff';
25+
cell.classList.add('e-cell-select');
26+
}
27+
28+
}
29+
</script>
30+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
<button class="e-btn" style="margin-bottom: 20px;" onclick="selectCell()">
3+
Select Cell
4+
</button>
5+
6+
<ejs-richtexteditor id="cellSelectionRTE" value="@ViewBag.value">
7+
</ejs-richtexteditor>
8+
9+
<script>
10+
function selectCell() {
11+
const panel = document.getElementById("cellSelectionRTE").ej2_instances[0].contentModule.getEditPanel();
12+
const cells = panel.querySelectorAll('td');
13+
14+
if (cells.length > 2) {
15+
const cell = cells[2]; // Third cell
16+
const range = document.createRange();
17+
range.selectNode(cell);
18+
19+
const selection = window.getSelection();
20+
if (selection) {
21+
selection.removeAllRanges();
22+
selection.addRange(range);
23+
}
24+
25+
cell.style.backgroundColor = '#cce5ff';
26+
cell.classList.add('e-cell-select');
27+
}
28+
29+
}
30+
</script>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
public class HomeController : Controller
2+
{
3+
4+
public ActionResult Index()
5+
{
6+
return View();
7+
}
8+
}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
2+
@using Syncfusion.EJ2.DropDowns
3+
4+
@{
5+
6+
string rteValue = @"<p>Dear <span contenteditable=""false"" class=""e-mention-chip""><span>{{FirstName}}</span></span> <span contenteditable=""false"" class=""e-mention-chip""><span>{{LastName}}</span></span>,</p>
7+
<p>We are thrilled to have you with us! Your unique promotional code for this month is: <span contenteditable=""false"" class=""e-mention-chip""><span>{{PromoCode}}</span></span>.</p>
8+
<p>Your current subscription plan is: <span contenteditable=""false"" class=""e-mention-chip""><span>{{SubscriptionPlan}}</span></span>.</p>
9+
<p>Your customer ID is: <span contenteditable=""false"" class=""e-mention-chip""><span>{{CustomerID}}</span></span>.</p>
10+
<p>Your promotional code expires on: <span contenteditable=""false"" class=""e-mention-chip""><span>{{ExpirationDate}}</span></span>.</p>
11+
<p>Feel free to browse our latest offerings and updates. If you need any assistance, don't hesitate to contact us at <a href=""mailto:{{SupportEmail}}""><span contenteditable=""false"" class=""e-mention-chip""><span>{{SupportEmail}}</span></span></a> or call us at <span contenteditable=""false"" class=""e-mention-chip""><span>{{SupportPhoneNumber}}</span></span>.</p>
12+
<p>Best regards,<br>The <span contenteditable=""false"" class=""e-mention-chip""><span>{{CompanyName}}</span></span> Team</p>";
13+
char mentionChar = '{';
14+
var tools = new object[]
15+
{
16+
"Bold",
17+
"Italic",
18+
"Underline",
19+
"|",
20+
"Formats",
21+
"Alignments",
22+
"OrderedList",
23+
"UnorderedList",
24+
"|",
25+
"CreateLink",
26+
"Image",
27+
"CreateTable",
28+
"|",
29+
new { tooltipText = "Merge Data", template = "#merge_data", command = "Custom" },
30+
new { tooltipText = "Insert Field", template = "#insert_Field", command = "Custom" },
31+
"SourceCode",
32+
"|",
33+
"Undo",
34+
"Redo",
35+
};
36+
var items = new List<object>
37+
{
38+
new { text = "First Name" },
39+
new { text = "Last Name" },
40+
new { text = "Support Email" },
41+
new { text = "Company Name" },
42+
new { text = "Promo Code" },
43+
new { text = "Support Phone Number" },
44+
new { text = "Customer ID" },
45+
new { text = "Expiration Date" },
46+
new { text = "Subscription Plan" }
47+
};
48+
49+
var mergeData = new List<object>
50+
{
51+
new { text = "First Name", value = "FirstName" },
52+
new { text = "Last Name", value = "LastName" },
53+
new { text = "Support Email", value = "SupportEmail" },
54+
new { text = "Company Name", value = "CompanyName" },
55+
new { text = "Promo Code", value = "PromoCode" },
56+
new { text = "Support Phone Number", value = "SupportPhoneNumber" },
57+
new { text = "Customer ID", value = "CustomerID" },
58+
new { text = "Expiration Date", value = "ExpirationDate" },
59+
new { text = "Subscription Plan", value = "SubscriptionPlan" }
60+
};
61+
}
62+
<div class="control-section">
63+
<div class="control-wrapper">
64+
@Html.EJS().RichTextEditor("mailMergeEditor").ActionBegin("actionBeginHandler").ActionComplete("actionCompleteHandler").SaveInterval(1).Created("created").ToolbarSettings(e => e.Items(tools)).Value(rteValue).Render()
65+
@Html.EJS().Button("merge_data").Content("Merge Data").Click("onClickHandler").CssClass("e-tbar-btn e-btn").Render()
66+
@Html.EJS().DropDownButton("insert_Field").Content("Insert Field").Close("onDropDownClose").Select("onItemSelect").Items(items).CssClass("e-rte-dropdown-btn e-rte-dropdown-popup e-rte-dropdown-items e-rte-elements e-rte-dropdown-menu").Render()
67+
@Html.EJS().Mention("mentionField").MentionChar(mentionChar).Created("onMentionCreate").Target("#mailMergeEditor_rte-edit-view").DataSource(mergeData).AllowSpaces(true).Fields(new MentionFieldSettings { Text = "Text" }).DisplayTemplate("<span> {{${Value}}} </span>").PopupWidth("250px").PopupHeight("200px").Render()
68+
</div>
69+
</div>
70+
71+
72+
73+
<script>
74+
var mailMergeEditor;
75+
var mentionObj;
76+
const textToValueMap = {
77+
'First Name': 'FirstName',
78+
'Last Name': 'LastName',
79+
'Support Email': 'SupportEmail',
80+
'Company Name': 'CompanyName',
81+
'Promo Code': 'PromoCode',
82+
'Support Phone Number': 'SupportPhoneNumber',
83+
'Customer ID': 'CustomerID',
84+
'Expiration Date': 'ExpirationDate',
85+
'Subscription Plan': 'SubscriptionPlan'
86+
};
87+
var placeholderData = {
88+
"FirstName": "John",
89+
"LastName": "Doe",
90+
"PromoCode": "ABC123",
91+
"SubscriptionPlan": "Premium",
92+
"CustomerID": "123456",
93+
"ExpirationDate": "2024-12-31",
94+
"SupportEmail": "[email protected]",
95+
"SupportPhoneNumber": "+1-800-555-5555",
96+
"CompanyName": "Example Inc."
97+
};
98+
function created() {
99+
mailMergeEditor = this;
100+
}
101+
function onMentionCreate() {
102+
mentionObj = this;
103+
}
104+
function actionBeginHandler(args) {
105+
if (
106+
args.requestType === 'EnterAction' &&
107+
mentionObj.element.classList.contains('e-popup-open')
108+
) {
109+
args.cancel = true;
110+
}
111+
}
112+
function onDropDownClose() {
113+
if (mailMergeEditor) {
114+
mailMergeEditor.focusIn();
115+
}
116+
}
117+
function onItemSelect(args) {
118+
if (args.item.text != null) {
119+
const value = textToValueMap[args.item.text];
120+
const trimmedValue = value.trim();
121+
mailMergeEditor.formatter.editorManager.nodeSelection.restore();
122+
mailMergeEditor.executeCommand(
123+
'insertHTML',
124+
`<span contenteditable="false" class="e-mention-chip"><span>{{${trimmedValue}}}</span></span>&nbsp;`,
125+
{ undo: true }
126+
);
127+
}
128+
}
129+
function actionCompleteHandler(e) {
130+
if (e.requestType === 'SourceCode') {
131+
mailMergeEditor.getToolbar().querySelector('#merge_data').parentElement.classList.add('e-overlay');
132+
mailMergeEditor.getToolbar().querySelector('#insert_Field').parentElement.classList.add('e-overlay');
133+
} else if (e.requestType === 'Preview') {
134+
mailMergeEditor.getToolbar().querySelector('#merge_data').parentElement.classList.remove('e-overlay');
135+
mailMergeEditor.getToolbar().querySelector('#insert_Field').parentElement.classList.remove('e-overlay');
136+
}
137+
}
138+
function onClickHandler() {
139+
if (mailMergeEditor) {
140+
let editorContent = mailMergeEditor.value;
141+
let mergedContent = replacePlaceholders(editorContent, placeholderData);
142+
if (mailMergeEditor.formatter.getUndoRedoStack().length === 0) {
143+
mailMergeEditor.formatter.saveData();
144+
}
145+
mailMergeEditor.value = mergedContent;
146+
mailMergeEditor.formatter.saveData();
147+
} else {
148+
console.log('MailMergeEditor is not initialized.');
149+
}
150+
}
151+
function replacePlaceholders(template, data) {
152+
return template.replace(/{{\s*(\w+)\s*}}/g, (match, key) => {
153+
var value = data[key.trim()];
154+
var result = value !== undefined ? value : match;
155+
return result;
156+
});
157+
}
158+
</script>

0 commit comments

Comments
 (0)