json.net object from directory - javascript

Tinymce is a fairly common WYSIWYG editor that allows users to purchase an image/file management system or build your own. I want to upgrade my Content Management system from tinymce 2x to 4x. In 4x the images need to be presented to the tinymce call as a json object in the image_list declaration: http://www.tinymce.com/wiki.php/Configuration:image_list
Based on this format, the goal is to have .Net read the image folder and present the title and value as the filename and 'images/filename' of each file. I've worked at it the past few days and I've made some headway but not to the point of a functional sample. This seems like it would be something that others using .Net and Tinymce would want to use if they roll their own image management system (which I have to do in this case).
This example (see link) seems to get close but my test (see code below) returns null values for the title and value. When I tried to include the other two variables in the example I get error messages that the variables are inaccessible or not available. Converting List of Files into JSON array in C#
Here is the C# script I'm trying to use in creating the JSON variable of image references:
<%# Import Namespace="Newtonsoft.Json" %>
<script runat="server">
public class FileInformation
{
[JsonProperty(PropertyName = "title")]
public string actualFileName {get;set;}
public string value {get;set;}
}
public string image_list()
{
string[] arr = new string[3]; // Initialize
arr[0] = ".jpg"; // Element 1
arr[1] = ".png"; // Element 2
arr[2] = ".gif"; // Element 3
var imgPath = Server.MapPath("~/images/");
var list = new List<FileInformation>();
//string[] fileNames = Directory.GetFiles(imgPath, "*", SearchOption.TopDirectoryOnly);
string[] fileNames = Directory.GetFiles(imgPath);
foreach (string filename in fileNames)
{
FileInfo fileInfo = new FileInfo(filename);
string actualFileName = fileInfo.Name;
string value = fileInfo.Name;
list.Add(new FileInformation(){});
}
var yourJSONString = JsonConvert.SerializeObject(list);
return yourJSONString;
}
...
</script>
Here is the Javascript call in the page:
<script type="text/javascript">
tinymce.init({
image_list: '<%= image_list()%>',
image_class_list: [
{title: 'None', value: ''},
{title: 'Float Right', value: 'img_fright'}
]
});
Abbreviated Source code from the pate where image_list is rendered:
image_list: '[{"title":null,"value":null},{"title":null,"value":null},{"title":null,"value":null}]',
Any thoughts of where this may be going wrong?

Sorry... not quite sure how to edit an answer. This one is a bit more clear an usable with commenting. This one actually filters out specific extensions that you probably want to do and can be used for the documents or media list as well (with some modification). Good luck. I've learned so much here it is good to give back when you can.
public class FileInformation
{
public string title {get;set;}
public string value {get;set;}
}
public string image_list()
{
//Set up the list of acceptible extensions
string[] arr = new string[3]; // Initialize
arr[0] = ".jpg"; // Element 1
arr[1] = ".png"; // Element 2
arr[2] = ".gif"; // Element 3
//Declare the variable
var filePath = "";
//Set the path
filePath = Server.MapPath("~/images/");
//Start the string for the list
var list = new List<FileInformation>();
//Get the filesnames from the path
string[] fileNames = Directory.GetFiles(filePath, "*", SearchOption.TopDirectoryOnly);
//Loop through each of the file names
foreach (string filename in fileNames)
{
//Get the information on the filename
FileInfo fileInfo = new FileInfo(filename);
//Loop through each of extension provided
foreach (var ext in arr) {
//If the extenion on the filename matches one of the list then...
if (fileInfo.Extension == ext) {
//Add the filename and location to the list in the title: filename, value: "images/filename" format
list.Add(new FileInformation(){ title = fileInfo.Name, value = "images/" + fileInfo.Name });
}
}
}
//Convert the list to a JSON string using JSON.net (use the correct framework format)
var yourJSONString = JsonConvert.SerializeObject(list);
//Return the JSON string for use in the javascript call.
return yourJSONString;
}
... And your javascript in the file:
<script src="//tinymce.cachefly.net/4.1/tinymce.min.js"></script>
<script type="text/javascript">
tinymce.init({
selector: "textarea",
theme: "modern",
encoding: 'xml',
convert_urls: false,
removed_menuitems: 'newdocument',
plugins: [
"advlist autolink lists link image charmap print preview hr anchor pagebreak",
"searchreplace wordcount visualblocks visualchars code fullscreen",
"insertdatetime media nonbreaking save table contextmenu directionality",
"template paste textpattern"
],
toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright | bullist numlist outdent indent | link image | print preview media",
content_css: "",
style_formats: [{ title: 'Bold', inline: 'span', classes: 'Bold' },
{ title: 'Italic', inline: 'span', classes: 'Italic' },
{ title: 'Superscript', inline: 'span', classes: 'Superscript' },
{ title: 'Subscript', inline: 'span', classes: 'Subscript' }],
document_base_url: '',
image_list: <%= image_list()%>,
image_class_list: [
{title: 'None', value: ''},
{title: 'Float Right', value: 'img_fright'}
],
cleanup: false,
image_advtab: true,
templates: [
{title: 'Test template 1', content: '<div row><div class="col-md-6">Content</div><div class="col-md-6">Content</div></div>'},
{title: 'Test template 2', content: 'Test 2'}
]
});
I plan to post the code if I write the json to file, as I want to dynamically be able to load and make the templates available to our users. If you have any example feel free to post here. Otherwise Good Luck!

Related

Quill JavaScript Rich Text Editor restrict tags

I'm trying to use Quill JavaScript Rich Text Editor. I need to configure it to use only a predefined tag set:
b, i, pre, a, br + Emoji
Right now I have configured it in the following way:
var Block = Quill.import('blots/block');
Block.tagName = 'PRE';
Quill.register(Block, true);
var quill = new Quill('#editor-container', {
modules: {
toolbar: true
},
theme: 'snow'
});
As you may see I already have changed the wrapper to PRE tag. How to also configure Quill to use the mentioned restricted tag set? No other tags can be allowed and must be automatically removed if present.
Define formats in the parameters of the constructor, there you can define which formats you want to support.
var quill = new Quill('#editor-container', {
formats: ['bold', 'italic', 'code', 'code-block', 'link'],
...
});
Quill works with Delta and formats, not directly with HTML and tags.
You can set the formats config option to limit the allowed formats.
Here is the list of all formats:
formats = [
// 'background',
'bold',
// 'color',
// 'font',
// 'code',
'italic',
// 'link',
// 'size',
// 'strike',
// 'script',
'underline',
// 'blockquote',
// 'header',
// 'indent',
'list',
// 'align',
// 'direction',
// 'code-block',
// 'formula'
// 'image'
// 'video'
];
You can use this to prevent some formats.

How can I send tinyMCE textarea editor content to inside controller using Symfony3 and Ajax

I have two tinyMCE editor with id's like #homepage, #thankyoupage, I want to send tinymce textarea content to inside symfony controller.
This is my front end part:
I am trying to send normal textarea value using jQuery ajax like below but I am getting undefined value.
$(document).ready(function () {
var array_data = {};
array_data['dedline'] = $('#homepage').val();
array_data['homepage'] = $('#thankyoupage').val();
array_data['thankyoupage'] = $('#deadlinetoanswer').val();
$.ajax({
type: 'POST',
url: Routing.generate("invitation"),
contentType: 'application/x-www-form-urlencoded',
data: {
data_array: array_data
},
success: function (result, status, xhr) {
var res = JSON.parse(result);
console.log(res);
},
error: function (xhr, status, error) {
console.log('error1');
}
});
});
This is my form:
$builder->add('deadlinetoanswer', ChoiceType::class, array(
'choices' => array(
'2 days' => 2,
'3 days' => 3,
'5 days' => 5,
'7 days' => 7,
'10 days' => 10,
'15 days' => 15,
'Until' => 'until'
)
));
$builder->add('prerecwelcomemsg', TextareaType::class, array(
'required' => true,
'attr' => array('class' => 'tinymce', 'id' => 'homepage', 'data-theme' => 'bbcode', 'style' => 'height: 380px', 'placeholder' => "Welcome...")
));
$builder->add('prerecthankyoumsg', TextareaType::class, array(
'required' => true,
'attr' => array('class' => 'tinymce', 'id' => 'thankyoupage', 'data-theme' => 'bbcode', 'style' => 'height: 380px', 'placeholder' => "Thank you...")
));
This is my controller:
/**
* #Route("/prerecorded/invitation", name="invitation", options={"expose"=true})
*/
public
function invitationAction(Request $request) {
$em = $this - > getDoctrine() - > getManager();
$form = $this - > createForm(InvitationType::class);
$form - > handleRequest($request);
if ($request - > isXmlHttpRequest()) {
$res_arr = $request - > request - > get('data_array');
// $this->container->get('logger')->addInfo('somesh'.$res_arr);
if ($res_arr) {
$campaignid = 1;
$campaign = $em - > getRepository('TraceBundle:Campaign') - > findOneBy(array('id' => $campaignid));
$campaign - > setDeadlinetoanswer('');
$campaign - > setPrerecwelcomemsg('hello');
$campaign - > setPrerecthankyoumsg('how r u');
$em - > persist($campaign);
$em - > flush();
return new Response(json_encode($campaignid));
}
}
return $this - > render('TraceBundle:Campaign:invitation.html.twig', array(
'form' => $form - > createView(),
));
}
and my config.yml
stfalcon_tinymce:
include_jquery: true
tinymce_jquery: true
selector: ".tinymce"
# base_url: "http://yourdomain.com/" # this parameter may be included if you need to override the assets_base_urls for your template engine (to override a CDN base url)
# Get current language from the parameters.ini
language: %locale%
# Custom buttons
tinymce_buttons:
stfalcon: # Id of the first button
title: "Stfalcon"
image: "http://stfalcon.com/favicon.ico"
theme:
# Simple theme: same as default theme
simple: ~
# Advanced theme with almost all enabled plugins
advanced:
plugins:
- "advlist autolink lists link image charmap print preview hr anchor pagebreak"
- "searchreplace wordcount visualblocks visualchars code fullscreen"
- "insertdatetime media nonbreaking save table contextmenu directionality"
- "emoticons template paste textcolor"
toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
toolbar2: "print preview media | forecolor backcolor emoticons | stfalcon | example"
image_advtab: true
templates:
- {title: 'Test template 1', content: 'Test 1'}
- {title: 'Test template 2', content: 'Test 2'}
# BBCode tag compatible theme (see http://www.bbcode.org/reference.php)
bbcode:
plugins: ["bbcode, code, link, preview"]
menubar: false
toolbar1: "styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist "
This is first time I am working tinyMCE editor, really I am not sure where I am doing wrong. Please help me anyone and let me know is there any extra information is needed.
Thanks in advance
1. Setting a custom id attribute in the form builder won't work.
There are two ways to fix that:
Don't change the default id
In your script, use the default id attributes, generated by Symfony. For simple properties it's the name of the form and the name of the field separated by an underscore, so you can target your fields this way (selector 'id ends with'):
array_data['homepage'] = $('[id$="_prerecwelcomemsg"]');
array_data['thankyoupage'] = $('[id$="_prerecthankyoumsg"]').val();
array_data['deadlinetoanswer'] = $('[id$="_deadlinetoanswer"]').val();
(*) check the id attributes generated in the rendered html page to be sure.
(**) notice that you swapped the fields in your script, setting array_data['dedline'] to $('#homepage').val().
If you really need to change the id attributes:
You can do it in the template when you render the fields with:
{{ form_row(form.prerecwelcomemsg, { 'id': 'homepage' }) }}
2. You have to use TinyMCE's methods to get the edited content.
For this, either:
Call tinyMCE.triggerSave(); before getting the fields value the way you do.
Or get the content with tinyMCE.get('fieldFullId').getContent();

tinymce remove span when submitting prism.js

So far when I open prism.js in tinymce text editor, it appears fine, it highlights the code, of course because when I inspect, the tag <span> exist inside the <pre> tag. The problem is, when submitted, the <span> tags don't follow any more. They just disappear. What's wrong? Is it famous unsolved problem of prism.js as tinymce plugin? Or am I missing something? I just need the <span> to be there when submitted. That's all.
Please help. Thanks in advance.
/------------- for clarity, here is the plugin code ---------------------/
tinymce.init({
selector: '.content_textarea',
plugins: 'advlist autolink link image lists charmap print preview codesample emoticons',
toolbar: 'undo redo | styleselect | bold italic | numlist bullist | codesample | link image | emoticons',
link_class_list: [
{title: 'None', value: ''},
{title: 'Demo', value: 'btn demo'},
{title: 'Download', value: 'btn download'}
],
codesample_languages: [
{text: 'HTML/XML', value: 'markup'},
{text: 'JavaScript', value: 'javascript'},
{text: 'CSS', value: 'css'},
{text: 'PHP', value: 'php'},
{text: 'Ruby', value: 'ruby'},
{text: 'Python', value: 'python'},
{text: 'Java', value: 'java'},
{text: 'C', value: 'c'},
{text: 'C#', value: 'csharp'},
{text: 'C++', value: 'cpp'}
],
valid_elements: "*[*]",
image_dimensions: false,
image_title: true,
image_caption: true,
// enable automatic uploads of images represented by blob or data URIs
automatic_uploads: true,
// URL of our upload handler (for more details check: https://www.tinymce.com/docs/configure/file-image-upload/#images_upload_url)
images_upload_url: base_url()+'admin_crud/img-upload-tinymce',
// here we add custom filepicker only to Image dialog
file_picker_types: 'image',
// and here's our custom image picker
file_picker_callback: function(cb, value, meta) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
// Note: In modern browsers input[type="file"] is functional without
// even adding it to the DOM, but that might not be the case in some older
// or quirky browsers like IE, so you might want to add it to the DOM
// just in case, and visually hide it. And do not forget do remove it
// once you do not need it anymore.
input.onchange = function() {
var file = this.files[0];
var orig_filename = this.files[0].name;
orig_filename = remove_ext(orig_filename);
// Note: Now we need to register the blob in TinyMCEs image blob
// registry. In the next release this part hopefully won't be
// necessary, as we are looking to handle it internally.
var id = orig_filename + (new Date()).getTime();
var blobCache = tinymce.activeEditor.editorUpload.blobCache;
var blobInfo = blobCache.create(id, file);
blobCache.add(blobInfo);
// call the callback and populate the Title field with the file name
cb(blobInfo.blobUri(), { title: remove_ext(file.name) });
};
input.click();
}
});
Those tags are added by Prism. TinyMCE calls Prism and when you add, edit or view your content inside of TinyMCE you will see the code highlighting. Viewing outside of TinyMCE results in not seeing the code highlights, this is because Prism has not been called.
In order for your code to look like what you saw inside of TinyMCE, you need to add
Prism.highlightAll()
or a variation of it depending on your use case on your page that does not call TinyMCE. See here: https://prismjs.com/extending.html#api

lost "this" in callback from tinymce

I have an angular2 app with tinyMce as a HTML editor. The only problem is, I need to convert the URLs in the html through my REST API. To do that I attempted to use "urlconverter_callback" from tinyMce, but I loose the reference to this and get stuck:
ngAfterViewInit(): void {
console.log('tinymce');
tinymce.init({
selector: `[data-tinymce-uniqueid=${this.uniqueId}]`,
theme: "modern",
skin: 'light',
height: 768,
toolbar: 'undo redo | styleselect | bold italic | link image | code',
plugins: 'code',
schema: 'html5',
urlconverter_callback: this.urlConverter,
setup: ed => {
ed.on('init', ed2 => {
if (this.innerValue) ed2.target.setContent(this.innerValue.text);
this.init = true;
});
}
});
// I chose to send an update on blur, you may choose otherwise
tinymce.activeEditor.on('blur', () => this.updateValue());
}
urlConverter(url, node, on_save): string {
console.log("TinyDirective.urlConverter(%o, %o, %o)", url, node, on_save);
console.log("TinyDirective.urlConverter: this = %o", this);
console.log("TinyDirective.urlConverter: this.innerValue = %o", this.innerValue);
return this.innerValue.url_converter(url);
}
From the console I can see, that this is no longer pointing to my directive. As a result I can't access the innerValue property.
How can I create a callback that will have a correct reference of my directive?
You can try one of these options:
1) use bind within tinymce.init
urlconverter_callback: this.urlConverter.bind(this)
or within constructor:
constuctor() {
this.urlConverter = this.urlConverter.bind(this);
}
2) use arrow function on the urlConverter method
urlConverter = (url, node, on_save): string => {
...
}
or within tinymce.init
urlconverter_callback: (url, node, on_save) => this.urlConverter(url, node, on_save)

TinyMCE 4 - getContent() not receiving value from dialog input field

For the software I am currently working on I am doing a small little CMS for our internal help documents, but I have been trying to use TinyMCE so that they can easily apply styles that fit our look and feel without needing to understand HTML. I have all of the custom buttons I need working, however I am having trouble with the final custom button.
What we need is a button that will automatically take a word they type as a query string parameter (FindWord?Word=[the input field]) which when clicked on the page later, would pop out a hidden div and anchor to the glossary word. However the getContent() function does not seem to be working for me, and after over 12+ hours of searching, and trying numerous examples, I can't seem to get it to work.
Other details i am not sure are important:
-Using MVC 4 with Razor views, TinyMCE 4 with the TinyMCE.Jquery package.
-This is the input field in question: http://i.imgur.com/wrMoTOP.png
Any help would be great! Thanks!
<script type="text/javascript">
tinyMCE.init({
mode: "specific_textareas",
editor_selector: "mceEditor",
theme: "modern",
plugins: "pagebreak,textcolor,layer,table,save,hr,image,link,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,fullscreen,visualchars,nonbreaking,template,wordcount,code,customcss_1,customcss_2",
menubar: "edit format view table tools",
toolbar: "undo redo print glossaryword | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | outdent alignleft aligncenter alignright alignjustify indent | bullist numlist hr |",
contextmenu: "undo redo | cut copy paste | link | customcss_1 customcss_2 glossaryword |",
height: 500,
setup: function (ed) {
ed.addButton('glossaryword', {
title: 'Query String Parameter',
onclick: function () {
ed.windowManager.open({
title: 'Query String Parameter',
body: [
{ type: 'textbox', name: 'source', label: 'Source' }
],
onsubmit: function (e) {
ed.focus();
ed.selection.setContent('' + ed.selection.getContent() + '');
}
});
}
});
}
});
After messing around awhile longer I realized I was being silly.
setup: function (ed) {
ed.addButton('glossaryword', {
title: 'Query String Parameter',
onclick: function () {
ed.windowManager.open({
title: 'Query String Parameter',
body: [
{ type: 'textbox', name: 'word', label: 'Glossary Word', id: 'popupword' }
],
onsubmit: function (e) {
ed.focus();
ed.selection.setContent('' + e.data.word + '');
}
});
}
});
}

Categories