Why delete does not work on CKEDITOR when selected? - ckeditor

I'm having a inline editable div. I can type, delete, add. Works great. I wanted the text within he div to be selected on focus (or if you click it). So I added the following to the code
var editor = CKEDITOR.instances.div#{attr};
var element = editor.document.getById('div#{attr}');
editor.getSelection().selectElement( element );
This works too. Fully selected on focus. However, if I press the delete key or any other character key to overwrite the programmatically selected text, it doesn't change. It's as if more than only the text is selected, and the browser doesn't let me delete it. If I select the text manually, it works.

The selection#selectElement method will start selection before passed element and end after it. This means that not only editable's content will be selected but also non-editable parts of contents outside it and therefore selection may not be editable.
This is a correct solution:
var editor = CKEDITOR.instances.editable,
el = CKEDITOR.document.getById( 'editable' ),
range = editor.createRange();
editor.focus();
range.selectNodeContents( el );
range.select();
But the easiest solution is to use selectAll command defined in selectall plugin:
editor.execCommand( 'selectAll' );

Related

How could I go about disabling the enter key whilst inside th tags for ckeditor 4?

Whenever a user creates a table in ckeditor 4 and presses the enter key whilst inside a table header (th) it creates a new paragraph. A paragraph inside a th is invalid HTML. Ideally I'd like to disable the enter key whenever the cursor is inside a th.
I'm aware of the enterMode config (changing it to a br or a div instead of a paragraph when enter is pressed) but that doesn't really solve the problem.
I guess I need to hook into the keypress event and then check which element type is the parent of the element in which the cursor is residing? But I'm not sure how to do that.
There is a similar question here but I'm specifically looking to disable the enter key in a particular scenario not just entirely. ckeditor turn off enter key
Any help appreciated, thanks.
I've figured this out, seems to work as I desired:
CKEDITOR.instances.editor1.on('key', function(event) {
var enterKeyPressed = event.data.keyCode === 13;
var isTH = CKEDITOR.instances.editor1.getSelection().getStartElement().$.nodeName === 'TH';
var parentisTH = CKEDITOR.instances.editor1.getSelection().getStartElement().$.parentNode.nodeName === 'TH';
if(enterKeyPressed && isTH || enterKeyPressed && parentisTH) {
event.cancel();
}
});

How to set focus and open the grid cell editor of a newly inserted row in vaadin 8 grid?

Is it possible to focus and open the grid cell editor directly after inserting a new row? I have searched a while but I didn't find anything helpful.
I am inserting rows with
grid.setItems(theListWithItems);
After the insertion the editor is closed and I have to double click the row to edit it.
I want the editor opens immediately after inserting the new row.
Any help is highly apreciated.
Thanks in advance
Since Vaadin 8.2 you can now call editRow() on the grid editor
grid.getEditor().editRow(theListWithItems.size() -1);
to open the editor for the newly inserted item. But there is no focus on it, you still have to click (once, no doubleclick) into the column that you wish to edit.
However, the row is not focused only by calling editRow(). To focus a certain column I have not found a simple function for it, but I have found a way to do it nevertheless:
Each column needs a defined Editor-Component (i.e. a TextField). For the column that you want to be initially focused, define a memberfield so it can be accessed when you add a new item. Then - after you call editRow() - you can call focus() on that Editor-Component.
private TextField fooEditorTextField = new TextField();
private createGrid(){
// create your grid as usual
// define Editor components for grid
grid.getEditor().setEnabled(true);
grid.getColumn("Foo").setEditorComponent(fooEditorTextField );
grid.getColumn("Bar").setEditorComponent(new TextField());
}
private void addNewItemToGrid(){
MyItem newItem = new MyItem();
theListWithItems.add(newItem);
grid.setItems(theListWithItems);
// open editor for new Item
grid.getEditor().editRow(theListWithItems.size() -1);
// Focus the "Foo" column in the editor of the new item
fooEditorTextField.focus();
}

How to indent the first line of a paragraph in CKEditor

I'm using CKEditor and I want to indent just the first line of the paragraph. What I've done before is click "Source" and edit the <p> style to include text-indent:12.7mm;, but when I click "Source" again to go back to the normal editor, my changes are gone and I have no idea why.
My preference would be to create a custom toolbar button, but I'm not sure how to do so or where to edit so that clicking a custom button would edit the <p> with the style attribute I want it to have.
Depending on which version of CKE you use, your changes most likely disappear because ether the style attribute or the text-indent style is not allowed in the content. This is due to the Allowed Content Filter feature of CKEditor, read more here: http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter
Like Ervald said in the comments, you can also use CSS to do this without adding the code manually - however, your targeting options are limited. Either you have to target all paragraphs or add an id or class property to your paragraph(s) and target that. Or if you use a selector like :first-child you are restricted to always having the first element indented only (which might be what you want, I don't know :D).
To use CSS like that, you have to add the relevant code to contents.css, which is the CSS file used in the Editor contents and also you have to include it wherever you output the Editor contents.
In my opinion the best solution would indeed be making a plugin that places an icon on the toolbar and that button, when clicked, would add or remove a class like "indentMePlease" to the currently active paragraph. Developing said plugin is quite simple and well documented, see the excellent example at http://docs.ckeditor.com/#!/guide/plugin_sdk_sample_1 - if you need more info or have questions about that, ask in the comments :)
If you do do that, you again need to add the "indentMePlease" style implementation in contents.css and the output page.
I've got a way to indent the first line without using style, because I'm using iReport to generate automatic reports. Jasper does not understand styles. So I assign by jQuery an onkeydown method to the main iframe of CKEditor 4.6 and I check the TAB and Shift key to do and undo the first line indentation.
// TAB
$(document).ready(function(){
startTab();
});
function startTab() {
setTimeout(function(){
var $iframe_document;
var $iframe;
$iframe_document = $('.cke_wysiwyg_frame').contents();
$iframe = $iframe_document.find('body');
$iframe.keydown(function(e){
event_onkeydown(e);
});
},300);
}
function event_onkeydown(event){
if(event.keyCode===9) { // key tab
event.preventDefault();
setTimeout(function(){
var editor = CKEDITOR.instances['editor1'], //get your CKEDITOR instance here
range = editor.getSelection().getRanges()[0],
startNode = range.startContainer,
element = startNode.$,
parent;
if(element.parentNode.tagName != 'BODY') // If you take an inner element of the paragraph, get the parentNode (P)
parent = element.parentNode;
else // If it takes BODY as parentNode, it updates the inner element
parent = element;
if(event.shiftKey) { // reverse tab
var res = parent.innerHTML.toString().split(' ');
var aux = [];
var count_space = 0;
for(var i=0;i<res.length;i++) {
// console.log(res[i]);
if(res[i] == "")
count_space++;
if(count_space > 8 || res[i] != "") {
if(!count_space > 8)
count_space = 9;
aux.push(res[i]);
}
}
parent.innerHTML = aux.join(' ');
}
else { // tab
var spaces = " ";
parent.innerHTML = spaces + parent.innerHTML;
}
},200);
}
}

How to I focus on an element after it is added in CKEditor?

I am using CKEditor 4.4.1 with CKEDITOR.config.enterMode set to ENTER_P.
I am adding a new paragraph programmatically and then moving the cursor to the new element:
var element = new CKEDITOR.dom.element('p', editor.document);
element.appendBogus();
var range = editor.createRange();
range.setStartAt(referenceNode, CKEDITOR.POSITION_AFTER_END);
range.collapse(true);
editor.editable().insertElement( element, range );
range.moveToElementEditStart( element );
editor.getSelection().selectRanges( [ range ] );
This creates and inserts the element in the correct place. However, for some reason, the cursor is not placed in the newly created element.
Why is this happening?
Because I was using a elements that were not part of CKEditor to trigger the insertion, the CKEditor instance was losing focus.
In addition to the code above, I also had to do editor.focus().

jqGrid inline delete: selected row "selrow" is incorrect

I have a in-line delete button, I want to append more data to the delete message pop-up like this:
"Delete selected row with code = 7 ?"
I'm using the following in the delOptions:
beforeShowForm: function ($form) {
var sel_id = $("#list").jqGrid('getGridParam', 'selrow');
$("td.delmsg", $form[0]).html("Delete record with <b>code=" + $("#list").jqGrid('getCell', sel_id, 'cd') + "</b>?");}
The problem is If I click on the delete button without first clicking on any part of the row, the selrow is either null or it gets the previously selected row not the currently selected!
How do I make the row selected when clicking on the trash bin icon?
Any help is appreciated
I suppose that you use the example which I posted in the old answer. It was written in case of usage of the Delete button (the part of form editing) from navigator bar.
There are one hidden row in the Delete dialog which could help you. Try this one
beforeShowForm: function ($form) {
// get comma separated list of ids of rows which will be delete
// in case of multiselect:true grid or just id of the row.
// In the code below we suppose that single row selection are used
var idOfDeletedRow = $("#DelData>td:nth-child(1)").text();
$form.find("td.delmsg").eq(0)
.html("Delete record with <b>code=" +
$(this).jqGrid('getCell', idOfDeletedRow, 'cd') + "</b>?");
// REMARK: in old versions of jqGrid you can't use $(this) and
// will have to use something like $("#list")
}

Resources