Egyedi widgetek

Prev Next

Készítsen saját widgeteket a Tulipban HTML, CSS és JavaScript segítségével

Who can use this feature

Users on Professional plans and above.

Requirement to use Custom Widget

Please allow Outgoing access to Custom Widgets. See Networking requirements for a Tulip Cloud Deployment to learn more.* *.tulip-custom-widgets.com

Azok az elemek, amelyeket drag-and-drop módszerrel az alkalmazásába húz, widgeteknek nevezik. Ezek lehetnek gombok, képek, beviteli mezők és bármi más, ami az eszköztáron elérhető.

Az egyéni widgetek lehetővé teszik, hogy saját kódot írjon, és saját widgeteket hozzon létre, amelyeket aztán áthúzhat az alkalmazásába, és amelyekkel interakcióba léphet. Ez a képesség lehetővé teszi a Tulip-felhasználók számára, hogy tágítsák a Tulip-ban elérhető lehetőségek határait.

Nézze meg az alábbi videót a funkció áttekintéséhez:

Tekintse meg a Tulip könyvtárban elérhető egyéni widgeteket.

Az egyéni widgetek alapjai

Az egyéni widgetek kezelőképernyője a fiókbeállítások oldalon található. Itt hozhat létre és törölhet widgeteket. Az egyéni widget-szerkesztő segítségével megírhatja a widget kódját, létrehozhat Props-okat és Events-eket, valamint megtekintheti a widget előnézetét. Az alábbi ábra bemutatja, hogy mik a Props-ok és az Events-ek:

Props: A props olyan adatok, amelyeket az egyéni widgetek és a Tulip-alkalmazások megosztanak egymással. A props az alkalmazásszerkesztőben jelennek meg, és lehetővé teszik az alkalmazásszerkesztők számára, hogy kiválasszák, mely változókat, táblázati rekordokat vagy egyéb információkat társítanak a prophoz.

Események: Az események olyan jelzések, amelyeket a widget küldhet az alkalmazásnak. Az események lehetővé teszik az alkalmazás számára, hogy egy triggerrel reagáljon, és információkat is hordozhatnak magukkal.

Az egyéni widgetek az Alkalmazásszerkesztő „Egyéni” legördülő menüjén keresztül érhetők el.

Widget létrehozása

Permission Required

Only users with access to account settings (i.e. Account Owners) or users with specific permission to access the custom widget page can use the custom widget editor.

A Widget-szerkesztő képernyő négy szakaszra van felosztva. A bal alsó szakaszban írt kód megjelenik az előnézeti szakaszban, miután rákattint az előnézeti szakaszra. A prop-értékek tesztelési célokra közvetlenül az előnézeti szakaszban módosíthatók.

Vannak speciális funkciók a propokkal és eseményekkel való interakcióhoz.

A propok értékének lekérése

Warning

It is not guaranteed that the prop being used by a widget will load before that widget loads, so all props associated with Table record fields, Aggregations, or any other dynamic value should include logic to support cases where they are null at the point the widget is loaded. See this section for details on triggering logic when a prop changes.

//A prop értékének lekérése getValue('My Prop');``//A prop tárolása egy változóban let myVariable = getValue('My Prop');

Művelet végrehajtása a prop értékének változásakor

//Valami végrehajtása, amikor a prop értéke megváltozik getValue('My Prop', (internalVariable) => { doSomething(internalVariable);});

A prop értékének beállítása


//A text prop értékének beállítása 'hello!'-ra setValue('My Text Prop', 'hello!');

//Állítsd be egy objektum elemének értékét setValue('My Object Prop', { 'Key inside object': 'new value' });```

### Esemény indítása

```**Esemény indítása** fireEvent('event', *payload*);

//Esemény indítása payload nélkül fireEvent('My Event');

//Esemény indítása payload-dal fireEvent('My Event', myVariable);```

Az alábbi ábra szemlélteti az információáramlást egy alkalmazáson belüli egyéni widgeten keresztül. A bemeneti változó adatai a prop-ba kerülnek tárolásra. Az értékváltozás egy eseményt jelzi, amelynek hatására egy trigger az adatokat a kimeneti változóba tárolja.

![Custom Widget App Setup Diagram](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Custom%20Widget%20App%20Setup%20Diagram.jpg){height="" width=""}

## Widget-készítési bemutató

![Video](https://www.youtube.com/embed/H08-W2M2Ypo?rel=0){height="576" width="1024"}

## Alkalmazások importálása/exportálása

További információkért lásd [az Importálás és exportálás](/r230/docs/import-export) című részt.

### Export

1. Az egyéni widgetek áttekintő oldalán válassza ki az exportálni kívánt widget melletti **három pontból álló menüt**.

![](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Custom%20Widgets%20Overview_477703991.png){height="" width=""}

1. Válassza **az Exportálás lehetőséget**.

![](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Custom%20Widgets%20Overview_477704053.png){height="" width="800"}

### Import

1. Az egyéni widgetek áttekintő képernyőjén válassza ki a tetején található **három pontból álló menüt**.

![](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Custom%20Widgets%20Overview_477704175.png){height="" width="800"}

1. Válassza **az Importálás lehetőséget**.

![](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Custom%20Widgets%20Overview_477704228.png){height="" width="350"}

1. Keresse meg a .json egyéni widget fájlt.

## Külső könyvtárak engedélyezése

A külső könyvtárak tovább bővítik az egyéni widgetek funkcióit. A külső könyvtárak elvégzik azt a manuális munkát, hogy a HTML-kódot közvetlenül JavaScriptben írják meg. A külső könyvtárakat minden olyan widgetnél engedélyezni kell, ahol használni szeretné őket.

1. A widgetben kattintson az oldal jobb felső sarkában található **három pontból álló menüre**.

![](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Custom%20Widgets%20Overview_477684182.png){height="" width=""}

1. Válassza a **„Külső könyvtár engedélyezése**” lehetőséget.

![](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Custom%20Widgets%20Overview_477684247.png){height="" width="250"}

1. Válassza ki az engedélyezni kívánt **kiterjesztést**.

![Screenshot 2025-02-06 at 9.13.14 AM](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Screenshot%202025-02-06%20at%209.13.14%20AM.png){height="" width=""}

Az egyes kiterjesztések funkcióinak alapvető leírása:

* **jQuery** – lehetővé teszi a HTML-elemek egyszerűbb kijelölését, valamint az elemek manipulálását.
* **D3 –** Az adatok vizualizációjának arany standardja; a tanulási görbe meredek, de rengeteg rugalmasságot kínál.
* **Google Visualization –** A neve is mutatja, kiváló eszköz a vizualizációhoz.
* **Lodash –** A Lodash rengeteg eszközt kínál, amelyek megkönnyítik a JavaScript adattípusokkal való munkát.
* **ChartJS –** A lehetséges legegyszerűbb grafikonkészítő könyvtár, rengeteg online forrással.
* **Moment –** A Moment rengeteg eszközt kínál a dátumok és időpontok kezeléséhez.

## Futtatási környezet verziója

Az új futásidejű környezetben az egyéni widgetek betöltésének módja frissült (lásd: [Az egyéni widgetek fejlesztései](/r230/docs/custom-widget-improvements)). Ez a változás hatással van arra, hogy mikor érheted el megbízhatóan a widget tulajdonságait, például `a getValue()` segítségével lekért tulajdonságokat.

A widget által használt futásidejű környezet verziójának megtekintéséhez:

* Az **Egyéni widgetek listáján** vagy a szerkesztőben, ha a widget neve mellett egy **„Legacy”** jelölés látható, akkor a widget a régi futtatókörnyezetet használja. Ha nincs jelölés, a widget az új futtatókörnyezetet használja.
* Az Egyéni widgetek információs oldalsávjában nézze meg a **Runtime** szakaszt.
* Egy egyéni widget **Engedélyezési beállításaiban**, ha az **Egyéni widget futási környezete** kapcsoló be van kapcsolva, akkor a widget az új futási környezetet használja.

:::(Info) (NOTE)
By default, newly created Custom Widgets use the old runtime.
:::

Egy egyéni widget futásidejű verziójának váltásához használja a **„Custom Widget Runtime”** kapcsolót **a „Permission settings” (Engedélybeállítások**) menüpontban.![Custom widget runtime toggle](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Custom%20widget%20runtime%20toggle.png){height="" width=""}

## Példák

Az alábbiakban a [Tulip Library](https://tulip.co/library/) -ből származó néhány egyéni widgetet mutatunk be, amelyek szemléltetik a fent leírt funkciókat:

### Egyszerű időzítő-widget

[Egyszerű időzítő-widget](https://library.tulip.co/apps/simple-timer-widget)

Felhasználóbarát időzítő-widget az alkalmazás munkafolyamatai során eltelt idő nyomon követéséhez. Az operátorok közvetlenül az alkalmazás felületéről indíthatják el, állíthatják le és állíthatják vissza az időzítőt, így ez hasznos lehet feladatok vagy folyamatok időzítéséhez.

![Screenshot 2025-07-02 at 15.33.20.png](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Screenshot%202025-07-02%20at%2015.33.20.png){height="" width=""}

### Radiális mérőműszer-widget

[Radiális mérőműszer-widget](https://library.tulip.co/apps/radial-gauge-widget)

Ez a widget egy testreszabható radiális mérővel jeleníti meg a numerikus értékeket. Ideális olyan mutatók megjelenítésére, mint a gép sebessége, a hőmérséklet vagy a folyamat előrehaladása, gyors és könnyen érthető formátumban.

![Screenshot 2025-07-02 at 15.34.22.png](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Screenshot%202025-07-02%20at%2015.34.22.png){height="" width=""}

### Idővonal-widget

[Idővonal-widget](https://library.tulip.co/apps/timeline-widget)

Az eseményeket vagy lépéseket egy vízszintes idővonalon jeleníti meg, segítve a felhasználókat a folyamatok szakaszait, a befejezett feladatokat vagy az időalapú adatokat egy pillanat alatt átlátni.

![Screenshot 2025-07-02 at 15.34.59.png](https://cdn.document360.io/7c6ff534-cad3-4fc8-9583-912c4016362f/Images/Documentation/Screenshot%202025-07-02%20at%2015.34.59.png){height="" width=""}

## Bevált gyakorlatok

### 1. A betöltéskor futó widget-kód nem kívánt mellékhatásainak megelőzése

A Tulip a widget tényleges kódját minden rendereléskor futtatja – nemcsak a Playerben, hanem az Egyéni widget szerkesztőben, az Alkalmazásszerkesztőben és az állomás Élő előnézetében is. Ez pontos, élő előnézetet biztosít a widgetről. A szkript legfelső szintjén található bármely mellékhatással járó kód (pl. API-hívások, táblázati írások, értesítések) a widget minden renderelésekor fut, beleértve azt is, amikor a widget újra megnyílik a szerkesztőben, vagy az előnézet újratöltődik.

Bármilyen, a valós világra hatással bíró műveletet egy kifejezett kiváltó esemény (pl. gombnyomás, felhasználói műveletre adott válaszként végrehajtott `fireEvent`, vagy Prop-változás) mögé kell helyezni, ahelyett, hogy automatikusan elindulna a betöltéskor.

```// JÓ: csak akkor fut le, ha az alkalmazás kifejezetten kéri: getValue('TriggerIncrement', (shouldIncrement) => { if (shouldIncrement) { fetch("https://api.example.com/increment-counter", { method: "POST" }); }});

// ROSSZ: minden alkalommal elindul, amikor a widget betöltődik, beleértve a szerkesztőt és az előnézetet isfetch("https://api.example.com/increment-counter", { method: "POST" });```Ha egy widgetnek automatikusan kell adatokat betöltenie, használjon csak olvasható vagy idempotens végpontot, hogy az ismételt betöltések ne okozzanak nem kívánt hatásokat.

### 2. Végezz iteratív tesztelést anélkül, hogy valódi mellékhatásokat váltanál ki

Ha olyan widgetet fejleszt, amely valódi mellékhatásokkal járó termelési API-t hív meg, addig mutasson egy teszt- vagy staging végpontra, amíg be nem fejezi az iterációt, majd a közzététel előtt váltson át a termelési végpontra. Ezzel elkerülhetőek a duplikált rekordok, értesítések vagy a widget szerkesztésének és előnézetének egyéb mellékhatásai.

Azoknál a műveleteknél, amelyeknek a közzététel után is a termelési környezetben kell végbemenniük, építsen be megerősítést a widget saját felhasználói felületébe, ahelyett, hogy a betöltési időzítésre támaszkodna. Ha látható műveletet (pl. gombnyomást) követel meg, a widgetet megtekintő személynek lesz ellenőrzése felett, hogy mikor következik be a hatás.

```// Kifejezett kattintást igényel, mielőtt a valódi művelet elindulna,// függetlenül attól, hogy a widgetet hányszor renderelték már document.getElementById('submitBtn')?.addEventListener('click', () => { fetch("https://api.example.com/submit-order", { method: "POST" });});

3. Prop-kezelés – A prop-érték érvényesítése

Győződjön meg arról, hogy az egyéni widget megbízhatóan kezeli az adatokat. A propok az információk widgetbe történő átadásának egyik módja, de értékeik változhatnak, vagy kezdetben meghatározatlanok lehetnek. Annak ellenére, hogy a propoknak meghatározott típusuk van, kezdetben meghatározatlanok lehetnek, ami hibákat okozhat az egyéni widget kódjában. A bevált minták követése megelőzi a hibákat, és robusztusabbá teszi a widgetet.

Az alábbi példában egy visszahívási függvényt használunk a getValue második paramétereként. Ez a visszahívás minden alkalommal fut, amikor az egyéni widget megkapja a frissített prop-értéket.

Mivel a prop kezdeti értéke meghatározatlan lehet, majd később megkaphatja a frissített értéket, gondoskodni kell arról, hogy a konfigurációt a frissített érték fogadását követően alkalmazzuk. A getValue visszahívási függvény nélküli használata a kódvégrehajtás adott pontján a prop értékét adja vissza.

getValue('config', function(config) { if (config) { applyConfiguration(config); }});

A következő példa nem ajánlott, mivel a prop kezdeti értéke undefined lehet:const config = getValue('config');applyConfiguration(config);

4. Eseménykezelés – Adatok érvényesítése

Az eseményadatoknak van típusuk. Bár egy helytelen adattípusú esemény kiváltása nem okoz összeomlást, és nem állítja le az egyéni widget kódjának végrehajtását, jó gyakorlat, ha saját ellenőrzőket épít be, amelyek biztosítják, hogy a fireEvent-ben elküldött adatok érvényesek és megfelelő típusúak legyenek.

Ez a gyakorlat megakadályozza a váratlan viselkedést, és kódját kiszámíthatóbbá teszi.

if (data != null && typeof data === 'string') { fireEvent(eventName, data);} else { // Opcionálisan kezelje az érvénytelen adatok esetét.}

5. Használjon visszahívási függvényt az aszinkron prop-hozzáféréshez

A setValue() hívásakor a prop frissítése aszinkron módon történik. Ez azt jelenti, hogy nem azonnal történik meg, mivel az egyéni widget egy iframe-ből kommunikál a főalkalmazással. A setValue() kérés elküldésre kerül, de a kód tovább fut, anélkül, hogy megvárná a változás hatályba lépését. Ha közvetlenül utána megpróbálja használni a getValue() függvényt, valószínűleg a régi értéket kapja meg.

A legfrissebb adatok lekéréséhez mindig használjon getValue()-t visszahívási függvénnyel. A visszahívás csak akkor hajtódik végre, ha a prop frissítése sikeresen megtörtént, ami garantálja, hogy a legfrissebb információkkal dolgozik.

Az alábbi példa szemlélteti ezt a bevált gyakorlatot:```// JÓ: A prop értékének aszinkron eléréseconst newConfig = { setting: 'value' };setValue('config', newConfig);

// A visszahívási függvény akkor fut le, amikor a prop frissítése befejeződött.getValue('config', function(updatedConfig) { console.log('A prop frissült. Az új konfiguráció:', updatedConfig); // Végezz el valamit a garantáltan új értékkel applyConfiguration(updatedConfig);});```

Az alábbi példa bemutatja, mit érdemes elkerülni:```// ROSSZ: Ez nem biztos, hogy a várt módon fog működni const newConfig = { setting: 'value' }; setValue('config', newConfig);

// Ez valószínűleg a régi értéket fogja naplózni, nem az újat.const currentConfig = getValue('config'); ```

6. Használjon támogatott fejléceket az API-hívásokhoz

Ha egyéni widgetekből külső API-hívásokat hajt végre, ügyeljen az HTTP-fejlécekre, hogy elkerülje a CORS (Cross-Origin Resource Sharing) problémákat. Az egyéni widgetek iframe-környezetben futnak, amelyre specifikus biztonsági korlátozások vonatkoznak.

Csak olyan fejléceket használjon, amelyeket kifejezetten támogatnak. A nem támogatott fejlécek, például a Content-Type vagy más egyéni fejlécek beállítása CORS-hibákat okozhat, és megakadályozhatja az API-hívások működését.

Az alábbi példa szemlélteti ezt a bevált gyakorlatot:// JÓ: Egyszerű API-hívás egyéni fejlécek nélkülfetch("https://akhatri.bulb.cloud/api/v3/w/1/tables", { headers: { Authorization: "<API-kulcs>", },}) .then((response) => response.json()) .then((data) => console.log(data)) .catch((error) => console.error("Hiba:", error));

Az alábbi példa bemutatja, mit kell elkerülni:// ROSSZ: A Content-Type fejléc beállítása CORS-problémákat okozfetch("https://api.example.com/data", { headers: { Authorization: "<API kulcs>", "Content-Type": "application/json", // Ez CORS-hibákat okoz },})

Troubleshoot CORS error

If you encounter CORS errors, first remove any custom headers you've set (especially Content-Type) and test with minimal headers. The iframe security model restricts which headers can be set from custom widgets.

7. A widgetek inicializálása a futási környezet alapján

További információkért lásd a Futási környezet verziója című részt.

Új futtatási környezet

Az új futtatási környezetben a src attribútum egy üres héj HTML-fájlt ad vissza. Betöltése után ez a héjfájl üzenetet küld a szülőalkalmazásnak. A szülőalkalmazás elküldi az egyéni widget kódját, a segédfüggvényeket (például a getValue()-t) és az iframe-be beillesztendő kezdeti prop-értékeket.

Emiatt a DOMContentLoaded és a window.onload események akkor váltanak ki, amikor az üres héj betöltődik, még mielőtt a widget kódja be lenne illesztve. Az ezekhez az eseményekhez kapcsolt kezelők regisztrációja túl későn történik: az esemény már kiváltódott, így a visszahívás soha nem fut le. Az ezekben a kezelőkben található kódot a rendszer észrevétlenül kihagyja, ahogyan az alábbi példában látható:

document.addEventListener('DOMContentLoaded', function() { // Akkor vált ki, amikor a SHELL betöltődik, még a felhasználói kód beillesztése előtt // A felhasználói kód még be sem került! const myProp = getValue('myProp'); // HIBÁ: a getValue nincs definiálva});

custom widgets -ben nem szükséges a DOMContentLoaded vagy a window.onload használata. A Tulip az erőforrásokat a következő sorrendben tölti be: harmadik féltől származó könyvtárak, felhasználói HTML, majd JavaScript. Mire a JavaScript fut, a DOM már elérhető. A DOM-elemekhez közvetlenül hozzáférhet anélkül, hogy megvárná a betöltési eseményt, amint az az alábbi példában látható:

// Biztonságosan közvetlenül meghívható — a DOM már betöltődött, amikor ez fut.const btn = document.getElementById('my-btn');

Régi futtatási környezet

A régi futtatási környezetben a srcDoc attribútum beilleszti az egyéni widget kódját az iframe-be, olyan segédfüggvényekkel együtt, mint a getValue() és a kezdeti prop-értékek. Mivel a widget kódja a kezdetektől fogva a dokumentum része, a getValue() és a prop-ok az iframe tartalmának betöltésekor azonnal elérhetőek.Ennek eredményeként a DOMContentLoaded és a window.onload a régi futásidejű környezetben a várakozásoknak megfelelően működnek, amint azt az alábbi példa is mutatja:

document.addEventListener('DOMContentLoaded', function() { // Akkor vált ki, amikor a felhasználó HTML-je készen áll // A propok már elérhetők const myProp = getValue('myProp'); // Azonnal működik});

{{snippet.Megtalálta, amit keresett?}}