Маска номера телефона детали ContactCommunication

Добрый день!

 

Подскажите варианты добаления маски номера телефона детали ContactCommunicationDetail.

 

На страничке раздела Контакты, при добавлении средства связи = моб телефон = была преднатсроена маска ввода номера телефона. 

Изображение удалено.

Нравится

2 комментария

Добрый вечер, Андрий!

 

На данный момент возможности настроить маску пользовательскими средствами нет.

 

Возможно, решить Вашу задачу поможет информация в этом посте https://community.terrasoft.ua/questions/maska-telefona-na-detali-sredstva-svyazi

Добрый день!

Как и сказала Алла, необходимы навыки разработки для добавления маски. Привожу пример как это сделать с колонкой контакта.

Для начала создаем модуль MultiMaskEdit

 define("MultiMaskEdit", ["ext-base", "terrasoft"], function(Ext, Terrasoft) {
    /**
     * @class Terrasoft.controls.MultiMaskEdit
     */
    Ext.define("Terrasoft.controls.MultiMaskEdit", {
        extend: "Terrasoft.TextEdit",
        alternateClassName: "Terrasoft.MultiMaskEdit",
 
        /**
         * @public
         * @type {Terrasoft.Align}
         */
        textAlign: Terrasoft.Align.LEFT,
        /**
         * @protected
         * @overridden
         */
        onFocus: function() {
            this.callParent(arguments);
            var value = this.getTypedValue();
            this.setDomValue(value);
        },
        /**
         * @protected
         * @virtual
         * @return {String}
         */
        getInitValue: function() {
            var value = this.callParent(arguments);
            if (!Ext.isEmpty(value) && !Ext.isEmpty(this.masks)) {
                var formatValue = this.formatValue(value);
                this.value = formatValue.value;
                var validationInfo = this.getValidationInfo(formatValue);
                this.setValidationInfo(validationInfo);
            }
            return this.value;
        },
        getValidationInfo: function(value) {
            var formatValue = (!Ext.isEmpty(value) && Ext.isBoolean(value.isComplete)) ? value : this.formatValue(value);
            var validationInfo = {
                isValid: true,
                invalidMessage: ""
            };
            if (!formatValue.isComplete) {
                validationInfo = {
                    isValid: false,
                    invalidMessage: this.getIncorrectNumberMessage()
                };
            }
            return validationInfo;
        },
        getIncorrectNumberMessage: function() {
            return "Invalid number";
        },
        /**
         * @protected
         * @overridden
         * @param  {Event} e DOM keypress
         * @param  {String} type (optional)
         * значение Terrasoft.DataValueType.FLOAT
         */
        onKeyPress: function(e) {
            this.callParent(arguments);
            if (this.readonly || Ext.isEmpty(this.masks)) {
                return;
            }
            var isSpecialKey = Ext.isGecko && e.isSpecialKey();
            if (isSpecialKey) {
                return;
            }
            e.preventDefault();
            var keyUnicode = e.getKey();
            var key = String.fromCharCode(keyUnicode);
            if (this.baseCharsRe && !this.baseCharsRe.test(key)) {
                return;
            }
            var domEl = e.getTarget();
            var info = this.getInputInfo(domEl);
            var formatValue = this.formatValueByInsChar(key, info.caretPosition, info.valueBeforeCaret, info.valueSelected,
                info.valueAfterCaret);
            if (!formatValue) {
                return;
            }
            domEl.value = formatValue.value;
            Terrasoft.utils.dom.setCaretPosition(domEl, formatValue.pos);
            if (!this.validationInfo.isValid && formatValue.isComplete) {
                var validationInfo = {
                    isValid: true,
                    invalidMessage: ""
                };
                this.setValidationInfo(validationInfo);
            }
        },
        getInputInfo: function(domEl) {
            var selectedTextLength = Terrasoft.utils.dom.getSelectedTextLength(domEl);
            var caretPosition = Terrasoft.utils.dom.getCaretPosition(domEl);
            var value = domEl.value;
            var valueBeforeCaret = "";
            var valueAfterCaret = "";
            var valueSelected = "";
            if (Ext.isIE) {
                valueBeforeCaret = value.slice(0, caretPosition - selectedTextLength);
                valueAfterCaret = value.slice(caretPosition);
                caretPosition -= selectedTextLength;
            } else {
                valueBeforeCaret = value.slice(0, caretPosition);
                valueAfterCaret = value.slice(caretPosition + selectedTextLength);
            }
            if (selectedTextLength > 0) {
                valueSelected = value.slice(caretPosition, selectedTextLength + caretPosition);
            }
            return {
                selectedTextLength: selectedTextLength,
                caretPosition: caretPosition,
                value: value,
                valueBeforeCaret: valueBeforeCaret,
                valueAfterCaret: valueAfterCaret,
                valueSelected: valueSelected
            };
        },
        /**
         * @protected
         */
        onKeyDown: function(e) {
            this.callParent(arguments);
            if (Ext.isEmpty(this.masks)) {
                return;
            }
            var key = e.getKey();
            var matches, masks, placeHolders, commonStr;
            if (key === e.BACKSPACE || key === e.DELETE) {
                e.preventDefault();
                var domEl = e.getTarget();
                var info = this.getInputInfo(domEl);
 
                if (info.valueBeforeCaret === "" && info.valueAfterCaret === "") {
                    this.setDomValue("");
                }
 
                else if (info.selectedTextLength > 0) {
 
                    if (Ext.isEmpty(info.valueAfterCaret)) {
                        this.setDomValue(this.removeEndPlaceHolders(info.valueBeforeCaret));
                    } else {
 
                        matches = this.getMatchesByValue(info.valueBeforeCaret);
                        if (matches.matches.length === 0) {
                            return;
                        }
 
                        masks = this.getPropertyValuesFromArray(matches.matches, "mask");
 
                        placeHolders = this.getPropertyValuesFromArray(masks, "placeHolder");
                        var replaceText = this.getCommonStartString(placeHolders).substr(info.caretPosition, info.selectedTextLength);
                        if (replaceText.length === info.selectedTextLength) {
                            this.setDomValue(info.valueBeforeCaret + replaceText + info.valueAfterCaret);
                        }
                    }
                } else if (key === e.BACKSPACE && !Ext.isEmpty(info.valueBeforeCaret)) {
                    matches = this.getMatchesByValue(info.valueBeforeCaret);
                    if (matches.matches.length === 0) {
                        return;
                    }
 
                    masks = this.getPropertyValuesFromArray(matches.matches, "mask");
 
                    placeHolders = this.getPropertyValuesFromArray(masks, "placeHolder");
                    commonStr = this.getCommonStartString(placeHolders);
                    if (commonStr.length >= info.caretPosition) {
                        this.setDomValueAndCaret(info.valueBeforeCaret.slice(0, -1) + commonStr.substr(info.caretPosition - 1, 1) +
                            info.valueAfterCaret, info.caretPosition - 1);
                    }
                } else if (key === e.DELETE && !Ext.isEmpty(info.valueAfterCaret)) {
 
                    matches = this.getMatchesByValue(info.valueBeforeCaret);
                    if (matches.matches.length === 0) {
                        return;
                    }
 
                    masks = this.getPropertyValuesFromArray(matches.matches, "mask");
 
                    placeHolders = this.getPropertyValuesFromArray(masks, "placeHolder");
                    commonStr = this.getCommonStartString(placeHolders);
                    if (commonStr.length > info.caretPosition) {
                        this.setDomValueAndCaret(info.valueBeforeCaret + commonStr.substr(info.caretPosition, 1) +
                            info.valueAfterCaret.slice(1), info.caretPosition + 1);
                    }
                }
            }
        },
        maskConfig: {
            definitions: {
                //numbers
                "9": {
                    re: "[0-9]"
                },
                //cyryllic
                "к": {
                    re: "[а-яА-ЯёЁ]"
                },
                //латинские
                "l": {
                    re: "[a-zA-Z]"
                },
                //any letter
                "c": {
                    re: "[а-яА-ЯёЁa-zA-Z]"
                },
                //any letter or number
                "#": {
                    re: "[а-яА-ЯёЁA-Za-z0-9]"
                }
            },
            placeHolderChar: "_"
        },
        mask: [],
        /**
         * @protected
         * @overridden
         */
        init: function() {
            this.callParent(arguments);
            this.reSpecChars = [
                "\\", "(", ")", "+"
            ];
            this.addEvents(
                "paste");
            this.on("paste", this.onPaste, this);
            this.setMasks(this.mask);
        },
        /**
         * @protected
         * */
        setMasks: function(value) {
            this.masks = [];
            if (Ext.isEmpty(value)) {
                value = {
                    formats: []
                };
            }
            Terrasoft.each(value.formats, function(format, i) {
                this.masks[i] = this.getMaskByFormat(format);
            }, this);
            this.changeValue(this.value);
        },
        /**
         * {@link Terrasoft.Bindable}.
         * @overridden
         */
        getBindConfig: function() {
            var bindConfig = this.callParent(arguments);
            var multiMaskEditBindConfig = {
                mask: {
                    changeMethod: "setMasks"
                }
            };
            Ext.apply(bindConfig, multiMaskEditBindConfig);
            return bindConfig;
        },
        getMaskByFormat: function(format) {
            var mask = {};
            var matches = [];
            var placeHolderChar;
            var placeHolder = "";
            var def;
            var allRe = "";
 
            if (format) {
                Terrasoft.each(format.split(""), function(c) {
                    def = this.maskConfig.definitions[c];
                    if (def) {
                        allRe += def.re;
                        placeHolderChar = def.placeHolderChar || this.maskConfig.placeHolderChar || "_";
                        matches.push({
                            re: new RegExp(def.re),
                            placeHolderChar: placeHolderChar
                        });
 
                        placeHolder += placeHolderChar;
                    } else {
                        placeHolder += c;
                        matches.push(c);
                        if (this.reSpecChars.indexOf(c) > 0) {
                            allRe += "\\" + c;
                        } else {
                            allRe += c;
                        }
                    }
                }, this);
                mask.placeHolder = placeHolder;
                mask.matches = matches;
                if (allRe !== "") {
                    mask.re = {};
                    mask.re.full = new RegExp("^" + allRe + "$");
                }
            }
            return mask;
        },
        /**
         * @param value
         */
        removeEndPlaceHolders: function(value) {
            if (!Ext.isEmpty(value)) {
                var pos;
 
                for (var i = (value.length - 1); i >= 0; i--) {
 
                    if (value[i] !== this.maskConfig.placeHolderChar) {
                        break;
                    }
                    pos = i;
                }
                if (pos === 0) {
                    value = "";
                } else if (pos) {
                    value = value.slice(0, pos);
                }
            }
            return value;
        },
        /**
         * @param mask
         * @param c
         * @param pos
         * @param textBefore
         * @param textReplaced
         * @param textAfter
         * @param allowAutoFill
         * @returns {*}
         */
        maskValidateByInsChar: function(mask, c, pos, textBefore, textReplaced, textAfter, allowAutoFill) {
            var replacedLength = textReplaced.length;
            if (replacedLength > 0) {
                textAfter = mask.placeHolder.slice(pos, pos + textReplaced.length) + textAfter;
            }
            var value = textBefore + textAfter;
            var maskValidate;
            var match;
            if (!Ext.isEmpty(textAfter)) {
                match = mask.matches[pos];
                if (match && !match.re && mask.matches[pos] === c) {
                    return {
                        value: value,
                        pos: pos,
                        result: this.maskValidateValue(mask, value)
                    };
                }
            }
            value = textBefore + c + textAfter;
            match = mask.matches[pos];
            if (match) {
                if (match.re) {
                    if (textAfter[0] === mask.placeHolder.substr(pos, 1)) {
                        value = textBefore + c + textAfter.substring(1);
                        maskValidate = this.maskValidateValue(mask, value);
                        if (maskValidate.isValid) {
                            return {
                                value: value,
                                pos: pos,
                                result: maskValidate
                            };
                        }
                    }
                }
            }
            maskValidate = this.maskValidateValue(mask, value);
            if (maskValidate.isValid) {
                return {
                    value: value,
                    pos: pos,
                    result: maskValidate
                };
            }
            if (match && !match.re && allowAutoFill && pos < mask.placeHolder.length) {
                var result = this.maskValidateByInsChar(mask, c, pos + 1, textBefore + match,
                    textReplaced, textAfter.substring(1), allowAutoFill);
                if (result) {
                    return result;
                }
                return this.maskValidateByInsChar(mask, c, pos + 1, textBefore + match,
                    textReplaced, textAfter.substring(2), allowAutoFill);
            }
            //}
        },
        /**
         * @param c
         * @param pos
         * @param textBefore
         * @param textAfter
         * @param allowAutoFill
         * @returns {*}
         */
        formatValueByInsChar: function(c, pos, textBefore, textReplaced, textAfter, allowAutoFill) {
            var maskValidation;
            var bestResults = [];
            Terrasoft.each(this.masks, function(item) {
                maskValidation = this.maskValidateByInsChar(item, c, pos, textBefore, textReplaced, textAfter, allowAutoFill);
                if (maskValidation) {
                    maskValidation.mask = item;
                    if (bestResults.length === 0) {
                        bestResults.push(maskValidation);
                    } else if (maskValidation.pos < bestResults[0].pos) {
                        bestResults = [maskValidation];
                    }
                }
            }, this);
            if (bestResults.length > 0) {
                maskValidation = bestResults[0];
 
                var formatValue = this.formatValue(maskValidation.value);
                formatValue.insPos = maskValidation.pos;
                return formatValue;
            }
        },
        /**
         * @param mask
         * @param value
         * @returns {*}
         */
        maskValidateValue: function(mask, value) {
            var match;
            var matchPos = 0;
            if (mask.re.full.test(value)) {
                return {
                    matchPos: value.length,
                    inputPos: value.length,
                    isValid: true,
                    isComplete: true
                };
            }
            var result = {
                matchPos: 0,
                inputPos: 0,
                isValid: true,
                isComplete: false
            };
            value = this.removeEndPlaceHolders(value);
            if (Ext.isEmpty(value)) {
                return result;
            } else {
                Terrasoft.each(value.split(""), function(c, i) {
                    match = mask.matches[i];
                    if (!match) {
                        result = {
                            isValid: false,
                            isComplete: false
                        };
                        return false;
                    } else if (match.re) {
                        if (!match.re.test(c)) {
                            if (match.placeHolderChar === c) {
                                if (!result.inputPos) {
                                    result.inputPos = i;
                                }
                            } else {
                                result = {
                                    isValid: false,
                                    isComplete: false
                                };
                                return false;
                            }
                        }
                    } else if (c !== match) {
                        result = {
                            isValid: false,
                            isComplete: false
                        };
                        return false;
                    }
                    matchPos = i;
                }, this);
                result.matchPos = matchPos;
                if (!result.inputPos) {
                    if (result.isValid) {
                        result.inputPos = result.matchPos + 1;
                    } else {
                        result.inputPos = value.length;
                    }
                }
            }
            return result;
        },
        /**
         * @param value
         * @returns {{matches: Array, matchPos: number, inputPos: number}}
         */
        getMatchesByValue: function(value) {
            var matches = [];
            var minPositions = [];
            var matchPos = 0;
            var inputPos = 0;
            var maskValidation;
            var isComplete = false;
            Terrasoft.each(this.masks, function(mask) {
                maskValidation = this.maskValidateValue(mask, value);
                if (maskValidation.isValid) {
                    var maskMinPos = mask.matches.length;
                    Terrasoft.each(mask.matches, function(match, pos) {
                        if (typeof match === "object" && maskMinPos > pos) {
                            maskMinPos = pos;
                        }
                    });
                    minPositions.push(maskMinPos);
                    if (maskValidation.isComplete) {
                        isComplete = true;
                    }
                    matches.push({
                        mask: mask,
                        validation: maskValidation
                    });
                    if (matchPos < maskValidation.matchPos) {
                        matchPos = maskValidation.matchPos;
                    }
                    if (inputPos < maskValidation.inputPos) {
                        inputPos = maskValidation.inputPos;
                    }
                }
            }, this);
            var minPos = Math.min.apply(0, minPositions);
            return {
                matches: matches,
                matchPos: matchPos,
                inputPos: inputPos,
                minPos: minPos,
                isComplete: isComplete
            };
        },
        /**
         * @param values
         * @returns {*}
         */
        getCommonStartString: function(values) {
            var valuesCount = values.length;
            if (valuesCount === 0) {
                return "";
            } else if (valuesCount === 1) {
                return values[0];
            }
            var commonStr = "";
            var minLen = values[0].length;
            Terrasoft.each(values, function(value) {
                minLen = Math.min(minLen, value.length);
            });
            var isMatch;
            var c;
            for (var i = 0; i < minLen; i++) {
                isMatch = true;
                for (var j = 1; j < valuesCount; j++) {
                    isMatch = values[j][i] === values[j - 1][i];
                    if (!isMatch) {
                        break;
                    }
                    c = values[j][i];
                }
                if (isMatch) {
                    commonStr += c;
                } else {
                    return commonStr;
                }
            }
            return commonStr;
        },
        /**
         * @param a
         * @param name
         * @returns {Array}
         */
        getPropertyValuesFromArray: function(a, name) {
            var result = [];
            Terrasoft.each(a, function(e) {
                result.push(e[name]);
            }, this);
            return result;
        },
        /**
         * @overridden
         * @protected
         */
        initDomEvents: function() {
            this.callParent(arguments);
            var el = this.getEl();
            el.on({
                "paste": {
                    fn: this.onPaste,
                    scope: this
                }
            });
        },
        onBeforePasteFormatValue: Ext.emptyFn,
        onPaste: function(e) {
            if (Ext.isEmpty(this.masks)) {
                return;
            }
            var getSplitText = function(v, p) {
                return {
                    pos: p,
                    before: v.substr(0, p),
                    after: v.substr(p)
                };
            };
            e.preventDefault();
            if (e.browserEvent.clipboardData && e.browserEvent.clipboardData.getData) {
                if (/text\/plain/.test(e.browserEvent.clipboardData.types)) {
                    var clipBoardValue = e.browserEvent.clipboardData.getData("text/plain");
                    clipBoardValue = this.onBeforePasteFormatValue(clipBoardValue) || clipBoardValue;
                    if (Ext.isEmpty(clipBoardValue)) {
                        return;
                    }
                    var domEl = e.getTarget();
                    var info = this.getInputInfo(domEl);
                    var pos = info.caretPosition;
                    var splitText = {
                        before: info.valueBeforeCaret,
                        after: info.valueAfterCaret
                    };
                    var newValue = splitText.before + splitText.after;
                    Terrasoft.each(clipBoardValue.split(""), function(c) {
                        var formatValue = this.formatValueByInsChar(c, pos, splitText.before, "", splitText.after, true);
                        if (formatValue) {
                            newValue = formatValue.value;
                            pos = formatValue.insPos + 1;
                            splitText = getSplitText(newValue, pos);
                        }
                    }, this);
                    domEl.value = newValue;
                }
            }
            return;
        },
        /**
         * @param value
         * @returns {*}
         */
        formatValue: function(value) {
            var newValue = value;
            var placeHolders;
            if (Ext.isEmpty(value)) {
                placeHolders = this.getPropertyValuesFromArray(this.masks, "placeHolder");
                newValue = this.getCommonStartString(placeHolders);
                if (!Ext.isEmpty(newValue)) {
                    return this.formatValue(newValue);
                }
                return {
                    pos: 0,
                    value: "",
                    isComplete: false
                };
            }
            var matches = this.getMatchesByValue(value);
            if (matches.matches.length === 0) {
                if (matches.matchPos > 0) {
                    newValue = value.substr(0, matches.matchPos + 1);
                } else {
 
                    return {
                        pos: 0,
                        value: value,
                        isComplete: false
                    };
                }
                return this.formatValue(newValue);
            }
            var masks = this.getPropertyValuesFromArray(matches.matches, "mask");
            placeHolders = this.getPropertyValuesFromArray(masks, "placeHolder");
            var afterText = this.getCommonStartString(placeHolders).substr(matches.matchPos + 1);
            newValue = value.substr(0, matches.matchPos + 1) + afterText;
            matches = this.getMatchesByValue(newValue);
            return {
                pos: matches.inputPos,
                min: matches.minPos,
                value: newValue,
                isComplete: matches.isComplete
            };
        },
        /**
         * @param value
         * @param caretPosition
         */
        setDomValueAndCaret: function(value, caretPosition) {
            var formatValue = this.formatValue(value);
            if (!this.validationInfo.isValid && formatValue.isComplete) {
                var validationInfo = {
                    isValid: true,
                    invalidMessage: ""
                };
                this.setValidationInfo(validationInfo);
            }
            var el = this.getEl();
            if (el) {
                el.dom.value = formatValue.value;
                caretPosition = caretPosition > formatValue.min ? caretPosition : formatValue.min;
                Terrasoft.utils.dom.setCaretPosition(el.dom, caretPosition);
            }
        },
        /**
         * @param {String} value
         * @protected
         * @virtual
         */
        setDomValue: function(value) {
            this.setDomValueAndCaret(value);
        },
        /**
         * @protected
         * @param  {String} value
         * @return {Boolean}
         */
        changeValue: function(value) {
            if (!Ext.isEmpty(this.masks)) {
                var formatValue = this.formatValue(value);
                if (formatValue.value === this.formatValue(null).value) {
                    value = null;
                    formatValue.isComplete = true;
                    var el = this.getEl();
                    if (el) {
                        el.dom.value = "";
                    }
                }
                var validationInfo = this.getValidationInfo(formatValue);
                this.setValidationInfo(validationInfo);
            }
            return this.callParent(arguments);
        }
    });
});

Используем этот модуль для колонки телефона:

define("ContactPageV2", ["MultiMaskEdit"], function() {
	return {
		entitySchemaName: "Contact",
		attributes: {},
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		methods: {},
		dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
		diff: /**SCHEMA_DIFF*/[
			{
                "operation": "merge",
                "name": "MobilePhone",
                "values": {
                    "controlConfig": {
                        "className": "Terrasoft.controls.MultiMaskEdit",
                        "mask": {
                            "formats": ["(99)999-99-99"]
                        }
                    }
                }
            }
		]/**SCHEMA_DIFF*/
	};
});

Должен заметить, что деталь Средства связи не совсем обычная. В ней присутствует много дополнительной логики, в связи с чем реализация вашей задачи может быть слишком трудозатратной на данный момент времени.

Показать все комментарии