CKEditor - how to get the template attributes - javascript

I'm using CKEditor's template plugin to load the templates in the editor. In the templates I've defined likt this.
templates: [
{
title: "Quickclick 1",
image: "template1.png",
description: "Quickclick 1 template",
html_et: "<span>test1</span>",
html:' <span>test</span>'
}]
When the user selects a template, the html is loaded which is fine. But also, it would be great if there is a way to get the property of the current selected template from the CKEditor instance.
I need to get the html_et property value in this case. I didn't find anything in the documentation related to this. Any help would be appreciated.

#Lingasamy Sakthivel that is not how you define templates in CKEditor.
If you want to use templates, you need to create a file like the default one in templates plugin: https://github.com/ckeditor/ckeditor-dev/blob/major/plugins/templates/templates/default.js
NOTE: when defining my test template file, I have named the file my_template.js and have given the same name to template definition CKEDITOR.addTemplates( 'my_templates', {... for simplicity.
Now, Once you have the file ready, you can assign it to editor. To do that you need to specify path to your file (full or relative to context of your application) and definitions that should be loaded.
In the example below I'm loading the default CKEditor file as well as my custom one:
var editor = CKEDITOR.replace( 'editor1', {
language: 'en',
templates_files : [
'/myApp/ckeditor/plugins/templates/templates/default.js',
'/myApp/ckeditor/my_templates.js'
],
templates : 'default,my_templates'
});
This is for files - https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_config.html#cfg-templates_files
This is for definitions - https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_config.html#cfg-templates
Now the hard part. You have written you want to know which template was selected but to be honest I don't know any way in which you could do that except for changing plugin code.
When template definition is loaded, templates inside it are loaded one by one
and assigned an onclick handler. This is IMHO the place we you could add your custom code for getting the html_et property - https://github.com/ckeditor/ckeditor-dev/blob/major/plugins/templates/dialogs/templates.js#L53-L55.
To do that you would need to get the source version of the editor, make changes in template plugin and then building your editor (recommended approach):
https://docs.ckeditor.com/ckeditor4/latest/guide/dev_source.html
https://docs.ckeditor.com/ckeditor4/latest/guide/dev_build.html
Alternatively you can download CKEditor without the templates plugin (can be done using online builder where you can remove templates plugin from your build). Next you need to manually download that plugin, make your changes and add that plugin to editor by dropping plugin folder inside ckeditor/plugins folder and using the extraPlugins setting.

Can you try like this?
var editor = CKEDITOR.replace('editor1', {
templates: [
{
title: "Quickclick 1",
image: "template1.png",
description: "Quickclick 1 template",
html_et: "<span>test1</span>",
html:' <span>test</span>'
}
]
});
alert(editor.config.templates[0].html_et);

Related

Using Material Icons in CKEDITOR

This is kind of an academic question because I've all but given up, but maybe we can learn a few things about CKEditor5 by trying to solve it!
I'm using a pretty bare-bones installation of CKEditor from https://ckeditor.com/ckeditor-5/online-builder with just some basic styling features.
My use case is pretty basic but my users need to enter certain special characters and I want to include support for material icons (from Google)
Something along these lines
If you're not familiar with material icons, they use a special font and some CSS wizardry to display icons similar to font awesome. They are here: https://fonts.google.com/icons?icon.set=Material+Icons they come in two varieties, icons and symbols which are very similar but we're concerned with icons in this case.
The syntax for the icons is
<span class="material-icons-outlined">
emoji_emotions
</span>
and it uses some font wizardry to make that turn into something like
You can also use a single entity such as  to accomplish the same behaviour and it's the option I've opted for in my implementation.
My chosen markup is
<material-icon class='material-icons'></material-icon>
A little redundant I know but I wanted to separate them from just spans.
Anyway, out of the box CKEditor doesn't allow pasting unknown elements and strips it down to just the html entity so you need to add a new schema, something like this
export default function schemaCustomization(editor) {
// Extend schema with custom HTML elements.
const dataFilter = editor.plugins.get('DataFilter');
const dataSchema = editor.plugins.get('DataSchema');
// Inline element
dataSchema.registerInlineElement({
view: 'material-icon',
model: 'materialIcon',
modelSchema: {
inheritAllFrom: '$inlineBlock'
},
attributeProperties: {
copyOnEnter: true,
},
});
// // Custom elements need to be registered using direct API instead of config.
dataFilter.allowElement('material-icon');
dataFilter.allowAttributes({ name: 'element-inline', classes: /^.*$/ });
}
This will register the element with the editor and allow it to be accepted into the document.
Then you add it to your options, alongside the previous htmlSupport plugin and you're good to go!
options = {
toolbar: {
items: [],
},
htmlSupport: {
allow: [
{
name: 'material-icon',
classes: /^.*$/,
},
],
disallow: [
/* HTML features to disallow */
],
},
extraPlugins: [schemaCustomization],
removePlugins: []
};
A lot of documentation I used comes from here: https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/schema.html
However, there's one problem!!
The element remains editable and if someone clicks inside the material-icon tag and starts entering text, it gets messed up.
I need a way to make the material-icon element be somehow self-contained or atomic and only allow a single character inside.
I've been playing around with all kinds of settings but I'm not sure which are the correct ones and where they're even meant to go.
For now I've switched to just using unicode emoji but they really don't look as nice.
I've tried a lot of the settings and options from https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/schema.html and I think there are multiple ways to register these sorts of elements.
I was expecting it to work somehow but the ability to edit within the tags and break the layout is an unintended side effect.
Does anyone have any experience with the latest version of CKEditor and performing these sorts of low-level mechanics? Any help is appreciated!

Is there a way to unit-test unobstrusive jQuery scenarios

I would like to test if certain javascript (using jQuery or any other framework) applied to a certain html code would create certain behaviour on a page. For example:
If I have html (written in a test as a stub)
<div class="order">
<div class="id">15</div>
<div class="client">John</div>
</div>
And I have a js files included (written in a test also):
jquery.js
orders.js (the one I want to test)
And the main part of the test (syntax is imagined)
part 1:
'client'.is 'hidden'
part 2:
'order'.click
'client'.should_be visible
I want the test to pass only if orders.js has this code:
$(function(){
$('.client').hide();
$('.order').click(function(){
$(this).children('.client').show();
});
});
I guess, I can do such things with rspec features or cucumber, but is there any more specific frameworks for such tests? Any help would be appreciated.
There are at least two solutions.
First is jasmine-jquery HTML fixtures. Citation:
The Fixture module of jasmine-jquery allows you to load HTML content
to be used by your tests. The overall workflow is as follows:
In myfixture.html file:
<div id="my-fixture">some complex content here</div>
Inside your test:
loadFixtures('myfixture.html')
$('#my-fixture').myTestedPlugin()
expect($('#my-fixture')).to...
and
Also, a helper method for creating HTML elements for your tests is
provided:
sandbox([{attributeName: value[, attributeName: value, ...]}])
It creates an empty DIV element with a default id="sandbox". If a hash of
attributes is provided, they will be set for this DIV tag. If a hash
of attributes contains id attribute it will override the default
value. Custom attributes can also be set.
And also there is jasmine-fixtures library. Citation:
Let's say you want to write a Jasmine spec for some code that needs to
select elements from the DOM with jQuery:
$('#toddler .hidden.toy input[name="toyName"][value="cuddle bunny"]')
...
jasmine-fixture's affix method lets you do this instead:
beforeEach(function(){
affix('#toddler .hidden.toy input[name="toyName"][value="cuddle bunny"]')
});

DOJO Custom Dialog Box - does not parse template file

I am new to DOJO. I have a custom widget , which uses a template file for the dialog box contents.
I am extending dijit.Dialog in the script file.
dojo.declare(
"custom.credentials",
[dijit._WidgetBase, dijit._Templated,dijit._WidgetsInTemplateMixin,**dijit.Dialog**],
{
templatePath: dojo.moduleUrl("custom", "templates/credentials.html"),
....
....
postCreate: function() {
this.inherited(arguments);
alert(this.containerNode);
alert(this.mainDIV);
},
});
My Template test file looks like this
<div data-dojo-attach-point="mainDIV">
Login Dialog Box template here
</div>
For some reason, when I alert on this.mainDIV, I get 'undefined'. It does not read the template file. Also, this.containerNode gives me 'HTMLDIVElement', (parent dijit dialog DIV).
I am not able to figure out after a lot of trial error where exactly the issue is. Any help would be greatly appreciated.
Calling code
function opnPop(){
var pop= dijit.byId("customPopup");
pop.show();
}
<div dojoType="custom.credentials" id="customPopup"/>
Note : *When dijit.Dialog is not extended* it reads the template file without any problem, I.e, I am able to access this.mainDIV.innerHTML , that contains my own inner html contents.
Thank you.
If Dialog has to be sub-classed, then it must be the base class. Here, it seems that it is used as a mixin. Anyways, the problem is with the template that is used.
The template will be parsed and used by the code in Dialog. So, the template mentioned here has nothing but a div element with an attach point. There is no "containerNode" element (ie. attach point) and you are trying to access it in your js code, which will give error.
More important, the "titleBar" & "titleNode" elements are also missing form template, which will give errors while parsing the template. In order to avoid that, the code part that uses these elements need to be removed from js, to avoid error. So the widget creation will be successful. Try with the standard dijit.Dialog's template.
Add the data-dojo-attach-point="mainDIV" to the top level Dialog's div in the template.
In template, more things can be added, which won't cause any issues. But, if removed anything, will cause problem. If we are sub-classing a class/widget, we need to comply to the existing code.

FineUploader div will not display class

Here's a snippet of code into a :
<div id="manual-fine-uploader"></div>
<div id="triggerUpload" class="button" style="margin-top: 10px;">Save</div>
<script type="text/javascript" src="~/js/fineuploader/fineuploader-3.5.0.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var manualuploader = new qq.FineUploader({
element: $('#manual-fine-uploader')[0],
request: {
endpoint: 'server/handleUploads'
},
autoUpload: false,
text: {
uploadButton: 'Select Files'
}
});
$('#triggerUpload').click(function () {
manualuploader.uploadStoredFiles();
});
});
</script>
As background, I'm using V3.5.0 of FineUploader, and I am using the standalone dependency free version. I've literally just copied this example for the FineUploader dev. I changed the second div to say class="button" (a CSS style I use everywhere in my application). However, no styling occurs. Also where would I put a reference to one of my styles to custom style uploadButton in the javascript?
Thanks.
As you mentioned in the comments, you want to style the "save" button (which you have created) and the "select files" button (which Fine Uploader creates).
As far as the "Save" button is concerned, that is not related to Fine Uploader at all. You have created this button, and it is not a part of Fine Uploader. You can style it however you like via CSS.
Regarding the "Select files" button, you have three options:
Create your own div/anchor/etc element, and pass it to Fine Uploader via the button option. Fine Uploader will add an opaque file input element as a child of this button element. Style your element however you like using CSS.
Create your own CSS (file), targeting the default button created by Fine Uploader's UI module. There are numerous ways to ensure your CSS properties "win", but that is strictly a CSS question, and out of scope here really.
Override the template option. I recommend not going this route. Fine Uploader's template options are brittle and need to be improved in a later version. You can read more about overriding the templates in the first half of the styling readme but, again, I suggest you not do this.
Of the three options above, the first option is the easiest and the one I personally recommend.
It also sounds like you are simply not importing the CSS file that ships with Fine Uploader properly. This is covered in the very first example "Setup" on the demo page/website.

Convert HTML to Sencha

I am very new to sencha and probably do not know how everything you need. I'm trying to extract some contents of an HTML page using ajax. For example, the text in a div with id = "content".
I want to put this content extracted in a panel or container Sencha.
This is the view that I have:
Ext.define("myapp.view.Main", {
extend: 'Ext.tab.Panel',
requires: ['Ext.TitleBar'],
config: {
tabBarPosition: 'bottom',
items: [
{
title: 'Welcome',
iconCls: 'home',
styleHtmlContent: true,
scrollable: true,
html: FUNCTION_TO_GET_CONTENT .join("")
}
]
}
});
I would like to know if there is any way to get the contents of the HTML page displayed in a panel, but I do not know how. Can someone please help me understand this and how I can best address this?
UPDATE:
Basically what I would like to do is to replicate the result of this JQuery statement:
$("#mylocaldiv").load("sourcePage.html #mainDiv");
and then append the result to the html property in the tab panel.
First, add an alias to your view (make sure it's preceded by widget.
Ext.define("myapp.view.Main", {
extend: 'Ext.tab.Panel',
alias: 'widget.Main',
...
});
Then get your view by doing either:
myView = Ext.Viewport.down('Main');
or
myView = Ext.ComponentQuery.query('Main');
Now you can access your items like so:
myView.items.items
And since your panel is the only item, it will be item zero. You can then use it's setHtml method to append html:
myView.items.items[0].setHtml('your html here');
In terms of loading an html file into the panel, I believe Sencha removed Ext.dom.Element.load(). I would use a simple Ajax request and then append the result into the panel in the success callback. See here: load an html file into a panel
sencha is not a good tool for building large applications, so better to choose another one. I was tried it and it sucks my time and no use at all, the windows panels and many more developed using images not with css. if we build large apps with that we may decline the performance of app.

Categories

Resources