I have an editor (classic mode) I use in an editor template like @(Html.Kendo().EditorFor(m => m.Content) for a grid to create and update HTML content coming from the database that has inputs and selects. When I first load the content to the editor, I have a processEditorInputs() JavaScript function that loops thru all the inputs and selects in the editor's iframe, adds a css class to them, and adds a dblclick event listener so they can be edited via a kendo dialog I have also in my view. Everything is working fine but I have an issue I have not been able to figure out. After the undo action is performed in the editor, either by ctrl+Z or toolbar action, all my inputs in the editor lose their doubleclick binding and therefore cannot be edited again via the dialog. I tried subscribing to the 'Execute' event of the editor to call my processEditorInputs() function again after undo is performed like below:
function onExecute(e) {
if(e.name == 'undo'){
processEditorInputs();
}
}
This seems to be only working after executing undo multiple times only and it does not seem reliable.
Here is my editor.
@(Html.Kendo()
.EditorFor(m => m.Content)
.StyleSheets(css => css.Add(Url.Content("~/css/site.css?3")))
.Tools(tools => tools
.Clear()
.ViewHtml()
.CustomTemplate(ct => ct.Template("<li class='k-tool-group k-button-group' role='presentation'><button type='button' onclick='openInsertCheckbox();' role='button' class='k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-tool' title='Insert Checkbox'><i class='mdi mdi-checkbox-marked-outline'></i></button><button type='button' onclick='openInsertInput();' role='button' class='k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-tool' title='Insert Input'><i class='mdi mdi-form-textbox'></i></button><button type='button' onclick='openInsertSelect();' role='button' class='k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-tool' title='Insert Select'><i class='mdi mdi-form-dropdown'></i></button></li>"))
.Undo()
.Redo()
.Bold()
.Italic()
.Underline()
.Strikethrough()
.JustifyLeft()
.JustifyCenter()
.JustifyRight()
.JustifyFull()
.InsertUnorderedList()
.InsertOrderedList()
.Outdent()
.Indent()
.CreateLink()
.Unlink()
.InsertImage()
.InsertFile()
.SubScript()
.SuperScript()
.TableEditing()
.Formatting()
.CleanFormatting()
.FontName()
.FontSize()
.ForeColor()
.BackColor()
.Pdf()
.Print()
.CustomTemplate(ct => ct.Template("<li class='k-tool-group k-button-group' role='presentation'><button type='button' onclick='insertPageBreak();' role='button' class='k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-tool' title='Insert Page Break'><i class='fas fa-grip-lines'></i></button>"))
).Events(events => events
.Execute("onExecute")
))
My javascript functions.
$(document).ready(function () {
$(".t-placeholder").on("dragstart", function (e) {
e.originalEvent.dataTransfer.setData("text", $(this).html());
});
processEditorInputs();
});
function processEditorInputs() {
let iframe = document.getElementsByClassName('k-iframe')[0];
let inputElements = iframe.contentWindow.document.getElementsByTagName('input');
let selectElements = iframe.contentWindow.document.getElementsByTagName('select');
//inputs
for (let i = 0; i < inputElements.length; i++) {
//style
styleEditorField(inputElements[i]);
//add unique identifier
if (!inputElements[i].id || inputElements[i].id == '') {
var id = generateUniqueId();
inputElements[i].id = `input-${id}`;
}
//add double click event listener to edit according to input type (if not already bound only)
bindEditOnDoubleClick(inputElements[i]);
}
//selects
for (let i = 0; i < selectElements.length; i++) {
//style
styleEditorField(selectElements[i]);
//add unique identifier
if (!selectElements[i].id || selectElements[i].id == '') {
var id = generateUniqueId();
selectElements[i].id = `select-${id}`;
}
//add double click event listener to edit
bindEditOnDoubleClick(selectElements[i]);
}
}
function generateUniqueId(){
return Date.now() + Math.floor(Math.random() * 1000000);
}
function bindEditOnDoubleClick(input){
//debugger;
if($(input).is('select')){
input.addEventListener("dblclick", function () {
openInsertSelect(this);
});
}
else{
switch (input.type) {
// If the input type is text, date, time, number
case 'text':
case 'date':
case 'time':
case 'number':
input.addEventListener("dblclick", function () {
openInsertInput(this);
});
break;
// If the input type is checkbox
case 'checkbox':
input.addEventListener("dblclick", function () {
openInsertCheckbox(this);
});
break;
}
}
}
function styleEditorField(input){
input.classList.add('k-edt-field');
}
I would appreciate your assistance with this matter. Please let me know if more information is needed.
Thanks.