Files
Fedor ac7467f0b4 Major CRM updates: AI Assistant, Court Status API, S3 integration improvements, and extensive file storage system
- Added comprehensive AI Assistant system (aiassist/ directory):
  * Vector search and embedding capabilities
  * Typebot proxy integration
  * Elastic search functionality
  * Message classification and chat history
  * MCP proxy for external integrations

- Implemented Court Status API (GetCourtStatus.php):
  * Real-time court document status checking
  * Integration with external court systems
  * Comprehensive error handling and logging

- Enhanced S3 integration:
  * Improved file backup system with metadata
  * Batch processing capabilities
  * Enhanced error logging and recovery
  * Copy operations with URL fixing

- Added Telegram contact creation API
- Improved error logging across all modules
- Enhanced callback system for AI responses
- Extensive backup file storage with timestamps
- Updated documentation and README files

- File storage improvements:
  * Thousands of backup files with proper metadata
  * Fix operations for broken file references
  * Project-specific backup and recovery systems
  * Comprehensive file integrity checking

Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
2025-10-16 11:17:21 +03:00

1826 lines
60 KiB
JavaScript

/*+***********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
*************************************************************************************/
jQuery.Class('Settings_LayoutEditor_Js', {
}, {
updatedBlockSequence : {},
reactiveFieldsList : [],
updatedRelatedList : {'updated' : [], 'deleted' : []},
removeModulesArray : false,
inActiveFieldsList : false,
updatedBlockFieldsList : [],
updatedBlocksList : [],
blockNamesList : [],
/**
* Function to set the removed modules array used in related list
*/
setRemovedModulesList : function() {
var thisInstance = this;
var relatedList = jQuery('#relatedTabOrder');
var container = relatedList.find('.relatedTabModulesList');
thisInstance.removeModulesArray = JSON.parse(container.find('.RemovedModulesListArray').val());
},
/**
* Function to set the inactive fields list used to show the inactive fields
*/
setInactiveFieldsList : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
thisInstance.inActiveFieldsList = JSON.parse(contents.find('.inActiveFieldsArray').val());
},
/**
* Function to regiser the event to make the blocks sortable
*/
makeBlocksListSortable : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
var table = contents.find('.blockSortable');
contents.sortable({
'containment' : contents,
'items' : table,
'revert' : true,
'tolerance':'pointer',
'cursor' : 'move',
'update' : function(e, ui) {
thisInstance.updateBlockSequence();
}
});
},
/**
* Function which will update block sequence
*/
updateBlockSequence : function() {
var thisInstance = this;
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var sequence = JSON.stringify(thisInstance.updateBlocksListByOrder());
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['action'] = 'Block';
params['mode'] = 'updateSequenceNumber';
params['sequence'] = sequence;
AppConnector.request(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
var params = {};
params['text'] = app.vtranslate('JS_BLOCK_SEQUENCE_UPDATED');
Settings_Vtiger_Index_Js.showMessage(params);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
}
);
},
/**
* Function which will arrange the sequence number of blocks
*/
updateBlocksListByOrder : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
contents.find('.editFieldsTable').each(function(index,domElement){
var blockTable = jQuery(domElement);
var blockId = blockTable.data('blockId');
var actualBlockSequence = blockTable.data('sequence');
var expectedBlockSequence = (index+1);
if(expectedBlockSequence != actualBlockSequence) {
blockTable.data('sequence', expectedBlockSequence);
}
thisInstance.updatedBlockSequence[blockId] = expectedBlockSequence;
});
return thisInstance.updatedBlockSequence;
},
/**
* Function to regiser the event to make the related modules sortable
*/
makeRelatedModuleSortable : function() {
var thisInstance = this;
var relatedModulesContainer = jQuery('#relatedTabOrder');
var modulesList = relatedModulesContainer.find('li.relatedModule');
relatedModulesContainer.sortable({
'containment' : relatedModulesContainer,
'items' : modulesList,
'revert' : true,
'tolerance':'pointer',
'cursor' : 'move',
'update' : function(e, ui) {
thisInstance.showSaveButton();
}
});
},
/**
* Function which will enable the save button in realted tabs list
*/
showSaveButton : function() {
var relatedList = jQuery('#relatedTabOrder');
var saveButton = relatedList.find('.saveRelatedList');
if(saveButton.attr('disabled') == 'disabled') {
saveButton.removeAttr('disabled');
}
},
/**
* Function which will disable the save button in related tabs list
*/
disableSaveButton : function() {
var relatedList = jQuery('#relatedTabOrder');
var saveButton = relatedList.find('.saveRelatedList');
saveButton.attr('disabled', 'disabled');
},
/**
* Function to register all the relatedList Events
*/
registerRelatedListEvents : function() {
var thisInstance = this;
var relatedList = jQuery('#relatedTabOrder');
var container = relatedList.find('.relatedTabModulesList');
var allModulesListArray = JSON.parse(container.find('.ModulesListArray').val());
var ulEle = container.find('ul.relatedModulesList');
var selectEle = container.find('[name="addToList"]');
app.showSelect2ElementView(selectEle, {maximumSelectionSize : 1, closeOnSelect : true, dropdownCss : {'z-index' : 0}});
selectEle.on('change', function() {
var selectedVal = selectEle.val();
var moduleLabel = allModulesListArray[selectedVal];
//remove the element if its already exists
ulEle.find('.module_'+selectedVal[0]).remove();
//append li element for the selected module
var liEle = container.find('.moduleCopy').clone(true, true);
liEle.data('relationId', selectedVal[0]).find('.moduleLabel').text(moduleLabel);
ulEle.append(liEle.removeClass('hide moduleCopy').addClass('relatedModule module_'+selectedVal[0]));
thisInstance.makeRelatedModuleSortable();
//remove that selected module from the select element
selectEle.select2('data',[]);
selectEle.find('option[value="'+selectedVal[0]+'"]').remove();
thisInstance.removeModulesArray.splice(thisInstance.removeModulesArray.indexOf(selectedVal[0]),1);
thisInstance.showSaveButton();
})
//register the event to click on close the related module
container.find('.close').one('click', function(e) {
var currentTarget = jQuery(e.currentTarget);
thisInstance.showSaveButton();
var liEle = currentTarget.closest('li.relatedModule');
var relationId = liEle.data('relationId');
var moduleLabel = liEle.find('.moduleLabel').text();
liEle.fadeOut('slow').addClass('deleted');
selectEle.append('<option value="'+relationId+'">'+moduleLabel+'</option>');
})
//register click event for save related list button
relatedList.on('click', '.saveRelatedList', function(e) {
var currentTarget = jQuery(e.currentTarget);
if(currentTarget.attr('disabled') != 'disabled') {
thisInstance.disableSaveButton();
thisInstance.updatedRelatedList['deleted'] = [];
for(var key in thisInstance.removeModulesArray) {
thisInstance.updatedRelatedList['deleted'].push(thisInstance.removeModulesArray[key]);
}
thisInstance.saveRelatedListInfo();
}
})
},
/**
* Function to save the updated information in related list
*/
saveRelatedListInfo : function() {
var thisInstance = this;
var aDeferred = jQuery.Deferred();
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['action'] = 'Relation';
params['related_info'] = thisInstance.getUpdatedModulesInfo();
params['sourceModule'] = jQuery('#selectedModuleName').val();
AppConnector.request(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
var params = {};
params['text'] = app.vtranslate('JS_RELATED_INFO_SAVED');
Settings_Vtiger_Index_Js.showMessage(params);
aDeferred.resolve(data);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
aDeferred.reject(error);
}
);
return aDeferred.promise();
},
/**
* Function to get the updates happened with the related modules list
*/
getUpdatedModulesInfo : function() {
var thisInstance = this;
var relatedList = jQuery('#relatedTabOrder');
var removedModulesList = relatedList.find('li.relatedModule').filter('.deleted');
var updatedModulesList = relatedList.find('li.relatedModule').not('.deleted');
thisInstance.updatedRelatedList['updated'] = [];
//update deleted related modules list
removedModulesList.each(function(index,domElement) {
var relationId = jQuery(domElement).data('relationId');
thisInstance.updatedRelatedList['deleted'].push(relationId);
});
//update the existing related modules list
updatedModulesList.each(function(index,domElement){
var relationId = jQuery(domElement).data('relationId');
thisInstance.updatedRelatedList['updated'].push(relationId);
});
return thisInstance.updatedRelatedList;
},
/**
* Function to regiser the event to make the fields sortable
*/
makeFieldsListSortable : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
var table = contents.find('.editFieldsTable');
table.find('ul[name=sortable1], ul[name=sortable2]').sortable({
'containment' : '#moduleBlocks',
'revert' : true,
'tolerance':'pointer',
'cursor' : 'move',
'connectWith' : '.connectedSortable',
'update' : function(e, ui) {
var currentField = ui['item'];
thisInstance.showSaveFieldSequenceButton();
thisInstance.createUpdatedBlocksList(currentField);
// rearrange the older block fields
if(ui.sender) {
var olderBlock = ui.sender.closest('.editFieldsTable');
thisInstance.reArrangeBlockFields(olderBlock);
}
}
});
},
/**
* Function to show the save button of fieldSequence
*/
showSaveFieldSequenceButton : function() {
var thisInstance = this;
var layout = jQuery('#detailViewLayout');
var saveButton = layout.find('.saveFieldSequence');
if(app.isHidden(saveButton)) {
thisInstance.updatedBlocksList = [];
thisInstance.updatedBlockFieldsList = [];
saveButton.removeClass('hide');
var params = {};
params['text'] = app.vtranslate('JS_SAVE_THE_CHANGES_TO_UPDATE_FIELD_SEQUENCE');
Settings_Vtiger_Index_Js.showMessage(params);
}
},
/**
* Function which will hide the saveFieldSequence button
*/
hideSaveFieldSequenceButton : function() {
var layout = jQuery('#detailViewLayout');
var saveButton = layout.find('.saveFieldSequence');
saveButton.addClass('hide');
},
/**
* Function to create the blocks list which are updated while sorting
*/
createUpdatedBlocksList : function(currentField) {
var thisInstance = this;
var block = currentField.closest('.editFieldsTable');
var updatedBlockId = block.data('blockId');
if(jQuery.inArray(updatedBlockId, thisInstance.updatedBlocksList) == -1) {
thisInstance.updatedBlocksList.push(updatedBlockId);
}
thisInstance.reArrangeBlockFields(block);
},
/**
* Function that rearranges fields in the block when the fields are moved
* @param <jQuery object> block
*/
reArrangeBlockFields : function(block) {
// 1.get the containers, 2.compare the length, 3.if uneven then move the last element
var leftSideContainer = block.find('ul[name=sortable1]');
var rightSideContainer = block.find('ul[name=sortable2]');
if(leftSideContainer.children().length < rightSideContainer.children().length) {
var lastElementInRightContainer = rightSideContainer.children(':last');
leftSideContainer.append(lastElementInRightContainer);
} else if(leftSideContainer.children().length > rightSideContainer.children().length+1) { //greater than 1
var lastElementInLeftContainer = leftSideContainer.children(':last');
rightSideContainer.append(lastElementInLeftContainer);
}
},
/**
* Function to create the list of updated blocks with all the fields and their sequences
*/
createUpdatedBlockFieldsList : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
for(var index in thisInstance.updatedBlocksList) {
var updatedBlockId = thisInstance.updatedBlocksList[index];
var updatedBlock = contents.find('.block_'+updatedBlockId);
var firstBlockSortFields = updatedBlock.find('ul[name=sortable1]');
var editFields = firstBlockSortFields.find('.editFields');
var expectedFieldSequence = 1;
editFields.each(function(i,domElement){
var fieldEle = jQuery(domElement);
var fieldId = fieldEle.data('fieldId');
thisInstance.updatedBlockFieldsList.push({'fieldid' : fieldId,'sequence' : expectedFieldSequence, 'block' : updatedBlockId});
expectedFieldSequence = expectedFieldSequence+2;
});
var secondBlockSortFields = updatedBlock.find('ul[name=sortable2]');
var secondEditFields = secondBlockSortFields.find('.editFields');
var sequenceValue = 2;
secondEditFields.each(function(i,domElement){
var fieldEle = jQuery(domElement);
var fieldId = fieldEle.data('fieldId');
thisInstance.updatedBlockFieldsList.push({'fieldid' : fieldId,'sequence' : sequenceValue, 'block' : updatedBlockId});
sequenceValue = sequenceValue+2;
});
}
},
/**
* Function to register click event for save button of fields sequence
*/
registerFieldSequenceSaveClick : function() {
var thisInstance = this;
var layout = jQuery('#detailViewLayout');
layout.on('click', '.saveFieldSequence', function() {
thisInstance.hideSaveFieldSequenceButton();
thisInstance.createUpdatedBlockFieldsList();
thisInstance.updateFieldSequence();
});
},
/**
* Function will save the field sequences
*/
updateFieldSequence : function() {
var thisInstance = this;
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['action'] = 'Field';
params['mode'] = 'move';
params['updatedFields'] = thisInstance.updatedBlockFieldsList;
AppConnector.request(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
window.location.reload();
var params = {};
params['text'] = app.vtranslate('JS_FIELD_SEQUENCE_UPDATED');
Settings_Vtiger_Index_Js.showMessage(params);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
}
);
},
/**
* Function to register click evnet add custom field button
*/
registerAddCustomFieldEvent : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
contents.find('.addCustomField').click(function(e) {
var blockId = jQuery(e.currentTarget).closest('.editFieldsTable').data('blockId');
var addFieldContainer = contents.find('.createFieldModal').clone(true, true);
addFieldContainer.removeClass('hide');
var callBackFunction = function(data) {
//register all select2 Elements
app.showSelect2ElementView(data.find('select'));
var form = data.find('.createCustomFieldForm');
form.attr('id', 'createFieldForm');
var select2params = {tags: [],tokenSeparators: [","]}
app.showSelect2ElementView(form.find('[name="pickListValues"]'), select2params);
thisInstance.registerFieldTypeChangeEvent(form);
var params = app.getvalidationEngineOptions(true);
params.onValidationComplete = function(form, valid){
if(valid) {
var fieldTypeValue = jQuery('[name="fieldType"]',form).val();
if(fieldTypeValue == 'Picklist' || fieldTypeValue == 'MultiSelectCombo') {
var pickListValueElement = jQuery('#picklistUi',form);
var pickLisValues = pickListValueElement.val();
var pickListValuesArray = pickLisValues.split(',');
var pickListValuesArraySize = pickListValuesArray.length;
var specialChars = /["]/ ;
for(var i=0;i<pickListValuesArray.length;i++) {
if (specialChars.test(pickListValuesArray[i])) {
var select2Element = app.getSelect2ElementFromSelect(pickListValueElement);
var message = app.vtranslate('JS_SPECIAL_CHARACTERS')+' " '+app.vtranslate('JS_NOT_ALLOWED');
select2Element.validationEngine('showPrompt', message , 'error','bottomLeft',true);
return false;
}
}
var lowerCasedpickListValuesArray = jQuery.map(pickListValuesArray, function(item, index) {
return item.toLowerCase();
});
var uniqueLowerCasedpickListValuesArray = jQuery.unique(lowerCasedpickListValuesArray);
var uniqueLowerCasedpickListValuesArraySize = uniqueLowerCasedpickListValuesArray.length;
var arrayDiffSize = pickListValuesArraySize-uniqueLowerCasedpickListValuesArraySize;
if(arrayDiffSize > 0) {
var select2Element = app.getSelect2ElementFromSelect(pickListValueElement);
var message = app.vtranslate('JS_DUPLICATES_VALUES_FOUND');
select2Element.validationEngine('showPrompt', message , 'error','bottomLeft',true);
return false;
}
}
var saveButton = form.find(':submit');
saveButton.attr('disabled', 'disabled');
thisInstance.addCustomField(blockId, form).then(
function(data) {
var result = data['result'];
var params = {};
if(data['success']) {
app.hideModalWindow();
params['text'] = app.vtranslate('JS_CUSTOM_FIELD_ADDED');
Settings_Vtiger_Index_Js.showMessage(params);
thisInstance.showCustomField(result);
} else {
var message = data['error']['message'];
form.find('[name="fieldLabel"]').validationEngine('showPrompt', message , 'error','topLeft',true);
saveButton.removeAttr('disabled');
}
}
);
}
//To prevent form submit
return false;
}
form.validationEngine(params);
}
app.showModalWindow(addFieldContainer,function(data) {
if(typeof callBackFunction == 'function') {
callBackFunction(data);
}
}, {'width':'1000px'});
});
},
/**
* Function to create the array of block names list
*/
setBlocksListArray : function(form) {
var thisInstance = this;
thisInstance.blockNamesList = [];
var blocksListSelect = form.find('[name="beforeBlockId"]');
blocksListSelect.find('option').each(function(index, ele) {
var option = jQuery(ele);
var label = option.data('label');
thisInstance.blockNamesList.push(label);
})
},
/**
* Function to save the custom field details
*/
addCustomField : function(blockId, form) {
var thisInstance = this;
var modalHeader = form.closest('#globalmodal').find('.modal-header h3');
var aDeferred = jQuery.Deferred();
modalHeader.progressIndicator({smallLoadingImage : true, imageContainerCss : {display : 'inline', 'margin-left' : '18%',position : 'absolute'}});
var params = form.serializeFormData();
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['action'] = 'Field';
params['mode'] = 'add';
params['blockid'] = blockId;
params['sourceModule'] = jQuery('#selectedModuleName').val();
AppConnector.request(params).then(
function(data) {
modalHeader.progressIndicator({'mode' : 'hide'});
aDeferred.resolve(data);
},
function(error) {
modalHeader.progressIndicator({'mode' : 'hide'});
aDeferred.reject(error);
}
);
return aDeferred.promise();
},
/**
* Function to register change event for fieldType while adding custom field
*/
registerFieldTypeChangeEvent : function(form) {
var thisInstance = this;
var lengthInput = form.find('[name="fieldLength"]');
//special validators while adding new field
var lengthValidator = [{'name' : 'DecimalMaxLength'}];
var maxLengthValidator = [{'name' : 'MaxLength'}];
var decimalValidator = [{'name' : 'FloatingDigits'}];
//By default add the max length validator
lengthInput.data('validator', maxLengthValidator);
//register the change event for field types
form.find('[name="fieldType"]').on('change', function(e) {
var currentTarget = jQuery(e.currentTarget);
var lengthInput = form.find('[name="fieldLength"]');
var selectedOption = currentTarget.find('option:selected');
//hide all the elements like length, decimal,picklist
form.find('.supportedType').addClass('hide');
if(selectedOption.data('lengthsupported')) {
form.find('.lengthsupported').removeClass('hide');
lengthInput.data('validator', maxLengthValidator);
}
if(selectedOption.data('decimalsupported')) {
var decimalFieldUi = form.find('.decimalsupported');
decimalFieldUi.removeClass('hide');
var decimalInput = decimalFieldUi.find('[name="decimal"]');
var maxFloatingDigits = selectedOption.data('maxfloatingdigits');
if(typeof maxFloatingDigits != "undefined") {
decimalInput.data('validator', decimalValidator);
lengthInput.data('validator', lengthValidator);
}
if(selectedOption.data('decimalreadonly')) {
decimalInput.val(maxFloatingDigits).attr('readonly', true);
} else {
decimalInput.removeAttr('readonly').val('');
}
}
if(selectedOption.data('predefinedvalueexists')) {
var pickListUi = form.find('.preDefinedValueExists');
pickListUi.removeClass('hide');
}
if(selectedOption.data('picklistoption')) {
var pickListOption = form.find('.picklistOption');
pickListOption.removeClass('hide');
}
})
},
/**
* Function to add new custom field ui to the list
*/
showCustomField : function(result) {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
var relatedBlock = contents.find('.block_'+result['blockid']);
var fieldCopy = contents.find('.newCustomFieldCopy').clone(true, true);
var fieldContainer = fieldCopy.find('div.marginLeftZero.border1px');
fieldContainer.addClass('opacity editFields').attr('data-field-id', result['id']).attr('data-block-id', result['blockid']);
fieldContainer.find('.deleteCustomField, .saveFieldDetails').attr('data-field-id', result['id']);
fieldContainer.find('.fieldLabel').html(result['label']);
if(!result['customField']){
fieldContainer.find('.deleteCustomField').remove();
}
var block = relatedBlock.find('.blockFieldsList');
var sortable1 = block.find('ul[name=sortable1]');
var length1 = sortable1.children().length;
var sortable2 = block.find('ul[name=sortable2]');
var length2 = sortable2.children().length;
// Deciding where to add the new field
if(length1 > length2) {
sortable2.append(fieldCopy.removeClass('hide newCustomFieldCopy'));
} else {
sortable1.append(fieldCopy.removeClass('hide newCustomFieldCopy'));
}
var form = fieldCopy.find('form.fieldDetailsForm');
thisInstance.setFieldDetails(result, form);
thisInstance.makeFieldsListSortable();
},
/**
* Function to set the field info for edit field actions
*/
setFieldDetails : function(result, form) {
var thisInstance = this;
//add field label to the field details
form.find('.modal-header').html(jQuery('<strong>'+result['label']+'</strong><div class="pull-right"><a href="javascript:void(0)" class="cancel">X</a></div>'));
var defaultValueUi = form.find('.defaultValueUi');
if(result['mandatory']) {
form.find('[name="mandatory"]').filter(':checkbox').attr('checked', true);
}
if(result['presence']) {
form.find('[name="presence"]').filter(':checkbox').attr('checked', true);
}
if(result['quickcreate']) {
form.find('[name="quickcreate"]').filter(':checkbox').attr('checked', true);
}
if(result['isQuickCreateDisabled']) {
form.find('[name="quickcreate"]').filter(':checkbox').attr('readonly', 'readonly').addClass('optionDisabled');
}
if(result['isSummaryField']) {
form.find('[name="summaryfield"]').filter(':checkbox').attr('checked', true);
}
if(result['isSummaryFieldDisabled']) {
form.find('[name="summaryfield"]').filter(':checkbox').attr('readonly', 'readonly').addClass('optionDisabled');
}
if(result['masseditable']) {
form.find('[name="masseditable"]').filter(':checkbox').attr('checked', true);
}
if(result['isMassEditDisabled']) {
form.find('[name="masseditable"]').filter(':checkbox').attr('readonly', 'readonly').addClass('optionDisabled');
}
if(result['isDefaultValueDisabled']) {
form.find('[name="defaultvalue"]').filter(':checkbox').attr('readonly', 'readonly').addClass('optionDisabled');
}
if(result['defaultvalue']) {
form.find('[name="defaultvalue"]').filter(':checkbox').attr('checked', true);
defaultValueUi.removeClass('zeroOpacity');
} else {
defaultValueUi.addClass('zeroOpacity');
}
//based on the field model it will give the respective ui for the field
var fieldModel = Vtiger_Field_Js.getInstance(result);
var fieldUi = fieldModel.getUiTypeSpecificHtml();
defaultValueUi.html(fieldUi);
defaultValueUi.find('.chzn-select').removeClass('chzn-select');
//Handled Time field UI
var timeField = defaultValueUi.find('.timepicker-default');
timeField.removeClass('timePicker timepicker-default');
timeField.attr('data-toregister','time');
//Handled date field UI
var dateField = defaultValueUi.find('.dateField')
dateField.removeClass('dateField');
dateField.attr('data-toregister','date');
defaultValueUi.find('[data-validation-engine]').attr('data-validation-engine','validate[required,funcCall[Vtiger_Base_Validator_Js.invokeValidation]]');
defaultValueUi.find('[name*='+result['name']+']').attr('name', 'fieldDefaultValue');
defaultValueUi.find('[name="fieldDefaultValue"]').attr('disabled','disabled');
defaultValueUi.find('input').addClass('input-medium');
defaultValueUi.find('.select2').addClass('row-fluid');
},
/**
* Function to register click event for add custom block button
*/
registerAddCustomBlockEvent : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
contents.find('.addCustomBlock').click(function(e) {
var addBlockContainer = contents.find('.addBlockModal').clone(true, true);
var callBackFunction = function(data) {
data.find('.addBlockModal').removeClass('hide');
//register all select2 Elements
app.showSelect2ElementView(data.find('select'));
var form = data.find('.addCustomBlockForm');
thisInstance.setBlocksListArray(form);
var fieldLabel = form.find('[name="label"]');
var params = app.validationEngineOptions;
params.onValidationComplete = function(form, valid){
if(valid) {
var formData = form.serializeFormData();
if(jQuery.inArray(formData['label'], thisInstance.blockNamesList) == -1) {
thisInstance.saveBlockDetails(form).then(
function(data) {
var params = {};
if(data['success']) {
var result = data['result'];
thisInstance.displayNewCustomBlock(result);
thisInstance.updateNewSequenceForBlocks(result['sequenceList']);
thisInstance.appendNewBlockToBlocksList(result, form);
thisInstance.makeFieldsListSortable();
params['text'] = app.vtranslate('JS_CUSTOM_BLOCK_ADDED');
} else {
params['text'] = data['error']['message'];
params['type'] = 'error';
}
Settings_Vtiger_Index_Js.showMessage(params);
}
);
app.hideModalWindow();
return valid;
} else {
var result = app.vtranslate('JS_BLOCK_NAME_EXISTS');
fieldLabel.validationEngine('showPrompt', result , 'error','topLeft',true);
e.preventDefault();
return;
}
}
}
form.validationEngine(params);
form.submit(function(e) {
e.preventDefault();
})
}
app.showModalWindow(addBlockContainer,function(data) {
if(typeof callBackFunction == 'function') {
callBackFunction(data);
}
}, {'width':'1000px'});
});
},
/**
* Function to save the new custom block details
*/
saveBlockDetails : function(form) {
var thisInstance = this;
var aDeferred = jQuery.Deferred();
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = form.serializeFormData();
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['sourceModule'] = jQuery('#selectedModuleName').val();
params['action'] = 'Block';
params['mode'] = 'save';
AppConnector.request(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
aDeferred.resolve(data);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
aDeferred.reject(error);
}
);
return aDeferred.promise();
},
/**
* Function used to display the new custom block ui after save
*/
displayNewCustomBlock : function(result) {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
var beforeBlockId = result['beforeBlockId'];
var beforeBlock = contents.find('.block_'+beforeBlockId);
var newBlockCloneCopy = contents.find('.newCustomBlockCopy').clone(true, true);
newBlockCloneCopy.data('blockId', result['id']).find('.blockLabel').append(jQuery('<strong>'+result['label']+'</strong>'));
newBlockCloneCopy.find('.blockVisibility').data('blockId', result['id']);
if(result['isAddCustomFieldEnabled']) {
newBlockCloneCopy.find('.addCustomField').removeClass('hide');
}
beforeBlock.after(newBlockCloneCopy.removeClass('hide newCustomBlockCopy').addClass('editFieldsTable block_'+result['id']));
newBlockCloneCopy.find('.blockFieldsList').sortable({'connectWith' : '.blockFieldsList'});
},
/**
* Function to update the sequence for all blocks after adding new Block
*/
updateNewSequenceForBlocks : function(sequenceList) {
var contents = jQuery('#layoutEditorContainer').find('.contents');
jQuery.each(sequenceList, function(blockId, sequence) {
contents.find('.block_'+blockId).data('sequence', sequence);
});
},
/**
* Function to update the block list with the new block label in the clone container
*/
appendNewBlockToBlocksList : function(result, form) {
var contents = jQuery('#layoutEditorContainer').find('.contents');
var hiddenAddBlockModel = contents.find('.addBlockModal');
var blocksListSelect = hiddenAddBlockModel.find('[name="beforeBlockId"]');
var option = jQuery("<option>",{
value: result['id'],
text: result['label']
})
blocksListSelect.append(option.attr('data-label', result['label']));
},
/**
* Function to update the block list to remove the deleted custom block label in the clone container
*/
removeBlockFromBlocksList : function(blockId) {
var contents = jQuery('#layoutEditorContainer').find('.contents');
var hiddenAddBlockModel = contents.find('.addBlockModal');
var blocksListSelect = hiddenAddBlockModel.find('[name="beforeBlockId"]');
blocksListSelect.find('option[value="'+blockId+'"]').remove();
},
/**
* Function to register the change event for block visibility
*/
registerBlockVisibilityEvent : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
contents.on('click', 'li.blockVisibility', function(e) {
var currentTarget = jQuery(e.currentTarget);
var oldDisplayStatus = currentTarget.data('visible');
if(oldDisplayStatus == '0') {
currentTarget.find('.icon-ok').removeClass('hide');
currentTarget.data('visible', '1');
} else {
currentTarget.find('.icon-ok').addClass('hide');
currentTarget.data('visible', '0');
}
thisInstance.updateBlockStatus(currentTarget);
})
},
/**
* Function to save the changed visibility for the block
*/
updateBlockStatus : function(currentTarget) {
var thisInstance = this;
var blockStatus = currentTarget.data('visible');
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['sourceModule'] = jQuery('#selectedModuleName').val();
params['action'] = 'Block';
params['mode'] = 'save';
params['blockid'] = currentTarget.data('blockId');
params['display_status'] = blockStatus;
AppConnector.request(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
var params = {};
if(blockStatus == '1') {
params['text'] = app.vtranslate('JS_BLOCK_VISIBILITY_SHOW');
} else {
params['text'] = app.vtranslate('JS_BLOCK_VISIBILITY_HIDE');
}
Settings_Vtiger_Index_Js.showMessage(params);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
}
);
},
/**
* Function to register the click event for inactive fields list
*/
registerInactiveFieldsEvent : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
contents.on('click', 'li.inActiveFields', function(e) {
var currentTarget = jQuery(e.currentTarget);
var currentBlock = currentTarget.closest('.editFieldsTable');
var blockId = currentBlock.data('blockId');
//If there are no hidden fields, show pnotify
if(jQuery.isEmptyObject(thisInstance.inActiveFieldsList[blockId])) {
var params = {};
params['text'] = app.vtranslate('JS_NO_HIDDEN_FIELDS_EXISTS');
params['type'] = 'error';
Settings_Vtiger_Index_Js.showMessage(params);
} else {
var inActiveFieldsContainer = contents.find('.inactiveFieldsModal').clone(true, true);
var callBackFunction = function(data) {
data.find('.inactiveFieldsModal').removeClass('hide');
thisInstance.reactiveFieldsList = [];
var form = data.find('.inactiveFieldsForm');
thisInstance.showHiddenFields(blockId, form);
//register click event for reactivate button in the inactive fields modal
data.find('[name="reactivateButton"]').click(function(e) {
thisInstance.createReactivateFieldslist(blockId, form);
thisInstance.reActivateHiddenFields(currentBlock);
app.hideModalWindow();
});
}
app.showModalWindow(inActiveFieldsContainer,function(data) {
if(typeof callBackFunction == 'function') {
callBackFunction(data);
}
}, {'width':'1000px'});
}
});
},
/**
* Function to show the list of inactive fields in the modal
*/
showHiddenFields : function(blockId, form) {
var thisInstance = this;
jQuery.each(thisInstance.inActiveFieldsList[blockId], function(key, value) {
var inActiveField = jQuery('<div class="span4 marginLeftZero padding-bottom1per"><label class="checkbox">\n\
<input type="checkbox" class="inActiveField" value="'+key+'" />&nbsp;'+value+'</label></div>');
form.find('.inActiveList').append(inActiveField);
});
},
/**
* Function to create the list of reactivate fields list
*/
createReactivateFieldslist : function(blockId, form) {
var thisInstance = this;
form.find('.inActiveField').each(function(index,domElement){
var element = jQuery(domElement);
var fieldId = element.val();
if(element.is(':checked')) {
delete thisInstance.inActiveFieldsList[blockId][fieldId];
thisInstance.reactiveFieldsList.push(fieldId);
}
});
},
/**
* Function to unHide the selected fields in the inactive fields modal
*/
reActivateHiddenFields : function(currentBlock) {
var thisInstance = this;
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['action'] = 'Field';
params['mode'] = 'unHide';
params['blockId'] = currentBlock.data('blockId');
params['fieldIdList'] = JSON.stringify(thisInstance.reactiveFieldsList);
AppConnector.request(params).then(
function(data) {
for(var index in data.result) {
thisInstance.showCustomField(data.result[index]);
}
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
var params = {};
params['text'] = app.vtranslate('JS_SELECTED_FIELDS_REACTIVATED');
Settings_Vtiger_Index_Js.showMessage(params);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
}
);
},
/**
* Function to register the click event for delete custom block
*/
registerDeleteCustomBlockEvent : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
var table = contents.find('.editFieldsTable');
contents.on('click', 'li.deleteCustomBlock', function(e) {
var currentTarget = jQuery(e.currentTarget);
var table = currentTarget.closest('div.editFieldsTable');
var blockId = table.data('blockId');
var message = app.vtranslate('JS_LBL_ARE_YOU_SURE_YOU_WANT_TO_DELETE');
Vtiger_Helper_Js.showConfirmationBox({'message' : message}).then(
function(e) {
thisInstance.deleteCustomBlock(blockId);
},
function(error, err){
}
);
});
},
/**
* Function to delete the custom block
*/
deleteCustomBlock : function(blockId) {
var thisInstance = this;
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['action'] = 'Block';
params['mode'] = 'delete';
params['blockid'] = blockId;
AppConnector.request(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
var params = {};
if(data['success']) {
thisInstance.removeDeletedBlock(blockId);
thisInstance.removeBlockFromBlocksList(blockId);
params['text'] = app.vtranslate('JS_CUSTOM_BLOCK_DELETED');
} else {
params['text'] = data['error']['message'];
params['type'] = 'error';
}
Settings_Vtiger_Index_Js.showMessage(params);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
}
);
},
/**
* Function to remove the deleted custom block from the ui
*/
removeDeletedBlock : function(blockId) {
var contents = jQuery('#layoutEditorContainer').find('.contents');
var deletedTable = contents.find('.block_'+blockId);
deletedTable.fadeOut('slow').remove();
},
/**
* Function to register the click event for delete custom field
*/
registerDeleteCustomFieldEvent : function(contents) {
var thisInstance = this;
if(typeof contents == 'undefined') {
contents = jQuery('#layoutEditorContainer').find('.contents');
}
contents.find('a.deleteCustomField').click(function(e) {
var currentTarget = jQuery(e.currentTarget);
var fieldId = currentTarget.data('fieldId');
var message = app.vtranslate('JS_LBL_ARE_YOU_SURE_YOU_WANT_TO_DELETE');
Vtiger_Helper_Js.showConfirmationBox({'message' : message}).then(
function(e) {
thisInstance.deleteCustomField(fieldId).then(
function(data) {
var field = currentTarget.closest('div.editFields');
var blockId = field.data('blockId');
field.parent().fadeOut('slow').remove();
var block = jQuery('#block_'+blockId);
thisInstance.reArrangeBlockFields(block);
var params = {};
params['text'] = app.vtranslate('JS_CUSTOM_FIELD_DELETED');
Settings_Vtiger_Index_Js.showMessage(params);
},function(error, err) {
}
);
},
function(error, err){
}
);
});
},
/**
* Function to delete the custom field
*/
deleteCustomField : function(fieldId) {
var thisInstance = this;
var aDeferred = jQuery.Deferred();
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['action'] = 'Field';
params['mode'] = 'delete';
params['fieldid'] = fieldId;
AppConnector.request(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
aDeferred.resolve(data);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
aDeferred.reject();
}
);
return aDeferred.promise();
},
/**
* Function to register the click event for save button after edit field details
*/
registerSaveFieldDetailsEvent : function(form) {
var thisInstance = this;
var submitButtton = form.find('.saveFieldDetails');
var fieldId = submitButtton.data('fieldId');
var block = submitButtton.closest('.editFieldsTable');
var blockId = block.data('blockId');
//close the drop down
submitButtton.closest('.btn-group').removeClass('open');
//adding class opacity to fieldRow - to give opacity to the actions of the fields
var fieldRow = submitButtton.closest('.editFields');
fieldRow.addClass('opacity');
thisInstance.saveFieldDetails(submitButtton).then(
function(data) {
var result = data['result'];
var fieldLabel = fieldRow.find('.fieldLabel');
if(result['presence'] == '1') {
fieldRow.parent().fadeOut('slow').remove();
if(jQuery.isEmptyObject(thisInstance.inActiveFieldsList[blockId])) {
if(thisInstance.inActiveFieldsList.length == '0') {
thisInstance.inActiveFieldsList = {};
}
thisInstance.inActiveFieldsList[blockId] = {};
thisInstance.inActiveFieldsList[blockId][fieldId] = result['label'];
} else {
thisInstance.inActiveFieldsList[blockId][fieldId] = result['label'];
}
thisInstance.reArrangeBlockFields(block);
}
if(result['mandatory']) {
if(fieldLabel.find('.redColor').length == '0') {
fieldRow.find('.fieldLabel').append(jQuery('<span class="redColor">*</span>'));
}
} else {
fieldRow.find('.fieldLabel').find('.redColor').remove();
}
//updating the hidden container with saved values.
var dropDownMenu = form.closest('.dropdown-menu');
app.destroyChosenElement(form);
var selectElemet = form.find('.defaultValueUi ').find('select');
var selectedvalue = selectElemet.val();
selectElemet.removeAttr('disabled');
selectElemet.find('option').removeAttr('selected');
if(selectedvalue != null ){
if(typeof(selectElemet.attr('multiple')) == 'undefined'){
var encodedSelectedValue = selectedvalue.replace(/"/g, '\\"');
selectElemet.find('[value="'+encodedSelectedValue+'"]').attr('selected','selected');
} else {
for (var i = 0; i < selectedvalue.length; i++) {
var encodedSelectedValue = selectedvalue[i].replace(/"/g, '\\"');
selectElemet.find('[value="'+encodedSelectedValue+'"]').attr('selected','selected');
}
}
}
//handled registration of time field
var timeFieldElement = form.find('[data-toregister="time"]');
if(timeFieldElement.length > 0){
app.destroyTimeFields(timeFieldElement);
}
var basicContents = form.closest('.editFields').find('.basicFieldOperations');
basicContents.html(form);
dropDownMenu.remove();
},
function(error, err) {
}
);
},
/**
* Function to save all the field details which are changed
*/
saveFieldDetails : function(currentTarget) {
var thisInstance = this;
var aDeferred = jQuery.Deferred();
var form = currentTarget.closest('form.fieldDetailsForm');
var fieldId = currentTarget.data('fieldId');
var defaultValueField = form.find('[name=fieldDefaultValue]');
var defaultValue = defaultValueField.val();
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = form.serializeFormData();
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['action'] = 'Field';
params['mode'] = 'save';
params['fieldid'] = fieldId;
params['sourceModule'] = jQuery('#selectedModuleName').val();
AppConnector.request(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
var params = {};
params['text'] = app.vtranslate('JS_FIELD_DETAILS_SAVED');
Settings_Vtiger_Index_Js.showMessage(params);
if(defaultValueField.prop("tagName") == 'TEXTAREA') {
defaultValueField.text(defaultValue);
}
aDeferred.resolve(data);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
aDeferred.reject();
}
);
return aDeferred.promise();
},
/**
* Function to register the cahnge event for mandatory & default checkboxes in edit field details
*/
registerFieldDetailsChange : function(contents) {
if(typeof contents == 'undefined') {
contents = jQuery('#layoutEditorContainer').find('.contents');
}
contents.on('change', '[name="mandatory"]', function(e) {
var currentTarget = jQuery(e.currentTarget);
if(currentTarget.attr('readonly') != 'readonly') {
var form = currentTarget.closest('.fieldDetailsForm');
var quickcreateEle = form.find('[name="quickcreate"]').filter(':checkbox').not('.optionDisabled');
var presenceEle = form.find('[name="presence"]').filter(':checkbox').not('.optionDisabled');
if(currentTarget.is(':checked')) {
quickcreateEle.attr('checked', true).attr('readonly', 'readonly');
presenceEle.attr('checked', true).attr('readonly', 'readonly');
} else {
quickcreateEle.removeAttr('readonly');
presenceEle.removeAttr('readonly');
}
}
})
contents.on('change', '[name="defaultvalue"]', function(e) {
var currentTarget = jQuery(e.currentTarget);
var defaultValueUi = currentTarget.closest('span').find('.defaultValueUi');
var defaultField = defaultValueUi.find('[name="fieldDefaultValue"]');
if(currentTarget.is(':checked')) {
defaultValueUi.removeClass('zeroOpacity');
defaultField.removeAttr('disabled');
if(defaultField.is('select')){
defaultField.trigger("liszt:updated");
}
} else {
defaultField.attr('disabled', 'disabled');
// defaultField.val('');
defaultValueUi.addClass('zeroOpacity');
}
})
},
/**
* Function to register the click event for related modules list tab
*/
relatedModulesTabClickEvent : function() {
var thisInstance = this;
var contents = jQuery('#layoutEditorContainer').find('.contents');
var relatedContainer = contents.find('#relatedTabOrder');
var relatedTab = contents.find('.relatedListTab');
relatedTab.click(function() {
if(relatedContainer.find('.relatedTabModulesList').length > 0) {
} else {
thisInstance.showRelatedTabModulesList(relatedContainer);
}
});
},
/**
* Function to show the related tab modules list in the tab
*/
showRelatedTabModulesList : function(relatedContainer) {
var thisInstance = this;
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['sourceModule'] = jQuery('#selectedModuleName').val();
params['view'] = 'Index';
params['mode'] = 'showRelatedListLayout';
AppConnector.request(params).then(
function(data) {
relatedContainer.html(data);
if(jQuery(data).find('.relatedListContainer').length > 0) {
thisInstance.makeRelatedModuleSortable();
thisInstance.registerRelatedListEvents();
thisInstance.setRemovedModulesList();
}
},
function(error) {
}
);
},
/**
* Function to get the respective module layout editor through pjax
*/
getModuleLayoutEditor : function(selectedModule) {
var thisInstance = this;
var aDeferred = jQuery.Deferred();
var progressIndicatorElement = jQuery.progressIndicator({
'position' : 'html',
'blockInfo' : {
'enabled' : true
}
});
var params = {};
params['module'] = app.getModuleName();
params['parent'] = app.getParentModuleName();
params['view'] = 'Index';
params['sourceModule'] = selectedModule;
AppConnector.requestPjax(params).then(
function(data) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
aDeferred.resolve(data);
},
function(error) {
progressIndicatorElement.progressIndicator({'mode' : 'hide'});
aDeferred.reject();
}
);
return aDeferred.promise();
},
/**
* Function to register the change event for layout editor modules list
*/
registerModulesChangeEvent : function() {
var thisInstance = this;
var container = jQuery('#layoutEditorContainer');
var contentsDiv = container.closest('.contentsDiv');
app.showSelect2ElementView(container.find('[name="layoutEditorModules"]'), {dropdownCss : {'z-index' : 0}});
container.on('change', '[name="layoutEditorModules"]', function(e) {
var currentTarget = jQuery(e.currentTarget);
var selectedModule = currentTarget.val();
thisInstance.getModuleLayoutEditor(selectedModule).then(
function(data) {
contentsDiv.html(data);
thisInstance.registerEvents();
}
);
});
},
/**
* Function to register click event for drop-downs in fields list
*/
avoidDropDownClick : function(dropDownContainer) {
dropDownContainer.find('.dropdown-menu').click(function(e) {
e.stopPropagation();
});
},
registerEditFieldDetailsClick : function(contents) {
var thisInstance = this;
if(typeof contents == 'undefined') {
contents = jQuery('#layoutEditorContainer').find('.contents');
}
contents.find('.editFieldDetails').click(function(e) {
var currentTarget = jQuery(e.currentTarget);
var fieldRow = currentTarget.closest('div.editFields');
fieldRow.removeClass('opacity');
var basicDropDown = fieldRow.find('.basicFieldOperations');
var dropDownContainer = currentTarget.closest('.btn-group');
dropDownContainer.find('.dropdown-menu').remove();
var dropDown = basicDropDown.clone().removeClass('basicFieldOperations hide').addClass('dropdown-menu');
dropDownContainer.append(dropDown);
var dropDownMenu = dropDownContainer.find('.dropdown-menu');
var params = app.getvalidationEngineOptions(true);
params.binded = false,
params.onValidationComplete = function(form,valid){
if(valid) {
if(form.hasClass('fieldDetailsForm')){
thisInstance.registerSaveFieldDetailsEvent(form);
}
}
return false;
}
dropDownMenu.find('form').validationEngine(params);
var defaultValueUiContainer = basicDropDown.find('.defaultValueUi');
//handled registration of chosen for select element
var selectElements = defaultValueUiContainer.find('select');
if(selectElements.length > 0) {
dropDownMenu.find('select').addClass('chzn-select');
app.changeSelectElementView(dropDownMenu);
}
//handled registration of time field
var timeFieldElement = defaultValueUiContainer.find('[data-toregister="time"]');
if(timeFieldElement.length > 0){
dropDownMenu.find('[data-toregister="time"]').addClass('timepicker-default timePicker');
app.registerEventForTimeFields(dropDownMenu);
}
//handled registration for date fields
var dateField = defaultValueUiContainer.find('[data-toregister="date"]');
if(dateField.length > 0) {
dropDownMenu.find('[data-toregister="date"]').addClass('dateField');
app.registerEventForDatePickerFields(dropDownMenu);
}
thisInstance.avoidDropDownClick(dropDownContainer);
dropDownMenu.on('change', ':checkbox', function(e) {
var currentTarget = jQuery(e.currentTarget);
if(currentTarget.attr('readonly') == 'readonly') {
var status = jQuery(e.currentTarget).is(':checked');
if(!status){
jQuery(e.currentTarget).attr('checked','checked')
}else{
jQuery(e.currentTarget).removeAttr('checked');
}
e.preventDefault();
}
});
//added for drop down position change
var offset = currentTarget.offset(),
height = currentTarget.outerHeight(),
dropHeight = dropDown.outerHeight(),
viewportBottom = $(window).scrollTop() + document.documentElement.clientHeight,
dropTop = offset.top + height,
enoughRoomBelow = dropTop + dropHeight <= viewportBottom;
if(!enoughRoomBelow) {
dropDown.addClass('bottom-up');
} else {
dropDown.removeClass('bottom-up');
}
var callbackFunction = function() {
fieldRow.addClass('opacity');
dropDown.remove();
jQuery('body').off('click.dropdown.data-api.layouteditor');
}
thisInstance.addClickOutSideEvent(dropDown, callbackFunction);
jQuery('.cancel').click(function(){
callbackFunction();
});
jQuery('body').on('click.dropdown.data-api.layouteditor',function(e){
var target = jQuery(e.target);
//user clicked on time picker
if(target.closest('.ui-timepicker-list').length > 0) {
e.stopPropagation();
}
})
});
},
/**
* Function to register all the events for blocks
*/
registerBlockEvents : function() {
var thisInstance = this;
thisInstance.makeBlocksListSortable();
thisInstance.registerAddCustomFieldEvent();
thisInstance.registerBlockVisibilityEvent();
thisInstance.registerInactiveFieldsEvent();
thisInstance.registerDeleteCustomBlockEvent();
},
/**
* Function to register all the events for fields
*/
registerFieldEvents : function(contents) {
var thisInstance = this;
if(typeof contents == 'undefined') {
contents = jQuery('#layoutEditorContainer').find('.contents');
}
app.registerEventForDatePickerFields(contents);
app.registerEventForTimeFields(contents);
app.changeSelectElementView(contents);
thisInstance.makeFieldsListSortable();
thisInstance.registerDeleteCustomFieldEvent(contents);
thisInstance.registerFieldDetailsChange(contents);
thisInstance.registerEditFieldDetailsClick(contents);
contents.find(':checkbox').change(function(e) {
var currentTarget = jQuery(e.currentTarget);
if(currentTarget.attr('readonly') == 'readonly') {
var status = jQuery(e.currentTarget).is(':checked');
if(!status){
jQuery(e.currentTarget).attr('checked','checked')
}else{
jQuery(e.currentTarget).removeAttr('checked');
}
e.preventDefault();
}
});
},
/*
* Function to add clickoutside event on the element - By using outside events plugin
* @params element---On which element you want to apply the click outside event
* @params callbackFunction---This function will contain the actions triggered after clickoutside event
*/
addClickOutSideEvent : function(element, callbackFunction) {
element.one('clickoutside',callbackFunction);
},
/**
* register events for layout editor
*/
registerEvents : function() {
var thisInstance = this;
thisInstance.registerBlockEvents();
thisInstance.registerFieldEvents();
thisInstance.setInactiveFieldsList();
thisInstance.registerAddCustomBlockEvent();
thisInstance.registerFieldSequenceSaveClick();
thisInstance.relatedModulesTabClickEvent();
thisInstance.registerModulesChangeEvent();
//SalesPlatform.ru begin fieldname tooltip
jQuery('[data-toggle="tooltip"]').tooltip();
//SalesPlatform.ru end
}
});
jQuery(document).ready(function() {
var instance = new Settings_LayoutEditor_Js();
instance.registerEvents();
})
Vtiger_WholeNumberGreaterThanZero_Validator_Js("Vtiger_FloatingDigits_Validator_Js",{
/**
*Function which invokes field validation
*@param accepts field element as parameter
* @return error if validation fails true on success
*/
invokeValidation: function(field, rules, i, options){
var rangeInstance = new Vtiger_FloatingDigits_Validator_Js();
rangeInstance.setElement(field);
var response = rangeInstance.validate();
if(response != true){
return rangeInstance.getError();
}
}
},{
/**
* Function to validate the decimals length
* @return true if validation is successfull
* @return false if validation error occurs
*/
validate: function(){
var response = this._super();
if(response != true){
return response;
}else{
var fieldValue = this.getFieldValue();
if (fieldValue < 2 || fieldValue > 5) {
var errorInfo = app.vtranslate('JS_PLEASE_ENTER_NUMBER_IN_RANGE_2TO5');
this.setError(errorInfo);
return false;
}
var specialChars = /^[+]/ ;
if (specialChars.test(fieldValue)) {
var error = app.vtranslate('JS_CONTAINS_ILLEGAL_CHARACTERS');
this.setError(error);
return false;
}
return true;
}
}
});
Vtiger_WholeNumberGreaterThanZero_Validator_Js("Vtiger_DecimalMaxLength_Validator_Js",{
/**
*Function which invokes field validation
*@param accepts field element as parameter
* @return error if validation fails true on success
*/
invokeValidation: function(field, rules, i, options){
var rangeInstance = new Vtiger_DecimalMaxLength_Validator_Js();
rangeInstance.setElement(field);
var response = rangeInstance.validate();
if(response != true){
return rangeInstance.getError();
}
}
},{
/**
* Function to validate the fieldLength
* @return true if validation is successfull
* @return false if validation error occurs
*/
validate: function(){
var response = this._super();
if(response != true){
return response;
}else{
var fieldValue = this.getFieldValue();
var decimalFieldValue = jQuery('#createFieldForm').find('[name="decimal"]').val();
var fieldLength = parseInt(64)-parseInt(decimalFieldValue);
if (fieldValue > fieldLength && !(fieldLength < 0) && fieldLength >= 59) {
var errorInfo = app.vtranslate('JS_LENGTH_SHOULD_BE_LESS_THAN_EQUAL_TO')+' '+fieldLength;
this.setError(errorInfo);
return false;
}
var specialChars = /^[+]/ ;
if (specialChars.test(fieldValue)) {
var error = app.vtranslate('JS_CONTAINS_ILLEGAL_CHARACTERS');
this.setError(error);
return false;
}
return true;
}
}
});
Vtiger_WholeNumberGreaterThanZero_Validator_Js("Vtiger_MaxLength_Validator_Js",{
/**
*Function which invokes field validation
*@param accepts field element as parameter
* @return error if validation fails true on success
*/
invokeValidation: function(field, rules, i, options){
var rangeInstance = new Vtiger_DecimalMaxLength_Validator_Js();
rangeInstance.setElement(field);
var response = rangeInstance.validate();
if(response != true){
return rangeInstance.getError();
}
}
},{
/**
* Function to validate the fieldLength
* @return true if validation is successfull
* @return false if validation error occurs
*/
validate: function(){
var response = this._super();
if(response != true){
return response;
}else{
var fieldValue = this.getFieldValue();
if (fieldValue > 255) {
var errorInfo = app.vtranslate('JS_LENGTH_SHOULD_BE_LESS_THAN_EQUAL_TO')+' 255';
this.setError(errorInfo);
return false;
}
var specialChars = /^[+]/ ;
if (specialChars.test(fieldValue)) {
var error = app.vtranslate('JS_CONTAINS_ILLEGAL_CHARACTERS');
this.setError(error);
return false;
}
return true;
}
}
});
Vtiger_Base_Validator_Js("Vtiger_FieldLabel_Validator_Js",{
/**
*Function which invokes field validation
*@param accepts field element as parameter
* @return error if validation fails true on success
*/
invokeValidation: function(field, rules, i, options){
var instance = new Vtiger_FieldLabel_Validator_Js();
instance.setElement(field);
var response = instance.validate();
if(response != true){
return instance.getError();
}
}
},{
/**
* Function to validate the field label
* @return true if validation is successfull
* @return false if validation error occurs
*/
validate: function(){
var fieldValue = this.getFieldValue();
return this.validateValue(fieldValue);
},
validateValue : function(fieldValue){
var specialChars = /[&\<\>\:\'\"\,\_]/ ;
if (specialChars.test(fieldValue)) {
var errorInfo = app.vtranslate('JS_SPECIAL_CHARACTERS')+" & < > ' \" : , _ "+app.vtranslate('JS_NOT_ALLOWED');
this.setError(errorInfo);
return false;
}
return true;
}
});
Vtiger_Base_Validator_Js("Vtiger_PicklistFieldValues_Validator_Js",{
/**
*Function which invokes field validation
*@param accepts field element as parameter
* @return error if validation fails true on success
*/
invokeValidation: function(field, rules, i, options){
var instance = new Vtiger_PicklistFieldValues_Validator_Js();
instance.setElement(field);
var response = instance.validate();
if(response != true){
return instance.getError();
}
}
},{
/**
* Function to validate the field label
* @return true if validation is successfull
* @return false if validation error occurs
*/
validate: function(){
var fieldValue = this.getFieldValue();
return this.validateValue(fieldValue);
},
validateValue : function(fieldValue){
var specialChars = /(\<|\>)/gi ;
if (specialChars.test(fieldValue)) {
var errorInfo = app.vtranslate('JS_SPECIAL_CHARACTERS')+" < >"+app.vtranslate('JS_NOT_ALLOWED');
this.setError(errorInfo);
return false;
}
return true;
}
});