{"result":{"depiction_url":null,"edges":{"subject":{"objects":[{"created":"2026-09-30T09:11:23Z","object_id":{"id":2555,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/2555"},"seq":1},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2563,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_frontend_developer","title":"Frontend developer","uri":"https:\/\/zotonic.com\/id\/2563"},"seq":2},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2641,"is_a":["categorization","keyword","keyword_task"],"name":"zotonic_topic_render","title":"Render","uri":"https:\/\/zotonic.com\/id\/2641"},"seq":3},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2673,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_javascript","title":"JavaScript","uri":"https:\/\/zotonic.com\/id\/2673"},"seq":4},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2718,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_cotonic","title":"Cotonic","uri":"https:\/\/zotonic.com\/id\/2718"},"seq":5},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2721,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_dom","title":"Document Object Model","uri":"https:\/\/zotonic.com\/id\/2721"},"seq":6}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":2730,"is_a":["text","documentation","reference","cotonic_reference"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/2730"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_cotonic_cotonic_ui","page_url":{"en":"https:\/\/zotonic.com\/cotonic\/cotonic_ui","x-default":"https:\/\/zotonic.com\/cotonic\/cotonic_ui"},"preview_url":null,"resource":{"version":15,"pivot_location_lat":null,"title":"cotonic.ui","is_authoritative":true,"body":"<a name=\"cotonic.ui\"><\/a><h3>ui<\/h3>\n\n            <p>\n            The user interface composer manages html snippets which can be placed in the DOM tree. When an\n            updated html snippet is delivered to the composer it will render it by using Google&#39;s incremental-dom library.\n            The updates will be applied <em>incrementally<\/em> directly to the DOM tree. The updates can be\n            delivered as html text snippets to the interface composer.\n            <\/p>\n\n            <!-- insert -->\n            <a name=\"cotonic.ui.insert\"><\/a><h4>insert <code>cotonic.ui.insert(targetId, mode, initialHTML, [priority])<\/code><\/h4><p>\n            Insert a new html snippet into the user interface composer. The snippet will be stored under the given\n            targetId. The element will not be placed in the dom-tree immediately. This will happen when one of the\n            render functions is called. Parameter <tt>mode<\/tt> supports the following options:\n            <\/p>\n            <dl>\n                <dt><tt>inner<\/tt> or <tt>true<\/tt><\/dt>\n                <dd>The html-snippets update the innerHTML of the element.<\/dd>\n\n                <dt><tt>outer<\/tt> or <tt>false<\/tt><\/dt>\n                <dd>The html-snippets update the outerHTML of the element.<\/dd>\n\n                <dt><tt>shadow-open<\/tt> or <tt>shadow<\/tt><\/dt>\n                <dd>The html-snippets update the shadow DOM of the element. The element will be the shadow host.\n                    The shadow dom will be put in &quot;open&quot; mode.  When the shadow dow was not yet initialised, it will\n                    be initialised when the element is rendered the first time. Using the shadow-dom makes it possible\n                    to isolate the component from the css rules which are present on the page.\n                <\/dd>\n\n                <dt><tt>shadow-closed<\/tt><\/dt>\n                <dd>Like &quot;shadow-open&quot;, with the difference that the shadow dom will be initialised in &quot;closed&quot; mode.<\/dd>\n            <\/dl>\n\n            <p>\n            The optional priority parameter indicates the render order of the elements.\n            Elements with a high priority are rendedered before lower priorities. This makes it possible to nest\n            elements.\n            <\/p>\n            <pre>\ncotonic.ui.insert(&quot;root&quot;, &quot;outer&quot;, &quot;&lt;p&gt;Hello World!&lt;\/p&gt;&quot;);\n\ncotonic.ui.insert(&quot;shadow-root&quot;, &quot;shadow&quot;, &quot;&lt;p&gt;Hello World!&lt;\/p&gt;&quot;); <\/pre>\n\n            <!-- get -->\n            <a name=\"cotonic.ui.get\"><\/a><h4>get <code>cotonic.ui.get(id)<\/code><\/h4><p>\n            Returns the current html snippet registered at <tt>id<\/tt>.\n            <\/p>\n            <pre>\nlet currentHTML = cotonic.ui.get(&quot;root&quot;);\n=&gt; &quot;<a href=\"https:\/\/cotonic.org\/example.com\">Hello World!<\/a>&quot;<\/pre>\n\n            <!-- remove -->\n            <a name=\"cotonic.ui.remove\"><\/a><h4>remove <code>cotonic.ui.remove(id)<\/code><\/h4><p>\n            Remove the html snippet registered at id. Note that this will not remove the element from the dom-tree,\n            it will only remove it from the user interface composer. When the element must be removed it should first\n            be updated and set to a blank string and a render operation should be done.\n            <\/p>\n            <pre>\ncotonic.ui.remove(&quot;root&quot;);<\/pre>\n\n            <!-- update -->\n            <a name=\"cotonic.ui.update\"><\/a><h4>update <code>cotonic.ui.update(id, htmlOrTokens)<\/code><\/h4><p>\n            Update the registered snippet for the registered element with the given id. The new snippet will be visible\n            after a render operation.\n            <\/p>\n            <pre>\ncotonic.ui.update(&quot;root&quot;, &quot;&lt;p&gt;Hello Everybody!&lt;\/p&gt;&quot;);\n=&gt; The root element on the page will be updated.<\/pre>\n\n            <!-- render -->\n            <a name=\"cotonic.ui.render\"><\/a><h4>render <code>cotonic.ui.render()<\/code><\/h4><p>\n            Trigger a render of all registered elements.\n            <\/p>\n            <pre>\ncotonic.ui.render();\n=&gt; All elements will be (re)rendered.<\/pre>\n\n            <!-- renderId -->\n            <a name=\"cotonic.ui.renderId\"><\/a><h4>renderId <code>cotonic.ui.renderId(id)<\/code><\/h4><p>\n            Just render the element with the given id.\n            <\/p>\n            <pre>\ncotonic.ui.renderId(&quot;root&quot;);<\/pre>\n\n            <!-- updateStateData -->\n            <a name=\"cotonic.ui.updateStateData\"><\/a><h4>updateStateData <code>cotonic.ui.updateStateData(model, states)<\/code><\/h4><p>\n            Communicate the state of the model to other non-cotonic components on the page. It can\n            be used to pass model state to SPA&#39;s or other modules. It sets a data attribute on the\n            html tag of the page.\n            The parameter <tt>model<\/tt> should be a string, <tt>states<\/tt> is an object\n            with values. The values of the states object are set as data attributes\n            on the html tag like this:\n            <tt>data-ui-&lt;model&gt;-&lt;key&gt;=&quot;&lt;value&gt;&quot;<\/tt>. When an empty object is\n            passed all data attributes of the model is cleared.\n            <\/p>\n            <pre>\ncotonic.ui.updateStateData(&quot;auth&quot;, {authorized: true});\n=&gt; &lt;html data-ui-state-auth-authorized=&quot;true&quot;&gt;\n...\ncotonic.ui.updateStateData(&quot;auth&quot;, {});\n=&gt; &lt;html&quot;&gt;\n...<\/pre>\n\n            <!-- updateStateClass -->\n            <a name=\"cotonic.ui.updateStateClass\"><\/a><h4>updateStateClass <code>cotonic.ui.updateStateClass(model, classes)<\/code><\/h4><p>\n            Update the class of the html tag. This makes it possible to communicate important\n            state changes to external components like SPA&#39;s. The parameter <tt>model<\/tt> should be\n            a string. Parameter <tt>classes<\/tt> a list of classes which must be set.\n            The following elements will be added to the class attribute\n            <tt>ui-state-&lt;model&gt;-&lt;class&gt;<\/tt>. Passing <tt>[]<\/tt> will clear all the class\n            attributes of the model.\n            <\/p>\n            <pre>\ncotonic.ui.updateStateClass(&quot;auth&quot;, [&quot;unauthorized&quot;, &quot;pending&quot;]);\n=&gt; &lt;html class=&quot;ui-state-auth-pending ui-state-auth-unauthorized&quot;&gt;\ncotonic.ui.updateStateClass(&quot;auth&quot;, [&quot;authorized&quot;]);\n=&gt; &lt;html class=&quot;ui-state-auth-authorized&quot;&gt;<\/pre>\n\n            <!-- on -->\n            <a name=\"cotonic.ui.on\"><\/a><h4>on <code>cotonic.ui.on(topic, msg, event, [options])<\/code><\/h4><p>\n            Publish a DOM event on the local broker. This allows subscribers to react to user interface\n            events. Parameter <tt>topic<\/tt> is the topic on which the event will be published. The parameters\n            <tt>msg<\/tt> and <tt>event<\/tt> are included in the message which is published. The event parameter\n            is expected to be a DOM event. The <tt>options<\/tt> parameter is optional, it\n            can contain a <tt>cancel<\/tt> property which can be set to <tt>true<\/tt>, <tt>false<\/tt> or\n            <tt>&quot;preventDefault&quot;<\/tt> to indicate if the event should be cancelled or prevented.\n            The other options can be the normal options found in\n            <a href=\"\/id\/doc_cotonic_cotonic_broker#cotonic.broker.publish\"><tt>publish<\/tt><\/a>.\n            <\/p>\n            <pre>\ndocument.addEvenListener(&quot;click&quot;, function(e) {\n    const topic = event.target.getAttribute(&quot;data-topic&quot;);\n    if(!topic) return;\n\n    cotonic.ui.on(topic, {foo: &quot;bar&quot;}, e);\n}, {passive: true})\n=&gt; When somebody clicks on an element with has a data-topic=&quot;a\/topic&quot;\n   attribute, the event will be published on that topic.<\/pre>\n\n            ","slug":"cotonic.ui","is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"70db2f2312cf1bda757bf679cd6506aa31010b80e8b10205d34352a7fad70e11","is_featured":false,"content_group_id":{"id":2551,"is_a":["meta","content_group"],"name":"content_group_imported_docs","title":"Imported documentation","uri":"https:\/\/zotonic.com\/id\/content_group_imported_docs"},"category_id":{"id":2722,"is_a":["meta","category"],"name":"cotonic_reference","title":"Cotonic","uri":"https:\/\/zotonic.com\/id\/cotonic_reference"},"doc_source_path":"index.html","publication_start":"2026-09-30T09:11:23Z","page_path":"\/cotonic\/cotonic_ui","github_url":"https:\/\/github.com\/cotonic\/cotonic\/blob\/master\/index.html","pivot_location_lng":null,"doc_source_kind":"cotonic","name":"doc_cotonic_cotonic_ui","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2026-09-30T09:11:23Z","uri":null,"doc_source_anchor":"cotonic.ui","doc_status":"current","is_dependent":false,"publication_end":"9999-06-01T00:00:00Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"privacy":0,"doc_source_commit":"f88cc928b997d10f7f19e6bd0ede80e1c8c619bc","creator_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"modified":"2026-09-30T09:57:31Z","title_slug":"cotonic.ui"},"uri":"https:\/\/zotonic.com\/id\/2730","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/2730"}},"status":"ok"}