SVGHMI: JsonTable can now have clickable elements, that trigger a request with extra argument whose content is taken from Json data. svghmi
authorEdouard Tisserant
Fri, 28 Aug 2020 15:29:35 +0200
branchsvghmi
changeset 3048 d46d545ff7b7
parent 3047 c113904f0e62
child 3049 4ac68ec9786f
SVGHMI: JsonTable can now have clickable elements, that trigger a request with extra argument whose content is taken from Json data.
svghmi/gen_index_xhtml.xslt
svghmi/widget_jsontable.ysl2
tests/svghmi/py_ext_0@py_ext/pyfile.xml
tests/svghmi/svghmi_0@svghmi/svghmi.svg
--- a/svghmi/gen_index_xhtml.xslt	Fri Aug 28 11:31:18 2020 +0200
+++ b/svghmi/gen_index_xhtml.xslt	Fri Aug 28 15:29:35 2020 +0200
@@ -3467,7 +3467,7 @@
 </xsl:text>
     <xsl:text>    cache = [];
 </xsl:text>
-    <xsl:text>    do_http_request() {
+    <xsl:text>    do_http_request(...opt) {
 </xsl:text>
     <xsl:text>        const query = {
 </xsl:text>
@@ -3475,7 +3475,9 @@
 </xsl:text>
     <xsl:text>            vars: this.cache,
 </xsl:text>
-    <xsl:text>            visible: this.visible
+    <xsl:text>            visible: this.visible,
+</xsl:text>
+    <xsl:text>            options: opt
 </xsl:text>
     <xsl:text>        };
 </xsl:text>
@@ -3511,15 +3513,9 @@
 </xsl:text>
     <xsl:text>    }
 </xsl:text>
-    <xsl:text>    on_click(evt) {
-</xsl:text>
-    <xsl:text>        this.do_http_request();
-</xsl:text>
-    <xsl:text>    }
-</xsl:text>
-    <xsl:text>    init() {
-</xsl:text>
-    <xsl:text>        this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)");
+    <xsl:text>    on_click(evt, ...options) {
+</xsl:text>
+    <xsl:text>        this.do_http_request(...options);
 </xsl:text>
     <xsl:text>    }
 </xsl:text>
@@ -3705,8 +3701,20 @@
     <xsl:param name="expressions"/>
     <xsl:param name="widget_elts"/>
     <xsl:param name="label"/>
+    <xsl:variable name="new_expressions" select="func:json_expressions($expressions, $label)"/>
+    <xsl:variable name="elt" select="."/>
+    <xsl:for-each select="$new_expressions/expression[position() &gt; 1][starts-with(@name,'onClick')]">
+      <xsl:text>        id("</xsl:text>
+      <xsl:value-of select="$elt/@id"/>
+      <xsl:text>").setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt, '</xsl:text>
+      <xsl:value-of select="@name"/>
+      <xsl:text>', '"+</xsl:text>
+      <xsl:value-of select="@content"/>
+      <xsl:text>+"')");
+</xsl:text>
+    </xsl:for-each>
     <xsl:apply-templates mode="json_table_elt_render" select=".">
-      <xsl:with-param name="expressions" select="func:json_expressions($expressions, $label)"/>
+      <xsl:with-param name="expressions" select="$new_expressions"/>
     </xsl:apply-templates>
   </xsl:template>
   <xsl:template mode="json_table_render" match="svg:g">
--- a/svghmi/widget_jsontable.ysl2	Fri Aug 28 11:31:18 2020 +0200
+++ b/svghmi/widget_jsontable.ysl2	Fri Aug 28 15:29:35 2020 +0200
@@ -4,11 +4,12 @@
     ||
     class JsonTableWidget extends Widget{
         cache = [];
-        do_http_request() {
+        do_http_request(...opt) {
             const query = {
                 args: this.args,
                 vars: this.cache,
-                visible: this.visible
+                visible: this.visible,
+                options: opt
             };
 
             const options = {
@@ -26,11 +27,8 @@
             this.cache[index] = value;
             this.do_http_request();
         }
-        on_click(evt) {
-            this.do_http_request();
-        }
-        init() {
-            this.element.setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt)");
+        on_click(evt, ...options) {
+            this.do_http_request(...options);
         }
     }
     ||
@@ -158,12 +156,20 @@
         }
 }
 
+
 template "svg:*", mode="json_table_render" {
     param "expressions";
     param "widget_elts";
     param "label";
+
+    const "new_expressions", "func:json_expressions($expressions, $label)";
+
+    const "elt",".";
+    foreach "$new_expressions/expression[position() > 1][starts-with(@name,'onClick')]"
+    |         id("«$elt/@id»").setAttribute("onclick", "hmi_widgets['"+this.element_id+"'].on_click(evt, '«@name»', '"+«@content»+"')");
+
     apply ".", mode="json_table_elt_render"
-        with "expressions", "func:json_expressions($expressions, $label)";
+        with "expressions", "$new_expressions";
 }
 
 template "svg:g", mode="json_table_render" {
--- a/tests/svghmi/py_ext_0@py_ext/pyfile.xml	Fri Aug 28 11:31:18 2020 +0200
+++ b/tests/svghmi/py_ext_0@py_ext/pyfile.xml	Fri Aug 28 15:29:35 2020 +0200
@@ -9,13 +9,18 @@
   <globals>
     <xhtml:p><![CDATA[
 from twisted.web.resource import Resource
-import json, time, random
+import json, time, random, collections
 
 Alarms = []
+AlarmIndex = {}
+lastid = 0
 
 def TriggerAlarm(changed_var_name):
-    global Alarms
-    Alarms.append((time.time(), PLCGlobals.AlarmText, PLCGlobals.AlarmStatus))
+    global Alarms, lastid
+    new_entry = [time.time(), PLCGlobals.AlarmText, PLCGlobals.AlarmStatus, lastid]
+    Alarms.append(new_entry)
+    AlarmIndex[lastid] = new_entry
+    lastid = lastid + 1
     PLCGlobals.AlarmNotify = random.randint(0, 4294967296)
 
 class AlarmJsonResource(Resource):
@@ -25,16 +30,21 @@
     def render_POST(self, request):
         newstr = request.content.getvalue()
         newdata = json.loads(newstr)
-        print newdata
         vars = newdata[u'vars']
         args = newdata[u'args']
         visible = newdata[u'visible']
+        options = newdata[u'options']
+
+        if len(options) == 2 :
+            action, alarmid = options
+            if action == "onClick[acknowledge]":
+                AlarmIndex[int(alarmid)][2] = "ack"
+
         svars = (vars + [0,0])[:3]
         range_feedback = svars[1]
         slider_position = svars[2]
         answer = self.renderTable(range_feedback, slider_position, visible, *(args+svars[3:]))
         janswer = json.dumps(answer)
-        print janswer
         return janswer
 
     def renderTable(self, old_range, old_position, visible, *options):
@@ -44,11 +54,12 @@
         new_visible = new_range if delta <= 0 else visible
         
         visible_alarms = []
-        for ts, text, status in Alarms[new_position:new_position + new_visible]:
+        for ts, text, status, alarmid in Alarms[new_position:new_position + new_visible]:
             visible_alarms.append({
                 "time": time.ctime(ts),
                 "text": text, # TODO translate text
-                "status": status
+                "status": status,
+                "alarmid": alarmid
             })
 
         return new_range, new_position, visible_alarms
--- a/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Fri Aug 28 11:31:18 2020 +0200
+++ b/tests/svghmi/svghmi_0@svghmi/svghmi.svg	Fri Aug 28 15:29:35 2020 +0200
@@ -200,9 +200,9 @@
      inkscape:current-layer="g1384"
      showgrid="false"
      units="px"
-     inkscape:zoom="0.77167689"
-     inkscape:cx="-954.74063"
-     inkscape:cy="270.19826"
+     inkscape:zoom="1.0913159"
+     inkscape:cx="-911.00114"
+     inkscape:cy="181.96708"
      inkscape:window-width="1800"
      inkscape:window-height="836"
      inkscape:window-x="0"
@@ -5259,11 +5259,6 @@
            inkscape:label="# commented group"
            transform="translate(419.716,-441.73566)">
           <path
-             inkscape:connector-curvature="0"
-             id="path898"
-             d="m 2360.9444,507.07858 c 71.4734,-75.13864 128.2855,23.82444 128.2855,23.82444 l 29.3224,-47.6489"
-             style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-          <path
              style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
              d="m 528.62458,486.07049 23.69122,21.00809"
              id="path903"
@@ -5280,7 +5275,7 @@
            width="100%"
            height="100%"
            transform="matrix(0.7609336,0,0,0.7609336,199.15217,164.3798)"
-           inkscape:label=".status" />
+           inkscape:label=".status onClick[acknowledge]=.alarmid" />
         <use
            transform="matrix(1.3019536,0,0,1.3019536,39.582906,238.73392)"
            x="0"