...

"Нативное" отображение не-переменных контекста на форме c типом данных элмы в виджете "Код".

Тема в разделе "Вопросы по ELMA365 Platform", создана пользователем unam3, 5 июл 2023.

  1. unam3

    unam3 Активный участник

    Можно ли и как отображать не-переменные контекста с типами элмы (TFile: FileItemRef, TBoolean: boolean, TUser: UserItemRef и прочее) контролами элмы в виджете "Код"?
    Последнее редактирование: 12 июл 2023
  2. miliakova

    miliakova Техническая поддержка

    Добрый день! Отображение контролов Элмы в виджете Код описано в статье https://tssdk.elma365.com/ru/interfaces/_102_ui_widgets_.widget.html#contextrow

    Вы можете использовать вывод контекстной строки приложения:

    <%= UI.widget.contextRow('price', { required: true, onChange: Scripts.calcTotal }) %>

    Это строка (название и значение) поля price контекста элемента приложения.

    Можно использовать вывод контекстной строки виджета:

    <%= UI.widget.viewContextRow('count', { required: true, onChange: Scripts.calcTotal }) %>

    Контрол со значением из контекста виджета. Контекст виджета - это служебные переменные, которые используются для настройки виджета. Они нужны для написания сценариев, определяющих поведение виджета, а также для получения информации из приложений, загрузки файлов и т. д. Это более гибкий контекст, чем контекст приложения. В контекст виджета можем записывать значения в сценарии виджета, например:

    async function onInit(): Promise<void> {

    ViewContext.data.polzovatel = await System.users.getCurrentUser();
    ViewContext.data.vybor = true
    ​
    }

    Этой гибкости достаточно, чтобы выводить контрол со значением, которое вы зададите.

    Нативно в виджет Код вы можете положить html код, в том числе скопировать контрол элмы из Элементов Инструментов разработчика, но наделять его функциональностью придется самостоятельно.

    Вложения:

    • smtng.png
      smtng.png
      Размер файла:
      76,3 КБ
      Просмотров:
      56
    • stroka.png
      stroka.png
      Размер файла:
      7,4 КБ
      Просмотров:
      51
    Последнее редактирование: 12 июл 2023
  3. unam3

    unam3 Активный участник

    Доброго.
    Обновил и прояснил заголовок и текст поста. Делает ответ неактуальным. Но путь к истине тернист и труден. Вдруг удастся получить необходимое.
  4. miliakova

    miliakova Техническая поддержка

    Не-переменные контекста надо положить в контекст виджета. Через контекстные переменные компоненты системы получают значения, обретают функционал. Строке формы Файл, Пользователь, Выбор да/нет нужны значения из контекста. Расскажите, пожалуйста, подробнее какая задача перед Вами стоит, чем обусловлена необходимость обхода контекста?
  5. unam3

    unam3 Активный участник

    Отображать в форме приложения/задач бп (1) больше пяти таблиц с одинаковой структурой (2) с ячейками только для чтения (3) с полями типа "Файл" и "Пользователи" с выбранным параметром "несколько".


    В этом слуачае не нужен функционал переменных контекста, затраты на их создание и поддержку.

    Можно обойтись генерацией таблицы в виджете "Код". Но для этого надо руками подтягивать имена файлов и пользователей для отображения.
  6. miliakova

    miliakova Техническая поддержка

    Добрый день! Генерация таблицы в виджете "Код" подробно описана в статье https://tssdk.elma365.com/ru/pages/how-to/make-custom-display-of-application-elements.html
    Если нет желания хранить данные в контексте, то создадим интерфейсы, которые наполним данными из приложения-источника.
    Привожу пример Формы просмотра элемента, на которую вынесен виджет код (таблица), в контексте данного виджета (ViewContext) только одно свойство - render (перерисовка таблицы). В сценарии созданы интерфейсы, функция onInit, функция заполнения таблицы данными fillTable, функция getElements, отдающая элементы виджету Код.
    Виджет Код:
    Код:
    
    <% if (ViewContext.data.render) { %>
        <
    div class="objects-container">
        <
    table>
            <
    thead>
                <
    tr>
                    <
    th>Название</th>
                    <
    th>Файлы</th>
                    <
    th>В наличии</th>
                    <
    th>Менеджеры</th>
                </
    tr>
            </
    thead>
            <
    tbody>
                <% for (
    let j=0;  j < getElements().length;j++) { %>
                    <%= 
    renderRow( getElements()[j] ) %>
               <% } %>
            </
    tbody>
        </
    table>
    </
    div>
    <% } %>

    <% 
    $template renderRow(el) %>
    <
    tr class="material-need-title">
    <
    td><a href="(p:item/forum_tablica/iskhodnoe/<%- el.nazvanie.elementId %>)"><%- el.nazvanie.elementName %></td>
    <
    td>
                 <% for (
    let i=0;  i < el.files.length; i++) { %>
                   <
    a href="(p:preview/<%- el.files.fileLink %>/readonly)?active=true)"><%- el.files.fileName %><br/>
                <% } %>
            </
    td>
            <
    td><%- el.bool ? "В наличии" : "Нет в наличии" %></td>
            <
    td>
                <% for (
    let j=0;  j < el.users.length; j++) { %>
                   <%- 
    el.users[j].userName %><br/>
                <% } %>
            </
    td>
        </
    tr>
    <% 
    $endtemplate %>

    <
    style>
        .
    objects-container table {
            
    width: 100%;
            
    border: 1px solid black;

        }
        .
    objects-container thead {
            
    background-color: #82bd8e;
            
    border: 1px solid black;
        }
        
    th {
            
    text-align: center;
            
    border: 1px solid black;
        }
        .
    objects-container th {
            
    padding: 18px 6px;
        }
        .
    objects-container td {
            
    padding: 18px 6px;
            
    border: 1px solid black;
        }
        
    td {
            
    text-align: center;
        }
        
    tr.material-need-title {
            
    font-weight: bold;
            
    background-color: #e3eef7;
        
    }
    </
    style>
    Сценарий:

    Код:
    
    interface ElementData {
    nazvanie: Element;
    files: MyFileData[];
    bool: TBoolean;
    users: MyUserData[];
    }
    interface 
    Element {
    elementName: string;
    elementId: string
    }
    interface 
    MyFileData {
    fileName: string;
    fileLink: string
    }
    interface 
    MyUserData {
    userName: string;
    userId: string
    }
    let elements: ElementData[]=[];

    async function onInit():p: Promise<void>{
    await fillTable();
    }

    async function fillTable(): Promise<void>{
    debugger;
    elements=[];
        const 
    need_elements = await Namespace.app.iskhodnoe.search()
    .
    where((f, g) => g.and(
    f.__deletedAt.eq(null),
    ))
    .
    size(1000)
    .
    all();
        for (const 
    el of need_elements) {
    let element: ElementData
    let files
    : TFile[] = el.data.faily!
    let filesData: MyFileData[]=[]
    let users: TUser[] = el.data.polzovateli!
    let usersData: MyUserData[]=[]

    const 
    promises = files.map(async (f: FileItemRef)=> {
    let data = await getFilesData(f);
    filesData.push(data)
            });
    await Promise.all(promises)
            const 
    promises2 = users.map(async (u: UserItemRef)=> {
    let data2 = await getUsersData(u);
    usersData.push(data2)
    });
            
    await Promise.all(promises2)

            
    element = {
    nazvanie: {
    elementName: el.data.__name,
    elementId: el.data.__id
                
    } ,
    files: filesData,
    bool: el.data.vybor_da_net!,
    users: usersData
            
    }
            
    elements.push(element!)
        };
        
    Context.data.render = Context.data.render
    }
    async function getFilesData(f: FileItemRef): Promise<MyFileData> {
        
    let fetched = await f.fetch();
        return {
            
    fileName: fetched.data.__name,
            
    fileLink: fetched.data.__id
        
    }
    }

    async function getUsersData(u: UserItemRef): Promise<MyUserData> {
        
    let fetched = await u.fetch();
        return {
            
    userName: fetched.data.__name,
            
    userId: fetched.data.__id
        
    }
    }

    function 
    getElements() {
        return 
    elements;
    }

    Вложения:

    • f1.jpg
      f1.jpg
      Размер файла:
      73 КБ
      Просмотров:
      37
    • f2.jpg
      f2.jpg
      Размер файла:
      154,7 КБ
      Просмотров:
      35
    • f3.jpg
      f3.jpg
      Размер файла:
      45,3 КБ
      Просмотров:
      30
    • f4.jpg
      f4.jpg
      Размер файла:
      132,9 КБ
      Просмотров:
      31
    • f5.jpg
      f5.jpg
      Размер файла:
      124 КБ
      Просмотров:
      33
    • f6.jpg
      f6.jpg
      Размер файла:
      100,9 КБ
      Просмотров:
      31
    • f7.jpg
      f7.jpg
      Размер файла:
      102,2 КБ
      Просмотров:
      30
    Последнее редактирование: 1 сен 2023
  7. unam3

    unam3 Активный участник

    Добрый!

    Что сейчас у себя делаю и делается в предоставленном вами коде:
    https://community.elma365.com/ru/threads/2770/#post-4047:~:text=let fetched = await f.fetch();
    https://community.elma365.com/ru/threads/2770/#post-4047:~:text=let fetched = await u.fetch()

    А хотелось бы обертку/функцию вокруг типов (например: FileItemRef, UserItemRef), чтобы скормил в нее id, а она вернула все или указанные поля.