Выбор из справочника для строкового поля

Добрый день!

Необходимо иметь возможность выбора из справочника в поле и указание вручную.
Я так полагаю тип = строка + возможность выбора из справочника.
Как это можно реализовать в bpm?
Версия 7.3.

Нравится

13 комментариев

Добрый день!
В базовом функционале, в одном поле в зависимости от его типа, вы можете указать либо строковое значение, либо справочное.
Есть реализация по выбору одного или более значений из справочника и вывод результата выбора в строковое поле через разделитель. Возможно это то, что вы искали.
Пример:

Для реализации примера, в схему страницы раздела добавьте следующий ниже код.
В примере приводится схема LeadPageV2 страницы раздела Лиды и строковое поле «Страны» (UsrCountries) с выбором из справочника «Страны» (Country). В definе и function нужно добавить зависимость с LookupUtilities.

define('LeadPageV2', ['LeadPageV2Resources', 'GeneralDetails', 'LookupUtilities'],
function(resources, GeneralDetails, LookupUtilities) {
    return {
        entitySchemaName: 'Lead',
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
    {
        "operation": "insert",
        "name": "UsrCountries",
        "values": {
            "layout": {
                "column": 12,
                "row": 2,
                "colSpan": 12,
                "rowSpan": 1
            },
            "bindTo": "UsrCountries",
            "caption": {
                "bindTo": "Resources.Strings.CountriesCaption"
            },
            "textSize": 0,
            "contentType": 1,
            "labelConfig": {
                "visible": true
            },
            "enabled": true,
            "controlConfig": {
                "className": "Terrasoft.TextEdit",
                "rightIconClasses": ["custom-right-item", "lookup-edit-right-icon"],
                "rightIconClick": {
                    "bindTo": "openLookup"
                }
            }
        },
        "parentName": "group_gridLayout",
        "propertyName": "items",
        "index": 7
    }
 
]/**SCHEMA_DIFF*/,
        attributes: {
 
        },
        methods: {
            /**
            * Открыть страницу выбора
             * @protected
             */
            openLookup: function() {
                var lookup = this.getLookupConfig("UsrCountries");
                lookup.config.actionsButtonVisible = false;
                LookupUtilities.Open(this.sandbox, lookup.config, lookup.callback, this, null, false, false);
            },
 
            /**
             * Сформировать настройки, необходимые для отображение страницы выбора из справочника
             * @protected
             * @param {String} columnName Имя колонки, для которой нужно указать значение из справочника
             * @return {Object}
             */
            getLookupConfig: function(columnName) {
                var scope = this;
                var callback = function(args) {
                    scope.onLookupSelected(args);
                };
                return {
                    config: {
                        entitySchemaName: "Country",
                        columnName: columnName,
                        multiSelect: true
                    },
                    callback: callback
                };
            },
            /**
             * Срабатывает, когда указаны значения на странице выбора из справочника
             * @param {Object} args
             */
            onLookupSelected: function(args) {
                var ext = this.Ext;
                var columnName = args.columnName;
                var items = args.selectedRows.collection.items;
                this.EntityCollection = this.EntityCollection || [];
                var collection = this.EntityCollection;
                var columnValue = this.get(columnName);
                if (ext.isEmpty(columnValue)) {
                    columnValue = "";
                } else {
                    columnValue = columnValue.trim();
                    var addSymbol = "";
                    var symbol = columnValue[columnValue.length - 1];
                    if (symbol === ";") {
                        addSymbol = " ";
                    } else {
                        addSymbol = "; ";
                    }
                    columnValue = columnValue + addSymbol;
                }
                Terrasoft.each(items, function(item) {
                    var id = item.Id;
                    var displayValue = item.displayValue;
                    if (collection.indexOf(id) < 0) {
                        collection.push(id);
                    }
                    var idx = columnValue.indexOf(displayValue + ";");
                    if (idx !== 0 && idx < 0) {
                        columnValue += displayValue + "; ";
                    }
                }, this);
                this.set(columnName, columnValue);
            },
        },
        rules: {},
        userCode: {}
    };
});

Здравствуйте, у меня тоже такая же проблема. Использовал точно тот же код (подобный), что Вы запостили. Такой код есть в стандартной поставке для множественного выбора email контактов "To" / "Copy". Однако, есть проблема. Полученную строку с разделителями нужно сохранить (в базу), и чтобы при повторном открытии окна были выбрать чекбоксы, соответствующие значениям в строке с разделителями. Я уже два 3-4 дня пытаюсь выбить у поддержки, как это сделать.

Пигарева Александра, предоставленная инструкция помогла в решении вашего вопроса?

trickbz, у Вас есть возможность перебросить ссылку на Ваше обращение в поддрежку?

trickbz, чтобы открыть лукап-страницу с уже выбранными записями необходимо при открытии в конфиг страницы передать эти значения в свойстве selectedValues. Обработка производится в LookupPage в callback метода getSchemaAndProfile в init:

init: function(callback, scope) {
 
	this.lookupInfo = this.sandbox.publish("LookupInfo", null, [this.sandbox.id]);
	this.processModuleFlag = this.sandbox.publish("CardProccessModuleInfo", null, [this.sandbox.id]);
 
	this.initHistoryState();
 
	this.getSchemaAndProfile(function(entitySchema, profile) {
//...
		if (this.lookupInfo.selectedValues) {
			viewModel.set("RestoreSelectedData", this.lookupInfo.selectedValues);
		}
//...
	});
},

trickbz, ранее подобной задачи не возникало, но принцип решения такой:
1) Создать таблицу развязки с колонкой-ссылкой на таблицу справочника, и колонкой-ссылкой на таблицу карточки.
2) В карточке добавить контрол, аналогичный UsrCountries (в примере выше), и виртуальную колонку с текстовым типом значения для него.
3) На инициализации страницы (initEntity) прочитать из таблицы развязки связаные записи, сохранить в их коллекции, сформировать на их основе текстовое значение для контрола.
4) В методе, аналогичном onLookupSelectedиз примера, сверять выбранные записи с теми, что в коллекции, и соответственно удалять/добавлять (Terrasoft.InsertQuery/ Terrasoft.DeleteQuery) их в таблице развязки (после чего актуализировать коллекцию и текстовую колонку)
5) В методе, аналогичном getLookupConfig кроме entitySchemaName и т.д. необходимо также формировать selectedValues на основе все той же коллекции

"Андрей Каспаревич" написал:

trickbz, чтобы открыть лукап-страницу с уже выбранными записями необходимо при открытии в конфиг страницы передать эти значения в свойстве selectedValues. Обработка производится в LookupPage в callback метода getSchemaAndProfile в init:

init: function(callback, scope) {

        this.lookupInfo = this.sandbox.publish("LookupInfo", null, [this.sandbox.id]);
        this.processModuleFlag = this.sandbox.publish("CardProccessModuleInfo", null, [this.sandbox.id]);

        this.initHistoryState();

        this.getSchemaAndProfile(function(entitySchema, profile) {
//...
                if (this.lookupInfo.selectedValues) {
                        viewModel.set("RestoreSelectedData", this.lookupInfo.selectedValues);
                }
//...
        });
},


Спасибо, что указали куда копать. Теперь не знаю, чем заполнить свойство "selectedValues". У меня это поле текстовое, и там содержитася строка типа "ASP; C++; C# ". Мне нужно эту строку преобразовать в формат понятный свойству "selectedValues". Не подскажите направление как это сделать?

Можно ли каким то образом обратиться к справочнику и получить коллекцию объектов в этом справочнике, чтобы можно было сравнить распарсеное значение из строки с displayValue, и сохранить GUID при совпадении?

"i.kleva" написал:

Пигарева Александра, предоставленная инструкция помогла в решении вашего вопроса?

Не совсем, мне надо иметь возможность потом изменять поле.

"i.kleva" написал:

Пигарева Александра, предоставленная инструкция помогла в решении вашего вопроса?

Не совсем, мне надо иметь возможность потом изменять поле.

"trickbz" написал:
Мне нужно эту строку преобразовать в формат понятный свойству "selectedValues". Не подскажите направление как это сделать?

Там должен быть массив Id
selectedValues: ["AD70B005-E8BB-DF11-B00F-001D60E938C6", "1A31FC91-EFD5-4D75-9A2C-F6A1B680A675"]

"Морякин Сергей" написал:Там должен быть массив Id
selectedValues: ["AD70B005-E8BB-DF11-B00F-001D60E938C6", "1A31FC91-EFD5-4D75-9A2C-F6A1B680A675"]

Спасибо! Я уже сам до этого дошел, руками подстваил айдишники и галочки поставились. А теперь наверное последний вопрос - как, зная название справочника и displayName получить соответствующий GUID / код? Т.е., справочника называется "Technologies", в нём есть значения "ASP", "C#" и т.п, каждому соответсвует GUID. Т.е., зная "ASP" получить допустим "AD70B005-E8BB-DF11-B00F-001D60E938C6" ? Из javascript.
Спасибо!

"trickbz" написал:А теперь наверное последний вопрос - как, зная название справочника и displayName получить соответствующий GUID / код? Т.е., справочника называется "Technologies", в нём есть значения "ASP", "C#" и т.п, каждому соответсвует GUID

Примерно, так:

getIds : function (stringValue, callback) {
	var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
			rootSchemaName : "Technologies"
		});
	esq.addColumn("Id");
	var values = stringValue.split("; ")
	esq.filters.add("ByNameFilter",
	      this.Terrasoft.createColumnInFilterWithParameters("Name", values));
	esq.getEntityCollection(function (result) {
		if (result.success) {
			var items = result.collection.getItems();
			var ids = [];
			this.Terrasoft.each(items, function (item) {
				ids.push(item.get("Id"));
			}, this);
			callback.call(this, ids);
		}
	}, this);
},
showIds : function () {
	this.getIds("ASP; C++; C#", function (Ids) {
		alert(JSON.stringify(Ids));
	});
}

Спасибо огромное, работает! Узнал много нового :razz:

Готовое сокращенное рабочее решение ниже. Уверен, кому-то да пригодится. Александра, может и Вам тоже. Извините, что вторгся в Вашу тему, в других мне толком не отвечали, а в Вашей дело пошло до победного конца :wink: Еще раз спасибо всем!
http://www.community.terrasoft.ru/forum/topic/12306

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