Вариант 5. Создание нового компонента
-------------------------------------

На текущую форму «Заявка на закуп» добавлен компонент «Пользовательский компонент».
В его настройках значением выбран такой пользовательский компонент, который
позволяет выбрать поставщика и посмотреть о нем подробную информацию.
HTML и JavaScript коды такого пользовательского компонента приведены ниже.
Список доступных действий:

  * выбор записи реестра поставщиков из диалогового окна с помощью кликабельного лейбла Выбрать из реестра (доступен всегда), в котором столбцы - это отображаемые поля реестра;

  * ручной ввод и подбор результатов среди записей реестра поставщиков (поиск производится по всем полям);

  * значения в выпадающем списке составлены из полей диалога (т.е. отображаемых полей реестра), разделенных тире;

  * выбранное значение компонента меняет его внешний вид: поле ввода заменяется на подчеркнутый и кликабельный лейбл, составленный из значащего содержимого этого реестра;

  * по нажатию на выбранную запись происходит открытие в диалоговом окне проигрывателя формы, который отображает эту запись из реестра поставщиков в режиме просмотра;

  * создание новой записи в реестре поставщиков прямо из текущей формы с помощью кликабельного лейбла +Создать (доступен всегда): проигрыватель формы в режиме редактирования открывается в диалоговом окне;

  * удаление текущего значения компонента с помощью кликабельного лейбла х Удалить (доступен только в случае, когда в компоненте выбрано какое-либо значение): компонент очищается и снова принимает вид поля ввода.

.. raw:: html

    <iframe src="../../_static/html/integration/extfp-usecases/uc5/index.html" scrolling='no' height="930px" width="100%" style="border:1px solid grey;"></iframe>

Исходный код JavaScript и CSS формы аналогичны :ref:`extfp-usecases-uc1-label`.

HTML код пользовательского компонента:

.. code-block:: xml

    <div innerId="textView" style="text-decoration:underline; cursor:pointer;width:calc(100% ); margin-bottom:2px"></div>
    <input type="text" class="asf-textBox" innerId="name" style="width:calc(100% )"/>
    <div style="color:#606060; text-decoration:underline" class="asf-InlineBlock asf-cursorPointer" innerId="add">+Создать</div>
    <div style="color:#606060; margin-left:10px; text-decoration:underline" class="asf-InlineBlock asf-cursorPointer" innerId="browse">Выбрать из реестра</div>
    <div style="color:#606060; margin-left:10px; text-decoration:underline" class="asf-InlineBlock asf-cursorPointer" innerId="delete">&#10005; Удалить</div>

JavaScript код пользовательского компонента:

.. code-block:: javascript

    /* инициализация модели */
    /**
     * текстовое значение записи реестра
     * @type {string}
     */
    model.textValue = "";
    /**
     * идентификатор файла по форме выбранной записи реестра
     * @type {string}
     */
    model.asfDataId = null;

    /**
     * метод должен возвращать идентификатор реестра, можно переопределить в скрипте пользовательского компонента
     * @returns {string}
     */
    if (!model.getRegistryID) {
        model.getRegistryID = function () {
            return "d67afba7-8f16-4f7e-a920-1eceb694f646";
        };
    }

    /**
     * обновить текстовое представление записи реестра
     */
    model.updateTextView = function () {
        if (!model.getValue()) {
            model.textValue = "";
            model.asfDataId = null;
            model.trigger(AS.FORMS.EVENT_TYPE.dataLoad, [model]);
            return;
        }
        AS.FORMS.ApiUtils.getAsfDataUUID(model.getValue(), function (newAsfDataId) {
            model.asfDataId = newAsfDataId;
            AS.FORMS.ApiUtils.getDocMeaningContent(model.getRegistryID(), newAsfDataId, function (text) {
                model.textValue = text;
                model.trigger(AS.FORMS.EVENT_TYPE.dataLoad, [model]);
            });
        });
    };

    /**
     * получить тестовое представление записи реестра
     * @returns {string|string|*}
     */
    model.getTextValue = function () {
        return model.textValue;
    };

    // подписываемся на событие модели об изменении содержания, чтобы подгрузить дополнительные данные
    model.on(AS.FORMS.EVENT_TYPE.valueChange, function () {
        model.updateTextView();
    });

    /**
     * метод реализовывает вставку asfData
     * @param asfData
     */
    model.setAsfData = function (asfData) {
        model.setValue(asfData.key);
    };

    /**
     * метод реализовывает получение данных компонента для сохранения
     * @param blockNumber
     * @returns {*}
     */
    model.getAsfData = function (blockNumber) {
        return AS.FORMS.ASFDataUtils.getBaseAsfData(model.asfProperty, blockNumber, model.textValue, model.value);
    };


    /* инициализация отображения */


    /**
     * реестр
     * @type {object}
     */
    var registry = null;
    /**
     * видимые колонки реестра
     * @type {Array}
     */
    var registryColumns = [];


    /**
     * поле ввода для поиска записей реестра
     * @type {XMLList|*}
     */
    var input = jQuery(view.container).children("[innerId='name']");
    /**
     * поле для отображения выбранной записи реестра
     * @type {XMLList|*}
     */
    var textView = jQuery(view.container).children("[innerId='textView']");
    /**
     * кнопка добавления записи
     * @type {XMLList|*}
     */
    var addIcon = jQuery(view.container).children("[innerId='add']");
    /**
     * кнопка выбора записи из реестра
     * @type {XMLList|*}
     */
    var browseIcon = jQuery(view.container).children("[innerId='browse']");
    /**
     * кнопка удаления текущей выбранной записи
     * @type {XMLList|*}
     */
    var deleteIcon = jQuery(view.container).children("[innerId='delete']");

    // кнопку удаления текущей выбраннйо записи скрываем
    deleteIcon.hide();

    // по нажатию на кнопку "выбрать из реестра" открываем стандратный диалог выбра записи реестра
    browseIcon.click(function () {
        AS.SERVICES.showRegisterLinkDialog(registry, function (documentId) {
            model.setValue(documentId);
        });
    });

    // по нажатию на кнопку "создать" открываем форму создания записи реестра
    addIcon.click(function () {
        if (!registry.rr_create) {
            alert("У вас нет прав на создание записей данного реестра");
            return;
        }

        var createPlayerDiv = jQuery("<div>");
        createPlayerDiv.css("width", "800px");

        createPlayerDiv.css("border", "1px solid #afafaf");

        var saveButton = jQuery("<button>", {class: "ns-approveButton ns-basicChooserApplyButton"});
        saveButton.button();
        saveButton.html("Добавить поставщика");
        saveButton.css("margin", "auto");
        saveButton.css("display", "block");

        var player = AS.FORMS.createPlayer();

        player.view.setEditable(true);
        player.showFormData(registry.formId);
        player.view.appendTo(createPlayerDiv);

        createPlayerDiv.append(saveButton);


        createPlayerDiv.dialog({
            width: 670,
            height: 400,
            modal: true
        });


        saveButton.click(function () {
            var valid = player.model.isValid();
            if (!valid) {
                alert("Введите все обязательные поля");
                return;
            }

            AS.SERVICES.showWaitWindow();
            AS.FORMS.ApiUtils.simpleAsyncGet("rest/api/registry/create_doc?registryID=" + registry.registryID, function (result) {
                if (result.errorCode != 0) {
                    AS.SERVICES.hideWaitWindow();
                    alert("Во время сохранения данных по форме произошли ошибки. Обратитесь к администратору");
                    return;
                }
                player.model.asfDataId = result.dataUUID;
                player.saveFormData(function (result) {
                    AS.SERVICES.hideWaitWindow();
                    if (_.isUndefined(result)) {
                        alert("Во время сохранения данных по форме произошли ошибки. Обратитесь к администратору");
                        return;
                    }

                    createPlayerDiv.dialog("destroy");

                    AS.FORMS.ApiUtils.getDocumentIdentifier(result, function (documentID) {
                        model.setValue(documentID);
                    });

                });
            });

        });


    });


    // по нажатию на кнопку удалить  - удаляем выбранное значение
    deleteIcon.click(function () {
        model.setValue(null);
    });


    // по нажатию на текстовое отображение  - открываем запись реестра на просмотр
    textView.click(function () {
        var createPlayerDiv = jQuery("<div>");
        createPlayerDiv.css("width", "800px");

        createPlayerDiv.css("border", "1px solid #afafaf");

        var player = AS.FORMS.createPlayer();

        player.view.setEditable(false);
        player.showFormData(null, null, model.asfDataId, 0);
        player.view.appendTo(createPlayerDiv);

        createPlayerDiv.dialog({
            width: 1000,
            height: 330,
            modal: true
        });
    });


    // скрываем или отображаем инпуты в зависимости от того режим чтения это или редактирования
    if (editable) {
        textView.hide();
    } else {
        input.hide();
        addIcon.hide();
        browseIcon.hide();
        deleteIcon.hide();
    }

    // релизовываем метод обновления отображения согласно изменившимся данным модели
    view.updateValueFromModel = function () {
        input.val("");
        if (model.getValue()) {
            textView.css("display", "");
            input.hide();
            textView.html(model.getTextValue());
            input.hide();
            if (editable) {
                deleteIcon.css("display", "");
            }
        } else {

            if (editable) {
                textView.hide();
                input.css("display", "");
            } else {
                textView.css("display", "");
                input.hide();
            }

            textView.html("");
            input.text("");
            deleteIcon.hide();
        }
    };

    // подписываем на событие подгрузки дополнительных данных значения
    model.on(AS.FORMS.EVENT_TYPE.dataLoad, function () {
        view.updateValueFromModel();
    });


    /**
     * если нет прав создания записи реестра, то кнопки создать не должно быть видно
     */
    function validateIconsState() {
        addIcon.hide();
        if (registry.rr_create) {
            addIcon.css("display", "");
        }
    }

    /**
     * инициализируем компонент (получаем реестр, колонки)
     */
    function initComponent() {
        if (!model.getRegistryID()) {
            return;
        }
        AS.FORMS.ApiUtils.getRegistry(model.getRegistryID(), function (reg) {
            registry = reg;

            registry.registryID = model.getRegistryID();

            registryColumns = [];
            registry.columns.forEach(function (col) {
                if (col.visible != 1) {
                    return;
                }
                registryColumns.push(col);
            });

            registryColumns = registryColumns.sort(function (item1, item2) {
                var number1 = item1.order;
                var number2 = item2.order;
                if (number1 === number2) {
                    if (item1.name < item2.name) {
                        return -1;
                    } else if (item1.name > item2.name) {
                        return 1;
                    }
                } else {
                    if (number1 === 0) {
                        return 1;
                    } else if (number2 === 0) {
                        return -1;
                    } else if (number1 < number2) {
                        return -1;
                    } else {
                        return 1;
                    }
                }
                return 0;
            });

            validateIconsState();
        });
    }

    // при вводе пользователя отображаем первые 20 результатов поиска
    input.on("input", function () {
        var search = input.val();
        if (search.length === 0 || !registry) {
            AS.SERVICES.showDropDown([]);
            return;
        }

        AS.FORMS.ApiUtils.getRegistryData(model.getRegistryID(), 0, 10, search, null, null, function (foundData) {
            var values = [];
            foundData.result.forEach(function (record) {
                var value = {value: record.documentID};
                var label = "";

                registryColumns.forEach(function (column) {
                    label += record.fieldValue[column.columnID] + " - ";
                });

                value.title = label;
                values.push(value);
            });

            AS.SERVICES.showDropDown(values, input, null, function (selectedValue) {
                model.setValue(selectedValue);
                view.updateValueFromModel();
            });

        });

    });


    setTimeout(function () {
        initComponent();
    }, 0);
