diff --git a/Gruntfile.js b/Gruntfile.js index 1cc86e548f6deb416ccf5c2325d2222980703d89..4eebc3e6cba7a48a93a7adf2d55da9c8cb6a9a1b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,7 @@ var path = require('path'); module.exports = function (grunt) { + 'use strict'; + var typo3_css = 'extension/Resources/Public/Css/'; var typo3_js = 'extension/Resources/Public/JavaScript/'; var typo3_fonts = 'extension/Resources/Public/fonts/'; @@ -233,6 +235,72 @@ module.exports = function (grunt) { } ] }, + tinymce: { + files: [ + { + cwd: 'bower_components/tinymce/', + src: [ + 'tinymce.min.js' + ], + expand: true, + dest: typo3_js, + flatten: true + }, + { + cwd: 'bower_components/tinymce/', + src: [ + 'themes/*/theme.min.js' + ], + dest: typo3_js, + expand: true, + // Tiny MCE expects the theme js files in ./themes. + flatten: false + }, + { + cwd: 'bower_components/tinymce/', + src: [ + 'skins/**' + ], + dest: typo3_js, + expand: true, + // Tiny MCE expects the theme js files in ./themes. + flatten: false + } + ] + }, + tinymce_devel: { + files: [ + { + cwd: 'bower_components/tinymce/', + src: [ + 'tinymce.min.js' + ], + expand: true, + dest: 'js/', + flatten: true + }, + { + cwd: 'bower_components/tinymce/', + src: [ + 'themes/*/theme.min.js' + ], + dest: 'js/', + expand: true, + // Tiny MCE expects the theme js files in ./themes. + flatten: false + }, + { + cwd: 'bower_components/tinymce/', + src: [ + 'skins/**' + ], + dest: 'js/', + expand: true, + // Tiny MCE expects the theme js files in ./themes. + flatten: false + } + ] + }, eventEmitter: { files: [ { @@ -266,9 +334,7 @@ module.exports = function (grunt) { } }, jshint: { - all: [ - 'javascript/src/*.js' - ] + all: js_sources }, concat_in_order: { debug_standalone: { @@ -356,12 +422,7 @@ module.exports = function (grunt) { }, watch: { scripts: { - files: [ - 'javascript/src/*.js', - 'javascript/src/Helper/*.js', - 'javascript/src/Element/*.js', - 'less/*.less' - ], + files: js_sources.concat(['less/*.less']), tasks: ['default'], options: { spawn: true diff --git a/bower.json b/bower.json index cc214a113df536af97d87a931fe494ec58897b5c..c18c82d62f13be4eaab49032888038d34c666eff 100644 --- a/bower.json +++ b/bower.json @@ -21,6 +21,8 @@ "jqwidgets": "4.2.1", "tablesorter": "jquery.tablesorter#^2.25.6", "eventEmitter": "^4.3.0", - "Chart.js": "^2.1.2" + "bootstrap-validator": "^0.10.2", + "Chart.js": "^2.1.2", + "tinymce": "tinymce-dist#^4.4.3" } } diff --git a/javascript/src/Form.js b/javascript/src/Form.js index 6c7f7cc557bfb812dc9f1bf21e53703a935d2e84..4568d391c23887f064921e70fb53a6ac5aa995dc 100644 --- a/javascript/src/Form.js +++ b/javascript/src/Form.js @@ -71,6 +71,7 @@ var QfqNS = QfqNS || {}; }; n.Form.prototype.submitTo = function (to) { + this.eventEmitter.emitEvent('form.submit.before', n.EventEmitter.makePayload(this, null)); $.post(to, this.$form.serialize()) .done(this.ajaxSuccessHandler.bind(this)) .fail(this.submitFailureHandler.bind(this)); diff --git a/javascript/src/Helper/tinyMCE.js b/javascript/src/Helper/tinyMCE.js new file mode 100644 index 0000000000000000000000000000000000000000..0c2f662624cdb80ffb6129cad2f2f80a58176473 --- /dev/null +++ b/javascript/src/Helper/tinyMCE.js @@ -0,0 +1,59 @@ +/** + * @author Rafael Ostertag <rafael.ostertag@math.uzh.ch> + */ +/* global console */ +/* global tinymce */ +/* global $ */ + +/** + * Qfq Namespace + * + * @namespace QfqNS + */ +var QfqNS = QfqNS || {}; +/** + * Qfq Helper Namespace + * + * @namespace QfqNS.Helper + */ +QfqNS.Helper = QfqNS.Helper || {}; + +(function (n) { + 'use strict'; + + /** + + * @function + * @name QfqNS.Helper.jqxEditor + */ + var tinyMce = function () { + if (!tinymce) { + return; + } + + tinymce.init({ + selector: ".qfq-tinymce", + setup: function (editor) { + editor.on('Change', function (e) { + console.log('Editor was changed'); + var eventTarget = e.target; + var $parentForm = $(eventTarget.formElement); + $parentForm.trigger("change"); + + }); + } + }); + }; + + tinyMce.prepareSave = function () { + if (!tinymce) { + return; + } + + tinymce.triggerSave(); + }; + + n.tinyMce = tinyMce; + + +})(QfqNS.Helper); \ No newline at end of file diff --git a/javascript/src/QfqForm.js b/javascript/src/QfqForm.js index ce33ae820f78de846029f068f7f06e5de74e98f3..fbf4c5b249090ccc9c9e6509270443eb4beb1b8f 100644 --- a/javascript/src/QfqForm.js +++ b/javascript/src/QfqForm.js @@ -86,7 +86,10 @@ var QfqNS = QfqNS || {}; n.Helper.jqxDateTimeInput(); // Initialize jqxComboBox elements. n.Helper.jqxComboBox(); - n.Helper.jqxEditor(); + // Deprecated + //n.Helper.jqxEditor(); + n.Helper.tinyMce(); + this.form.on('form.submit.before', n.Helper.tinyMce.prepareSave); }; n.QfqForm.prototype.on = n.EventEmitter.onMixin; @@ -464,7 +467,7 @@ var QfqNS = QfqNS || {}; if (data.redirect === "url" || data['redirect-url']) { window.location = data['redirect-url']; - return; + } }; diff --git a/mockup/richtexteditor.html b/mockup/richtexteditor.html new file mode 100644 index 0000000000000000000000000000000000000000..4818a806365e98e8b90b93bdd856375b0606970d --- /dev/null +++ b/mockup/richtexteditor.html @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + + <link rel="stylesheet" href="../css/bootstrap.min.css"> + <link rel="stylesheet" href="../css/bootstrap-theme.min.css"> + <link rel="stylesheet" href="../css/qfq-bs.css"> + <title>Rich Text Editor Mock</title> + + +</head> +<body> +<div class="container-fluid"> + <div class="row"> + <div class="col-md-2 "> + <div class="btn-toolbar pull-right" role="toolbar"> + <div class="btn-group" role="group"> + <button id="save-button" type="button" class="btn btn-default navbar-btn"><span + class="glyphicon glyphicon-ok"></span></button> + <button id="close-button" type="button" class="btn btn-default navbar-btn"><span + class="glyphicon glyphicon-remove"></span></button> + </div> + <div class="btn-group" role="group"> + <button id="delete-button" type="button" class="btn btn-default navbar-btn"><span + class="glyphicon glyphicon-trash"></span></button> + </div> + <div class="btn-group" role="group"> + <a id="form-new-button" href="personmock.html?s=badcaffe1" class="btn btn-default navbar-btn"><span + class="glyphicon glyphicon-plus"></span></a> + </div> + </div> + </div> + + </div> + <div class="row hidden-xs"> + <div class="col-md-12"> + <h1>Title with a long text</h1> + </div> + </div> + + + <form id="myForm" class="form-horizontal" action="richtexteditor.html" method="post"> + + <div class="form-group"> + <div class="col-md-2"> + <label for="name" class="control-label">Name</label> + </div> + + <div class="col-md-6"> + <input id="name" name="name" type="text" class="form-control"> + </div> + + </div> + + <div class="form-group"> + <div class="col-md-2"> + <label for="text" class="control-label">Rich Text Editor</label> + </div> + + <div class="col-md-6"> + <textarea id="text" class="qfq-tinymce" name="rte">Input + </textarea> + </div> + + </div> + + <button type="submit">Do</button> + + </form> +</div> + +<script src="../js/jquery.min.js"></script> +<script src="../js/bootstrap.min.js"></script> +<script src="../js/EventEmitter.min.js"></script> +<script src="../js/qfq.debug.js"></script> +<script src="../js/tinymce.min.js"></script> +<script type="text/javascript"> + $(function () { + var qfqPage = new QfqNS.QfqPage({ + tabsId: 'myTabs', + formId: 'myForm', + submitTo: 'richtexteditor.html', + deleteUrl: 'api/' + $("#deleteUrl").val(), + fileUploadTo: 'api/' + $("#uploadTo").val(), + fileDeleteUrl: 'api/' + $("#fileDeleteUrl").val(), + }); + }); +</script> +</body> +</html> \ No newline at end of file