CKEditor: how to reset or reuse instance? - javascript

I have an instance of CKEditor on a content-editing page. I'm looking to re-use or reset a CKEditor instance.
Use case
I have a table of which each cell is editable. When the user clicks a cell, I present them the CKEditor which provides editing functionality.
I'm setting data using CKEDITOR.instances.cellContent.setData( cellContent );
I'm getting data with var cellContent = CKEDITOR.instances.cellContent.getData();
This works well, except the CKEditor still thinks it has the old content after I call a setData()
user clicks cell #1
user edits cell #1, uses the color 'red' on a word
user saves cell #1
user clicks cell #2
now CKEditor shows the color 'red' as being active/used. But in fact it isn't because since that color has been used, other content has been loaded in the editor.
Does anyone know how to reset, reuse or (efficiently) re-instantiating a CKEditor instance?
(Google did not help me on this one)
Thanks for thinking along!
UPDATE 1
I'm using a single editor instance, which will be reused for editing of each table cell. (hidden when inactive, by setting display:none on containing element)
UPDATE 2
I'm using firefox 13.0.1 for Mac. Allthough this color problem does not occur on Chrome, the same issue does happen with the bold/italic buttons.

It's not possible to re-instantiate editor on new element. One instance is bound to one editable for its entire life.
You haven't mentioned how do you initialize editor. For each table cell, because you want to have editors in cells? Or you have one editor, outside the table and you just want to load content of clicked cell there and update it on blur/change/etc.
If you chose the first option, then you have to create editor instance for each table cell. You don't have to do this on page load - it'd be better to do this on cell click. When user leaves the cell you don't have to destroy (editor#destroy) editor - it's better to hide it and reuse for the same cell later.
If you chose the second option, then setData/getData should be enough to refresh editor's UI (buttons states). I checked now and this looks like a bug. Luckily it can be easily fixed by calling editor#focus after setting data - then UI is updated (at least in my quick test). If it won't work, delay focusing, because I was testing this manually from the console, so it was delayed by default.

Related

W2UI Grid selects entire row when clicked, how to select single cell or column for copying?

Running into an issue with the W2UI grid.
Goal: I'd like to be able to select an entire column and copy/paste it to Gsheets. Alternately I'd like to be able to click a single cell and copy it's contents too.
Issue: When clicking it selects the entire row including all irrelevant columns, and copying that includes headers too, meaning it has to be cleaned manually before it can be inserted into a spreadsheet.
The "editable" property allows me to select a single cells contents but even that's not quite what I'm looking for as it required 2 clicks, highlighting text then copying, adding 3-4 button presses to the process.
Can't seem to find the answer on how to fix this in the documentation but I may just be missing something.
Option 1:
You could (temporarily) switch the select type from row (default) to cell.
Just make sure to remove any existing row selection first, otherwise it may look confusing.
Assuming your grid is named grid:
w2ui.grid.selectNone();
w2ui.grid.selectType = 'cell';
w2ui.grid.refresh();
Fiddle: http://jsfiddle.net/yghueLxp/
Option 2:
There's also a new (undocumented) feature to add a copy icon to whole columns - also demonstrated in the linked fiddle, on the first column.
All you have to do is add clipboardCopy: true to the column properties.
For this new feature you'll have to use the dist files of the current github master - it's not available in w2ui 1.5 RC.
By the way, you can make the grid behave similar to an Excel sheet, allowing copy & paste of multiple cells, see: Spreadsheet Like JavaScript Grid
I'd like to be able to [...] paste it to Gsheets
The copied values are TAB separated. This works well when you copy&paste to/from MS Excel. I don't know about Gsheets.

In in-cell edit mode, kendo (sortable) grid values do not update when clicking a different row

In in-cell edit mode, grid values do not update when clicking a different row. The update is only triggered when the user hits enter, when clicking outside of the grid, OR by tabbing/clicking to another cell in the same row. The other examples I've seen don't have this behavior so I'm wondering what I might be doing wrong. This has been an issue for sometime now and it has to be fixed before going live.
I have been able to duplicate the issue in an isolated state. Implementing drag and drop reordering (Kendo Sortable) seems to cause this behavior. Again, the behavior is when you are in an editor, change the value in the editor and click an editor in a different row - you will notice that the value doesn't update. Is this a documented bug? What is your suggested workaround?
Here is a jsfiddle demonstrating the issue:
https://jsfiddle.net/bhr7Lmpy/1/
<script async src="//jsfiddle.net/bhr7Lmpy/1/embed/"></script>
The Telerik Team responded here:
https://www.telerik.com/forums/in-in-cell-edit-mode-grid-values-do-not-update-when-i-click-a-different-row#aIdr3qwkX0aJnnNY9irSJg
You might be able to put a focusout event on the grid cell that programatically presses the enter key or clicks the save button.

CKEditor: Possible to invoke action by double-clicking on text inside editor?

I've googled and found nothing, so here I am. If this is in the CKEditor documentation, I haven't found it there either.
The powers that be want a user to be able to double-click on a piece of text (say, a word) in CKEditor, and have that be able to open up a new HTML element outside of CKEditor (such as a Bootstrap Modal). Is this even possible, and if so, how do I go about it?
For example, I've written a separate "Agenda Builder" which is really just where you pick some stuff from drop downs like the name of a meeting room, how many seats you'll need, etc, and enter some dates and times. That all gets saved to the database. But in the text in CKEditor, they want to be able to double-click on [[agenda]] and have it then open up that feature for the user to create their agenda and save it (an entirely separate thing from CKEditor), and then later I will "insert" the agenda into the document in place of the [[agenda]] tag. Make sense?
Thanks!
I think I manage to find the answers to these after posting the question... here's what I came up with:
editor.on('doubleclick', function(e) {
var element = e.data.element.$.innerText;
if (element =='[[agenda]]' ) {
alert("clicked on agenda");
}
});
We solved this exact scenario by creating a CKEditor Plugin(for our own use). When you highlight a word and select a drop down from the plugin, it edits the element highlighted.
In our scenario we used an Angular directive for the navigation.

Sorting called Muliple times Using igGrid on igDialog Ignite UI Control

I am Using Ignite UI Control I am facing a sorting issue
Let me explain the scenario
I am opening an igDialog and in that dialog box I am opening a Grid view using igGrid which looked like below
Fig(1)
For the first time it working fine now when I click on each column is grid sorting is executed once but when I clicked on the add button the I replace the the dialog contents with the add content now this dialog box will be look like that.
Fig(2)
When click on the cancel button Above it again load the content of listing view and show Fig (1).
The problem I faced is actually when I clicked on any column it called the sorting function twice and it hit my controller action twice.
No of times I go to add view and then back to list view it called sorting multiple times.
Now I don’t know what's happening here ?
Note : I am using $(gridId).igDialog("content", html); to loaded content dynamically
It would be better if you can include the code which handles the view changes inside the dialog. What you're describing sound like grid events are attached multiple times on the same elements. If you're not disposing the grid, or attaching custom events every time it's shown, then this would be the result.
I will update the answer to be more concrete once you include the code in the question.

How to commit changes in a cell from code in slickgrid

I have used custom formatter and editor in slickgrid, which is simply checkbox angular directive. I am using twice the directive, once for formatter, and once for editor. Formatter and Editors are served from angular service. Slickgrid itself is wrapped into an angular directive.
Editors are implemented according to slickgrid doc Writing custom editors
The slickgrid directive is used in several places. One scenario, which I am struggling with, is when there is a grid, and there are buttons outside of grid.
When one clicks one of this button, I have to get the values from cells/editors.
When grid is rendered, once sees checkbox. it is checked/unchecked based on current value of a cell where this formatter is used.
And when one clicked on a cell with checkbox, the checkbox changes from unchecked to checked or vice versa. And then one clickes somewhere else in the grid in the value of editor checkbox copied to cell, and then formatter shows checked/unchecked.
Back to my scenario: when one checkes/unchecks checkbox in editor mode, and directly clickes one of the buttons outside grid, the value of editor is not applied yet to cell, thus the wrong value is send. While we are still in editor mode, and value is not committed.
Now the question, how to commit changes to cell right after the value of checkbox is changed dynamically without waiting for slickgrid to change from editor mode to formatter mode?
Found this question relative, but my environment is not the same.
I found that editor takes args argument which has commitChanges() method, but how to use it?
Best
I have tried a lot of methods of slickgrid, but did not find a better solution but this.
Inside my custom Editor constructor, I have added a watcher that watches changes to checked attribute of Checkbox directive.
$timeout(function () {
controlScope.$watch('checked', function () {
$timeout(function() {
args.grid.getEditController().commitCurrentEdit();
args.grid.resetActiveCell();
});
});
});
The first timeout is not to break the running digest cycle, and just digest it on next run.
And the next timeout is needed to wait until angular is finished with changing scope, and only then commit changes. Otherwise the commitCurrentEdit() will kill the editor, and thus the scope of Checkbox directive.
I hope there will be a better solution.
1 EDIT: This solution brings weird behavior. The first click works good, but the next click on the same cell does not change the checkbox checked.
2 EDIT: I have added resetActiveCell() of grid to leave the focus of active cell, and now it works as I wanted.
3 EDIT: We could not find a better solution without changing the source code of Slickgrid, which is not wished. After searching alternatives and solution for the problem, we decided to use the ui.grid and it plays well with our environment , since we are using angular. And most of the problem we faced with slickgrid, is by default fixed just by using ui.grid without customization. Slickgrid is still of the best grids available for javascript developers, but it seems like it is slowing down from JavaScript progress.
Another solution to commit the change to the grid is call:
Slick.GlobalEditorLock.commitCurrentEdit();

Categories