| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737 |
- /**
- * Save fields to server
- *
- * @param {boolean} [includeAll] if set to true then export all shown or hidden fields
- * @param {function} [callback] Callback for save complete
- * @param {boolean} [force] Force save and ignore changes status
- * @return {Object[]} Field objects list
- */
- function saveFields(includeAll, callback, force)
- {
- if(typeof includeAll === 'function')
- {
- callback = includeAll;
- includeAll = false;
- }
- var fieldsList = [];
- var changedFields = [];
- var revertChanges = function()
- {
- for(var i = 0; i < changedFields.length; ++i)
- {
- changedFields[i].changed = true;
- }
- };
- var errorsCount = 0;
- for(var i = 0; i < fields.length; ++i)
- {
- var originField = fields[i];
- if(originField.changed)
- {
- originField.changed = false;
- changedFields.push(originField);
- }
- if(!includeAll && originField.show !== '1') continue;
- var field = $.extend({}, originField);
- if(originField.errors && originField.errors.$length) errorsCount++;
- field.order = i + 1;
- if(field.id[0] === '_') delete field.id;
- if(field.type === 'decimal')
- {
- field.length = field.integerDigits + ',' + field.decimalDigits;
- }
- delete field.unsaved;
- delete field._options;
- delete field.errors;
- delete field.changed;
- delete field.rules;
- delete field.optionClass;
- if($.isArray(field.options))
- {
- var options = {};
- for(var j = 0; j < field.options.length; ++j)
- {
- var option = field.options[j];
- if(option.value) options[option.value] = option.text;
- }
- field.options = options;
- }
- if($.isArray(field.layoutRules))
- {
- field.layoutRules = field.layoutRules.join(',');
- }
- fieldsList.push(field);
- }
- if(!force && !changedFields.length) return;
- if(errorsCount)
- {
- revertChanges();
- $('#editor').addClass('highlight-errors');
- setTimeout(function()
- {
- $('#editor').removeClass('highlight-errors');
- }, 5000);
- return new $.zui.Messager(window.validateMessages.failSummary.replace('%s', errorsCount),
- {
- type: 'danger',
- icon: 'bell',
- placement: 'center',
- }).show();
- }
- var link = createLink('workflow', 'ui', 'module=' + window.flowModule + '&action=' + window.action + '&groupID=' + groupID);
- $.post(link, {fields: JSON.stringify(fieldsList)}, function(response)
- {
- try {response = JSON.parse(response);}
- catch(error)
- {
- response = response ? response : window.unknownError;
- new $.zui.Messager(response,
- {
- type: 'danger',
- icon: 'bell',
- placement: 'center',
- time: 10000
- }).show();
- revertChanges();
- if(callback) callback(false, response);
- return;
- }
- if(response.result == 'fail')
- {
- if(typeof response.message === 'string') bootbox.alert(response.message);
- else if($.isPlainObject(response.message))
- {
- var errors = {};
- if(response.field) errors[response.field] = response.message;
- else errors = response.message;
- window.updateFieldsErrors(errors);
- }
- revertChanges();
- if(callback) callback(false, response);
- }
- else
- {
- $('#saveBtn').popover(
- {
- trigger: 'manual',
- content: response.message,
- tipClass: 'popover-success popover-form-result',
- placement: 'left'
- }).popover('show');
- setTimeout(function(){$('#saveBtn').popover('destroy')}, 2000);
- if(callback) callback(true, response);
- }
- });
- return true;
- }
- /**
- * Get default options list of specific option type
- *
- * @param {Object} field field object
- * @param {Function} callback callback
- * @return {Object} return default options key-value with a object
- */
- function getDefaultsOfOption(field, callback)
- {
- if(field.options == 'sql' && field.sql == '') return false;
- /* Fetch default options from server, then call callback on ready */
- var sql = window.btoa(encodeURI(field.sql));
- var control = window.btoa(encodeURI(field.control));
- var optionType = field.options;
- var type = field.type;
- var value = window.btoa(encodeURI(field.defaultValue));
- var link = createLink('workflowfield', 'ajaxGetDefaultControl', 'mode=quick&control=' + control + '&optionType=' + optionType + '&type=' + type + '&sql=' + sql + '&sqlVars=&elementName=&default=' + value);
- $.getJSON(link, callback);
- }
- function initDefault(field, isCustomOptions)
- {
- var $fieldDefaultValue = $('#fieldDefaultValue');
- var chosen = $fieldDefaultValue.data('chosen');
- var picker = $fieldDefaultValue.data('zui.picker');
- if($fieldDefaultValue.find('option[value=ajax_search_more]').length == 1)
- {
- $fieldDefaultValue.find('option[value=ajax_search_more]').remove();
- if(chosen) chosen.destroy();
- var control = window.btoa(encodeURI(field.control));
- var optionType = field.options;
- var type = field.type;
- var sql = '';
- var url = createLink('workflowfield', 'ajaxGetMoreDefault', 'mode=advanced&control=' + control + '&optionType=' + optionType + '&type=' + type + '&sql=' + sql + '&sqlVars=&search={search}');
- initPicker($('#fieldDefaultValue'), {remote: url});
- }
- else
- {
- if(picker) picker.destroy();
- if(chosen)
- {
- $fieldDefaultValue.trigger('chosen:updated');
- }
- else
- {
- $fieldDefaultValue.chosen({allow_single_deselect: true});
- }
- }
- }
- /**
- * Get default field properties by control type
- *
- * @param {String} controlType
- * @return {Object}
- */
- function getDefaultFieldByControl(controlType)
- {
- var field =
- {
- type: fieldDefault.type,
- optionClass: fieldDefault.optionClass,
- integerDigits: fieldDefault.integerDigits,
- decimalDigits: fieldDefault.decimalDigits,
- };
- switch(controlType)
- {
- case 'label' :
- field.type = 'mediumint';
- field.optionClass = 'integer';
- break;
- case 'formula' :
- case 'decimal' :
- field.type = 'decimal';
- field.optionClass = 'decimal';
- break;
- case 'integer' :
- field.type = 'int';
- field.optionClass = 'integer';
- break;
- case 'multi-select' :
- case 'checkbox' :
- case 'textarea' :
- case 'richtext' :
- field.type = 'text';
- field.optionClass = 'text';
- break;
- case 'date' :
- field.type = 'date';
- field.optionClass = 'date';
- break;
- case 'datetime' :
- field.type = 'datetime';
- field.optionClass = 'time';
- break;
- }
- return field;
- }
- function removeOptionError(field)
- {
- if(field.errors.options)
- {
- delete field.errors.options;
- field.errors.$length --;
- $('#field-' + field.id).toggleClass('has-error', !!(field.errors && field.errors.$length))
- $('#fieldOptionsMessage').hide();;
- }
- }
- /* https://tc39.github.io/ecma262/#sec-array.prototype.findIndex */
- if (!Array.prototype.findIndex)
- {
- Object.defineProperty(Array.prototype, 'findIndex',
- {
- value: function(predicate)
- {
- if(this == null) throw new TypeError('"this" is null or not defined');
- var o = Object(this);
- var len = o.length >>> 0;
- if(typeof predicate !== 'function') throw new TypeError('predicate must be a function');
- var thisArg = arguments[1];
- var k = 0;
- while(k < len)
- {
- var kValue = o[k];
- if(predicate.call(thisArg, kValue, k, o)) return k;
- k++;
- }
- return -1;
- }
- });
- }
- $(function()
- {
- var isForm = uiMode === 'form';
- var isView = uiMode === 'view';
- var isBatchForm = uiMode === 'batchForm';
- var canSetWidth = uiMode === 'browse' || isBatchForm;
- var canSetPosition = canSetWidth || uiMode === 'view';
- var $previewBox = $('#editorPreview');
- var $preview = $(isForm ? '#uiPreview' : isView ? '#uiViewWrapper' : '#uiListHeader');
- var $infoPreview = isView ? $('#uiInfoViewPreview') : null;
- var $basicPreview = isView ? $('#uiBasicViewPreview') : null;
- var $listPreview = canSetWidth ? $('#uiListPreviewItems') : null;
- var $filedEditForm = $('#filedEditForm');
- var remoteOptions = window.remoteOptions = fieldDefaultOptions || {};
- var hasActionsInList;
- var activedField;
- /* Format options to standart, like [{text: 'Today', value: 'today'}, ...] */
- var formatOptions = function(options)
- {
- if(typeof options === 'string')
- {
- options = options.split(',');
- }
- if($.isArray(options) || $.isPlainObject(options))
- {
- var optionsList = [];
- $.each(options, function(value, text)
- {
- optionsList[text.length ? 'push' : 'unshift']({value: value, text: text});
- });
- options = optionsList;
- }
- return options;
- };
- /* Get keys of a object */
- var getObjectKeys = function(obj, filter)
- {
- var keys = [];
- $.each(obj, function(key)
- {
- if(filter && !filter(key)) return;
- keys.push(key);
- });
- return keys;
- };
- /* Get field index in list by id or field code */
- var getFieldIndex = function(id)
- {
- id = String(id);
- return fields.findIndex(function(field)
- {
- return String(field.id) === id || String(field.field) === id;
- });
- };
- /* Get field object by id or field code */
- var getField = function(id)
- {
- var index = getFieldIndex(id);
- return index > -1 ? fields[index] : null;
- };
- /* Check whether the field is buildin */
- var isBuildInField = function(field)
- {
- return field.buildin === '1' || defaultFields[field.field];
- };
- /* Get field select control type, return 'multi', 'single' or false */
- var getFieldSelectType = function(field)
- {
- if(isBuildInField(field) && field.field !== 'status') return false;
- if(field.control === 'multi-select' || field.control === 'checkbox') return field.options !== 'prevModule' ? 'multi' : 'text';
- else if(field.control === 'select' || field.control === 'radio') return field.options !== 'prevModule' ? 'single' : 'text';
- return false;
- };
- /* Create preview control element for form mode */
- var createFieldControl = function(field, onlyHtml)
- {
- var controlType = field.control;
- var html = '';
- switch(controlType)
- {
- case 'label':
- html = '<p class="form-control-static"></p>';
- break;
- case 'textarea':
- case 'richtext':
- html = '<textarea class="form-control" rows="' + (isBatchForm ? 1 : 3) + '" style="resize:' + (isBatchForm ? 'none' : 'vertical') + '"></textarea>';
- break;
- case 'select':
- html = '<select class="form-control"></select>';
- break;
- case 'multi-select':
- html = '<select class="form-control" multiple></select>';
- break;
- case 'checkbox':
- html = '<div class="checkbox-list"></div>';
- break;
- case 'radio':
- html = '<div class="radio-list"></div>';
- break;
- case 'file':
- html = '<div class="file-input-list"><div class="file-input-empty"><button type="button" class="btn btn-link file-input-btn"><i class="icon icon-plus"></i> ' + window.langAddFile + '</button></div></div>';
- break;
- default:
- html = '<input type="text" class="form-control">';
- }
- return onlyHtml ? html : $(html);
- };
- /* Update field preview control for form mode */
- var updateFieldControl = function($wrapper, field)
- {
- if(field.field === 'file') return;
- var controlType = field.control;
- var readonly = field.readonly;
- var defaultValue = field.defaultValue;
- switch(controlType)
- {
- case 'label':
- $wrapper.find('.form-control-static').text(defaultValue);
- break;
- case 'textarea':
- case 'richtext':
- $wrapper.find('textarea').val(defaultValue);
- break;
- case 'select':
- case 'multi-select':
- var $select = $wrapper.find('select');
- $select.empty();
- defaultValue = ',' + defaultValue + ',';
- if(typeof field.options === 'object')
- {
- $.each(field.options, function(_, option)
- {
- var $option = $('<option></option>').attr('value', option.value).text(option.text);
- if(defaultValue.indexOf(',' + option.value + ',') != -1) $option = $option.prop('selected', 'selected');
- $select.append($option);
- });
- }
- else
- {
- if(field.optionsData)
- {
- $.each(field.optionsData, function(value, text)
- {
- var $option = $('<option></option>').attr('value', value).text(text);
- if(defaultValue.indexOf(',' + value + ',') != -1) $option = $option.prop('selected', 'selected');
- $select.append($option);
- });
- }
- }
- if(!$select.data('chosen')) $select.chosen();
- else $select.trigger('chosen:updated');
- break;
- case 'checkbox':
- case 'radio':
- var $list = $wrapper.find('.' + controlType + '-list');
- $list.empty();
- var name = 'field-' + controlType + '-' + field.id;
- var options = typeof field.options === 'object' ? field.options : [{value: '__example', text: ''}];
- $.each(options, function(_, option)
- {
- var $label = $('<label class="'+ controlType + '-inline"></label>');
- var $option = $('<input type="' + controlType + '">').attr({name: name, value: option.value});
- $label.append($option).append($('<span></span>').text(option.text));
- if(option.value === '__example') $label.find('span').addClass('example-text-holder');
- $list.append($label);
- });
- break;
- case 'date':
- var $input = $wrapper.find('.form-control');
- if(defaultValue == 'currentTime') defaultValue = window.currentDate;
- $input.val(defaultValue).attr('readonly', readonly === '1' ? 'readonly' : null);
- if(!$input.data('datetimepicker')) $input.datepicker();
- break;
- case 'datetime':
- var $input = $wrapper.find('.form-control');
- if(defaultValue == 'currentTime') defaultValue = window.currentTime;
- $input.val(defaultValue).attr('readonly', readonly === '1' ? 'readonly' : null);
- if(!$input.data('datetimepicker')) $input.datetimepicker();
- break;
- default:
- $wrapper.find('.form-control').val(defaultValue);
- }
- };
- /* Update field detail view item for view mode */
- var updateFieldView = function($wrapper, field)
- {
- var $label = $wrapper.find('.field-label');
- $label.text(field.name);
- if(field.position !== $wrapper.closest('.view-dropbox').data('position'))
- {
- var $viewBox = field.position === 'basic' ? $basicPreview : $infoPreview;
- var inserted = false;
- $viewBox.find('.field-view-item').each(function()
- {
- var $field = $(this);
- if(field.order >= $field.data('order'))
- {
- $field.after($wrapper);
- inserted = true;
- return false;
- }
- });
- if(!inserted) $viewBox.append($wrapper);
- }
- };
- /* Update field preview control for list column */
- var updateFieldColumn = function($wrapper, field)
- {
- var $label = $wrapper.find('.field-col-item-label');
- $label.text(field.name);
- $wrapper.css(
- {
- width: field.width,
- textAlign: field.position
- });
- };
- var createListPreviewItem = function(field)
- {
- return isBatchForm ? '<div class="field-col-preview-form">' + (field ? createFieldControl(field, true) : '<input type="text" class="form-control" />') + '</div>' : ('<div class="field-col-preview-view"><div class="example-text-holder" data-size="' + (Math.floor(Math.random() * 8) + 2) + '"></div></div>');;
- };
- /* Update list preview */
- var updateListPreview = function()
- {
- if(!canSetWidth) return;
- var $columns = $listPreview.children('.field-col-preview').addClass('expired');
- var totalWidth = 8;
- $preview.find('.field-col-item').each(function()
- {
- var $colHeader = $(this);
- var colId = $colHeader.data('id');
- var colWidth = $colHeader.outerWidth();
- var $col = $columns.filter('[data-id="' + colId + '"]');
- var field = isBatchForm ? getField(colId) : null;
- if(!$col.length)
- {
- $col = $([
- '<div class="field-col-preview">',
- createListPreviewItem(field), createListPreviewItem(field), createListPreviewItem(field), createListPreviewItem(field), createListPreviewItem(field),
- '</div>'
- ].join('')).attr('data-id', colId);
- }
- $col.css('width', colWidth).removeClass('expired').appendTo($listPreview);
- if(isBatchForm) updateFieldControl($col.find('.field-col-preview-form'), field);
- totalWidth += colWidth;
- });
- $listPreview.css('width', totalWidth);
- $columns.filter('.expired').remove();
- };
- /* Update field preview control */
- var updateField = function(field, relativeField, relativeAsNext)
- {
- var id = field.id;
- var $field = $('#field-' + id);
- if(field.show !== '1')
- {
- if($field.length) $field.remove();
- return;
- }
- if(!$field.length)
- {
- var fieldHtmlLines;
- if(isForm)
- {
- let disabled = (field.field != '' && field.field == flowBelong && action == 'create') ? 'disabled' : '';
- fieldHtmlLines =
- [
- '<div data-field="' + (field.field || '') + '" data-id="' + id + '" id="field-' + id + '" class="field-item">',
- '<div class="field-item-row">',
- '<div class="field-label"></div>',
- '<div class="field-control"></div>',
- '<div class="field-buttons">',
- '<button type="button" class="btn btn-link field-sort-handler" data-type="move"><i class="icon icon-move"></i></button>',
- '<button type="button" class="btn btn-link field-delete-btn" ' + disabled + ' data-type="delete"><i class="icon icon-trash"></i></button>',
- '<button type="button" class="btn btn-link field-copy-btn" data-type="copy"><i class="icon icon-copy"></i></button><button type="button" class="btn btn-link field-error-btn" data-toggle="tooltip"><i class="icon icon-alert text-danger"></i></button>',
- '</div>',
- '</div>',
- '</div>'
- ];
- }
- else if (isView)
- {
- fieldHtmlLines =
- [
- '<div data-field="' + (field.field || '') + '" data-id="' + id + '" id="field-' + id + '" class="field-view-item">',
- '<div class="field-item-row">',
- '<div class="field-label"></div>',
- '<div class="field-value"><div class="example-text-holder"></div></div>',
- '<div class="field-buttons">',
- '<button type="button" class="btn btn-link field-sort-handler" data-type="move"><i class="icon icon-move"></i></button>',
- '<button type="button" class="btn btn-link field-delete-btn" data-type="delete"><i class="icon icon-trash"></i></button>',
- '<button type="button" class="btn btn-link field-copy-btn" data-type="copy"><i class="icon icon-copy"></i></button><button type="button" class="btn btn-link field-error-btn" data-toggle="tooltip"><i class="icon icon-alert text-danger"></i></button>',
- '</div>',
- '</div>',
- '</div>'
- ];
- }
- else
- {
- fieldHtmlLines =
- [
- '<div data-field="' + field.field + '" data-id="' + id + '" id="field-' + id + '" class="field-col-item">',
- '<i class="icon icon-move field-sort-handler"></i>',
- '<span class="field-col-item-label field-sort-handler"></span>',
- '<i class="icon icon-sort text-primary"></i>',
- '<button type="button" class="btn btn-link field-delete-btn" data-type="delete"><i class="icon icon-trash"></i></button>',
- '<button type="button" class="btn btn-link field-error-btn" data-toggle="tooltip"><i class="icon icon-alert text-danger"></i></button>',
- '</div>'
- ];
- }
- $field = $(fieldHtmlLines.join(''));
- if(field.field === 'actions' && !isForm)
- {
- $field.find('.field-col-item-label').removeClass('field-sort-handler');
- }
- if(relativeField)
- {
- var $relativeField = $('#field-' + relativeField.id);
- if($relativeField.length) $relativeField[relativeAsNext ? 'before' : 'after']($field);
- }
- else if(isView)
- {
- $field.find('.example-text-holder').attr('data-size', Math.floor(Math.random() * 10) + 1);
- $field.appendTo(field.position === 'basic' ? $basicPreview : $infoPreview);
- }
- else $field.appendTo($preview);
- $field.find('.field-error-btn').tooltip(
- {
- placement: 'top',
- container: 'body',
- tipClass: 'tooltip-danger',
- html: true,
- title: function()
- {
- if(field.errors && field.errors.$length)
- {
- var messages = [];
- $.each(field.errors, function(key, message)
- {
- if(key[0] === '$') return;
- messages.push(message);
- });
- return messages.join('<br>');
- }
- }
- });
- }
- if(isForm)
- {
- var $control = $field.find('.field-control');
- var controlType = field.control;
- if($control.data('type') !== controlType) {
- $control.data('type', controlType).empty().append(createFieldControl(field));
- }
- updateFieldControl($control, field);
- }
- else if(isView) updateFieldView($field, field);
- else updateFieldColumn($field, field);
- $field.find('.field-label').text(field.name);
- $field.attr('data-order', field.order)
- .attr('data-field', field.field)
- .data('order', field.order)
- .toggleClass('has-error', !!(field.errors && field.errors.$length))
- .toggleClass('active', !!(activedField && activedField.id === id))
- .toggleClass('field-required', (',' + field.layoutRules + ',').indexOf(',' + window.notEmptyRule + ',') > -1);
- updateListPreview(field);
- };
- /* Update showed field list at left of page */
- var updateShowedFields = function()
- {
- var showedFields = [];
- for(var i = 0; i < fields.length; ++i)
- {
- var field = fields[i];
- if(field.show === '0' && !field.unsaved) showedFields.push(field);
- }
- showedFields.sort(function(field1, field2)
- {
- return ('' + field1.name).localeCompare(field2.name);
- });
- var $editorShowedFields = $('#editorShowedFields');
- var $fields = $editorShowedFields.find('.btn').addClass('can-remove');
- for(var i = 0; i < showedFields.length; ++i)
- {
- var field = showedFields[i];
- var $field = $fields.filter('[data-field="' + field.field + '"]');
- if($field.length) $field.removeClass('can-remove').appendTo($editorShowedFields);
- else $('<button type="button" class="btn btn-field-control" data-field="' + field.field + '">' + field.name + '</button>').appendTo($editorShowedFields);
- }
- $fields.filter('.can-remove').remove();
- };
- /* Sort fields by order property */
- var sortFields = function()
- {
- fields.sort(function(x, y){return x.order * 1 - y.order * 1;});
- var order = 0;
- $.each(fields, function(index, field)
- {
- field.order = order;
- order = order + 2;
- });
- };
- /* Update all fields */
- var updateFields = function(sort)
- {
- hasActionsInList = false;
- if(sort) sortFields();
- for(var i = 0; i < fields.length; ++i)
- {
- var field = fields[i];
- if(!field.id) field.id = '_' + $.zui.uuid();
- if(sort) field.order = i * 100 + 1;
- if($.isPlainObject(field.options))
- {
- var options = [];
- $.each(field.options, function(value, text)
- {
- options[text.length ? 'push' : 'unshift']({value: value, text: text});
- });
- field.options = options;
- field._options = options;
- }
- else if($.isArray(field.options))
- {
- var options = [];
- $.each(field.options, function(index, option)
- {
- if(typeof option === 'string') option = {value: String(index), text: option};
- else option = $.extend({value: '', text: ''}, option);
- options[option.text.length ? 'push' : 'unshift'](option);
- });
- field.options = options;
- }
- if(field.field === 'file') field.control = 'file';
- if(typeof field.show === 'number') field.show = String(field.show);
- if(field.type === 'decimal')
- {
- var digits = field.length.split(',');
- field.integerDigits = Number.parseInt(digits[0], 10);
- field.decimalDigits = Number.parseInt(digits[1], 10);
- if(Number.isNaN(field.integerDigits)) field.integerDigits = fieldDefault.integerDigits;
- if(Number.isNaN(field.decimalDigits)) field.decimalDigits = fieldDefault.decimalDigits;
- }
- if(field.name === null) field.name = '';
- if(!field.length) field.length = fieldDefault.fieldLength[field.field];
- validateField(field);
- updateField(field);
- if(!isForm && field.field === 'actions') hasActionsInList = true;
- }
- };
- /* Validate field properties */
- var validateField = function(field, includeHiddenField)
- {
- if(!field)
- {
- var errorsCount;
- for(var i = 0; i < fields.length; ++i)
- {
- if(validateField(fields[i], includeHiddenField)) {
- errorsCount++;
- }
- }
- return errorsCount;
- }
- if(typeof field === 'string')
- {
- field = getField(field);
- if(!field) return;
- }
- if(!includeHiddenField && field.show !== '1') return;
- var errors = field.errors || {};
- if(!errors.name)
- {
- if(typeof field.name !== 'string' || !field.name.length) errors.name = window.validateMessages.nameRequired;
- else
- {
- for(var i = 0; i < fields.length; ++i)
- {
- var thisField = fields[i];
- if(thisField.id !== field.id && thisField.name === field.name)
- {
- errors.name = window.validateMessages.nameDuplicated;
- break;
- }
- }
- }
- }
- var buildin = field.buildin === '1' || defaultFields[field.field];
- var isTypeLengthRequired = field.type === 'char' || field.type === 'varchar';
- var isDecimalType = field.type === 'decimal';
- var isCustomOptions = typeof field.options === 'object';
- if(!buildin)
- {
- if(!errors.field)
- {
- if(typeof field.field !== 'string' || !field.field.length) errors.field = window.validateMessages.fieldRequired;
- else if(!/^[a-zA-Z]+$/.test(field.field)) errors.field = window.validateMessages.fieldInvalid;
- else
- {
- for(var i = 0; i < fields.length; ++i)
- {
- var thisField = fields[i];
- if(thisField.id !== field.id && thisField.field === field.field)
- {
- errors.field = window.validateMessages.fieldDuplicated.replace('%s', thisField.name);
- break;
- }
- }
- }
- }
- if(!errors.length && isTypeLengthRequired)
- {
- if(typeof field.length !== 'string' || !field.length.length) errors.length = window.validateMessages.lengthRequired;
- }
- if(!errors.defaultValue && typeof field.defaultValue === 'string' && field.defaultValue.length)
- {
- var fieldSelectType = getFieldSelectType(field);
- if(fieldSelectType)
- {
- var isCustomOption = typeof field.options === 'object';
- var optionsKey = field.module + '_' + field.field + '_' + field.options;
- var fieldOptions = isCustomOption ? field.options : remoteOptions[optionsKey];
- if(fieldOptions)
- {
- var isMultiSelect = fieldSelectType === 'multi';
- var defaultValues = isMultiSelect ? field.defaultValue.split(',') : [field.defaultValue];
- var defaultValueError;
- for(var i = 0; i < defaultValues.length; ++i)
- {
- var defaultValue = defaultValues[i];
- var optionIndex = fieldOptions.findIndex(function(option)
- {
- return option.value == defaultValue;
- });
- if(optionIndex < 0)
- {
- if(fieldOptions.findIndex(function(option){return option.text === defaultValue;}) > 0) defaultValueError = window.validateMessages.defaultNotOptionKey.replace('%s', defaultValue);
- else defaultValueError = window.validateMessages.defaultNotInOptions.replace('%s', defaultValue);
- break;
- }
- }
- if(defaultValueError) errors.defaultValue = defaultValueError;
- }
- else if(!isCustomOption)
- {
- delete errors.defaultValue;
- }
- }
- }
- }
- if(!errors.width && canSetWidth && field.width && field.width !== 'auto' && !/^\d+$/.test(field.width))
- {
- errors.width = window.validateMessages.widthInvalid;
- }
- errors.$length = getObjectKeys(errors, function(key)
- {
- return key[0] !== '$';
- }).length;
- if(activedField && activedField.id === field.id)
- {
- var $fieldNameMessage = $('#fieldNameMessage');
- if(errors.name) $fieldNameMessage.html(errors.name).show();
- else $fieldNameMessage.hide();
- $('#fieldEditName').toggleClass('has-error', !!errors.name);
- if(!buildin)
- {
- var $fieldFieldMessage = $('#fieldFieldMessage');
- if(errors.field) $fieldFieldMessage.html(errors.field).show();
- else $fieldFieldMessage.hide();
- $('#fieldEditField').toggleClass('has-error', !!errors.field);
- var $fieldLengthMessage = $('#fieldLengthMessage');
- var lengthError = errors.length || errors.integerDigits || errors.decimalDigits;
- if(lengthError) $fieldLengthMessage.html(lengthError).show();
- else $fieldLengthMessage.hide();
- $('#fieldLength').toggleClass('has-error', !!errors.length);
- $('#integerDigits').toggleClass('has-error', !!errors.integerDigits);
- $('#decimalDigits').toggleClass('has-error', !!errors.decimalDigits);
- $('#fieldEditType').toggleClass('hide-type-length', !isTypeLengthRequired);
- $('#decimalDigitsGroup').toggleClass('hidden', !isDecimalType);
- var $fieldDefaultValueMessage = $('#fieldDefaultValueMessage');
- if(errors.default) $fieldDefaultValueMessage.html(errors.default).show();
- else $fieldDefaultValueMessage.hide();
- $('#fieldEditDefaultValue').toggleClass('has-error', !!errors.default);
- }
- if(canSetWidth)
- {
- var $fieldWidthMessage = $('#fieldWidthMessage');
- if(errors.width) $fieldWidthMessage.html(errors.width).show();
- else $fieldWidthMessage.hide();
- $('#widthEditControl').toggleClass('has-error', !!errors.width);
- }
- if(isCustomOptions)
- {
- var $fieldOptionsMessage = $('#fieldOptionsMessage');
- if(errors.options) $fieldOptionsMessage.html(errors.options).show();
- else $fieldOptionsMessage.hide();
- }
- }
- field.errors = errors;
- updateField(field);
- return errors.$length;
- };
- /* Public method to update field errors, usually used for form submit result */
- window.updateFieldsErrors = function(errors)
- {
- var firstField;
- var errorsCount = 0;
- $.each(errors, function(fieldId, errorsMap)
- {
- var field = getField(fieldId);
- if(field)
- {
- field.errors = errorsMap;
- if(field.errors) field.errors.$length = getObjectKeys(field.errors).length;
- updateField(field);
- if(!firstField) firstField = field;
- errorsCount++;
- }
- });
- if(firstField)
- {
- activeField(firstField.id, true);
- $('#editor').addClass('highlight-errors');
- setTimeout(function()
- {
- $('#editor').removeClass('highlight-errors');
- }, 5000);
- return new $.zui.Messager(window.validateMessages.failSummary.replace('%s', errorsCount),
- {
- type: 'danger',
- icon: 'bell',
- placement: 'center',
- }).show();
- }
- };
- /* Edit field properties and update editor at right of page */
- var editField = function(field)
- {
- if(typeof field === 'string') field = getField(field);
- var $filedEditTip = $('#filedEditTip');
- if(!field)
- {
- $filedEditTip.show();
- $filedEditForm.hide();
- return;
- }
- $filedEditTip.hide();
- var isFileOrActions = field.field === 'file' || field.field === 'actions' || field.buildin == '1';
- var isQuote = field.role == 'quote';
- $filedEditForm.find('#fieldName').val(field.name).attr('readonly', isFileOrActions || isQuote);
- var errors = field.errors || {};
- var buildin = isBuildInField(field);
- var $fieldNameMessage = $('#fieldNameMessage');
- if(errors.name) $fieldNameMessage.html(errors.name).show();
- else $fieldNameMessage.hide();
- $('#fieldEditName').toggleClass('has-error', !!errors.name).toggleClass('required', !isFileOrActions);
- $('#fieldControl').val(field.control).attr('disabled', isQuote).change();
- if(!buildin && !isFileOrActions)
- {
- $('#fieldField').val(field.field);
- $filedEditForm.find('#fieldField').attr('disabled', typeof field.field != 'undefined' && field.field != '');
- var $fieldFieldMessage = $('#fieldFieldMessage');
- if(errors.field) $fieldFieldMessage.html(errors.field).show();
- else $fieldFieldMessage.hide();
- $('#fieldEditField').toggleClass('has-error', !!errors.field);
- $('#fieldType').val(field.type).attr('disabled', isQuote);
- $('#fieldLength').val(field.length).attr('disabled', isQuote);
- var defaultValue = field.defaultValue;
- if(field.control == 'datetime' && defaultValue == 'currentTime') defaultValue = window.currentTime;
- if(field.control == 'date' && defaultValue == 'currentTime') defaultValue = window.currentDate;
- $('#fieldDefaultValue').val(defaultValue);
- $('#fieldRules').val((typeof field.layoutRules === 'string' && field.layoutRules.length) ? field.layoutRules.split(',') : field.layoutRules).trigger('chosen:updated');
- $('#fieldSql').val(field.sql);
- $('#integerDigits').val(field.integerDigits);
- $('#decimalDigits').val(field.decimalDigits);
- var $fieldLengthMessage = $('#fieldLengthMessage');
- if(errors.length) $fieldLengthMessage.html(errors.length).show();
- else $fieldLengthMessage.hide();
- $('#fieldLength').toggleClass('has-error', !!errors.length);
- var $fieldDefaultValueMessage = $('#fieldDefaultValueMessage');
- if(errors.default) $fieldDefaultValueMessage.html(errors.default).show();
- else $fieldDefaultValueMessage.hide();
- $('#fieldEditDefaultValue').toggleClass('has-error', !!errors.default);
- }
- if(canSetWidth)
- {
- var $fieldWidthMessage = $('#fieldWidthMessage');
- if(errors.width) $fieldWidthMessage.html(errors.width).show();
- else $fieldWidthMessage.hide();
- $('#widthEditControl').toggleClass('has-error', !!errors.width);
- }
- if(!buildin || field.field === 'status')
- {
- var isCustomOptions = typeof field.options === 'object';
- $('#fieldOptionType').val(isCustomOptions ? 'custom' : field.options).attr('disabled', isQuote).change();
- }
- if(canSetWidth) $('#fieldWidth').val(field.width);
- if(canSetPosition) $('#fieldPosition').val(field.position);
- $('#fieldIsValue').prop('checked', field.isValue === '1');
- $filedEditForm.toggleClass('is-status', field.field === 'status').toggleClass('is-file', isFileOrActions).toggleClass('is-buildin', !!buildin).show();
- };
- /* Unactive field in preview */
- var unactiveField = function()
- {
- if(activedField)
- {
- var oldActiveField = activedField;
- activedField = null;
- updateField(oldActiveField);
- editField();
- }
- };
- /* Active field in preview */
- var activeField = function(id, force)
- {
- var oldActiveField = activedField;
- var field = typeof id === 'object' ? id : getField(id);
- if(field && field.show === '1' && (force || !oldActiveField || oldActiveField.id !== field.id))
- {
- activedField = field;
- if(oldActiveField) updateField(oldActiveField);
- updateField(field);
- editField(field);
- var $field = $('#field-' + field.id);
- if($field.length && $field[0].scrollIntoViewIfNeeded)
- {
- $field[0].scrollIntoViewIfNeeded();
- }
- }
- };
- /* Delete field in preview */
- var deleteField = function(id)
- {
- var field = getField(id);
- if(field)
- {
- field.show = '0';
- field.changed = true;
- updateField(field);
- updateShowedFields();
- if(activedField && activedField.id === field.id) unactiveField();
- updateListPreview();
- }
- };
- /* Clone field in preview */
- var cloneField = function(id)
- {
- var fieldIndex = getFieldIndex(id);
- if(fieldIndex > -1)
- {
- var field = fields[fieldIndex];
- var copyField = $.extend({}, field, {id: '_' + $.zui.uuid(), order: field.order + 1, field: '', name: '', changed: true, unsaved: true, buildin: '0', role: 'custom', errors: {$length: 0}});
- fields.splice(fieldIndex + 1, 0, copyField);
- updateField(copyField, field);
- validateField(copyField);
- activeField(copyField.id);
- }
- };
- /* Update fields preview controls and showed list on left */
- updateFields(true);
- updateShowedFields();
- /* Bind events on preview element */
- $preview.on('click', '.field-buttons>.btn,.field-delete-btn', function(e)
- {
- var $this = $(this);
- var btnType = $this.data('type');
- var id = $this.closest('.field-item,.field-col-item,.field-view-item').data('id');
- if(btnType === 'delete') deleteField(id);
- else if(btnType === 'copy') cloneField(id);
- e.stopPropagation();
- }).on('click', '.field-item,.field-col-item,.field-view-item', function()
- {
- activeField($(this).data('id'));
- });
- /* Make preview control sortable */
- $preview.sortable(
- {
- selector: '.field-item,.field-col-item,.field-view-item',
- trigger: '.field-sort-handler',
- containerSelector: isView ? '#uiInfoViewPreview, #uiBasicViewPreview' : false,
- start: function(){$('#editorPreview').addClass('editor-sorting');},
- stopPropagation: false,
- before: function(e)
- {
- /* Fix backyard task #11550 https://back.zcorp.cc/pms/task-view-11550.html */
- e.event.preventDefault = function(){};
- },
- finish: function(e)
- {
- $('#editorPreview').removeClass('editor-sorting');
- if(e.changed)
- {
- for(var i = 0; i < e.list.length; ++i)
- {
- var $item = e.list[i].item;
- var field = getField($item.data('id'));
- field.order = i * 100 + 1;
- field.changed = true;
- }
- sortFields();
- if(isView)
- {
- var field = getField(e.element.data('id'));
- var newPosition = e.element.closest('.view-dropbox').data('position');
- if(newPosition !== field.position)
- {
- field.position = newPosition;
- field.changed = true;
- updateField(field);
- }
- }
- updateListPreview();
- }
- }
- });
- /* Update field type tip */
- var updateFieldTypeTip = function(field)
- {
- var tip = '';
- switch(field.type)
- {
- case 'tinyint':
- case 'smallint':
- case 'mediumint':
- case 'int':
- var max = fieldMax[field.type];
- var min = fieldMin[field.type];
- tip = window.tips.number.replace(/MAX/, max).replace(/MIN/, min);
- $('#fieldDefaultValue').attr({min: min, max: max});
- break;
- case 'decimal':
- var integerDigits = field.integerDigits;
- var decimalDigits = field.decimalDigits;
- integerDigits = integerDigits ? parseInt(integerDigits) : 0;
- integerDigits = integerDigits > fieldMax.integerDigits ? fieldMax.integerDigits : integerDigits;
- integerDigits = integerDigits < fieldMin.integerDigits ? fieldDefault.integerDigits : integerDigits;
- integerDigits = parseInt(integerDigits);
- decimalDigits = decimalDigits ? parseInt(decimalDigits) : 0;
- decimalDigits = decimalDigits > fieldMax.decimalDigits ? fieldMax.decimalDigits : decimalDigits;
- decimalDigits = decimalDigits < fieldMin.integerDigits ? fieldDefault.decimalDigits : decimalDigits;
- decimalDigits = parseInt(decimalDigits);
- var max = '.'.padStart(integerDigits + 1, 9).padEnd(integerDigits + decimalDigits + 1, 9);
- var min = '-' + max;
- tip = window.tips.number.replace(/MAX/, max).replace(/MIN/, min);
- $('#fieldDefaultValue').attr({min: min, max: max});
- break;
- case 'char':
- var length = field.length;
- length = length ? parseInt(length) : 0;
- length = length > fieldMax.charLength ? fieldMax.charLength : length;
- length = length < fieldMin.charLength ? fieldDefault.charLength : length;
- tip = window.tips.string.replace(/LENGTH/, length);
- break;
- case 'varchar':
- var length = field.length;
- length = length ? parseInt(length) : 0;
- length = length > fieldMax.varcharLength ? fieldMax.varcharLength : length;
- length = length < fieldMin.varcharLength ? fieldDefault.varcharLength : length;
- tip = window.tips.string.replace(/LENGTH/, length);
- break;
- }
- $('#fieldTypeTip').toggleClass('hidden', !tip).html(tip);
- };
- /* Bind events on properties editor */
- var $fieldEditOptionsList = $('#fieldEditOptionsList');
- $filedEditForm.on('change', function(e)
- {
- var field = activedField;
- if(!field) return;
- var $control = $(e.target);
- if($control.closest('.field-option-item').length)
- {
- $control = $('#fieldControl');
- }
- var controlName = $control.attr('name');
- if(!controlName) return;
- var oldValue = field[controlName];
- var controlValue = $control.val();
- if($control.is(':checkbox')) controlValue = $control.prop('checked') ? controlValue : '';
- var optionsKey = field.module + '_' + field.field + '_' + field.options;
- if(controlName === 'length' || controlName === 'integerDigits' || controlName === 'decimalDigits')
- {
- var numValue = Number.parseInt(controlValue, 10);
- var valueName = controlName === 'length' ? (field.type + 'Length') : controlName;
- if(Number.isNaN(numValue)) controlValue = Number.parseInt(fieldDefault[valueName], 10);
- else
- {
- var min = Number.parseInt(fieldMin[valueName], 10);
- var max = Number.parseInt(fieldMax[valueName], 10);
- var fixValue = Math.floor(Math.max(min, Math.min(max, numValue))) + '';
- if(fixValue !== controlValue)
- {
- $control.val(fixValue);
- controlValue = fixValue + '';
- }
- }
- }
- else if(controlName === 'defaultValue')
- {
- if(field.control === 'integer' || field.control === 'decimal')
- {
- var $fieldDefaultValue = $('#fieldDefaultValue');
- controlValue = Math.min(Math.max(Number.parseInt(controlValue, 10), Number.parseInt($fieldDefaultValue.attr('min'), 10)), Number.parseInt($fieldDefaultValue.attr('max'), 10)) + '';
- $fieldDefaultValue.val(controlValue);
- }
- if(controlValue)
- {
- var fieldOptions = remoteOptions[optionsKey];
- if(fieldOptions)
- {
- var optionIndex = fieldOptions.findIndex(function(option)
- {
- return option.value == controlValue;
- });
- if(optionIndex < 0)
- {
- var controlText = $control.text();
- fieldOptions.push({value: controlValue, text: controlText});
- }
- }
- }
- }
- if(controlName === 'optionType')
- {
- oldValue = typeof field.options === 'object' ? 'custom' : String(field.options);
- if(controlValue === 'custom')
- {
- field.options = field._options || [];
- }
- else
- {
- if(typeof field.options === 'object') field._options = field.options;
- field.options = controlValue;
- }
- }
- else field[controlName] = controlValue;
- if(controlName === 'control' || controlName === 'optionType')
- {
- var optionSelectType = getFieldSelectType(field);
- $filedEditForm.find('#fieldEditOptionType').toggleClass('hide', !optionSelectType);
- var isCustomOptions = optionSelectType && typeof field.options === 'object';
- $('#fieldEditOptions').toggleClass('hide', !isCustomOptions);
- $('#fieldEditSql').toggleClass('hide', isCustomOptions || !optionSelectType || field.options !== 'sql');
- var $optionsList = $fieldEditOptionsList.empty();
- var $fieldDefaultValue = $('#fieldDefaultValue');
- var isMultiSelect = optionSelectType === 'multi';
- if(oldValue !== controlValue) field.defaultValue = '';
- if($('#dateCustom').length && field.control !== 'datetime' && field.control !== 'date')
- {
- $('#dateCustom').after($fieldDefaultValue);
- $('#dateCustom').remove();
- }
- if(optionSelectType && optionSelectType !== 'text')
- {
- var picker = $fieldDefaultValue.data('zui.picker');
- if(picker) picker.destroy();
- if(!$fieldDefaultValue.is('select'))
- {
- $fieldDefaultValue.replaceWith($('<select id="fieldDefaultValue" name="defaultValue" class="form-control"><option value=""></option></select>').attr('multiple', isMultiSelect ? 'multiple' : null));
- $fieldDefaultValue = $('#fieldDefaultValue');
- }
- else if(isMultiSelect !== !!$fieldDefaultValue.attr('multiple'))
- {
- var chosen = $fieldDefaultValue.data('chosen');
- if(chosen) chosen.destroy();
- $fieldDefaultValue.attr('multiple', isMultiSelect ? 'multiple' : null);
- }
- $fieldDefaultValue.empty();
- if(isCustomOptions)
- {
- var hasEmptyOption;
- if(!field.options.length) field.options.push({value: '', text: ''});
- $.each(field.options, function(_, option)
- {
- var $inputGroup = $('<div class="input-group field-option-item"></div>');
- $inputGroup.append('<span class="input-group-addon">' + window.keyValueList.key + '</span>');
- $inputGroup.append($('<input name="optionValue" class="form-control w-50px" placeholder="' + window.langOptionCode + '" />').val(option.value));
- $inputGroup.append('<span class="input-group-addon">' + window.keyValueList.value + '</span>');
- $inputGroup.append($('<input name="optionText" class="form-control" />').val(option.text));
- $inputGroup.append('<span class="input-group-addon" style="padding: 4px 2px"><i class="icon icon-plus" data-type="add"></i><i class="icon icon-minus" data-type="delete"></i></span>');
- $optionsList.append($inputGroup);
- $fieldDefaultValue.append($('<option>').attr('value', option.value).text(option.text));
- if(!option.value.length) hasEmptyOption = true;
- });
- if(!hasEmptyOption) $fieldDefaultValue.prepend('<option value=""></option>');
- }
- else
- {
- var options = remoteOptions[optionsKey];
- var hasEmptyOption;
- if(options)
- {
- $.each(options, function(_, option)
- {
- if(!option.value.length) hasEmptyOption = true;
- $fieldDefaultValue.append($('<option>').attr('value', option.value).text(option.text));
- });
- }
- if(!hasEmptyOption) $fieldDefaultValue.prepend('<option value=""></option>');
- }
- var fieldValue = (typeof field.defaultValue === 'string' && field.defaultValue.length) ? field.defaultValue.split(',') : field.defaultValue;
- $fieldDefaultValue.val(fieldValue);
- initDefault(field, isCustomOptions);
- }
- else
- {
- if(!$fieldDefaultValue.is('input'))
- {
- var chosen = $fieldDefaultValue.data('chosen');
- var picker = $fieldDefaultValue.data('zui.picker');
- if(chosen) chosen.destroy();
- if(picker) picker.destroy();
- $fieldDefaultValue.replaceWith('<input type="text" id="fieldDefaultValue" name="defaultValue" class="form-control" />');
- $fieldDefaultValue = $('#fieldDefaultValue').val(field.defaultValue);
- }
- var dateType = (field.control === 'datetime' || field.control === 'date') ? field.control : false;
- if($fieldDefaultValue.data('dateType') !== dateType)
- {
- $fieldDefaultValue.data('dateType', dateType);
- $fieldDefaultValue.attr('autocomplete', 'off');
- var datepicker = $fieldDefaultValue.data('datetimepicker');
- if(datepicker) datepicker.remove();
- $fieldDefaultValue.val(field.defaultValue);
- if(dateType) $fieldDefaultValue[dateType + 'picker']();
- }
- if(dateType == 'date' || dateType == 'datetime')
- {
- window.dateType = dateType;
- fieldDefaultValue = field.defaultValue;
- if($('#dateCustom').length === 0)
- {
- checked = field.defaultValue != 'currentTime' ? 'checked' : '';
- $fieldDefaultValue.before("<div class='input-group' id='dateCustom'><span class='input-group-addon'><div class='checkbox-primary'><input type='checkbox' id='custom' value='1' " + checked + "/><label>" + window.custom + "</label></div></span></div>");
- $('#dateCustom').prepend($fieldDefaultValue);
- $('#custom').change();
- }
- else
- {
- $('#custom').prop('checked', field.defaultValue != 'currentTime').change();
- }
- $fieldDefaultValue = $('#fieldDefaultValue');
- $fieldDefaultValue.val(field.defaultValue);
- }
- if(!dateType)
- {
- var isNumber = field.control === 'integer' || field.control === 'decimal';
- $fieldDefaultValue.attr({type: isNumber ? 'number' : 'text', min: null, max: null});
- }
- }
- $fieldDefaultValue.attr('placeholder', isMultiSelect ? window.multiDefaultPlaceholder : '');
- if(controlName === 'optionType' && optionSelectType && !isCustomOptions)
- {
- getDefaultsOfOption(field, function(options)
- {
- optionsKey = field.module + '_' + field.field + '_' + field.options;
- activedField.optionsData = options;
- remoteOptions[optionsKey] = formatOptions(options);
- validateField(field);
- $('#fieldControl').change();
- });
- }
- else if(controlName === 'control')
- {
- $filedEditForm.attr('data-control', controlValue);
- if(controlValue !== 'file')
- {
- var defaultProps = getDefaultFieldByControl(controlValue);
- var $hiddenOptions = $('#fieldType option').show().not('.' + defaultProps.optionClass).hide();
- if($hiddenOptions.filter('[value="' + field.type + '"]').length)
- {
- $('#fieldType').val(defaultProps.type).change();
- }
- }
- }
- }
- else if(controlName === 'type')
- {
- var typeHasLength = field.type === 'char' || field.type === 'varchar';
- $('#fieldEditType').toggleClass('hide-type-length', !typeHasLength);
- if(typeHasLength)
- {
- var valueName = field.type + 'Length';
- var min = Number.parseInt(fieldMin[valueName], 10);
- var max = Number.parseInt(fieldMax[valueName], 10);
- var numValue = Number.parseInt(field.length, 10);
- var fixValue = Math.floor(Math.max(min, Math.min(max, numValue))) + '';
- $('#fieldLength').attr({min: min, max: max}).val(fixValue);
- }
- $('#decimalDigitsGroup').toggleClass('hidden', field.type !== 'decimal');
- }
- if(oldValue !== controlValue)
- {
- field.changed = true;
- if(field.errors)
- {
- if(field.errors && field.errors[controlName]) delete field.errors[controlName];
- if(controlName === 'control' || controlName === 'optionType') delete field.errors.defaultValue;
- if(controlName === 'type') delete field.errors.length;
- if(controlName === 'integerDigits') delete field.errors.integerDigits;
- if(controlName === 'decimalDigits')
- {
- delete field.errors.decimalDigits;
- delete field.errors.integerDigits;
- }
- }
- }
- validateField(field);
- updateField(field);
- updateFieldTypeTip(field);
- });
- /* Synchronize field options after use change it */
- var syncFieldOptions = function()
- {
- if(!activedField || typeof activedField.options !== 'object') return;
- var options = [];
- $fieldEditOptionsList.find('.field-option-item').each(function()
- {
- var $item = $(this);
- var value = $item.find('[name="optionValue"]').val();
- var text = $item.find('[name="optionText"]').val();
- options.push(
- {
- value: value,
- text: text,
- });
- });
- activedField.options = options;
- activedField._options = options;
- activedField.changed = true;
- delete activedField.errors.defaultValue;
- validateField(activedField);
- $('#fieldControl').change();
- };
- $fieldEditOptionsList.on('focus', 'input', function()
- {
- $(this).closest('.field-option-item').addClass('active');
- }).on('blur', 'input', function()
- {
- $(this).closest('.field-option-item').removeClass('active');
- }).on('click', '.icon', function()
- {
- var $this = $(this);
- var type = $this.data('type');
- var $item = $this.closest('.field-option-item');
- if(type === 'add')
- {
- var $newItem = $item.clone();
- $newItem.find('[name="optionValue"],[name="optionText"]').val('');
- $item.after($newItem);
- }
- else
- {
- if($fieldEditOptionsList.find('.field-option-item').length === 1)
- {
- $item.find('[name="optionValue"],[name="optionText"]').val('');
- }
- else $item.remove();
- }
- syncFieldOptions();
- }).on('change', syncFieldOptions);
- /* Support to add fields to preview section with drag-and-drop */
- $('#editorControls').droppable(
- {
- container: 'body',
- selector: '.btn-field-control',
- target: '.field-item,#uiPreview,.field-col-item' + (hasActionsInList ? '' : ',#uiListHeader,#uiInfoViewPreview,#uiBasicViewPreview,.field-view-item'),
- stopPropagation: true,
- nested: true,
- start: function()
- {
- $('input').blur();
- $('#editor').addClass('editor-dragging');
- },
- always: function()
- {
- $('#editor').removeClass('editor-dragging');
- },
- drag: function(e)
- {
- $previewBox.find('.drop-hover').removeClass('drop-hover');
- if(e.isIn) $(e.target).closest('#uiListTable,#uiPreviewWrapper,.view-panel').addClass('drop-hover');
- },
- drop: function(e)
- {
- var $element = e.element;
- var field = $element.data('field');
- var nextField;
- var getOrder = function()
- {
- var $target = e.target;
- nextField = $target.is('#uiPreview,#uiListHeader,#uiInfoViewPreview,#uiBasicViewPreview') ? null : getField($target.data('id'));
- if(nextField) return nextField.order - 1;
- var lastField = getField($preview.find('.field-item,.field-col-item,.field-view-item').last().data('id'));
- return lastField ? lastField.order + 1 : fields.length * 100 + 2;
- }
- if(field)
- {
- field = getField(field);
- if(field)
- {
- field.show = '1';
- field.order = getOrder();
- field.changed = true;
- if(isView)
- {
- field.position = e.target.closest('.view-dropbox').data('position');
- }
- }
- }
- else
- {
- var controlType = $element.data('type');
- if(controlType)
- {
- field =
- $.extend({
- id : '_' + $.zui.uuid(),
- control : controlType,
- name : window.controlTypeList[controlType],
- order : getOrder(),
- buildin : '0',
- layoutRules : '',
- defaultValue : '',
- mobileShow : '0',
- module : window.flowModule,
- options : [{value: '', text: ''}],
- position : isView ? e.target.closest('.view-dropbox').data('position') : 'left',
- readonly : '0',
- rules : '',
- show : '1',
- summary : '',
- length : '255',
- width : 'auto',
- changed : true,
- isValue : '0',
- unsaved : true
- }, getDefaultFieldByControl(controlType));
- fields.push(field);
- }
- }
- if(field && typeof field === 'object')
- {
- if(nextField) nextField.changed = true;
- field.changed = true;
- sortFields();
- updateField(field, nextField, true);
- updateShowedFields();
- activeField(field);
- }
- }
- });
- /* Limit input content to prevent mistakes */
- $('#fieldLength').on('change', function()
- {
- var $input = $(this);
- $input.val($input.val().replace(/[^\d,]/g, ''));
- });
- $('#fieldField').on('change', function()
- {
- var $input = $(this);
- $input.val($input.val().replace(/[^a-zA-Z]/g, ''));
- });
- $('#fieldEditOptionsList').on('change', '[name="optionValue"]', function()
- {
- var $input = $(this);
- $input.val($input.val().replace(/[^a-zA-Z\d]/g, ''));
- });
- $('#fieldEditOptionsList').on('change', '[name="optionText"]', function(){removeOptionError(activedField);});
- $('#fieldEditOptionsList').on('click', '.icon-minus', function(){removeOptionError(activedField);});
- /* Bind event to make list preview auto scroll with header */
- $preview.on('scroll', function()
- {
- $('#uiListBody').scrollLeft($preview.scrollLeft());
- });
- /* Bind event to unactive field on use click top menu */
- $('#editorNav').on('click', unactiveField);
- $('#saveBtn').on('click', saveFields.bind(null, false, function(result)
- {
- if(result) setTimeout(function(){location.href = location.href;}, 1200);
- },
- true
- ));
- $('a.btn.release').on('click', function()
- {
- if(saveFields(function(result)
- {
- if(result) $('a.btn.release').click();
- })) return false;
- });
- $(document).on('change', '#custom', function()
- {
- var $fieldDefaultValue = $('#fieldDefaultValue');
- if(!$(this).prop('checked'))
- {
- $fieldDefaultValue.replaceWith($('<select id="fieldDefaultValue" name="defaultValue" class="form-control"><option value=""></option><option value="currentTime">' + window.currentTimeLang + '</option></select>'));
- $fieldDefaultValue = $('#fieldDefaultValue');
- }
- else
- {
- $fieldDefaultValue.replaceWith($('<input type="text" id="fieldDefaultValue" name="defaultValue" class="form-control"/>'));
- $fieldDefaultValue = $('#fieldDefaultValue');
- if(window.dateType) $fieldDefaultValue[window.dateType + 'picker']();
- }
- $fieldDefaultValue.data('dateType', window.dateType).attr('autocomplete', 'off');
- });
- $(document).on('hidden.zui.modal', '#triggerModal', function()
- {
- location.reload();
- });
- $('#editorPages > .btn, .prevStep').on('click', function()
- {
- var url = $(this).attr('href');
- if(saveFields(function(result)
- {
- if(result) setTimeout(function(){location.href = url;}, 1200);
- })) return false;
- });
- $('.release.btn').on('click', function(){$('#confirmReleaseModal .close').click();});
- /* Show alert before user leave page without save changes */
- $(window).on('beforeunload', function(e)
- {
- var hasChanges;
- for(var i = 0; i < fields.length; ++i)
- {
- var field = fields[i];
- if(field.changed)
- {
- hasChanges = true;
- break;
- }
- }
- if(hasChanges)
- {
- e = e || window.event;
- // IE8, Firefox 4
- if(e) e.returnValue = window.leavePageTip;
- // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
- return window.leavePageTip;
- }
- });
- setAutoHeight();
- $(window).on('resize', setAutoHeight);
- /* Clear default error tips when input default. */
- $('#fieldEditDefaultValue').on('input', function(e){
- var field = activedField;
- if(field.errors.default)
- {
- $('#fieldDefaultValueMessage').hide();
- $('#fieldEditDefaultValue').toggleClass('has-error',false);
- delete field.errors.default;
- field.errors.$length --;
- $('#field-' + field.id).toggleClass('has-error', !!(field.errors && field.errors.$length))
- }
- });
- });
|