Unable to add table option to syncfusion richtexteditor - rich-text-editor

I am using syncfusion ej2 richtexteditor component for asp.net mvc. All tools are working fine but when I add "table" option to the tools it gives error in the console and toolbar does not shows.
Following error appears on the console.
Uncaught TypeError: Cannot read property 'id' of undefined
at e.getObject (constants.js:78)
at e.getItems (constants.js:78)
at e.getToolbarOptions (constants.js:78)
at e.render (constants.js:78)
at e.renderToolbar (constants.js:78)
at e.notify (constants.js:78)
at t.notify (constants.js:78)
at t.render (constants.js:78)
at t.appendTo (constants.js:78)
at Contact:130
Here is my initialization code in the view:
#Html.EJS().RichTextEditor("table").ToolbarSettings(e => e.Items((object)ViewBag.tools)).Value((string)ViewBag.value).QuickToolbarSettings(e => { e.Table((object)ViewBag.table); }).ShowCharCount(true).MaxLength(2000).Render()
Controller code:
public ActionResult Contact()
{
ViewBag.tools = new[] {
"Bold", "Italic", "Underline", "StrikeThrough",
"FontName", "FontSize", "FontColor", "BackgroundColor",
"LowerCase", "UpperCase", "|",
"Formats", "Alignments", "OrderedList", "UnorderedList",
"Outdent", "Indent", "|",
"CreateLink", "Image","table", "|", "ClearFormat", "Print",
"SourceCode", "FullScreen", "|", "Undo", "Redo"
};
ViewBag.table = new[] {
"Rows", "Columns", "tableCellVerticalAlign"
};
ViewBag.value = #"<p>The rich text editor component is WYSIWYG ('what you see is what you get') editor that provides the best user experience to create and update the content.
Users can format their content using standard toolbar commands.</p>
<p><b> Key features:</b></p>
<ul>
<li><p> Provides & lt; IFRAME & gt; and & lt; DIV & gt; modes </p></li>
<li><p> Capable of handling markdown editing.</p></li>
<li><p> Contains a modular library to load the necessary functionality on demand.</p></li>
<li><p> Provides a fully customizable toolbar.</p></li>
<li><p> Provides HTML view to edit the source directly for developers.</p></li>
<li><p> Supports third - party library integration.</p></li>
<li><p> Allows preview of modified content before saving it.</p></li>
<li><p> Handles images, hyperlinks, video, hyperlinks, uploads, etc.</p></li>
<li><p> Contains undo / redo manager.</p></li>
<li><p> Creates bulleted and numbered lists.</p></li>
</ul>";
return View();
}
Can anyone please tell where I am missing the trick.

The support for tables in EJ2 Rich Text Editor control was provided from the version 16.3.21. Refer to the release notes for more information.
You can use a version specific CDN files to ensure it in your end. Refer to the following links:
Script: http://cdn.syncfusion.com/ej2/16.3.21/dist/ej2.min.js
Theme: https://cdn.syncfusion.com/ej2/16.3.21/material.css
To enable tables in the RTE’s toolbar, you need to add it to the toolslist as shown in the following code.
[View]
#Html.EJS().RichTextEditor("default").ToolbarSettings(e => e.Items((object)ViewBag.tools)).Value((string)ViewBag.value).Render()
[Controller]
public ActionResult Index()
{
ViewBag.value = #"<p>The rich text editor is WYSIWYG ('what you see is what you get') editor useful to create and edit content</p>";
ViewBag.tools = new[] { "Bold", "Italic", "Underline", "StrikeThrough",
"FontName", "FontSize", "FontColor", "BackgroundColor",
"LowerCase", "UpperCase", "|",
"Formats", "Alignments", "OrderedList", "UnorderedList",
"Outdent", "Indent", "|",
"CreateTable", "CreateLink", "Image", "|", "ClearFormat", "Print",
"SourceCode", "FullScreen", "|", "Undo", "Redo" };
return View();
}
Make sure that you have included the dependent scripts and theme files in the _layout.cshtml page. For further information, refer to the Getting Started documentation
Sample

I was using "Table" property in ViewBag.tools to render table icon. I needed to add "CreateTable" instead of Table.

Related

CKEditor 5 - Using HTML inside mentions

I have been using mentions in CKEditor 5 to tag certain system variables. A typical tag looks like as:
<span contenteditable="false" class="mention document_variable" style="color:var(--ck-color-mention-text);" data-mention="#ApprovedCosts" data-documentid="185" data-version="-1" data-container="#Variable-tab-textarea" href="javascript:void(0)">
#ApprovedCosts
</span>
When I try to render the following (the idea is to show the variable value when the user clicks preview, while he continues editing):
<span contenteditable="false" class="mention document_variable" style="color:var(--ck-color-mention-text);" data-mention="#ApprovedCosts" data-documentid="185" data-version="-1" data-container="#Variable-tab-textarea" href="javascript:void(0)">
<p>Nice rendered <b>html</b></p>
</span>
CKEditor goes bonkers.
My requirement is to show a nicely formatted variable name inside the tag. I know I can control via CSS, but there could be a situation where I might end-up rendering a small table (if variable points to a data set), etc.
Help will be appreciated.
Cheers.
Generally speaking, CKEditor 5 documentations refrain from going with your basic plain HTML approach, as seen in the comments:
This plugin customizes the way mentions are handled in the editor model and data.
Instead of a classic <span class="mention"></span>,
Within their mentions documentation (by the way, highly suggested to take a look at - it's very well documented with lots of useful examples in case you're stuck!), they're defining a ClassicEditor (to be precise, they want to mimic a chat platform in which you can tag a user and will receive a list of users in return).
ClassicEditor
.create( document.querySelector( '.chat__editor' ), {
extraPlugins: [ Essentials, Paragraph, Mention, MentionLinks, Bold, Italic, Underline, Strikethrough, Link ],
toolbar: {
items: [
'bold', 'italic', 'underline', 'strikethrough', '|', 'link', '|', 'undo', 'redo'
]
},
mention: {
feeds: [
{
marker: '#',
feed: [
{ id: '#cflores', avatar: 'm_1', name: 'Charles Flores' },
[...]
],
itemRenderer: customItemRenderer
[...]
After the mention object is created, they're calling the customItemRenderer function. This infrastructure could nearly identical be copied. For your part the function MentionLinks is important, as you can customize how mentions are handled, i.e. let's take a look at their example:
function MentionLinks( editor ) {
editor.conversion.for( 'upcast' ).elementToAttribute( {
view: {
name: 'a',
key: 'data-mention',
classes: 'mention',
attributes: {
href: true
}
},
model: {
key: 'mention',
value: viewItem => editor.plugins.get( 'Mention' ).toMentionAttribute( viewItem )
},
converterPriority: 'high'
} );
Basically, you can customize all the properties within the MentionLinks function. CKEditor 5 did a good job documenting the mention plugin very hierarchically:
The documentation can be found here.
On a slight off-topic note I noticed your code passage <p>Nice rendered <b>html</b><p> contains little formality issues, i.e. you need to close the <p> tag by assigning a close tag </p>:
<p>Nice rendered <b>html</b></p>
Though I'm pretty sure that's not the error as you're talking about HTML in general and not only this code passage.
I think your main issue is your tags. Your paragraph tags (<p>) don't have a closing tag, only two opening tags. It should be <p>***your text here***</p>. If this doesn't fix the issue, please leave a comment.

CKEditor Prevent block elements ? like (`div,p,h1,h2, etc`)

How can prevent block elements in ckeditor?
I want to don't let to ckeditor to accept block elements.
With prevent enter key i can do this but if i paste some text that's include enter key or several paragraph in ckeditor everything down.
In other word i want a textbox with ckeditor.
Quoting an official weekly blog post:
CKEditor core developer, Olek Nowodziński, was hacking the editor a bit in his spare time and here is the result...
Editable header that does not break with Enter key or pasted multi–line content: https://jsfiddle.net/540ckczt/
var editor = CKEDITOR.inline( 'editor', {
plugins: 'clipboard,floatingspace,toolbar,undo,basicstyles,link',
toolbar: [ [ 'Undo', 'Redo' ], [ 'Bold', 'Italic' ], [ 'Link', 'Unlink' ] ],
// Enter mode ill be set to BR automatically if editor was enabled on some element
// which cannot contain blocks (like <h1 for instance).
// If you want to enable editor on different elements, set BR mode here.
// Read the note below to learn why.
enterMode: CKEDITOR.ENTER_BR,
on: {
instanceReady: function() {
// Remove all "br"s from the data being inputted into the editor.
editor.dataProcessor.dataFilter.addRules( {
elements: {
br: function() {
return false;
}
}
} );
this.editable().on( 'keydown', function( evt ) {
var keystroke = evt.data.getKeystroke();
if ( keystroke == CKEDITOR.SHIFT + 13 || keystroke == 13 ) {
evt.data.preventDefault();
}
} );
}
}
} );
Note that the crucial part of this code is that the ACF filters out the rest of block tags (other than <br>). In the case above the ACF works in an automatic mode where it's configured by the enabled features. And since there's no Format dropdown or any other feature creating blocks, none of them is allowed. Read more in the Advanced Content Filter guide.
I expect that one could ask now: "Why can't we configure ACF to filter out <br>s too?"
The answer is that ACF must be able to normalise blocks which are not allowed to some content, and as CKEditor does not support "no enter" mode officially, it choses between normalising to <p>, <div> or <br>. The decision is made based on the enter mode, so that's why it's important to configure such editor to enter mode BR.

separate ckeditor template for each page

I want to have separate config for ckditor.
For example in page temp1.html i want to have 'links' and in page temp2.html i don't want to have links.
Whats the good config for this?
I think configuration in below code is proper place for do this.
//var editor_data = CKEDITOR.instances.editor1.getData();
$('textarea#editor').ckeditor(
function () {
/* callback code */
},
//configuration
{
toolbar: 'Basic',
language: 'en',
});
You can use config.removePlugins to control the presence of certain plugins, like link (also config.removeButtons). But please note that since CKEditor 4.1, by doing this you restrict the content of the editor associated with the plugin or button (no link plugin or button = no links in the content).
So if you want to share the same content between different templates which use a different sets of plugins you need to explicitly expand config.extraAllowedContent of some editors:
$('#editor-linkless').ckeditor( function() {}, {
removePlugins: 'link',
extraAllowedContent: 'a[href,name,id,target]'
} );
$('#editor-regular').ckeditor();
JSFiddle.
See the official guide about ACF. Also this answer to know more.

CKEDITOR inline and multiple toolbars

I have multiple instances of a CKEDITOR inline on a page.
I want to be able to customise the toolbar for each of these to display different fonts in each of them.
So I have something like the following:
CKEDITOR.disableAutoInline = true;
var editor1 = CKEDITOR.inline(document.getElementById('editable_476'));
CKEDITOR.config.toolbar = [ .....
];
CKEDITOR.config.font_names = 'Helvetica Nueue/Helvetica Nueue';
This works well if I have one, but If I use the same code for another CKEDITOR instance, the font is overwritten.
How do I use different toolbars for different CKEDITOR instances?
Thanks
UPDATE:
CKEDITOR.inline( editable_498, {
toolbar: [
['Bold','Italic','Underline'],
['NumberedList','BulletedList'],
['JustifyLeft','JustifyCenter','JustifyRight'],
['Undo','Redo'],
'/',
['TextColor','Font','FontSize']
],
font_names: 'Helvetica Nueue/Helvetica Nueue';
});
This throws a syntax error:
Uncaught SyntaxError: Unexpected token ;
The line is font_names: 'Helvetica Nueue/Helvetica Nueue';
Use per-instance config:
CKEDITOR.inline( element, {
toolbar: [
...
],
font_names: '...'
});
CKEDITOR.config is something that all instances inherit from. Use config for a specific instance, it'll overwrite global rules from CKEDITOR.config.
See the official configuration guide.

Kendo UI Globalization / Language packs

Kendo UI does not come with localization packs. You can only chose a culture file which will only setup number and date formats, but not the actual texts displayed in the widgets (for example: the pager texts - items per page, next page, etc., the filter menus (Is equal to, etc.), the grid parts (Drag a column here....), etc.)
To localize a widget one must pass, in the individual options of each widget, a bunch of messages to override the messages used by default by Kendo UI. Something like this:
filterable: {
messages: {
info: "Título:", // sets the text on top of the filter menu
filter: "Filtrar", // sets the text for the "Filter" button
clear: "Limpar", // sets the text for the "Clear" button
// when filtering boolean numbers
isTrue: "é verdadeiro", // sets the text for "isTrue" radio button
isFalse: "é falso", // sets the text for "isFalse" radio button
//changes the text of the "And" and "Or" of the filter menu
and: "E",
or: "Ou"
},
operators: {
//filter menu for "string" type columns
string: {
eq: "Igual a",
neq: "Diferente de",
startswith: "Começa com",
contains: "Contém",
endswith: "Termina em"
},
//filter menu for "number" type columns
number: {
eq: "Igual a",
neq: "Diferente de",
gte: "Maior que ou igual a",
gt: "Mair que",
lte: "Menor que ou igual a",
lt: "Menor que"
},
//filter menu for "date" type columns
date: {
eq: "Igual a",
neq: "Diferente de",
gte: "Maior que ou igual a",
gt: "Mair que",
lte: "Menor que ou igual a",
lt: "Menor que"
}
}
},
groupable: {
messages: {
empty: "Arraste colunas aqui para agrupar pelas mesmas"
}
}
Of course you could share this options in a single JavaScript variable, but then you will face an unexpected problem: if you have messages for ALL options of all widgets collected in a single option variable, it will TURN ON all those options for all grids. If you want a grid without grouping you will have to have a separate localized options variable without the groupable or else, even if you don't want, the group will show because the groupable: { messages: { .... } } will make Kendo recognize it as enabled.
It doesn't seem to be any way to localize the controls by including just an extra JavaScript to override those messages as can be seen on Kendo UI forums.
Is there any other way to do that?
(notice that I'll be answering my own question, and I do not suffer from Bipolar Disorder! It is just a way to get the involvement of the community on the kendo-global project!)
The kendo-global project on github makes it easy to localize all localizable texts on all Kendo UI widgets by only including the desired language file like this:
<script src="http://cdn.kendostatic.com/2012.3.1114/js/kendo.all.min.js"></script>
<script src="/js/lang/kendo.pt-BR.js"></script>
It works by overriding the default options on the prototypes of the widgets, so it will work as if those widgets were created natively in the expected language.
Since it doesn't change anything, and don't override any method, you'll still be able to pass customized options with custom messages by using the standard approach if you need a specific message on a individual widget (instead of "10 itens" you may want to show "10 products" in the pager of the grid...)
The project currently has only a few language packs. Translating is very easy and full credits will be given to every and each translator. So contributors are really, really welcome.
The project's page can be found here: https://github.com/loudenvier/kendo-global
I am working with Telerik Controls Q1 2013 SP1.
It looks like you can no longer override the messages for many of the Kendo grid's labels or tooltips. Here is a list of several messages/tooltips that I was not able to override using a kendo-global language file:
ItemsPerPage
First
Previous
Next
Last
I have no good answer to the original question.
It may be worth mentioning that for my purpose the solution was to use the Fluent API
#(Html.Kendo().Grid<Whatever>()
.Name("Grid")
.Pageable(e => e
.Messages(p => p.ItemsPerPage("")
.First("לדף הראשון")
.Previous("לדף הקודם")
.Next("לדף הבא")
.Last("לדף האחרון")
.Refresh("ריענון")
.Display("מציג {0}-{1} מתוך {2} רשומות")
.Page("דף")
.Of("מתוך {0}")))
...
If a more dynamic option is needed I think getting the current localization and initialize the widget would be a good option.
#{
var culture = System.Threading.Thread.CurrentThread.CurrentCulture.ToString();
}
#section HeadContent {
<script src="#Url.Content("~/Scripts/cultures/kendo.culture." + culture + ".min.js")"></script>
}
Here is more documentation about
https://demos.telerik.com/aspnet-mvc/grid/globalization?culture=ru-RU&_ga=2.268933617.1296110429.1575874528-1040251397.1575554475

Resources