Files
soneta-erp-skills/soneta-form-xml/SKILL.md
T
2026-03-05 15:31:31 +01:00

15 KiB

name, description
name description
soneta-form-xml Specjalistyczna wiedza o WŁASNOŚCIOWYM formacie plików form.xml platformy enova365/Soneta — bez tego skilla Claude generuje błędne XML z nieistniejącymi elementami. ZAWSZE używaj tego skilla gdy użytkownik: (1) prosi o utworzenie lub modyfikację pliku pageform.xml, viewform.xml, form.xml, lookupform.xml lub gridform.xml dla enova365/Soneta; (2) pyta o elementy DataForm, Page, Group, Grid, Field, Row, Stack, Flow, Command, Include, Appearance, GroupBy w enova365; (3) pyta o składnię EditValue, DataContext, Visibility, RowCondition, Renderable, CaptionHtml, Footer, Class lub układ UI formularzy enova365; (4) pokazuje istniejący plik form.xml/pageform.xml/viewform.xml i pyta o jego strukturę lub chce go rozszerzyć; (5) pyta o warunkową widoczność, formatowanie warunkowe (Appearance), bindowanie danych lub wzorce UI w Soneta/enova365.

Soneta Form XML - Formularze UI

Typy plików formularzy

Typ pliku Wzorzec nazwy Przeznaczenie
pageform.xml {DataType}.{PageName}.pageform.xml Zakładka formularza edycji obiektu
viewform.xml {NazwaWidoku}.viewform.xml Widok listy zarejestrowanej jako folder (listy główne)
gridform.xml {IdentyfikatorListy}.gridform.xml Indywidualne ustawienia listy na formularzu
lookupform.xml {NazwaPodpowiedzi}.lookupform.xml Lista wyboru (lookup)
form.xml {Nazwa}.form.xml Współdzielony fragment UI (include)

Przykłady pageform.xml: Towar.Ogolne.pageform.xml, Kontrahent.Adresy.pageform.xml

Struktura dokumentu

Każdy plik formularza zaczyna się od deklaracji XML i elementu DataForm:

<?xml version="1.0" encoding="utf-8"?>
<DataForm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns="http://www.enova.pl/schema/form.xsd"
          xsi:schemaLocation="http://www.enova.pl/schema/ http://www.enova.pl/schema/form.xsd">
  <!-- zawartość -->
</DataForm>

Atrybuty DataForm

Atrybut Opis
Priority Kolejność zakładek (domyślnie 100, niższa = wcześniej)
RightName Opcjonalny. Nazwa uprawnienia do zakładki
Contexts Warunki licencyjne, np. "Licence.HAN | Licence.FA"
ViewType Typ widoku: None, Dialog, Form, Folder
Mode Tryb: None, Form, Folder, Wizard, Modal, Popup, Frame
DataType Opcjonalny. Pełna nazwa typu gdy nie wynika z nazwy pliku

Wspólne atrybuty elementów

Atrybut Opis
Name Identyfikator elementu (dostępny w kodzie C#)
Class Klasy stylów (lista wartości oddzielonych spacją)
DataContext Zmienia kontekst danych dla elementu i elementów podrzędnych
Visibility Warunek widoczności (bindowalne): true/false/{wyrażenie}
Renderable Czy element ma być dostępny — liczone raz przy logowaniu
Width Szerokość w znakach lub px; "*" = wypełnij
Height Wysokość w wierszach lub px; "*" = wypełnij

Atrybut CaptionHtml

  • Tekst etykiety (w formacie HTML)
  • Wyrażenia bindowane: {Właściwość} → wartość automatycznie kodowana do HTML
  • Wyrażenia HTML: {WłaściwośćHtml} → sufiks Html wyłącza kodowanie
  • Podwójne klamry dla literałów: {{{
  • Alternatywa: CaptionMarkdown dla Markdown

Specjalne przypadki w Field:

  • Brak atrybutu → automatyczna etykieta wyliczana na podstawie danych
  • CaptionHtml=" " (spacja) → pusta etykieta (miejsce zachowane)
  • CaptionHtml="" (pusty) → brak etykiety i miejsca

Elementy kontenerowe

Page - Zakładka

<Page CaptionHtml="Ogólne" DataContext="{DataSource}">
  <!-- zawartość zakładki -->
</Page>
Atrybut Opis
CaptionHtml Tytuł; może zawierać / do grupowania (np. "Dokumenty/Faktury")
DataContext Źródło danych; {DataSource} = obiekt edytowany
Visibility Wyrażenie warunkowe widoczności (bindowalne)
Renderable Liczone raz przy logowaniu — dla warunków licencji/środowiska
Key Skrót klawiaturowy

Group - Grupa pól

<Group CaptionHtml="Dane podstawowe" LabelWidth="20">
  <Field CaptionHtml="Kod" Width="20" EditValue="{Kod}" />
  <Field CaptionHtml="Nazwa" Width="*" EditValue="{Nazwa}" />
</Group>

LabelWidth ustawia szerokość etykiet dla wszystkich pól w grupie.

Stack, Row, Flow - Układ elementów

<!-- Stack: układ pionowy (elementy jeden pod drugim) -->
<Stack LabelWidth="15">
  <Field CaptionHtml="Pole 1" EditValue="{Pole1}" />
</Stack>

<!-- Row: układ poziomy -->
<Row>
  <Field CaptionHtml="Kod" Width="20" EditValue="{Kod}" />
  <Gap Width="*" />  <!-- przesuwa kolejne elementy do prawej -->
  <Field CaptionHtml="Status" Width="15" EditValue="{Status}" />
</Row>

<!-- Flow: elementy od lewej do prawej z zawijaniem -->
<Flow Align="true">
  <Field CaptionHtml="Data od" Width="15" EditValue="{DataOd}" />
  <Field CaptionHtml="Data do" Width="15" EditValue="{DataDo}" />
</Flow>

Układ dwukolumnowy: <Row> zawierający dwa <Stack>.

Zasada budowania zakładki

<Page CaptionHtml="Ogólne" DataContext="{DataSource}">
  <Group CaptionHtml="Dane podstawowe">
    <!-- pola pionowo -->
    <Field CaptionHtml="Kod" Width="20" EditValue="{Kod}" />
    <!-- lub wielokolumnowo: -->
    <Row>
      <Stack><Field ... /></Stack>
      <Stack><Field ... /></Stack>
    </Row>
  </Group>
  <Group CaptionHtml="Pozycje">
    <Grid Width="*" Height="*" EditValue="{Pozycje}" IsToolbarVisible="true">
      <Field CaptionHtml="Nazwa" Width="*" EditValue="{Nazwa}" />
    </Grid>
  </Group>
</Page>

Elementy pól i kontrolek

Field - Pole edycyjne

Jest generowany dynamicznie — typ właściwości decyduje o kontrolce (int → liczba, bool → checkbox, typ Sonety → lookup).

<Field CaptionHtml="Nazwa pola" Width="20" EditValue="{Właściwość}"
       Important="true" IsReadOnly="{Warunek}" />
Atrybut Opis
EditValue Wymagany. Binding do właściwości: {Właściwość} lub {new Ext.Właściwość}
CaptionHtml Etykieta pola
Width Szerokość pola (* = wypełnij)
Height Wysokość (dla pól wieloliniowych)
Important true — pole oznaczone jako ważne (wyróżnione w widoku)
IsReadOnly Warunek tylko do odczytu (bindowalne)
Format Formatowanie w standardzie .NET: N2, d, C
Footer Agregacja w stopce listy: Sum, Count, Average, Min, Max
CheckedValue Wartość dla RadioButton
Class Klasy stylów

RadioButton — pola z tym samym EditValue i różnymi CheckedValue:

<Field Width="15" CaptionHtml="Towar" EditValue="{Typ}" CheckedValue="Towar" />
<Field Width="15" CaptionHtml="Usługa" EditValue="{Typ}" CheckedValue="Usługa" />

Label, Gap, Command, Include

<Label CaptionHtml="Tekst informacyjny" Width="30" />
<Gap Width="*" />   <!-- wypełniacz; pusty na końcu wiersza nic nie zmienia -->

<Command CaptionHtml="Zapisz" MethodName="Zapisz"
         DataContext="{new MojExtender}" Visibility="{IsVisible}"
         CommandStyle="Important" Key="F5" />

<!-- Dołączenie pliku form.xml -->
<Include Source="Adres.form.xml" DataContext="{Adres}" />
<!-- Dynamiczny element z kodu C# -->
<Include Source="{DynamicznyFormularz}" />

Kolekcje i listy

Grid / List - Tabela danych

<Grid Width="*" Height="*"
      EditValue="{Pozycje}"
      IsToolbarVisible="true"
      IsFilterRowVisible="false"
      EditInPlace="true"
      NewInPlace="true"
      OrderBy="Data desc"
      SumType="All"
      FilterPanelWidth="136"
      SelectedValue="{WybranePozycje}"
      FocusedValue="{AktualnaPozycja}">
  <Field CaptionHtml="Kod" Width="15" EditValue="{Kod}" />
  <Field CaptionHtml="Ilość" Width="10" EditValue="{Ilosc}" Footer="Sum" />
  <GroupBy EditValue="{Kategoria}" IsDescending="false" />
  <UserFilter Value="Status='Aktywny'" />
  <Data Name="nazwaParametru" Value="wartość" />
</Grid>
Atrybut Default Opis
EditValue Źródło danych kolekcji
IsToolbarVisible false Pasek narzędzi
IsFilterRowVisible false Wiersz filtrujący
EditInPlace false Edycja bezpośrednio w komórkach
NewInPlace false Dodawanie przez kliknięcie pustego wiersza
OrderBy Domyślne sortowanie: "Kolumna desc"
FilterPanelWidth Szerokość panelu filtrów
SumType None None, Selected, All, Groups, GroupsNewLine
IsSmartOpen Kolumna ze strzałką do otwarcia formularza
VisibleFeatures Lista widocznych cech: "Asortyment,Producent"
SelectedValue Binding do zaznaczonych wierszy (tablica)
FocusedValue Binding do aktywnego wiersza

Przyciski: NewButton, EditButton, RemoveButton, SearchButton — wartości Auto, None, Visible.

Bindowanie danych

Powiązanie typu z formularzem

  1. Przez nazwę plikuTowar.Ogolne.pageform.xml → kontekst klasy Towar
  2. Przez atrybut DataType<DataForm DataType="Soneta.Handel.Towar,Soneta.Handel">
  3. Przez rejestrację FolderViewAttribute — dla viewform.xml

Zmiana kontekstu danych

  • DataContext="{Adres}" — zmienia kontekst aktualnego elementu i podrzędnych
  • EditValue="{Pozycje}" na Grid — zmienia kontekst tylko podrzędnych (pola wewnątrz Grida)

Składnia wyrażeń {...}

Składnia Opis
{Właściwość} Publiczna właściwość w kontekście
{Obiekt.Właściwość} Właściwość zagnieżdżona
{Obiekt+SubObiekt.Właściwość} Operator + — nawigacja przez powiązany obiekt ViewInfo
{Workers.NazwaWorkera.Pole} Właściwość workera
{new NazwaExtender.Pole} Właściwość extendera
{Features.NazwaCechy} Cechy powiązane z Row
{Context.TypDanych.Pole} Wartość z kontekstu UI (Soneta.Business.Context)
{Licence.HAN} Warunek licencji (używany w Renderable)
{.} Aktualna wartość w kontekście elementu

Wyrażenia warunkowe (RowCondition)

Visibility="{?State=Added}"             <!-- równość -->
Visibility="{?!State=Added}"            <!-- negacja -->
Visibility="{?Typ=Towar or Typ=Usługa}" <!-- OR -->
Visibility="{?Aktywny and Widoczny}"    <!-- AND -->

Atrybut Class — najważniejsze wartości

Style etykiet: BoldLabel, CenterLabel, RightLabel, WarningLabel, InfoLabel, NoColonLabel

Style czcionek: BoldFont, LargeFont, GreenFont, RedFont

Typy edytorów: PasswordEdit, RichEdit, ImageEdit, HyperlinkEdit, EmailEdit, PhoneEdit, ColorEdit, ProgressEdit, RatingEdit, FileEdit

Zachowania kontenerów: Collapsable, Expandable, Expanded, Scrollable, FirstResponder

Przyciski: MainCommand, SplitCommand, CommandNoText, CommandIcoText

Wyrównanie: LeftAlign, RightAlign, TextRight

Pozycjonowanie: GroupItem — element na poziomie nagłówka Group (zwykle po prawej)

Pełna lista Class: references/ELEMENTS.md

Appearance - Warunkowe formatowanie

<Field EditValue="{Saldo}">
  <Appearance Condition="{?Saldo&lt;0}" ForeColor="Red" FontBold="true" />
  <Appearance Condition="{?Saldo&gt;1000}" BackColor="LightGreen" />
</Field>

Składnia Condition może używać nawiasów kwadratowych gdy nazwa pola zawiera spacje lub operator porównania wymaga jawnego typu:

<Appearance Condition="{?[Typ] = 'usługa'}" ForeColor="#800080" />

Przykład: pageform.xml

Plik: MojObiekt.Ogolne.pageform.xml

<?xml version="1.0" encoding="utf-8"?>
<DataForm xmlns="http://www.enova.pl/schema/form.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xsi:schemaLocation="http://www.enova.pl/schema/ http://www.enova.pl/schema/form.xsd"
          Priority="10">
  <Page CaptionHtml="Ogólne" DataContext="{DataSource}">
    <Group CaptionHtml="Dane podstawowe">
      <Field CaptionHtml="Kod" Width="20" EditValue="{Kod}" />
      <Field CaptionHtml="Nazwa" Width="*" EditValue="{Nazwa}" />
    </Group>
    <Group CaptionHtml="Pozycje">
      <Grid Width="*" Height="*" EditValue="{Pozycje}" IsToolbarVisible="true">
        <Field CaptionHtml="Lp" Width="5" EditValue="{Lp}" />
        <Field CaptionHtml="Wartość" Width="15" EditValue="{Wartosc}" Footer="Sum" />
      </Grid>
    </Group>
  </Page>
</DataForm>

Przykład: viewform.xml z FilterPanel

Widok listy z panelem filtrów powyżej grida. <Flow> jako FilterPanel to standardowy wzorzec.

<?xml version="1.0" encoding="utf-8"?>
<DataForm xmlns="http://www.enova.pl/schema/form.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xsi:schemaLocation="http://www.enova.pl/schema/ http://www.enova.pl/schema/form.xsd">
  <Flow Name="FilterPanel">
    <Field CaptionHtml="Status" Width="15" EditValue="{ViewInfo+Params.Status}" Important="true" />
    <Field CaptionHtml="Typ" Width="12" EditValue="{ViewInfo+Params.Typ}" Important="true" />
    <Field CaptionHtml="Data od" Width="14" EditValue="{ViewInfo+Params.DataOd}" />
  </Flow>
  <Grid Name="List" OrderBy="Nazwa" FilterPanelWidth="136"
        IsToolbarVisible="true" IsFilterRowVisible="false">
    <Appearance Condition="{?[Status] = 'nieaktywny'}" ForeColor="#808080" />
    <Field CaptionHtml="Kod" Width="20" EditValue="{Kod}" />
    <Field CaptionHtml="Nazwa" Width="30" EditValue="{Nazwa}" />
    <Field CaptionHtml="Status" Width="15" EditValue="{Status}" />
    <UserFilter Value="Status='Aktywny'" />
  </Grid>
</DataForm>

Uwaga: Pliki viewform.xml zawierają Grid bezpośrednio w DataForm (bez Page). Atrybuty ViewType i Mode na DataForm są opcjonalne — dodaj je tylko gdy rejestrujesz widok przez FolderViewAttribute.

Współdzielony fragment (form.xml)

<?xml version="1.0" encoding="utf-8"?>
<DataForm xmlns="http://www.enova.pl/schema/form.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xsi:schemaLocation="http://www.enova.pl/schema/ http://www.enova.pl/schema/form.xsd">
  <Stack>
    <Row>
      <Field CaptionHtml="Ulica" Width="40" EditValue="{Ulica}" />
      <Field CaptionHtml="Nr domu" Width="10" EditValue="{NrDomu}" />
    </Row>
    <Row>
      <Field CaptionHtml="Kod pocztowy" Width="12" EditValue="{KodPocztowy}" />
      <Field CaptionHtml="Miasto" Width="*" EditValue="{Miasto}" />
    </Row>
  </Stack>
</DataForm>

Dołączanie: <Include Source="Adres.form.xml" DataContext="{Adres}" />

Referencje