Mingcedar

Product: Mingcedar Studio DESIGNER

Change component layout through scripts | Mingcedar Studio

Add runtime logic to the current page with JavaScript. Top-level Page Script variables, constants, classes, and functions are available to every animation and expression on that page. Use ReadTag helpers for Tag values and hqVisuDesigner to drive components and navigation; hqVisuDesignerPageReady runs when the page is ready. Read one bit with the "TAGNAME[bit]" bracket syntax.

Published Updated

<section id="imperative-layout" class="docs-block docs-block-intro docs-block-current"> <span class="section-kicker">Feature</span> <h2>Change component layout through scripts</h2> <p>Add runtime logic to the current page with JavaScript. Top-level Page Script variables, constants, classes, and functions are available to every animation and expression on that page. Use ReadTag helpers for Tag values and hqVisuDesigner to drive components and navigation; hqVisuDesignerPageReady runs when the page is ready. Read one bit with the &quot;TAGNAME[bit]&quot; bracket syntax.</p> <div class="docs-detail-list"> <article id="imperative-layout-item-1" class="docs-detail-row"> <strong>Overview</strong> <p>Scripts add runtime logic to the current page, all in JavaScript. The plugin does not provide a Global Script document shared by the whole PowerPoint file. The Scripts group on the ribbon has one current-page entry point, Page Script; alarm.js is also a protected document for that page. Page Script top-level declarations are available to behaviors on the same page but do not automatically exist on other pages. ReadTag helpers read Tag values, while hqVisuDesigner changes component text, color, visibility, layout, and navigation. WriteTag helpers are allowed during real user click, press or release actions, not in Page Script, Setup Script, or Hover Script. Behavior Setup Script / Condition / Value / Text fields use the same ECMAScript 2022 syntax boundary; expression fields must return one synchronous result.</p> </article><article id="imperative-layout-item-2" class="docs-detail-row"> <strong>Use Script Workspace from New to Save</strong> <p>Open Scripts → Page Script. Select a document, or click New and enter Folder and Name. Write in Code; clear Enabled to keep a document without exporting it. Save validates and writes all enabled documents on this page.</p> <ul> <li>Scope: confirm that the target page is active.</li><li>New or Ctrl+N: create a script document.</li><li>Folder: optional slash-separated path.</li><li>Name: document name without the .js extension.</li><li>Enabled: a disabled document is retained but not exported or validated on Save.</li><li>Script Library or Ctrl+J: insert a method or template at the caret.</li><li>Save or Ctrl+S: validate and save the complete workspace.</li><li>Help or F1: open script help.</li> </ul> </article><article id="imperative-layout-item-3" class="docs-detail-row"> <strong>Quick Methods library</strong> <p>Open Quick Methods: filter categories on the left, select a method in the middle, and review its purpose, example and parameters on the right. Search and click Insert to add a snippet. Available methods depend on the installed version.</p> </article><article id="imperative-layout-item-4" class="docs-detail-row"> <strong>Delete documents and keep protected alarm.js</strong> <p>Select a custom document, click Delete and confirm. Protected alarm.js cannot be deleted; edit its alarm configuration to disable or change page alarm display.</p> <ul> <li>Before deleting, confirm no behavior or other document uses its functions or variables.</li><li>Delete applies only to removable custom documents.</li><li>alarm.js is protected; edit its configuration instead.</li><li>Choose Cancel, not Save, when you want to discard all pending workspace edits.</li> </ul> </article><article id="imperative-layout-item-5" class="docs-detail-row"> <strong>How to use it: common methods and syntax</strong> <p>Set window.hqVisuDesignerPageReady in Page Script for initialization; it runs once when the page runtime is ready. Common methods follow:</p> <ul> <li>Read tags, ReadTag family: ReadTagBoolean / ReadTagInteger / ReadTagDouble / ReadTagString; the second argument is the fallback value used when the tag cannot be read</li><li>Date/time helpers: GetCurrentDate() returns yyyy-MM-dd, GetCurrentDateTime() returns yyyy-MM-dd HH:mm:ss, and FormatDateTime(value, &quot;yyyy/MM/dd HH:mm:ss&quot;) formats an existing date/time value; search keywords include time, date, datetime, 时间, 日期</li><li>Read a single bit (key point): append a bracketed bit number to the complete tag name, for example &quot;PLC_LINE01.PUMP01.STATUS[3]&quot;, and read it with ReadTagBoolean; the bit number is zero-based, range 0-31, with no spaces inside the brackets</li><li>Tag quality: ReadTagQuality(name, &quot;bad&quot;) returns the quality text, ReadTagQualityGood(name) tests whether it is good (quality is only good / bad, not the process value)</li><li>Write tags, WriteTag family: use only in a real user-click script; the host still decides permission, confirmation, reason capture, and the final asynchronous outcome</li><li>Drive components, hqVisuDesigner: setComponentText(nameOrId, value), setComponentFill, setComponentBorder, setComponentVisible, setComponentLayout, findComponent, getComponentData</li><li>Navigation and variables, hqVisuDesigner: openPage(&quot;PageName&quot;), openScreen(&quot;SCREEN_CODE&quot;), openWebsite(url, openInNewWindow), writeVariable(name, value), and refreshView()</li> </ul> <pre class="docs-code-block"><code>// Page Script: initialize when the page is ready

window.hqVisuDesignerPageReady = function (ctx) {

// Read bit 0 from an integer tag (bracket syntax, no spaces)

const pumpRun = ReadTagBoolean(&quot;PLC_LINE01.PUMP01.STATUS[0]&quot;, false);

hqVisuDesigner.setComponentText(&quot;Title 1&quot;, pumpRun ? &quot;RUN&quot; : &quot;STOP&quot;);

hqVisuDesigner.setComponentFill(&quot;Lamp 1&quot;, pumpRun ? &quot;#22C55E&quot; : &quot;#EF4444&quot;);

hqVisuDesigner.refreshView();

};</code></pre> </article><article id="imperative-layout-item-6" class="docs-detail-row"> <strong>Common JS snippets: date/time, status text, and safe defaults</strong> <p>Use these snippets in Page Script, Click Script, or a behavior Setup Script area. Condition / Value / Text slots should contain only the final expression that returns immediately; longer checks and formatting belong in Setup Script or a script body.</p> <ul> <li>Ternary expression: condition ? trueValue : falseValue, useful for converting a boolean to text, color, or a numeric value.</li><li>Safe defaults: the second argument of ReadTagBoolean / ReadTagDouble and similar helpers is the fallback when the tag cannot be read.</li><li>Date/time text: use GetCurrentDate() for the current date, GetCurrentDateTime() for the current date-time, and FormatDateTime(...) for display formatting.</li><li>Multiple conditions: use a ternary for simple cases; use if / else to prepare variables before writing to a component or returning a behavior value.</li> </ul> <pre class="docs-code-block"><code>// date / time

const today = GetCurrentDate(); // yyyy-MM-dd

const nowText = GetCurrentDateTime(); // yyyy-MM-dd HH:mm:ss

const displayTime = FormatDateTime(nowText, &quot;yyyy/MM/dd HH:mm:ss&quot;);

// Boolean status to text

const currentValue = ReadTagBoolean(&quot;PLC_LINE01.PUMP01.READY&quot;, false);

let text = currentValue ? &quot;OK&quot; : &quot;Fault&quot;;

// Numeric banding

const speed = ReadTagDouble(&quot;PLC_LINE01.MOTOR01.SPEED&quot;, 0);

const levelText = speed &gt;= 80 ? &quot;High&quot; : (speed &gt;= 40 ? &quot;Medium&quot; : &quot;Low&quot;);

// Quality guard: show communication fault first when quality is bad

if (!ReadTagQualityGood(&quot;PLC_LINE01.MOTOR01.SPEED&quot;)) {

text = &quot;Communication fault&quot;;

}

hqVisuDesigner.setComponentText(&quot;StatusText&quot;, `${text} / ${displayTime}`);

hqVisuDesigner.setComponentText(&quot;LevelText&quot;, levelText);</code></pre> </article><article id="imperative-layout-item-7" class="docs-detail-row"> <strong>Common JS syntax: string concatenation, number formatting, arrays, and objects</strong> <p>Format Tag values with strings, numbers, arrays and objects in Setup Script or Page Script, then return the result to a behavior or write it to a component.</p> <ul> <li>String concatenation: use &#39;Speed: &#39; + speed for simple text; use template strings like `Speed: ${speed}` when several values are involved.</li><li>Number formatting: use Number(value).toFixed(1) to control decimal places.</li><li>Arrays: keep status lists, alarm lists, or multiple component names in arrays, then loop through them.</li><li>Objects: keep lookup tables such as state code to text, color, and priority.</li> </ul> <pre class="docs-code-block"><code>// String concatenation and template strings

const speed = ReadTagDouble(&#39;PLC_LINE01.MOTOR01.SPEED&#39;, 0);

const unit = &#39; rpm&#39;;

const speedText = `Speed: ${Number(speed).toFixed(1)}${unit}`;

const timeText = `Updated: ${GetCurrentDateTime()}`;

// Object map: state code to text and color

const state = ReadTagInteger(&#39;PLC_LINE01.MOTOR01.STATE&#39;, 0);

const stateMap = {

0: { text: &#39;Stopped&#39;, color: &#39;#94A3B8&#39; },

1: { text: &#39;Running&#39;, color: &#39;#22C55E&#39; },

2: { text: &#39;Fault&#39;, color: &#39;#EF4444&#39; }

};

const stateInfo = stateMap[state] ?? { text: &#39;Unknown&#39;, color: &#39;#F59E0B&#39; };

// Arrays: update several components

const targetNames = [&#39;SpeedText&#39;, &#39;SpeedTextCopy&#39;];

targetNames.forEach((name) =&gt; hqVisuDesigner.setComponentText(name, speedText));

hqVisuDesigner.setComponentText(&#39;StateText&#39;, `${stateInfo.text} / ${timeText}`);

hqVisuDesigner.setComponentFill(&#39;StateLamp&#39;, stateInfo.color);</code></pre> </article><article id="imperative-layout-item-8" class="docs-detail-row"> <strong>When to use it</strong> <p>Put shared page functions, constants and Tag prefixes at Page Script top level; put initialization in hqVisuDesignerPageReady. For advanced cross-page reuse, use the host runtime, custom SDK or templates. Use bracket bit reads to drive displays from an integer Tag’s Boolean bit.</p> <ul> <li>Put same-page helpers, constants, and Tag prefixes in the current page&#39;s Page Script</li><li>Use hqVisuDesigner.openPage(...) for same-package pages and hqVisuDesigner.openScreen(...) across packages; do not write disk-relative paths like ../../other-screen/index.html</li> </ul> </article><article id="imperative-layout-item-9" class="docs-detail-row"> <strong>Limitations and troubleshooting</strong> <p>Configuration requirements: (1) Bit-read must use exact &quot;TAGNAME[bit]&quot; syntax with no spaces, and bit numbers are 0-31. Bit writes use the parent integer Tag plus BitIndex; never write TAGNAME[3] as an ordinary Tag. (2) WriteTag is allowed during real user click, press or release actions and is still subject to host permission, confirmation, reason capture, and asynchronous outcome. (3) Async APIs belong only in script-body fields; await must be inside an async function and top-level await is unsupported. (4) import/export are module syntax and are not supported by page documents or animation expressions; advanced modules belong in the custom SDK.</p> </article> </div> <div class="docs-note-grid"> <figure id="imperative-layout-image-1" class="docs-note-card manual-doc-image-card"> <img src="/WEB_img/HQPPT/current/scripts/workspace.png" alt="Mingcedar Studio Script Workspace" loading="lazy" decoding="async"> <figcaption> <strong>Script Workspace</strong> <p>Edit JavaScript documents for the current page; at runtime use ReadTag and hqVisuDesigner to drive the screen.</p> </figcaption> </figure><figure id="imperative-layout-image-2" class="docs-note-card manual-doc-image-card"> <img src="/WEB_img/HQPPT/current-20261021/quick-methods.png" alt="Quick Methods library showing categories, methods, code example, and parameter details" loading="lazy" decoding="async"> <figcaption> <strong>Quick Methods library</strong> <p>Browse or search for a method, review its example and parameters, then click Insert. The visible count belongs to this plugin version.</p> </figcaption> </figure> </div> </section>