/*globals window, define*/ /*jslint nomen:true, unparam: true*/ /** * Open a dialog to edit custom form fields. * * The `.customformUiCustomform()` method opens a dialog when the element is clicked. The dialog can be used to edit new custom form fields. * The element has to contain two data attributes, data-formfieldid (representing the ID for the form field type, e.g. textarea, select ..) and data-objectid (representing the ID of the existing form field). * * ### Examples * Edit a existing custom form field * * JavaScript: * * * de_epages('.editCustomField').customformUiCustomform({ * width: 800, * height: 400, * languageId: 1, * languages: {'2' : 'English', '1' : 'Deutsch'}, * afterSaveDialog: function (widget, data){ * console.debug(widget, data); * } * }); * * HTML: * * <a href="#" class="editCustomField" data-formfieldid="5094" data-objectid="16211">Feldname</a> * * * @class jQuery.ui.customformUiCustomform * @extends jQuery.widget * * @uses ep * @uses jQuery.dict * @uses jQuery.fn.scrollTo * @uses ep.dict * @uses jQuery.tmpl * @uses jQuery.metaparse * @uses jQuery.ui.widget * @uses ep.ui.dialog * @uses ep.ui.validate * @uses ep.validate * @since 6.15.0 */ /** * @cfg {Integer} [width] An integer representing the width of the dialog. */ /** * @cfg {Integer} [height] An integer representing the height of the dialog. */ /** * @cfg {Integer} [languageId] An integer respresenting the ID of the currently active language. */ /** * @cfg {Object} [languages] A object representing the languages (id-name pairs, e.g. {'2' : 'English', '1' : 'Deutsch'}). */ /** * @cfg {Object} [afterSaveDialog] Callback function which is called after the new form field values were successfully saved. */ /** * See `jQuery.ui.customformUiCustomform` for details. * * @param {Object} [options] A map of additional options pass to the method. * @param {Integer} [width] An integer representing the width of the dialog. * @param {Integer} [height] An integer representing the height of the dialog. * @param {Integer} [languageId] An integer respresenting the ID of the currently active language. * @param {Object} [languages] A object representing the languages (id-name pairs, e.g. {'2' : 'English', '1' : 'Deutsch'}). * @param {Object} [afterSaveDialog] Callback function which is called after the new form field values were successfully saved. * * @method customformUiCustomform * @member jQuery * * @since 6.15.0 */ /* * @copyright © Copyright 2006-2012, epages GmbH, All Rights Reserved. * * @module de_epages.customform.ui.customform * * @revision $Revision: 1.10 $ */ define("de_epages/customform/ui/customform", [ "jquery", "ep", "de_epages", "$dict!../dictionary", "$tmpl!./customform-edit", "$tmpl!./customform-newoption", "jquery/metaparse", "jquery/fn/scrollto", "jquery/ui/widget", "ep/validate", "ep/ui/dialog", "ep/ui/validate" ], function ($, ep, de_epages, customformDict, tmplCustomformEdit, tmplCustomformNewoption) { 'use strict'; /* * @dictionary ep.dict * * @translation {Type} * {MandatoryStar} * {yes} * {no} * {Apply} * {Cancel} * * @dictionary de_epages.customform.dictionary * * @translation {FieldName} * {MandatoryForUsers} * {AdditionalFormFieldText} * {EditFormField} * {HeaderRadioOptions} * {HeaderSelectOptions} * {AddFormFieldOption} * {NewOption} */ var translationsDialog = { tType: customformDict.translate('Type'), tYes: customformDict.translate('yes'), tNo: customformDict.translate('no'), tAdd: customformDict.translate('Apply'), tCancel: customformDict.translate('Cancel'), tTitle: customformDict.translate('EditFormField'), tFieldName: customformDict.translate('FieldName'), tMandatoryStar: customformDict.translate('MandatoryStar'), tMandatoryForUsers: customformDict.translate('MandatoryForUsers'), tAdditionalFormFieldText: customformDict.translate('AdditionalFormFieldText'), tHeaderRadioOptions: customformDict.translate('HeaderRadioOptions'), tHeaderSelectOptions: customformDict.translate('HeaderSelectOptions'), tAddFormFieldOption: customformDict.translate('AddFormFieldOption'), tNewOption: customformDict.translate('NewOption') }; $.widget('ui.customformUiCustomform', { // _newOptionCounter: undefined, // ObjectID: undefined, // default options options: { ViewAction: 'JSONGetFieldData', dialogContentId: 'editDialogContent', isPreview: false, languages: {}, languageId: 1, width: 800, height: 400 }, _create: function () { var self = this, elem = self.element, o = self.options; // get the object ID self.ObjectID = elem.data('objectid'); // get the form field ID self.FormFieldID = elem.data('formfieldid'); // get the mandatory checkbox if (!o.isPreview) { self._mandatoryField = $("input[value=" + self.ObjectID + "][name=IsMandatoryObjectID]"); } // handle click to open dialog to edit form field elem.on('click', function (event) { // remove already existing dialog if ($('#' + o.dialogContentId).length) { $('#' + o.dialogContentId).remove(); } self.dialogContentHolder = ep('<div id="' + o.dialogContentId + '" />'); self.dialogContentHolder.appendTo('body'); // create dialog to edit form field self.dialog = self.dialogContentHolder.uiDialog({ title: translationsDialog.tTitle + ": ", modal: true, width: o.width, height: o.height, position: ['center', $('window').scrollTop() + 30], form: { action: '?', method: 'post', options: { ajax: function (send) { send({ dataType: 'json', data: { ChangeAction: "JSONAlterField", ObjectID: self.ObjectID, ChangeObjectID: self.ObjectID, FormFieldID: self.FormFieldID, FieldClassID: self.FormFieldID } }) .done(function (data, status, jqXHR) { // uncomment next line for debug use //console.log("done:", data); // widget was called from preview if (o.isPreview) { // execute callback if (typeof o.afterSaveDialog === "function") { o.afterSaveDialog(self, data); } } else { // set mandatory checkbox if necessary if (data.IsMandatory !== self._isMandatory) { self._mandatoryField.attr('checked', !self._isMandatory); } // set field name if necessary var rewriteFieldName = data.FieldName || data.Alias; if (self._fieldName !== rewriteFieldName) { $('#alterLink_' + self.ObjectID).html(rewriteFieldName); } } self.dialogContentHolder.uiDialog('close'); }); } } }, open: function () { // get data from server self._getFieldData(); }, buttons: [{ type: "submit", text: translationsDialog.tAdd }, { text: translationsDialog.tCancel, click: function () { ep(this).uiDialog('close'); } }] }); // handle form errors for FieldNames (at least one field is requested) self.form = self.dialog.uiDialog('option', 'form') .on('submit', function (event) { if (self.Alias !== "CaptionFormField") { var elem = $(this), first, isInvalid = true; elem .find('input[name=FieldName]') .each(function (i) { var input = ep(this); // remember first input if (i === 0) { first = input; } // if a not empty input was found -> mark as valid and leave each if (input.val() !== "") { isInvalid = false; return false; } }); if (isInvalid) { first .uiValidate({required: true}) .trigger('focus') .trigger('validate'); event.preventDefault(); } else { first .uiValidate({required: false}) .trigger('validate'); } } }); }); }, _getFieldData: function () { var self = this, o = self.options; ep.ajax({ dataType: 'json', data: { ViewAction: o.ViewAction, ObjectID : self.ObjectID } }) .done(function (data) { self.Alias = data.Alias; // mandatory on start up self._isMandatory = parseInt(data.IsMandatory, 10); if (!o.isPreview) { // check if mandatory value from document is the same as the requested one self._isMandatory = (self._mandatoryField.is(':checked') === !!self._isMandatory) ? self._isMandatory : [1, 0][self._isMandatory]; } data.IsMandatory = self._isMandatory; // get the fieldname for the custom form field (for default language) $.each(data.LocalizedTexts, function (key, value) { if (o.languageId === value.LanguageID) { self._fieldName = value.FieldName; return false; } }); // save original data self.currentData = data; // process request data self._processFieldData(data); }) .fail(function (xhr, status, error) { // ToDo: something more // console.warn(error); return; }); }, _processFieldData: function () { var self = this, elem = self.element, o = self.options; if (self.dialog === undefined) { self.dialog = self.dialogContentHolder.uiDialog(); } // extend currentData with additional attributes as default language id, type name and language object (key == languageId) $.extend(self.currentData, { languageId: o.languageId, alias: self.currentData.NameOrAlias[o.languageId], languages: o.languages }); // complete dialog title with field name var fieldname = (elem.closest('dl')[0] && elem.closest('dl').data('fieldname')) ? elem.closest('dl').data('fieldname') : undefined; fieldname = (fieldname === undefined) ? elem.text() : fieldname; self.dialog.uiDialog('option', 'title', self.dialog.uiDialog('option', 'title') + " " + fieldname); // append necessary template to dialog tmplCustomformEdit($.extend(self.currentData, translationsDialog)).appendTo(self.dialogContentHolder); // resolve metaparse parts in dialog ep('#' + o.dialogContentId + ' *').metaparse(); // if custom form field needs handling for options if (self.currentData.HasOptions) { // initialize counter for new options self._newOptionCounter = 0; // get DOM element which holds all options (new options get the class "epCustomFormAddNewOption") self.optionsHolder = self.dialog.find('.epCustomFormOptions'); // delete options self.optionsHolder.find('a[data-deleteoptionid]').on('click', function (evt) { var _this = $(this), form = $(this).closest('form'), hidden = $('<input type="hidden" name="DeleteOptionID" value="' + _this.data('deleteoptionid') + '" />'); // fade out parent table row _this.closest('li').fadeOut(); // add hidden input containing delete information (send and deleted when "Save" is pressed) hidden.appendTo(form); // prevent default action for preview if (o.isPreview) { evt.preventDefault(); } }); // delete new added options self.optionsHolder.on('click', 'a.deleteNewOptionLink', function (evt) { var _this = $(this); // fade out parent table row _this.closest('li').slideUp(500, function () { $(this).remove(); }); // prevent default action for preview if (o.isPreview) { evt.preventDefault(); } }); // get DOM element to add a new option and set an event handler self.newOptionLink = self.dialog.find('#addNewOptionLink'); self.newOptionLink.on('click', function (evt) { self._handleNewOption(); }); } }, _handleNewOption: function () { var self = this; // increment new option counter self._newOptionCounter++; // append template for new option to dialog tmplCustomformNewoption(self.currentData, {count: self._newOptionCounter}).appendTo(self.optionsHolder); var lastOptionElement = self.optionsHolder.children(':last'); // fade new option element in lastOptionElement.fadeIn(500, function () { // resolve metaparse parts in template ep(lastOptionElement.find('input')).metaparse(); // move next animation to another thread window.setTimeout(function () { // scroll down to last option element self.optionsHolder.scrollTo(lastOptionElement, 800); }, 1); }); } }); return de_epages; });