I'd like to add an input field in my TinyMCE editor instead of font size picker. This gives more options to the user, and is neater than dropdown imo.
I tried with this
tinymce.PluginManager.add('fontsize', function(editor, url) {
editor.addButton('fontsize', {
text: '',
title: 'Font Size',
body: [
{
type: 'textbox',
name: 'font_size',
label: 'font_size',
value: '',
classes: 'font_size_input',
},
]
});
editor.addCommand('fontsize', function(e) {
var selected_text = editor.selection.getContent({
'format': 'html'
});
var open_span = '<span style="font-size: '+e.data.font_size+';" data-mce-style="font-size: '+e.data.font_size+';">';
var close_span = '</span>';
var return_text = '';
return_text = open_span + selected_text + close_span;
editor.execCommand('mceReplaceContent', false, return_text);
return;
});
});
But this gives me a button. I searched for any sign of addInput but I didn't find it.
Is there a made method for editor, or will I need to create a custom one to show input field (and can this be done in the first place)?
Related
So I'm making my own plugin to the ckeditor, since I need a special case. Anyway, I can't make textarea element editable. This is my whole code to my own dialog (for the plugin):
CKEDITOR.dialog.add('myDialog', function(editor) {
return {
title: 'My Plugin',
minWidth: 750,
minHeight: 500,
onShow: function(evt) {
var selection = editor.getSelection();
var widget = editor.widgets.selected[0];
var element = !!widget && !!widget.parts ? widget.parts['my'] : false;
var command = this.getName();
if(command == 'myDialog') {
var code = selection.getSelectedElement();
if(code && !!element) {
this.setupContent(code);
widget.data.myinput = element.getHtml();
}
}
},
contents: [{
id: 'info',
label: 'Info',
accessKey: 'I',
elements: [{
id: 'myinput',
type: 'textarea',
required: true,
label: 'Content',
rows: 42,
setup: function(widget) {
this.setValue(widget.data.myinput);
},
commit: function(widget) {
widget.setData('myinput', this.getValue());
}
}]
}],
};
});
Problem is only within contents.myinput. It type is textarea but when I open the dialog its not editable. When I change type to the text and remove rows, then text input shows up, working great and so on. Only textarea is problem. This is how it looks like after opening the dialog:
Version of my CKEditor is 4.5. I already made 3 plugins before, but never had to use textarea so all other plugins works except this one. I would append jsFiddle, if there was any site offering "ckeditor plugin tester" so I just post my code.
Problem is that I init ckeditor in the bootstrap's dialog. So the solution for my problem is to apply the following lines of code after initialization:
$.fn.modal.Constructor.prototype.enforceFocus = function() {
var $modalElement = this.$element;
$(document).on('focusin.modal', function(e) {
var $parent = $(e.target.parentNode);
if($modalElement[0] !== e.target
&& !$modalElement.has(e.target).length
&& !$parent.hasClass('cke_dialog_ui_input_select')
&& !$parent.hasClass('cke_dialog_ui_input_text')
&& !$parent.hasClass('cke_dialog_ui_input_textarea')) {
$modalElement.focus();
}
})
};
I had this code before the problem, but I was missing !$parent.hasClass('cke_dialog_ui_input_textarea') which I forget to add, so this was my fault :)
document_table_Settings : function ()
{
return{
rowsPerPage: 5,
showNavigation: 'auto',
showColumnToggles: false,
fields: [
{key: 'para',label: 'Para',sortable: false},
{key: 'desc', label: 'Description',sortable: false},
{
key: 'rowId', label: 'Delete',sortable: false, fn: function (rowId, object) {
var html = "<button name='Del' id=" + rowId + " class='btn btn-danger'>Delete</button>"
return new Spacebars.SafeString(html);
}
},
{
key: 'rowId', label: 'Edit',sortable: false, fn: function (rowId, object) {
var html = "<button name='edit' id=" + rowId + " class='btn btn-warning'>Edit</button>"
return new Spacebars.SafeString(html);
}
}
]
};
}
I want to show description entries having show more and show less feature .As the description is long enough. so after 100 character it shows button to toggle.
If I understand you correctly, you are trying to only show the first 100 characters of the 'Description' column in the Reactive Table and then add some mechanism so that the user can click or rollover to see the entire 'Description' text.
There are a few ways to achieve this and I have provided two options below (in order of simplicity).
For a low tech rollover option, truncate the text to only show the first 100 characters, add an ellipsis (...) to the end of your text, then use the title property in a span element to show the full text on rollover.
First you will need to define a 'truncate' Template helper (I would make this a global helper so that you can use anywhere in your app).
Template.registerHelper('truncate', function(strValue, length) {
var len = DEFAULT_TRUNCATE_LENGTH;
var truncatedString = strValue;
if (length && length instanceof Number) {
len = length;
}
if (strValue.length > len) {
truncatedString = strValue.substr(1, len) + "...";
}
return truncatedString;
});
Then create a new Template for the column.
<template name="field_description">
<span title="{{data.description}}">{{truncate data.description}}</span>
</template>
And finally, change your Reactive Table configuration to use a Template.
fields: [
...,
{ key: 'desc', label: 'Description', tmpl: Template.field_description }
...,
];
For a slightly more complicated option, you can take a similar approach but add a clickable link that would show more or less detail. To get it to work you have to define a few Reactive Vars, define an event handler, and change your 'Description' Template accordingly. Here is a rough solution that should work.
Change your template like so.
<template name="field_description">
<span>{{truncatedDescription}}
{{#if showLink}}
{{linkState}}
{{/if}}
</span>
</template>
Then add the necessary logic to your field_description template (including an event handler).
import { Template } from 'meteor/templating';
import './field-description.html';
Template.field_descirption.onCreated(function() {
const MAX_LENGTH = 100;
this.description = new ReactiveVar(Template.currentData().description);
this.showMore = new ReactiveVar(true);
if (this.description.get().length > MAX_LENGTH) {
this.description.set(Template.currentData().description.substr(1, MAX_LENGTH));
}
this.showLink = () => {
return Template.currentData().description.length > MAX_LENGTH;
};
this.toggleTruncate = () => {
if (this.showMore.get()) {
this.description.set(Template.currentData().description);
this.showMore.set(false);
} else {
this.description.set(Template.currentData().description.substr(1, MAX_LENGTH));
this.showMore.set(true);
}
};
});
Template.field_descirption.helpers({
truncatedDescription: function() {
return Template.instance().description.get();
},
showLink: function() {
return Template.instance().showLink();
},
linkState: function() {
if (Template.instance().showMore.get()) {
return 'show more';
} else {
return 'show less';
}
};
});
Template.field_descirption.events({
'click .js-more-less'(event, instance) {
instance.toggleTruncate();
},
});
Lastly, make sure your Reactive Table config is still setup to use a Template for the field.
fields: [
...,
{ key: 'desc', label: 'Description', tmpl: Template.field_description }
...,
];
Note that the second option makes use of Meteor's Reactivity to solve the problem. Let me know if you need additional explanation on how the 2nd solution works.
That should do it!
I need to show/hide a particular field in jtable jquery depending upon selection in edit window (updateAction:).
I have tried doing so by css show/hide, but its showing / hiding only input box , and it leaves the title of input, which looks weird.
What i really want is to hide whole "jtable-input-field-container", but just for a particular field/input.
here is the snippet:
fields: {
contentType: {
title: 'Content Type',
list: false,
options: { '1': 'message', '2': 'Image'},
onchange : 'select_function(this)',
edit:true
},
title: {
title: 'Title',
width: '8%',
edit:true
},
message: {
title: 'Message',
width: '8%',
list: true,
edit: true
},
imageurl: {
title: 'image URL',
width: '8%',
edit: true
},
......
}
Here i want , if contentType is set to image, then imageurl field should be shown otherwise hidden, in edit window , which we define under updateAction.
Please help.
I found a solution, which is working fine :).
What I am doing is based on selection, i iterate over all .jtable-input-field-container' , and check if innerText is same as in given in title of field.
Based on that , i hide/show that div.
Iteration can be avoided if you are sure that indexenter code here of field will not change.
Code Snippet:
function select_function(target){
var myselect = target.value;
if(myselect=='1')
{
var data = $('.jtable-input-field-container');
for (j = 0; j< data.length ;j++)
{
console.log(j);
console.log("+"+data[j].innerText+"+");
if (data[j].innerText.indexOf("image URL") != -1)
{
$(data[j]).hide();
console.log(data[j]);
}
}
console.log(data);
}
else
{
var data = $('.jtable-input-field-container');
for (j = 0; j< data.length ;j++)
{
console.log(j);
console.log("+"+data[j].innerText+"+");
if (data[j].innerText.indexOf("image URL") != -1)
{
$(data[j]).show();
console.log(data[j]);
}
}
}
I want to code CKEditor plugin. I have added button on panel and when I press it dialog is shown. In this dialog I can set text and after OK pressed this text inserted to the editor.
But I want add functionality. When I select text in editor and press this button I want see selected text in that dialog field. And after editing and press Ok selected text must be replaced with new one.
Thanks!
This is not 100% working, the first part is working, the final replacement isn't..
CKEDITOR.plugins.add( 'example',
{
init: function( editor )
{
editor.addCommand( 'exampleDialog', new CKEDITOR.dialogCommand( 'exampleDialog' ) );
editor.ui.addButton( 'example',
{
label: 'Insert a Link',
command: 'exampleDialog'//,
//icon: this.path + 'images/icon.png'
} );
CKEDITOR.dialog.add( 'exampleDialog', function( editor )
{
return {
title : 'example Properties',
minWidth : 400,
minHeight : 200,
contents :
[
{
id : 'general',
label : 'Settings',
elements :
[
{
type : 'text',
id : 'mystring',
label : 'text',
commit : function( data )
{
data.text = this.getValue();
}
}
]
}
],
onShow : function() {
//this._ranges = editor.getSelection().getRanges()
var mySelection = editor.getSelection().getSelectedText();
this.setValueOf("general","mystring",mySelection);
},
onOk : function()
{
var data = {};
this.commitContent( data );
var txt = data.text;
editor.insertText(txt); //this is not correct, since selection is being cleared...
}
};
});
}
});
My solution was to simply set it inide the onShow function:
onShow: function () {
this.setValueOf('my-tab-id', 'my-element-id', editor.getSelection().getSelectedText());
// ...
},
Full code skeleton:
(function () {
CKEDITOR.dialog.add('mySelectorDialog', function (editor) {
return {
contents: [
{
id: 'my-tab-id',
label: 'My Tab Label',
elements: [
{
id: 'my-element-id',
type: 'text',
label: 'My Element Label'
}
// ...
]
}
],
onShow: function () {
this.setValueOf('my-tab-id', 'my-element-id', editor.getSelection().getSelectedText());
// ...
},
onOk: function () {
// ...
}
// ...
};
});
})();
Having a really hard time figuring this out. I need to submit a form in an ExtJS application and then download the data in a .CSV file. The problem is, the way ExtJS has me submitting the form with "isUpload" the parameters I'm POSTing are being sent as "mulitpart/form-data" and I can't consume them or parse them. I have multiple values of the same input field name.
field: A
field: B
field: C
When I submit for my grids they go over as multiple instances like above. As soon as I introduce "isUpload" to the form they go overs as:
field: A,B,C
My program reads field as "A,B,C" and not three separate instances of field!
Here's my code. Interesting that when I examine in Firebug the Params tab looks correct, but the POST tab has then all in one value.
I just recently added the parameters to the url to try and fake it out!
Ext.Ajax.request({
url : '/cgi-bin/cgijson007.pgm' + '?' + parameters,
form : myForm,
params : parameters,
standardSubmit : true,
isUpload : true
});
isUpload: true only defines that you want to upload a file along with fields, so multipart is correct. To download I recommend you to use a hidden frame. For that use a helper defined within a Namespace.
helper.util.HiddenForm = function(url,fields){
if (!Ext.isArray(fields))
return;
var body = Ext.getBody(),
frame = body.createChild({
tag:'iframe',
cls:'x-hidden',
id:'hiddenform-iframe',
name:'iframe'
}),
form = body.createChild({
tag:'form',
cls:'x-hidden',
id:'hiddenform-form',
action: url,
target:'iframe'
});
Ext.each(fields, function(el,i){
if (!Ext.isArray(el))
return false;
form.createChild({
tag:'input',
type:'text',
cls:'x-hidden',
id: 'hiddenform-' + el[0],
name: el[0],
value: el[1]
});
});
form.dom.submit();
return frame;
}
// Use it like
helper.util.HiddenForm('my/realtive/path', [["fieldname","fieldValue"]]);
If the server answer with a download the save window will popup.
Below is how I handler a post download on a grid listing:
First, I create html form container with hidden filed contains the parameters to post, and also a submit function.
var txtFileId = Ext.create('Ext.form.field.Hidden', { name: 'fid', value: 0 });
var dwFrm = Ext.create('Ext.container.Container', {
autoEl: { tag: 'form', method: 'POST', target: '_BLANK',
action: '/download/files' }, style: { hidden: true },
items: [txtFileId, {
xtype: 'hidden', name: 'userId', value: '1111'
}],
submit: function (fid) {
if (fid) {
txtFileId.setValue(fid);
this.el.dom.submit();
}
}
});
Second, I dock the above component into grid's toolbar
var grid = Ext.create('Ext.grid.Panel', {
.....
dockedItems: [Ext.create("Ext.Toolbar", {
dock: "top", items: [
dwFrm,
{ text: "Download Selected",
handler: function () {
var sm = grid.getSelectionModel();
if (!sm.hasSelection()) return null;
var recs = sm.getSelection();
dwFrm.submit(recs.data.id);
}
}
]
})]
.....
});
This works perfectly. Arrays included.
downloadFile: function (url, params) {
debugger;
var body = Ext.getBody(),
frame = body.createChild({
tag: 'iframe',
cls: 'x-hidden',
id: 'hiddenform-iframe',
name: 'iframe'
}),
form = body.createChild({
tag: 'form',
method: 'POST',
cls: 'x-hidden',
id: 'hiddenform-form',
action: url,
target: 'iframe'
});
for (var i in params) {
if (Ext.isArray(params[i])) {
for (var j = 0; j < params[i].length; j++) {
form.createChild({
tag: 'input',
type: 'hidden',
cls: 'x-hidden',
id: 'hiddenform-' + i,
name: i,
value: params[i][j]
});
}
} else {
form.createChild({
tag: 'input',
type: 'hidden',
cls: 'x-hidden',
id: 'hiddenform-' + i,
name: i,
value: params[i]
});
}
}
form.dom.submit();
return frame;
}