# HG changeset patch # User Edouard Tisserant # Date 1598621375 -7200 # Node ID d46d545ff7b791b54fa7bcefbbbdf79f693d9238 # Parent c113904f0e62558358568e46b38d82b808b43a10 SVGHMI: JsonTable can now have clickable elements, that trigger a request with extra argument whose content is taken from Json data. diff -r c113904f0e62 -r d46d545ff7b7 svghmi/gen_index_xhtml.xslt --- 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() > 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"> diff -r c113904f0e62 -r d46d545ff7b7 svghmi/widget_jsontable.ysl2 --- 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" { diff -r c113904f0e62 -r d46d545ff7b7 tests/svghmi/py_ext_0@py_ext/pyfile.xml --- 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 diff -r c113904f0e62 -r d46d545ff7b7 tests/svghmi/svghmi_0@svghmi/svghmi.svg --- 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"