Hi!
Trying to implement some chips functionality in text editor. But have 2 problems:
1) I insert chip programmatically via button click on that place where cursor was. For that purpose I use .getRange() with (blur) method and .selectRange() before insertion. The problem is: when I insert 2 o more chips in a row, they become nested (chip which contain next chip which contain one more chip..). Code:
onSaveSelection(): void {
this.curPos = this.editor.getRange();
}
addValue(value, type): void {
this.uuidValue = 'dynamic_' + UUID();
let chip;
switch (type) {
case 'addDefinedField':
chip =
'<span id=' + '\'' + this.uuidValue + '\'' +
' class="e-chip-list" style="display:inline" contenteditable="false"> <span class="e-chip"> <span class="e-chip-text red"> ' +
value + '</span><span class="e-chip-delete e-dlt-btn"> </span></span> </span>';
break;
case 'addTemplate':
chip =
'<span id=' + '\'' + this.uuidValue + '\'' +
' class="e-chip-list" style="display:inline" contenteditable="false"> <span class="e-chip"> <span class="e-chip-text green"> ' +
value + '</span><span class="e-chip-delete e-dlt-btn"> </span></span> </span>';
break;
}
if (this.curPos) {
this.editor.selectRange(this.curPos);
}
this.editor.executeCommand('insertHTML', chip);
const deleteBtn = document.querySelector(`#${this.uuidValue} .e-chip-delete`);
deleteBtn.addEventListener('click', () => {
deleteBtn.closest('.e-chip-list').remove();
});
}
2) The second problem is: when I've added a chip - it has Event for deleting, but after adding another chip, the previous one lost its event and click doesn't work.
this.rteObj.getContent().addEventListener('click', this.remove.bind(this));
remove(args) {
if (args.target.classList.contains('e-chip-delete')) {
(args as any).target.closest('.e-chip-list').remove();
}
}
|
I found solution with deleting chips, but checked yours and it also works.
But with chip adding still have a problem because in your example you have drop event. I my case there isn't any event. Chip is added by clicking from other component. I suppose it's a common problem to get caret position in contenteditable areas.
Maybe there is any method to save/get caret (cursor) position? So it will be a working example both in Chrome and Safari.
Onchange(args) {
if (
this.textInserted &&
this.rteObj.contentModule.getDocument() &&
this.rteObj.contentModule.getDocument().caretRangeFromPoint
) {
if (document.getElementById(this.uuidValue)) {
this.range = this.rteObj.contentModule
.getDocument()
.caretRangeFromPoint(
document.getElementById(this.uuidValue).getBoundingClientRect().x,
document.getElementById(this.uuidValue).getBoundingClientRect().y
);
this.saveSelection = this.selection.save(this.range, document);
}
}
this.textInserted = false;
}
clicked(args) {
this.textInserted = true;
this.uuidValue = 'dynamic_' + UUID.UUID();
if (this.saveSelection) {
this.saveSelection.restore();
}
var value =
'<span id=' +
"'" +
this.uuidValue +
"'" +
' class="e-chip-list" style="display:inline" contenteditable="false"> <span class="e-chip"> <span class="e-chip-text"> ' +
args.target.innerText +
'</span><span id=' +
"'" +
this.uuidValue +
'-deleteId' +
"'" +
' class="e-chip-delete e-dlt-btn"> </span>';
this.rteObj.executeCommand('insertHTML', value);
var deleteBtn = document.querySelector('#' + this.uuidValue + '-deleteId');
}
|
Hi, Indrajith
It doesn't work in Opera, Firefox. It works 50/50 in Chrome and works in Safari.
And as I know .caretRangeFromPoint
is deprecated and is not stable in different browsers.
I'm looking for cross-browser solution.
Summary:
1) Opera - doesn't work
2) Firefox - doesn't work and if you click 2 times in a raw - inserted chip is going wrong (it inserts chip into chip)
3) Chrome - works 50/50, sometimes it insert chip at the beginning or at the wrong place
4) Safari - works
Any suggestions?
Onchange(args) {
this.range = this.selection.getRange(this.rteObj.contentModule.getDocument());
if (this.range.startContainer.nodeType === 3 && this.range.startContainer.parentElement &&
this.range.startContainer.parentElement.classList.contains('e-chip-delete')) {
var rangeElement = this.range.startContainer;
this.range.setStart(rangeElement.parentElement.closest('p'), 0);
this.range.setEnd(rangeElement.parentElement.closest('p'), 0);
}
this.saveSelection = this.selection.save(this.range, document);
}
|
Hi!
It does work like a charm almost in all browsers, except Safari. Bug founded:
if you set cursor somewhere in text, then before clicking the button to insert chip - click somewhere else on the page just to loose focus and then inset chip - it will appear at the beginning of editor.
Other browsers - absolutely ok!
<ejs-richtexteditor #RTE id="defaultRTE" (blur)="OnBlur()" >
OnBlur() {
this.range = this.rteObj.getRange();
this.saveSelection = this.selection.save(this.range, document);
}
|
Hi there!
This trick doesn't work on Safari, I've already tried it yesterday and have checked once again right now. Safari behaves itself some strange, because when focus is lost - it remembers not that place where cursor was, but where it was clicked after blur event.
onCreate() {
this.listviewEle = document.getElementById('listview');
this.editArea = document.querySelector('#defaultRTE .e-content');
this.rteObj.getContent().addEventListener('click', this.remove.bind(this));
document.addEventListener('mousedown', this.onMouseDown.bind(this));
}
onMouseDown(args) {
if (!args.target.closest('.e-richtexteditor') && !args.target.closest('button')) {
this.range = this.rteObj.getRange();
this.saveSelection = this.selection.save(this.range, document);
}
}
|