/** * CS-Editor * Stellt die Grundsätzlichen Funktionen des Editors her. * Bindet die einzelnen Editoren bei Aufruf ein. * * Created by CS medien- & kommunikationssysteme. * @author Christian Steinle * @date 30.09.2016 * * @copyright CS medien- & kommunikationssysteme (http://www.steinle-computer.de) */ var CS = new Object({ /** * Standard-Variablen für den Editor */ editorType: '', editorTemplate: '', editorTitle: '', editorName: '', editorHtml: '', editorDataID: 0, editorData: null, editor: null, preventSortStop: false, /** * jQuery-Elemente für den Editor */ pageElement: null, editorConfirmElement: null, layerElement: null, waitingElement: null, titleElement: null, closeElement: null, contentElement: null, editableElement: null, editableHoverClassName: '', sortableElement: null, editorOpenElement: null, editorSortElement: null, editorTrashElement: null, /** * jQuery-Elemente für neue Seiten-Inhalte */ newObjectElement: null, newObjectTitleElement: null, newObjectMinElement: null, newSubLineElement: null, newTextElement: null, newTextImageElement: null, newTextImageTextElement: null, newTextImageImageElement: null, newElementsClass: null, newElementsClassName: '', /** * Initialisiert die Icons und deren Funktionen, die bei $(document).ready gesetzt werden. * onclick Events... werden sonst mehrfach gefeuert */ initPermanentFunctions: function () { /** * Editor Schließen */ CS.closeElement.on('click', function () { CS.closeEditor(); }); /** * Minimieren / Maximieren der Box mit neuen Seiten-Elementen */ CS.newObjectElement.on('click', CS.newObjectMinElement, function (event) { if (!$(event.target).hasClass('glyphicon')) { return; } if (CS.newObjectTitleElement.html() !== ' ') { CS.newObjectTitleElement.html(' '); CS.newObjectMinElement.removeClass('glyphicon-chevron-right'); CS.newObjectMinElement.addClass('glyphicon-chevron-left'); $(this).css({width: 45, height: 42}); } else { CS.newObjectTitleElement.html(csEditorLang.newContent.title); CS.newObjectMinElement.removeClass('glyphicon-chevron-left'); CS.newObjectMinElement.addClass('glyphicon-chevron-right'); $(this).css({width: '', height: ''}); } }); }, /** * Initialisiert den Editor */ initEditor: function () { CS.initElements(); CS.initEvents(); }, /** * Initialisiert die jQuery Elemente * zum Bearbeiten und Einfügen neuer Inhalte */ initElements: function () { CS.pageElement = $('.sortable', '#content'); CS.editorConfirmElement = $('#csEditorConfirm'); /** * Elemente des Editor-Layers */ CS.layerElement = $('#csEditorLayer'); CS.waitingElement = $('#csEditorWaiting'); CS.titleElement = $('#csEditorTitle'); CS.closeElement = $('#csEditorLayerClose'); CS.contentElement = $('#csEditorContent'); CS.editableElement = $('[data-editor]'); CS.editableHoverClassName = 'editableHover'; CS.sortableElement = $('[data-editor]', '.sortable'); CS.editorTitle = CS.titleElement.html(); /** * Elemente für neue Seiten-Inhalte */ CS.newObjectElement = $('#csEditorPageElements'); CS.newObjectTitleElement = $('#csEditorPageElementsTitle', CS.newObjectElement); CS.newObjectMinElement = $('#csEditorPageElementsMin', CS.newObjectElement); CS.newSubLineElement = $('[data-editor="Subline"] h2', CS.newObjectElement); CS.newTextElement = $('[data-editor="Text"] p', CS.newObjectElement); CS.newTextImageElement = $('[data-editor="ImageText"]', CS.newObjectElement); CS.newTextImageTextElement = $('p', CS.newTextImageElement); CS.newTextImageImageElement = $('img', CS.newTextImageElement); CS.newElementsClassName = 'btn btn-default btn-block'; CS.newElementsClass = $('.' + CS.newElementsClassName.replace(/ /g, '.')); /** * Texte und Daten für neue Seiten-Inhalte */ CS.newObjectTitleElement.html(csEditorLang.newContent.title); CS.newSubLineElement.html(csEditorLang.newContent.subline); CS.newTextElement.html(csEditorLang.newContent.text); CS.newTextImageTextElement.html(csEditorLang.newContent.textImage); CS.newTextImageImageElement.attr('src', csEditorParams.imageDimension.image.standardImage); }, /** * Initialisiert die Events für den Editor * - Bearbeitung * - Sortierung * - Einfügen neuer Inhalte * - Speichern * - Abbrechen * - Vor / Zurück */ initEvents: function () { CS.initIcons(); CS.initIconFunctions(); CS.initEditorFunctions(); CS.initNewElementFunctions(); }, /** * Editier-, Sortier- und Lösch-Icons setzen */ initIcons: function () { $('.glyphicon.glyphicon-pencil, .glyphicon.glyphicon-sort, .glyphicon.glyphicon-trash').remove(); CS.editableElement.each(function () { if ($(this).parents('#csEditorPageElements').length > 0) { return true; } var style = (this.dataset.editor === 'Headline' || this.dataset.editor === 'Navigation' || this.dataset.editor === 'Subline') ? ' style="margin-top:24px;"' : ''; $(this).append(''); }); if (CS.sortableElement.length > 1) { CS.sortableElement.each(function () { var style = (this.dataset.editor === 'Subline') ? ' style="margin-top:24px;"' : ''; $(this).append(''); }); } CS.sortableElement.each(function () { var style = (this.dataset.editor === 'Subline') ? ' style="margin-top:24px;"' : ''; $(this).append(''); }); }, /** * Funktionalität auf die Icons legen */ initIconFunctions: function () { CS.editorOpenElement = $('.glyphicon-pencil'); CS.editorSortElement = $('.glyphicon-sort'); CS.editorTrashElement = $('.glyphicon-trash'); /** * Hover Effekte */ CS.editorOpenElement.on('mouseenter', function () { $(this).parent('[data-editor]').addClass(CS.editableHoverClassName); }); CS.editorOpenElement.on('mouseleave', function () { $(this).parent('[data-editor]').removeClass(CS.editableHoverClassName); }); CS.editorSortElement.on('mouseenter', function () { $(this).parent('[data-editor]').addClass(CS.editableHoverClassName); }); CS.editorSortElement.on('mouseleave', function () { $(this).parent('[data-editor]').removeClass(CS.editableHoverClassName); }); CS.editorTrashElement.on('mouseenter', function () { $(this).parent('[data-editor]').addClass(CS.editableHoverClassName); }); CS.editorTrashElement.on('mouseleave', function () { $(this).parent('[data-editor]').removeClass(CS.editableHoverClassName); }); /** * Sortierung der Seiten-Elemente und Einordnen neuer Elemente */ CS.pageElement.sortable({ axis: 'y', forcePlaceholderSize: true, handle: '.glyphicon-sort', placeholder: CS.editableHoverClassName, receive: function (event, ui) { CS.preventSortStop = true; ui.helper.removeAttr('style'); var sortOrder = CS.pageElement.sortable('toArray', {attribute: 'data-element'}); var formData = new FormData(); formData.append('request', 'insertContent'); formData.append('navID', csEditorParams.navID); formData.append('token', csEditorParams.token); formData.append('sortOrder', sortOrder); var returnData = CS.sendRequest(formData, true); if (!isNaN(returnData.responseJSON)) { /** * Arbeiten auf Attributen, data-Elemente funktionieren sonst in der stop-Funktion nicht! */ $(ui.helper).attr('data-id', returnData.responseJSON); $(ui.helper).attr('data-element', $(ui.helper).attr('data-editor') + '_' + returnData.responseJSON); CS.initEditor(); } else { alert('Fehler beim Einfügen des neuen Seiten-Inhalts'); } }, stop: function () { if (CS.preventSortStop === true) { CS.preventSortStop = false; return; } var sortOrder = CS.pageElement.sortable('toArray', {attribute: 'data-element'}); var formData = new FormData(); formData.append('request', 'updateContentSort'); formData.append('navID', csEditorParams.navID); formData.append('token', csEditorParams.token); formData.append('sortOrder', sortOrder); CS.sendRequest(formData); } }); }, /** * Funktionalität im Editor-Layer festlegen */ initEditorFunctions: function () { /** * Editor öffnen */ CS.editorOpenElement.on('click', function () { CS.editorType = $(this).parent('[data-editor]').data('editor'); CS.editorTemplate = CS.editorType.toLowerCase() + '.php'; CS.editorDataID = $(this).parent('[data-editor]').data('id'); CS.editorTitle = CS.titleElement.html(); CS.editorName = CS.editorType.toUpperCase(); CS.titleElement.html(CS.editorTitle.replace('%%editor%%', CS.editorName)); if (CS.callEditor() === false) { return false; } CS.waitingElement.show(); CS.layerElement.show(); }); /** * Dialog vor dem Löschen */ CS.editorConfirmElement.dialog({ autoOpen: false, resizable: false, classes: { 'ui-dialog': 'panel panel-primary', 'ui-dialog-titlebar': 'panel-heading', 'ui-dialog-titlebar-close': 'glyphicon glyphicon-remove', 'ui-dialog-content': 'panel-body', 'ui-dialog-buttonpane': 'panel-footer', }, height: 'auto', width: 400, modal: true, closeOnEscape: true, buttons: [ { text: csEditorLang.button.delete, click: function () { var formData = new FormData(); formData.append('token', csEditorParams.token); formData.append('request', 'deleteContentElement'); formData.append('navID', csEditorParams.navID); formData.append('editorType', CS.editorType); formData.append('editorDataID', CS.editorDataID); var returnData = CS.sendRequest(formData, true); if (!isNaN(returnData.responseJSON) && returnData.responseJSON > 0) { $('div[data-element="' + CS.editorType + '_' + CS.editorDataID + '"]').remove(); $(this).dialog('close'); } } }, { text: csEditorLang['button']['cancel'], click: function () { $(this).dialog('close'); } } ] }); $('.ui-icon-alert', CS.editorConfirmElement).addClass('glyphicon glyphicon-alert'); $('button', '.ui-dialog-buttonset').addClass('btn btn-default'); /** * Löschen von Elementen, danach kommt der Dialog */ CS.editorTrashElement.on('click', function () { CS.editorDataID = $(this).parent().data('id'); CS.editorType = $(this).parent().data('editor'); CS.editorConfirmElement.dialog('open'); }); /** * Zur Sicherheit Funktionen von den Handlern entfernen * Ansonsten werden diese Events mehrfach getriggert, wenn neue Seitenelement hinzugefügt werden */ CS.contentElement.off('click', '.formCancel'); CS.contentElement.off('click', '.formNext'); CS.contentElement.off('click', '.formPrev'); CS.contentElement.off('click', '.formSubmit'); /** * Button zum Absenden der Daten */ CS.contentElement.on('click', '.formSubmit', function () { /** * Update der CKEditor-Instanzen, rückschreiben in die Textareas */ $.each(CKEDITOR.instances, function (key) { CKEDITOR.instances[key].updateElement(); }); var form = document.getElementById('csEditorForm'); var formData = new FormData(form); formData.append('token', csEditorParams.token); var returnData = CS.sendRequest(formData, true); if (!isNaN(returnData.responseJSON) && returnData.responseJSON > 0) { CS.resetEditor(); CS.callEditor(); } else { /** * TODO: Fehlermeldung mit Übersetzung */ alert('Fehler beim Speichern der Daten'); } }); /** * Button zum Abbrechen, schließt den Editor */ CS.contentElement.on('click', '.formCancel', function () { CS.closeEditor(); }); /** * Weiter, benötigt für Editoren mit mehreren Seiten */ CS.contentElement.on('click', '.formNext', function () { var actualInnerSlider = $(this).parents('.csEditorSliderContent'); actualInnerSlider.hide(); actualInnerSlider.next('.csEditorSliderContent').show(); }); /** * Zurück, benötigt für Editoren mit mehreren Seiten */ CS.contentElement.on('click', '.formPrev', function () { var actualInnerSlider = $(this).parents('.csEditorSliderContent'); actualInnerSlider.hide(); actualInnerSlider.prev('.csEditorSliderContent').show(); }); }, initNewElementFunctions: function () { /** * Verschiebbarkeit der Box */ CS.newObjectElement.draggable({ addClasses: false, handle: CS.newObjectTitleElement, stop: function () { CS.newObjectElement.css({ left: 'auto', right: ($(document).innerWidth - CS.newObjectElement.position().left - CS.newObjectElement.innerWidth) }); } }); /** * Hinzufügen neuer Seiten-Inhalte * TODO: Ausblenden nicht vorhandener Neuer Elemente anhand der Konfiguration */ CS.newElementsClass.draggable({ connectToSortable: CS.pageElement, helper: 'clone', start: function (event, ui) { ui.helper.removeClass(CS.newElementsClassName); ui.helper.removeClass(CS.editableHoverClassName); $('div', ui.helper).removeClass(CS.editableHoverClassName); } }); }, callEditor: function () { switch (CS.editorType) { case 'Navigation': CS.editor = Navigation; break; case 'Headline': CS.editor = Headline; break; case 'Subline': CS.editor = Subline; break; case 'Text': CS.editor = Text; break; case 'ImageText': CS.editor = ImageText; break; case 'KeyVisual': CS.editor = KeyVisual; break; default: alert('JavaScript Funktionalität ist für diesen Editoren-Typ (' + CS.editorType + ') noch nicht implementiert!'); return false; break; } if (CS.editor !== null) { CS.fetchHTML(); CS.fetchData(); CS.editor.fillEditorContent(); return true; } }, resetEditor: function () { CS.editor.close(); CS.contentElement.html(''); CS.editorHtml = ''; CS.editorData = null; }, closeEditor: function () { CS.resetEditor(); CS.titleElement.html(CS.editorTitle); CS.editorTitle = ''; CS.editorType = ''; CS.editorTemplate = ''; CS.editorName = ''; CS.editorDataID = 0; CS.editor = null; CS.waitingElement.hide(); CS.layerElement.hide(); location.reload(); }, sendRequest: function (formData, sync) { sync = (sync) ? sync : false; return $.ajax({ url: csEditorParams.backendUrl, data: formData, dataType: 'json', method: 'post', async: !sync, processData: false, contentType: false, error: function (jqXHR, textStatus, errorThrown) { alert(csEditorLang.error.sendData + '\n' + csEditorLang.error.status + '"' + textStatus + '"\n' + csEditorLang.error.errorMessage + '"' + errorThrown + '"'); } }); }, fetchHTML: function () { $.ajax({ url: csEditorParams.editorUrl + csEditorParams.editorVersion + '/templates/' + CS.editorTemplate, data: {lang: csEditorParams.sessionLanguage}, dataType: 'html', method: 'post', error: function () { alert(csEditorLang.error.template + '\n' + CS.editorTemplate); }, success: function (editorHtml) { CS.editorHtml = editorHtml; CS.contentElement.html(editorHtml); } }); }, fetchData: function () { $.ajax({ url: csEditorParams.backendUrl, data: {token: csEditorParams.token, request: 'get' + CS.editorType, ID: CS.editorDataID}, dataType: 'json', method: 'post', error: function (jqXHR, textStatus, errorThrown) { alert(csEditorLang.error.fetchData + '\n' + csEditorLang.error.status + '"' + textStatus + '"\n' + csEditorLang.error.errorMessage + '"' + errorThrown + '"'); }, success: function (editorData) { CS.editorData = editorData; } }); } }); $(document).ready(function () { var body = $('body'); body.prepend(csEditorTemplate); body.append(csEditorPageElements); CS.initEditor(); CS.initPermanentFunctions(); });