Custom Page Features: Difference between revisions

From MidasWiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(6 intermediate revisions by 2 users not shown)
Line 13: Line 13:


= Introduction =
= Introduction =
This page describes some of the special features provided for use on a user-created [[Custom Page|Custom Web Page]] running under [[mhttpd]].
;NOTE
: Since 2018, many of the features described here can now be implemented more simply using the  mod* JS functions (see [[Custom Page|Custom Web Page]]).
: '''If writing a new web page, it is strongly recommended you make use of the mod*JS features. '''
 
This page describes some of the special features provided for use on a user-created [[Custom Page|Custom Web Page]] using the [[#The MIDAS Javascript Library]], which was the recommended way to write Custom Pages before the [[Custom Page#modb* Javascript scheme]] was available.


<br><br>


= The MIDAS Javascript Library =
= The MIDAS Javascript Library =
Line 25: Line 30:
Web developers are moving away from synchronous RPC requests, which are now deprecated [https://midas.triumf.ca/elog/Midas/1128]. Some modern browsers return a warning on a synchronous RPC request.  
Web developers are moving away from synchronous RPC requests, which are now deprecated [https://midas.triumf.ca/elog/Midas/1128]. Some modern browsers return a warning on a synchronous RPC request.  


A new group of JSON-RPC functions using  [[mjsonrpc#Javascript client library|Promises]] has been added to the MIDAS Javascript Library (January 2016). These are asynchronous only, and they also provide more functionality and have better error handling than the older AJAX calls, which are also inconsistent in how they handle Booleans. They also have much improved handling of reading/writing arrays to the ODB. It is {{Important|text=recommended that all new Custom Pages are written using these JSON-RPC functions}}. They do require an up-to-date browser that supports Promises (see [https://midas.triumf.ca/elog/Midas/1145]). If using an older browser version, the asynchronous AJAX calls (e.g. ODBMCopy) should be used in order to avoid having to rewrite the web page at a later date to remove all synchronous calls.   
A new group of JSON-RPC functions using  [[mjsonrpc#Javascript client library|Promises]] has been added to the MIDAS Javascript Library (January 2016). These are asynchronous only, and they also provide more functionality and have better error handling than the older AJAX calls, which are also inconsistent in how they handle Booleans. They also have much improved handling of reading/writing arrays to the ODB. Before 2018 it was recommended that all new Custom Pages are written using these JSON-RPC functions.  {{Important|text=Since 2018 the [[Custom Page#modb* Javascript scheme]] is recommended for new Custom Pages}}.
 
The MIDAS Javascript Library routines requires an up-to-date browser that supports Promises (see [https://midas.triumf.ca/elog/Midas/1145]). If using an older browser version, the asynchronous AJAX calls (e.g. ODBMCopy) should be used in order to avoid having to rewrite the web page at a later date to remove all synchronous calls.   
   
   
 
<br><br>
== Access the ODB using mjson-rpc asynchronous functions ==
== Access the ODB using mjson-rpc asynchronous functions ==


Line 38: Line 45:
Examples showing how to read and write to the ODB can be found at [[mjsonrpc#examples]]. Also included are examples using arrays.  
Examples showing how to read and write to the ODB can be found at [[mjsonrpc#examples]]. Also included are examples using arrays.  


<br><br>
== Access the ODB using asynchronous AJAX calls ==
== Access the ODB using asynchronous AJAX calls ==
;NOTE
;NOTE
Line 45: Line 53:




 
<br><br>
== Access the ODB using synchronous AJAX requests ==
== Access the ODB using synchronous AJAX requests ==
;NOTE
;NOTE
Line 52: Line 60:
See [[#Example 3 : Synchronous Calls using Javascript and AJAX]].
See [[#Example 3 : Synchronous Calls using Javascript and AJAX]].


 
<br><br>
= Access the ODB with HTML-style <span style="color:seagreen font-style:italic"><odb></span> tags =
= Access the ODB with HTML-style <span style="color:seagreen font-style:italic"><odb></span> tags =


Line 95: Line 103:
See also [[Custom Page#How to write a Custom Page|HTML Custom Page example]].
See also [[Custom Page#How to write a Custom Page|HTML Custom Page example]].


<br><br>
= ODB RPC access =
= ODB RPC access =
The [[Mhttpd.js|MIDAS Javascript Library]] function ODBRpc() defined for RPC access.
The [[Mhttpd.js|MIDAS Javascript Library]] function ODBRpc() defined for RPC access.
Line 100: Line 110:
This permits buttons on MIDAS "custom" web pages to invoke RPC calls directly into user frontend programs, for example to turn hardware modules on or off.
This permits buttons on MIDAS "custom" web pages to invoke RPC calls directly into user frontend programs, for example to turn hardware modules on or off.


<br><br>
= JSON support =
= JSON support =
[[mjsonrpc#JSON general information|JSON]] support is provided with the [[Mhttpd.js|MIDAS Javascript Library]].
[[mjsonrpc#JSON general information|JSON]] support is provided with the [[Mhttpd.js|MIDAS Javascript Library]].




<br><br>
=  Access to the MIDAS Menu buttons =


=  Access to the MIDAS Menu buttons =
;NOTE
: '''New (since 2018) custom pages using the [[Custom Page#modb* Javascript scheme]] should follow the instructions there to include the standard MIDAS Menu buttons.'''
<br><br>
Access to the standard MIDAS Menu buttons can be provided with HTML {{HtmlTag|tag=<input...>}} tags of the form:
Access to the standard MIDAS Menu buttons can be provided with HTML {{HtmlTag|tag=<input...>}} tags of the form:


Line 125: Line 141:
See also [[#Redirect]].
See also [[#Redirect]].


<br><br>
= Redirect =
= Redirect =


Line 134: Line 152:
{{Html|text=<input type=hidden name="redir" value="my_custom_page&">}}
{{Html|text=<input type=hidden name="redir" value="my_custom_page&">}}


;NOTE
See also [[#Replace Status Page by a Custom page|Redirect when a Custom Page replaces the Status Page]].
When a custom page [[#Replace Status Page by a Custom Status page|replaces the Status Page]], a redirect '''must''' be included, or you will see the message
<br><br>
Invalid custom page:NULL path
The redirect statement should be of the form
{{Html|text=<input type=hidden name="redir" value="../">}}
 


= CustomScript Buttons =
= CustomScript Buttons =


[[/Customscript ODB tree#Customscript-button|CustomScript buttons]] can be provided on [[Custom Page|Custom Pages]]. These buttons are equivalent to optional [[/Script ODB tree#Script-button|script buttons]] on the [[Status Page]], and allow a particular action to be performed when the button is pressed. Customscript buttons can be set up through the [[/Customscript ODB tree]].
[[/Customscript ODB tree#Customscript-button|CustomScript buttons]] can be provided on [[Custom Page|Custom Pages]]. These buttons are equivalent to optional '''script buttons''' on the [[Status Page]], which call a script to perform a particular action when the button is pressed. See [[/Script ODB tree#Script-button|script buttons]] for details. Customscript buttons can be set up through the [[/Customscript ODB tree]].


Any key <span style="color:purple; font-style:italic">/CustomScript/my button</span> will appear as a customscript-button  
Any key <span style="color:purple; font-style:italic">/CustomScript/test</span> will appear as a customscript-button  
<span style="color: #444444; background-color: #CCCCCC; font-style:italic; font-size: 90; padding:0.25em;padding-left: 0.5em;padding-right: 0.5em;border:1px solid #808080;border-radius: 5px;margin-bottom:1px;">my button</span> on a custom page whose code includes an HTML {{HtmlTag|tag=<input...>}} tag of the form:
<span style="color: #444444; background-color: #CCCCCC; font-style:italic; font-size: 90; padding:0.25em;padding-left: 0.5em;padding-right: 0.5em;border:1px solid #808080;border-radius: 5px;margin-bottom:1px;">test</span> on a custom page whose code includes an HTML {{HtmlTag|tag=<input...>}} tag of the form:
{{Html|text=<input type=submit name=customscript value="my button">}}
{{Html|text=<input type=submit name=customscript value="test">}}
where the action of the button <span style="color: #444444; background-color: #CCCCCC; font-style:italic; font-size: 90; padding:0.25em;padding-left: 0.5em;padding-right: 0.5em;border:1px solid #808080;border-radius: 5px;margin-bottom:1px;">my button</span> will be found in the <span style="color:purple; font-style:italic">/customscript/my button</span> subdirectory.
where the action of the button <span style="color: #444444; background-color: #CCCCCC; font-style:italic; font-size: 90; padding:0.25em;padding-left: 0.5em;padding-right: 0.5em;border:1px solid #808080;border-radius: 5px;margin-bottom:1px;">test</span> will be found in the <span style="color:purple; font-style:italic">/customscript/test</span> subdirectory.


After pressing a customscript-button, the [[Status Page]] will be shown, unless a redirect input tag is included to redirect back to the original custom page (see [[#redirect]]).
After pressing a customscript-button, the ''type=submit'' in the HTML {{HtmlTag|tag=<input>}} will cause a page reload. This will result in a switch to the [[Status Page]], unless a [[#redirect]] input tag is included to redirect back to the original custom page.




== Customscript button without a page reload ==
To define a customscript button that does '''not''' cause a page reload, set the ''type'' in the HTML {{HtmlTag|tag=<input>}} to "button", i.e.
{{Html|text=<input name="customscript" value="test" type="button" onClick=cs_button(this.value)>  <!-- Customscript button does not reload page; no callback -->}}
and use ''"onClick"'' to call a function to [[#Send an Ajax Request]] instead. The following function sends an asynchronous request, with an optional callback.
{{HtmlTag|tag=<script>}}
<div style="background-color:floralwhite; color:steelblue; font-style:italic">
function cs_button(cmd, callback)<br>
{  // send a request to execute a custom script
:  var url;
:  var request = XMLHttpRequestGeneric();
:
:  url = ODBUrlBase
:  if(document.getElementById("redir") != null)
::    url +=  '?redir='+document.getElementById('redir').value
:  url+='&customscript='+ encodeURIComponent(cmd);
:  request.open('GET', url, true); // asynchronous request
:  request.send(null);
:  if(callback!=undefined) {
::      request.onreadystatechange = function() {
:::        if (request.readyState == 4) {
::::            if (request.status == 200)
:::::                callback();
::::            else
:::::                alert('cs_button: Error after sending request to Custom Script "'+cmd+'" :\nHTTP Status: '+request.status)
:::            }
::        }
:  }
:  else {
::  if (request.status != 200)
:::      alert('cs_button: Error after sending request to Custom Script "'+cmd+'" :\nHTTP Status: '+request.status)
:   }
}
</div>
{{HtmlTag|tag=</script>}}
<br><br>
= Resource files =
= Resource files =
It is often desirable to have resource files (such as an external stylesheet or a file of javascript functions) available to a custom page.  
== MIDAS resource files ==
A number of resource files have been provided in the MIDAS packages under {{Filepath|path=../packages/midas/resources}}.  When including a MIDAS resource file, no key in  {{Odbpath|path=/Custom}} needs to be defined as the MIDAS resources directory is searched automatically.
 
One such resource file is a condensed stylesheet {{File|name=midas.css}} for users who would like their custom pages to have a similar "look and feel" to that of the standard pages. To include the MIDAS stylesheet, in the HTML header, add
{{HtmlTag|tag=<link rel="stylesheet" type="text/css" href="midas.css">}}
Other resource files can provide [[Custom Page#How to use the standard MIDAS navigation bars on your custom page|the standard MIDAS navigation bars]].
 
== Custom resource files ==
It is often desirable to serve resource files (i.e. '''local files''' such as an external stylesheet, javascript files or images'''<sup>***</sup>''') to a custom page. The following sections describe two alternative ways of serving resource files to a custom page:
* [[#Resource files served WITH /custom/path key defined|with  /custom/path key defined]]
* [[#Resource files served WITHOUT /custom/path key defined|without  /custom/path key defined]]
See also serving resources to a [[#Replace Status Page by a Custom Status page|Custom Status page]].
;NOTE
;NOTE
: If serving resource files to a Custom Status page (i.e. a Custom page that replaces the MIDAS status page), see [[#Replace Status Page by a Custom Status page|Custom Status page]].
: '''<sup>***</sup>''' To superimpose labels, bars or fills onto an image, the image cannot be served as a resource file. See [[#Image insertion]].


== With <span style="color: purple; font-style:italic;">/custom/path</span> key defined ==
=== Resource files served WITH <span style="color: purple; font-style:italic;">/custom/path</span> key defined ===
When a number of resource files are required, it is convenient to place them in the same directory on the disk, and create a key  {{Odbpath|path=/Custom/Path}} to contain this directory.  
When a number of resource files are required, it is convenient to place them in the same directory on the disk, and create a key  {{Odbpath|path=/Custom/Path}} to contain this directory.  


  $ ls  /home/midas/online/custom/
  $ ls  /home/midas/online/custom/
   custom_functions.js      custom_globals.js    custom_page.html    custom_stylesheet.css
   custom_functions.js      custom_globals.js    custom_page.html    custom_stylesheet.css     test_image.png
With the  {{Odbpath|path=/Custom/Path}} key defined, [[/Custom ODB tree#Custom-Link|custom-links]] for individual resource files need not be created in the  {{Odbpath|path=/Custom/Path}} tree. The custom link  {{Odbpath|path=custom_page&}} is created so that the custom page can be accessed from the Status Page.
With the  {{Odbpath|path=/Custom/Path}} key defined, [[/Custom ODB tree#Custom-Link|custom-links]] for individual resource files need not be created in the  {{Odbpath|path=/Custom/Path}} tree. The custom-link  {{Odbpath|path=custom_page&}} '''is''' required so that the custom page can be accessed from the [[/Custom ODB tree#Custom-Button|custom-button]]  {{Button|name=custom_page}} on the Status Page. The key name ends in the special character "&" so that it will open in the same window as the Status page (see [[/Custom ODB tree#Key names|key names]]).
  $ odbedit
  $ odbedit
   [local:exp:S] ls /custom
   [local:exp:S] ls /custom
Line 175: Line 236:
<br> and a {{HtmlTag|tag=<link>}} tag for an external stylesheet
<br> and a {{HtmlTag|tag=<link>}} tag for an external stylesheet
{{Html|text=<link type="text/css" rel="stylesheet" href="custom_stylesheet.css" title="Stylesheet">}}
{{Html|text=<link type="text/css" rel="stylesheet" href="custom_stylesheet.css" title="Stylesheet">}}
An image tag is placed in the body of  {{File|name=custom_page.html}}
{{Html|text=<img src="test_image.png"> }}
[[mhttpd]] then loads the resource file from the directory indicated by the Path key with the correct MIME type (see  [[/Custom ODB tree#Keys in the /Custom tree|Custom tree keys]] for supported MIME types).


[[mhttpd]] then loads the resource file from the directory indicated by the Path key with the correct mime-type (see  [[/Custom ODB tree#Keys in the /Custom tree|Custom tree keys]] for supported mime-types).
=== Resource files served WITHOUT <span style="color: purple; font-style:italic;">/custom/path</span> key defined ===
 
Alternatively, resource files can be served to a [[Custom Page]] by creating a key for every resource file in the [[/Custom ODB tree]]. These keys must contain the full path of the file on the disk, and the key {{Odbpath|path=/Custom/Path}} must NOT be defined. The resource files can be in different directories on the disk. By defining the key names with an appropriate file extension, the resource files are served with the appropriate MIME types. The key names end in the special character "!" so that they will not appear on the Status page as custom-links (see [[/Custom ODB tree#Key names|key names]].
== Without <span style="color: purple; font-style:italic;">/custom/path</span> key defined ==
Alternatively, resource files can be served to a [[Custom Page]] by creating a key for every resource file in the [[/Custom ODB tree]]. These keys must contain the full path of the file on the disk, and the key {{Odbpath|path=/Custom/Path}} must NOT be defined. The resource files can be in different directories on the disk. By defining the key names with an appropriate file extension, the resource files are served with the appropriate mime-types. The key names end in the special character "!" so that they will not appear on the Status page as custom-links (see [[/Custom ODB tree#Key names|key names]].


Without the {{Odbpath|path=/Custom/Path}} key,  the links for the above example in the {{Odbpath|path=/Custom}} tree might look like
Without the {{Odbpath|path=/Custom/Path}} key,  the links for the above example in the {{Odbpath|path=/Custom}} tree might look like
Line 185: Line 247:
   [local:exp:S] ls /custom
   [local:exp:S] ls /custom
   custom_page&                  /home/midas/online/custom/custom_page.html
   custom_page&                  /home/midas/online/custom/custom_page.html
   custom_functions.js!          /home/midas/online/custom/resources/custom_functions.js
   custom_functions.js!          /home/midas/online/resources/custom_functions.js
   globals.js!                    /home/midas/online/custom/resources/custom_functions.js
   globals.js!                    /home/midas/online/resources/custom_functions.js
   stylesheet.css!                /home/midas/online/custom/resources/custom_stylesheet.css
   stylesheet.css!                /home/midas/online/stylesheets/custom_stylesheet.css
  image.png!                    /home/midas/images/test_image.png 


assuming the resource files are now in the subdirectory {{Filepath|path=../resources}}.
assuming the resource files are now in the subdirectories indicated.
The {{HtmlTag|tag=<script>}} tag for each resource file to be served (specifying the custom-link) is then placed in the header of  {{File|name=custom_page.html}}  
The {{HtmlTag|tag=<script>}} tag for each resource file to be served (specifying the custom-link) is then placed in the header of  {{File|name=custom_page.html}}  
i.e.
i.e.
Line 196: Line 259:
<br> and a {{HtmlTag|tag=<link>}} tag for an external stylesheet
<br> and a {{HtmlTag|tag=<link>}} tag for an external stylesheet
{{Html|text=<link type="text/css" rel="stylesheet" href="stylesheet.css!" title="Stylesheet">}}
{{Html|text=<link type="text/css" rel="stylesheet" href="stylesheet.css!" title="Stylesheet">}}
An image tag is placed in the body of  {{File|name=custom_page.html}}
{{Html|text=<img src="image.png!"> }}


= MIDAS stylesheet =


The MIDAS package provides a condensed stylesheet
<br><br>
: {{Filepath|path=/home/midas/packages/midas/resources/}}{{File|name=mhttpd.css}}
for users who would like their custom pages to have a similar "look and feel" to that of the standard pages.


To include the MIDAS stylesheet, in the HTML header, add
{{HtmlTag|tag=<link rel="stylesheet" type="text/css" href="mhttpd.css">}}
No ''custom link'' needs to be defined.
<br>


The resulting Demo custom page is shown in Figure 5, which can be compared with [[Custom Page#Demo Custom Page|Demo page, no stylesheet]].  
The resulting Demo custom page is shown in Figure 1, which can be compared with Figure 2 (no stylesheet).  
[[File:Mhxcustom03.jpg|thumb|left|Figure 5: Demo Custom Page using MIDAS stylesheet]]
{| class="wikitable"
<br clear=all> <!-- clear wraparound after thumbnail -->
|-
! Figure 1  !! Figure 2
|-
| Demo Custom Page using MIDAS stylesheet || Demo Custom Page
|-


| [[File:Mhxcustom03.jpg|thumb|300px]] || [[File:Mhxcustom02.jpg|thumb|200px]]
|}
<br clear=all>




<br><br>
=  Alias-Buttons and Hyperlinks =
=  Alias-Buttons and Hyperlinks =
Any hyperlink can easily be included on a [[Custom Page]] by using the standard HTML anchor {{HtmlTag|tag=<a...>}} tag, e.g.
Any hyperlink can easily be included on a [[Custom Page]] by using the standard HTML anchor {{HtmlTag|tag=<a...>}} tag, e.g.
Line 222: Line 288:
See the [[/Alias ODB tree]] for details.
See the [[/Alias ODB tree]] for details.


 
<br><br>
=    Page refresh =
=    Page refresh =
The following {{HtmlTag|tag=<meta...>}} tag included in the HTML header code will cause the whole custom page to refresh in 60 seconds :
The following {{HtmlTag|tag=<meta...>}} tag included in the HTML header code will cause the whole custom page to refresh in 60 seconds :
Line 228: Line 294:
It is also possible to [[#Periodic update of parts of a custom page|periodically update parts]] of a custom page.
It is also possible to [[#Periodic update of parts of a custom page|periodically update parts]] of a custom page.


<br><br>
= Periodic update of parts of a custom page =
= Periodic update of parts of a custom page =


Line 246: Line 314:




<br><br>
= Display last MIDAS message(s) =
= Display last MIDAS message(s) =


Line 257: Line 326:
: Coming soon - a [[mjsonrpc]] function
: Coming soon - a [[mjsonrpc]] function


<br><br>
= Generate a message log entry =
= Generate a message log entry =


Line 262: Line 333:




<br><br>
=  Checkboxes =
;NOTE
: '''New  (since 2018) custom pages using the [[Custom Page#modb* Javascript scheme]] should use [[Custom Page#modbcheckbox|modbcheckbox]] to create a checkbox.'''
<Br><br>


=  Checkboxes =
The function [[Mhttpd.js|ODBSet]] (provided the [[Mhttpd.js#include js lib|JS library is included]]) can be used when one clicks on a checkbox for example:
The function [[Mhttpd.js|ODBSet]] (provided the [[Mhttpd.js#include js lib|JS library is included]]) can be used when one clicks on a checkbox for example:
{{Html|text=<input  name="box0"  type="checkbox"  onClick="ODBSet(my_path, this.checked?'1':'0')">}}
{{Html|text=<input  name="box0"  type="checkbox"  onClick="ODBSet(my_path, this.checked?'1':'0')">}}
Line 269: Line 344:
{{JS|text=document.form1.box0.checked= ODBGet(my_path));  // initialize to the correct value}}
{{JS|text=document.form1.box0.checked= ODBGet(my_path));  // initialize to the correct value}}


<br><br>
= Replace Status Page by a Custom page =
= Replace Status Page by a Custom page =


Click to enlarge thumbnail
Click to enlarge thumbnail
[[File:Mhcustom_status.jpg|thumbnail|left|Figure 7: ODB /Custom/Status custom-link to a custom status page]]
[[File:Mhcustom_status.jpg|thumbnail|left|Figure 3: ODB /Custom/Status custom-link to a custom status page]]
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->


If a custom-link with the [[/Custom ODB tree#Key names|reserved key name]] "Status" (no "& or !") is created in the [[/Custom ODB tree]] (as shown in  Figure 7), then that custom page will '''replace the default Status Page'''.  
If a custom-link with the [[/Custom ODB tree#Key names|reserved key name]] '''Status''' (not "Status&" or "Status!") is created in the [[/Custom ODB tree]] (as shown in  Figure 3), then that custom page will '''replace the default Status Page'''.  
    
    
Clicking on the {{Button|name=Status}} button on any of the sub-pages (e.g. [[ODB Page]], [[Programs Page]] etc.) will now return to the Custom Status Page. If there are buttons on the Custom Status page, you must include a  [[#Redirect]] statement.
Clicking on the {{Button|name=Status}} button on any of the sub-pages (e.g. [[ODB Page]], [[Programs Page]] etc.) will now return to the Custom Status Page. If there are buttons on the Custom Status page, you '''must''' include a  [[#Redirect]] statement of the form
{{Html|text=<input type=hidden name="redir" value="../">}}
or you will see the message
Invalid custom page:NULL path


If the Custom Status page includes [[#Resource files]] served on a regular custom page with a statement such as
If the Custom Status page includes [[#Resource files]] served on a regular custom page with a statement such as
<script type="text/javascript" src="cs_functions!">
{{Html|text=<script type="text/javascript" src="cs_functions!">}}
to serve them in a Custom Status page, the statement would be
to serve them in a Custom Status page, the statement would be
<script type="text/javascript" src="<span style="font-weight:bold">/CS/</span>cs_functions!">
{{Html|text=<script type="text/javascript" src="<span style="font-weight:bold">/CS/</span>cs_functions!">}}
In fact, this statement can be used in a regular custom page, as the "/CS/" is ignored in that case.
In fact, this statement can be used in a regular custom page, as the "/CS/" is ignored in that case.


To return to the default Status Page, delete the <span style="color: purple; font-style:italic;">/Custom/Status</span> key.  
To return to the default Status Page, delete the <span style="color: purple; font-style:italic;">/Custom/Status</span> key.  


<br><br>
= Start, Stop and Check if a program is running =
= Start, Stop and Check if a program is running =
There are [[mjsonrpc]] functions that implemented all three program management functions - start program,  
There are [[mjsonrpc]] functions that implemented all three program management functions - start program,  
Line 292: Line 374:




<br><br>
= Send an Ajax request =
= Send an Ajax request =
By sending an Ajax request from a custom page, you can make a button perform a specific function.  
By sending an Ajax request from a custom page, you can make a button perform a specific function.  
Line 297: Line 380:
All functions in midas are controlled through special URLs. So the URL
All functions in midas are controlled through special URLs. So the URL
  http://<host:port>/?cmd=Start&value=10
  http://<host:port>/?cmd=Start&value=10
will start run #10. Although it is easier to use the [[access to the MIDAS Menu buttons]] method,  
will start run #10.
 
Although it is easier to use an HTML input statement to [[#Access to the MIDAS Menu buttons]],  
to send an Ajax request, you can use the function ''XMLHttpRequestGeneric'' which is in the MIDAS Javascript library [[mhttpd.js]].
to send an Ajax request, you can use the function ''XMLHttpRequestGeneric'' which is in the MIDAS Javascript library [[mhttpd.js]].
Then the HTML code would be
Then the HTML code would be
Line 315: Line 400:
} <br>
} <br>
</div>
</div>
See also [[#Access to the MIDAS Menu buttons]].
See also [[#Access to the MIDAS Menu buttons]]. Another example with optional callback can be found in [[#Customscript button without a page reload]].
 
This mechanism can be used for starting a particular program, see for example (see [https://midas.triumf.ca/elog/Midas/1046]). However, this functionality is now provided by [[mjsonrpc]] functions - see [[#Start, Stop and Check if a program is running]].
This mechanism can be used for starting a particular program, see for example (see [https://midas.triumf.ca/elog/Midas/1046]). However, this functionality is now provided by [[mjsonrpc]] functions - see [[#Start, Stop and Check if a program is running]].


<br><br>
=    Image insertion  =
=    Image insertion  =
;Note
An image can be loaded from the web using an HTML {{HtmlTag|tag=<img...>}}, e.g.
:      The image file must be in '''gif''' format.
  {{Html|text="TRIUMF logo" <img src="https://lixenon.triumf.ca/InternalDocuments/Alice/figures/TRIUMF-logo.jpg/image_preview">}}
Click to enlarge thumbnail
or a MIDAS History image can be inserted into a custom page using an HTML {{HtmlTag|tag=<img...>}} tag of the following form:
[[File:Mhcustom_images.jpg|thumbnail|left|Figure 5: /Custom/Images ODB Tree]]
{{Html|text=blah<img src="http://hostname.domain:port/HS/Meterdis.gif&scale=12h&width=300">}}


Image insertion into a Custom page will be illustrated using the Demo custom page shown in [[Custom Page#How to write a custom page|Figure 4]]. It is assumed that a [[/Custom ODB tree#Custom-Link|custom-link]] to the Demo custom page file ''myexpt.html'' has already been made.
If the image file is on the local disk, it can be loaded as a '''resource file'''. The image can be of format .pdf, .jpg, .gif, .png. See loading [[#Resource files]].


To make the image ''myexpt.gif'' visible on the custom page, the path and filename of the image file must be defined in the   {{Odbpath|path=/Custom/images}} subtree.
If you wish to superimpose features such as '''labels and fills''', the image file cannot be served as a [[#Resource files|resource file]]. Instead, the image file must be in '''gif''' format, and must be included in the {{Odbpath|path=/Custom/images}} subtree (Figure 4). Image insertion into a Custom page will be illustrated using the Demo custom page shown in [[#MIDAS stylesheet|Figure 2]]. All the files required for this demo can be found in the MIDAS package at $MIDASSYS/examples/custom. If you do not wish to create
the keys yourself, proceed to [[#Superimposing Labels, Bars and Fills onto a gif image]].  


Create the  subtrees {{Odbpath|path=/Custom/images/myexpt.gif}} where the subtree name "myexpt.gif" is named for the imagefile you are going to use. Multiple images can be used, by creating multiple imagefile subtrees.
Make a [[/Custom ODB tree#Custom-Link|custom-link]] to the Demo custom page file ''myexpt.html'' , i.e.
[local:js:S]/>ls /custom
    myexpt&                  /home/test/packages/midas/examples/custom/myexpt.html
To make the image ''myexpt.gif'' visible on the custom page, the path and filename of the image file must be defined in the  {{Odbpath|path=/Custom/images}} subtree. To do this,
create the  subtrees {{Odbpath|path=/Custom/images/myexpt.gif}} where the subtree name "myexpt.gif" is named for the image file you are going to use. Multiple images can be used, by creating multiple imagefile subtrees.


In the imagefile subtree {{Odbpath|path=myexpt.gif}}, create the STRING key  {{Odbpath|path=Background}}, and set it to contain the path and name of the imagefile.  The tree structure should then look similar to Figure 5, minus the labels/bars/fill subtrees which will be added to the ODB later.
In the imagefile subtree {{Odbpath|path=myexpt.gif}}, create the STRING key  {{Odbpath|path=Background}}, and set it to contain the path and name of the image file.  The tree structure should then look similar to Figure 4, minus the labels/bars/fill subtrees which will be added to the ODB later.


The image must also be referenced in the custom HTML file ''myexpt.html'' in the "src" field of an HTML {{HtmlTag|tag=<img...>}} tag, e.g.  
The image must also be referenced in the custom HTML file ''myexpt.html'' in the "src" field of an HTML {{HtmlTag|tag=<img...>}} tag, e.g.  
{{Html|text=<img '''src="myexpt.gif"'''>}}
{{Html|text=<img '''src="myexpt.gif"'''>}}


==  Inserting a history image  ==
Click to enlarge thumbnail
In the special case where the image to be inserted is a History image, it can be inserted into a custom page using an HTML {{HtmlTag|tag=<img...>}} tag of the following form:
[[File:Mhcustom_images.jpg|thumbnail|left|Figure 4: /Custom/Images ODB Tree]]
  {{Html|text=blah<img src="http://hostname.domain:port/HS/Meterdis.gif&scale=12h&width=300">}}
<br clear=all>
Once the image is visible, enable [[#HTML mapping]], optionally [[#Display mouse position]] and proceed to [[#Superimposing Labels, Bars and Fills onto a gif image]].  




<br><br>
== HTML mapping ==
== HTML mapping ==
Note that if additional features such as active clickable areas and labels, bars and fills superimposed on the image are also required, HTML mapping must also be activated with the HTML {{HtmlTag|tag=<map...>}} tag and the "usemap" attribute of the HTML {{HtmlTag|tag=<img>}} tag
Note that if additional features such as active clickable areas and labels, bars and fills superimposed on the image are also required, HTML mapping must also be activated with the HTML {{HtmlTag|tag=<map...>}} tag and the "usemap" attribute of the HTML {{HtmlTag|tag=<img>}} tag
{{Html|text=  <map '''name="myexpt.map"'''> <br> <img src="myexpt.gif" '''usemap="#myexpt.map"'''> <br>...<br> </map>"}}
{{Html|text=  <map '''name="myexpt.map"'''> <br> <img src="myexpt.gif" '''usemap="#myexpt.map"'''> <br>...<br> </map>"}}


<br><br>
== Display mouse position ==
== Display mouse position ==
[[File:Cursor.png|thumbnail|left|Figure 9: MEG Gas System Custom Page showing cursor position]]
[[File:Cursor.png|thumbnail|left|Figure 5: MEG Gas System Custom Page showing cursor position]]
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->


Line 359: Line 457:
</div>
</div>


If the "'''refimg'''" tag is present, the cursor changes into a crosshair, and its absolute and relative locations in respect to the reference image are shown in the status bar (Figure 9).
If the "'''refimg'''" tag is present, the cursor changes into a crosshair, and its absolute and relative locations in respect to the reference image are shown in the status bar (Figure 5).


==  Superimposing Labels, Bars and Fills onto an image ==
 
You can enhance your custom page by superimposing multiple features based on ODB variables onto  
<br><br>
[[#Image insertion into a Custom page|an image]], such as
==  Superimposing Labels, Bars and Fills onto a gif image ==
You can enhance your custom page by superimposing multiple features based on ODB variables onto an image (e.g. [[#Display mouse position|Figure 5]]), such as


*    labels: "live" ODB values positioned in a particular location of the page
*    labels: "live" ODB values positioned in a particular location of the page
Line 377: Line 476:
: [[#HTML mapping]] must be activated for labels/bars/fills to work
: [[#HTML mapping]] must be activated for labels/bars/fills to work


A Demo custom page showing labels,bars and fills superimposed on an image is shown in [[Custom Page#How to write a custom page|Figure 4]]. The file [http://ladd00.triumf.ca/~daqweb/doc/midas/doc/html/xcustom_8odb_source.html xcustom.odb]
A Demo custom page showing labels, bars and fills superimposed on an image is shown in [[#MIDAS stylesheet|Figure 2]].  
contains the ODB keys required, including those to insert the image and superimpose the various labels, fills etc.  
All the files for this demo can be found in $MIDASSYS/examples/custom/. The file xcustom.odb contains the ODB keys required, including those to insert the image and superimpose the various labels, fills etc. This file can be loaded into the ODB with the  {{Odbedit cmd|cmd=load}}.


<br><br>
=== Adding Labels ===
=== Adding Labels ===


Line 388: Line 488:
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->


<br><br>
=== Adding Bars ===
=== Adding Bars ===
   
   
[[File:Mhcustom_fill.jpg|thumbnail|left|Figure 7: /Custom/Images/Fills ODB subtree]]
[[File:Mhcustom_fill.jpg|thumbnail|left|Figure 7: /Custom/Images/Fills ODB subtree]]


In a similar way, Bars can be superimposed on the image. Create  a new ODB subdirectory  {{Odbpath|path=/Custom/images/<imagefile.gif/Bars}}. Create a subdirectory for a particular Bar ({{Odbpath|path=<bar name>}}) in the {{Odbpath|path=Bars}}  subdirectory. Refresh the web page and fill the various keys as desired.  See [[/Custom ODB tree#Bars subtree]] for details of the various fields.  Examples of a <bar-name> subtree is shown in Figures 7.
In a similar way, Bars can be superimposed on the image. Create  a new ODB subdirectory  {{Odbpath|path=/Custom/images/<imagefile.gif/Bars}}. Create a subdirectory for a particular Bar ({{Odbpath|path=<bar name>}}) in the {{Odbpath|path=Bars}}  subdirectory. Refresh the web page and fill the various keys as desired.  See [[/Custom ODB tree#Bars subtree]] for details of the various fields.  Examples of a <bar-name> subtree is shown in Figure 7.
   
   
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->


<br><br>
=== Adding Fills ===
=== Adding Fills ===
[[File:Mhcustom_bar.jpg|thumbnail|left|Figure 8: /Custom/Images/Bars ODB subtree]]
[[File:Mhcustom_bar.jpg|thumbnail|left|Figure 8: /Custom/Images/Bars ODB subtree]]


In a similar way, Fills can be superimposed on the image. Create new ODB subdirectory  {{Odbpath|path=/Custom/images/<imagefile.gif/Fills}}. Create a subdirectory for a particular  Fill ({{Odbpath|path=<fill name>}}) in the {{Odbpath|path=Fills}} subdirectory. Refresh the web page and fill the various keys as desired.  See  [[/Custom ODB tree#Fills subtree]] for details of the various fields.  Examples of a ({{Odbpath|path=<fill name>}}  subtree is shown in Figures 8.  
In a similar way, Fills can be superimposed on the image. Create new ODB subdirectory  {{Odbpath|path=/Custom/images/<imagefile.gif/Fills}}. Create a subdirectory for a particular  Fill ({{Odbpath|path=<fill name>}}) in the {{Odbpath|path=Fills}} subdirectory. Refresh the web page and fill the various keys as desired.  See  [[/Custom ODB tree#Fills subtree]] for details of the various fields.  Examples of a ({{Odbpath|path=<fill name>}}  subtree is shown in Figure 8.  


<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->
<div style="clear: both"></div>  <!-- clear wraparound after thumbnail -->


<br><br>
== Mapping active areas onto the image ==
== Mapping active areas onto the image ==
Provided [[#HTML mapping]] is activated, "clickable" areas can be created on the image.
Provided [[#HTML mapping]] is activated, "clickable" areas can be created on the image.
Line 411: Line 517:
This defines a clickable map on top of the custom image. The area(s) should match with some area(s) on the image, e.g. the box of a valve. Determining the co-ordinates of this area is simplified by using the Display mouse position feature.
This defines a clickable map on top of the custom image. The area(s) should match with some area(s) on the image, e.g. the box of a valve. Determining the co-ordinates of this area is simplified by using the Display mouse position feature.


By clicking on this area, the supplied path to the ODB is used (in this case  {{Odbpath|path=/Equipment/Environment/Variables/Output[2]}}) and its value is toggled. If the valve value is then used in the image via a [[#Adding Fills|Fill]] statement to change the color of the valve, it can turn green or red depending on its state. This is illustrated in Figure 9.
By clicking on this area, the supplied path to the ODB is used (in this case  {{Odbpath|path=/Equipment/Environment/Variables/Output[2]}}) and its value is toggled. If the valve value is then used in the image via a [[#Adding Fills|Fill]] statement to change the color of the valve, it can turn green or red depending on its state. This is illustrated in [[#Display mouse position|Figure 5]].
 




Line 420: Line 527:




<br><br>
== Edit boxes floating on top of a graphic ==
== Edit boxes floating on top of a graphic ==


An edit box can be placed on top of a graphic in a particular position by means of an HTML {{HtmlTag|tag=<div>}} tag. Using the ODBEdit function from the Midas JS library [[Mhttpd.js]], the custom page code would look like this:
An edit box can be placed on top of a graphic in a particular position by means of an HTML <span style="color:green">&lt;div&gt;</span> tag. Using the ODBEdit function from the Midas JS library [[Mhttpd.js]], the custom page code would look like this:
<!-- Complicated... have to use <pre> because of <div>, then a table to keep the background colour between <pre>s -->
<!-- Complicated... have to use <pre> because of <div>, then a table to keep the background colour between <pre>s -->
{|  style="text-align: left; width: 100%; background-color: floralwhite;" border="0" cellpadding="1" cellspacing="1"
{|  style="text-align: left; width: 100%; background-color: floralwhite;" border="0" cellpadding="1" cellspacing="1"
Line 451: Line 560:
</pre>
</pre>


<br><br>
= Examples =
= Examples =
For more examples of accessing the ODB with the Javascript library [[mhttpd.js]] look at the example experiment in the MIDAS package $MIDASSYS/examples/javascript1/example.html.
For more examples of accessing the ODB with the Javascript library [[mhttpd.js]] look at the example experiment in the MIDAS package $MIDASSYS/examples/javascript1/example.html.
Line 460: Line 571:


Example 2 shows html code illustrating the use of ODBMCopy(), where innerHTML is used to display the data. On a page with images or a lot of data, innerHTML allows you to update variables without having to reload the whole page. In the example, a timer causes the page to update every 10s (reread the data). Often the ODB data for the whole page can be read by one asynchronous ODBMCopy() call, rather than scattering synchronous ODBGet() calls throughout the page.   
Example 2 shows html code illustrating the use of ODBMCopy(), where innerHTML is used to display the data. On a page with images or a lot of data, innerHTML allows you to update variables without having to reload the whole page. In the example, a timer causes the page to update every 10s (reread the data). Often the ODB data for the whole page can be read by one asynchronous ODBMCopy() call, rather than scattering synchronous ODBGet() calls throughout the page.   
Access to the ODB is provided by the  [[Mhttpd.js|MIDAS Javascript Library]], included with the line
 
{{Html|text=<script src='mhttpd.js'></script>}}.
Access to the ODB is provided by the  [[Mhttpd.js|MIDAS Javascript Library]], included with the line <span style="color:green">&lt;script src='mhttpd.js'&gt;&lt;/script&gt;</span>.


<div style="background-color:floralwhite; color:seagreen; font-style:italic">
<div style="background-color:floralwhite; color:seagreen; font-style:italic">
Line 498: Line 609:
</head> <br>  
</head> <br>  
<body> <br>  
<body> <br>  
<b>Javascript code using ODBMCopy with callback</b> <br>  
&lt;b&gt;Javascript code using ODBMCopy with callback&lt;/b&gt; <br>  
The data on the page is updated every 10 sec using a timer<br>  
The data on the page is updated every 10 sec using a timer<br>  
<p id="LastUpdated">Last updated: never</p>  
&lt;p id="LastUpdated" &gt; Last updated: never&lt;/p&gt;<br>  
<p id="rn">Run Number : unknown</p>
&lt;p id="rn"&gt; Run Number : unknown &lt;/p&gt;<br>  
<p id="state">State : unknown</p>  
&lt;p id="state"&gt; State : unknown&lt;/p&gt;<br>  
<p id="name">Experiment name : unknown</p>
&lt;p id="name"&gt; Experiment name : unknown &lt;/p&gt;<br>  
<p id="counter">Counter: zero</p>
&lt;p id="counter"&gt;Counter: zero &lt;/p&gt;<br>  
<script type="text/javascript"> </div>   
<script type="text/javascript"> </div>   
<div style="background-color:floralwhite; color:steelblue; font-style:italic">
<div style="background-color:floralwhite; color:steelblue; font-style:italic">
Line 513: Line 624:
</body> </html></div>  
</body> </html></div>  


<br><br>
== Example 3 : Synchronous Calls using Javascript and AJAX ==
== Example 3 : Synchronous Calls using Javascript and AJAX ==
In the following example, JS functions ODBGet and  ODBEdit from the [[Mhttpd.js|MIDAS Javascript Library]] are used to access the ODB.   
In the following example, JS functions ODBGet and  ODBEdit from the [[Mhttpd.js|MIDAS Javascript Library]] are used to access the ODB.   

Latest revision as of 15:25, 28 May 2019


Links


Introduction

NOTE
Since 2018, many of the features described here can now be implemented more simply using the mod* JS functions (see Custom Web Page).
If writing a new web page, it is strongly recommended you make use of the mod*JS features.

This page describes some of the special features provided for use on a user-created Custom Web Page using the #The MIDAS Javascript Library, which was the recommended way to write Custom Pages before the Custom Page#modb* Javascript scheme was available.



The MIDAS Javascript Library

The MIDAS Javascript Library mhttpd.js includes routines written in Javascript and AJAX to provide features useful for writers of Custom Pages, such as access to the ODB. Recently asynchronous JSON-RPC functions using Promises has been added (January 2016).

NOTE
To use functions in this library, it must be included in the HTML code.

Many of the older routines (ODBGet, ODBSet) use synchronous RPC requests. With synchronous request, a second RPC request must wait until the first request is complete. This can significantly slow down web pages where many calls to ODBGet are made. For this reason, functions were developed that can be synchronous or asynchronous (e.g. ODBMCopy) that include a callback mechanism. The data from ODBMCopy can be formatted in JSON.

Web developers are moving away from synchronous RPC requests, which are now deprecated [1]. Some modern browsers return a warning on a synchronous RPC request.

A new group of JSON-RPC functions using Promises has been added to the MIDAS Javascript Library (January 2016). These are asynchronous only, and they also provide more functionality and have better error handling than the older AJAX calls, which are also inconsistent in how they handle Booleans. They also have much improved handling of reading/writing arrays to the ODB. Before 2018 it was recommended that all new Custom Pages are written using these JSON-RPC functions. Since 2018 the Custom Page#modb* Javascript scheme is recommended for new Custom Pages.

The MIDAS Javascript Library routines requires an up-to-date browser that supports Promises (see [2]). If using an older browser version, the asynchronous AJAX calls (e.g. ODBMCopy) should be used in order to avoid having to rewrite the web page at a later date to remove all synchronous calls.



Access the ODB using mjson-rpc asynchronous functions

Access to the ODB is provided by the MIDAS Javascript Library, which (since January 2016) includes the mjsonrpc functions. It is recommended that these functions are used for new pages rather than the older AJAX calls (see below).

To run these functions you need

  1. to include the Javascript library in the HTML code
  2. to use an up-to-date browser that supports Promises (see [3]).

Examples showing how to read and write to the ODB can be found at mjsonrpc#examples. Also included are examples using arrays.



Access the ODB using asynchronous AJAX calls

NOTE
It is recommended that asynchronous MIDAS JSON-RPC functions are used for new pages rather than the older AJAX calls (see above).

Example 2 uses the asynchronous call ODBMCopy() with callback to read the data. The data are converted into JSON format. In this case, when accessing the JSON data, the ODB Keynames must be in the same case as they are in the ODB, even though the case is ignored by the ODB. If you find this feature annoying, use mjson-rpc function db_get_values() as all keynames are converted to lower case.




Access the ODB using synchronous AJAX requests

NOTE
Synchronous requests are now deprecated (see above). New pages should be written #Using mjson-rpc asynchronous functions.

See #Example 3 : Synchronous Calls using Javascript and AJAX.



Access the ODB with HTML-style <odb> tags

NOTE
This method pre-dates the MIDAS Javascript Library. It is recommended that the MIDAS Javascript Library be used for ODB access.

If Javascript (JS) is not available, the older HTML-style <odb> tags are still available and provide limited functionality.

The HTML-style <odb> tag has been defined for read/write access to the ODB under HTML. The <odb> tags are declared within enclosing HTML <form...>....</form> tags.

Access to ODB from HTML
HTML ODB tag Meaning
<odb src="odb path"> Display ODB field (read only)
<odb src="odb path" edit=1 pwd="CustomPwd"> Display an Editable ODB field (inline style). Optional password protection with pwd .
<odb src="odb path" edit=2 pwd="CustomPwd"> Display an Editable ODB field (popup style). Optional password protection with pwd .
NOTE
The Optional password protection with pwd (documented in the OldMidas Document) may not be working.
Use the Web Password security instead.


<odb> tags are included in the HTML code e.g.

Experiment Name: <odb src="/Experiment/Name">
Run Number: <odb src="/runinfo/run number" edit=1>

See also HTML Custom Page example.




ODB RPC access

The MIDAS Javascript Library function ODBRpc() defined for RPC access.

This permits buttons on MIDAS "custom" web pages to invoke RPC calls directly into user frontend programs, for example to turn hardware modules on or off.




JSON support

JSON support is provided with the MIDAS Javascript Library.




Access to the MIDAS Menu buttons

NOTE
New (since 2018) custom pages using the Custom Page#modb* Javascript scheme should follow the instructions there to include the standard MIDAS Menu buttons.



Access to the standard MIDAS Menu buttons can be provided with HTML <input...> tags of the form:


<input name="cmd" value=<button-name> type="submit" >

Valid values are the standard MIDAS Menu buttons, i.e. (Start, Pause, Resume, Stop, ODB, Elog, Alarms, History, Programs etc). The <input...> tags must be declared within enclosing HTML <form...>....</form> tags (see above).

The following HTML fragment shows the inclusion of three of the standard buttons, giving access to the Main Status, ODB and Messages pages :

<form name="form1" method="Get" action="/CS/MyExpt&">
<input name="cmd" value="Status" type="submit">
<input name="cmd" value="ODB" type="submit">
<input name="cmd" value="Messages" type="submit">
...
</form>

See also #Redirect.




Redirect

When buttons are included on a Custom Page, after pressing a button (e.g. the Start or Stop button) it may be desirable to return to the same custom page, rather than returning to the Status Page.

This can be done by including an HTML <input...> tag with the attributes type set to "hidden" and name set to "redir". This name ("redir") is detected by Mhttpd, causing a redirect to the specified custom link in the value attribute.

For example, the following redirects the screen back to the custom page link /Custom/my_custom_page& when buttons are pressed:

<input type=hidden name="redir" value="my_custom_page&">

See also Redirect when a Custom Page replaces the Status Page.

CustomScript Buttons

CustomScript buttons can be provided on Custom Pages. These buttons are equivalent to optional script buttons on the Status Page, which call a script to perform a particular action when the button is pressed. See script buttons for details. Customscript buttons can be set up through the /Customscript ODB tree.

Any key /CustomScript/test will appear as a customscript-button test on a custom page whose code includes an HTML <input...> tag of the form:

<input type=submit name=customscript value="test">

where the action of the button test will be found in the /customscript/test subdirectory.

After pressing a customscript-button, the type=submit in the HTML <input> will cause a page reload. This will result in a switch to the Status Page, unless a #redirect input tag is included to redirect back to the original custom page.


Customscript button without a page reload

To define a customscript button that does not cause a page reload, set the type in the HTML <input> to "button", i.e.

<input name="customscript" value="test" type="button" onClick=cs_button(this.value)>

and use "onClick" to call a function to #Send an Ajax Request instead. The following function sends an asynchronous request, with an optional callback.

<script>

function cs_button(cmd, callback)
{ // send a request to execute a custom script

var url;
var request = XMLHttpRequestGeneric();
url = ODBUrlBase
if(document.getElementById("redir") != null)
url += '?redir='+document.getElementById('redir').value
url+='&customscript='+ encodeURIComponent(cmd);
request.open('GET', url, true); // asynchronous request
request.send(null);
if(callback!=undefined) {
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200)
callback();
else
alert('cs_button: Error after sending request to Custom Script "'+cmd+'" :\nHTTP Status: '+request.status)
}
}
}
else {
if (request.status != 200)
alert('cs_button: Error after sending request to Custom Script "'+cmd+'" :\nHTTP Status: '+request.status)
}

}

</script>



Resource files

MIDAS resource files

A number of resource files have been provided in the MIDAS packages under ../packages/midas/resources. When including a MIDAS resource file, no key in /Custom needs to be defined as the MIDAS resources directory is searched automatically.

One such resource file is a condensed stylesheet midas.css for users who would like their custom pages to have a similar "look and feel" to that of the standard pages. To include the MIDAS stylesheet, in the HTML header, add

<link rel="stylesheet" type="text/css" href="midas.css"> Other resource files can provide the standard MIDAS navigation bars.

Custom resource files

It is often desirable to serve resource files (i.e. local files such as an external stylesheet, javascript files or images***) to a custom page. The following sections describe two alternative ways of serving resource files to a custom page:

See also serving resources to a Custom Status page.

NOTE
*** To superimpose labels, bars or fills onto an image, the image cannot be served as a resource file. See #Image insertion.

Resource files served WITH /custom/path key defined

When a number of resource files are required, it is convenient to place them in the same directory on the disk, and create a key /Custom/Path to contain this directory.

$ ls  /home/midas/online/custom/
  custom_functions.js       custom_globals.js     custom_page.html    custom_stylesheet.css      test_image.png

With the /Custom/Path key defined, custom-links for individual resource files need not be created in the /Custom/Path tree. The custom-link custom_page& is required so that the custom page can be accessed from the custom-button custom_page on the Status Page. The key name ends in the special character "&" so that it will open in the same window as the Status page (see key names).

$ odbedit
  [local:exp:S] ls /custom
  path                           /home/midas/online/custom/
  custom_page&                   custom_page.html

A <script> tag for each resource file to be served (specifying the file name) is then placed in the header of custom_page.html i.e.

<script type="text/javascript" src="custom_functions.js"></script>
<script type="text/javascript" src="custom_globals.js"></script>


and a <link> tag for an external stylesheet

<link type="text/css" rel="stylesheet" href="custom_stylesheet.css" title="Stylesheet">

An image tag is placed in the body of custom_page.html

<img src="test_image.png">

mhttpd then loads the resource file from the directory indicated by the Path key with the correct MIME type (see Custom tree keys for supported MIME types).

Resource files served WITHOUT /custom/path key defined

Alternatively, resource files can be served to a Custom Page by creating a key for every resource file in the /Custom ODB tree. These keys must contain the full path of the file on the disk, and the key /Custom/Path must NOT be defined. The resource files can be in different directories on the disk. By defining the key names with an appropriate file extension, the resource files are served with the appropriate MIME types. The key names end in the special character "!" so that they will not appear on the Status page as custom-links (see key names.

Without the /Custom/Path key, the links for the above example in the /Custom tree might look like

$ odbedit
  [local:exp:S] ls /custom
  custom_page&                   /home/midas/online/custom/custom_page.html
  custom_functions.js!           /home/midas/online/resources/custom_functions.js
  globals.js!                    /home/midas/online/resources/custom_functions.js
  stylesheet.css!                /home/midas/online/stylesheets/custom_stylesheet.css
  image.png!                     /home/midas/images/test_image.png  

assuming the resource files are now in the subdirectories indicated. The <script> tag for each resource file to be served (specifying the custom-link) is then placed in the header of custom_page.html i.e.

<script type="text/javascript" src="custom_functions.js!"></script>
<script type="text/javascript" src="globals.js!"></script>


and a <link> tag for an external stylesheet

<link type="text/css" rel="stylesheet" href="stylesheet.css!" title="Stylesheet">

An image tag is placed in the body of custom_page.html

<img src="image.png!">





The resulting Demo custom page is shown in Figure 1, which can be compared with Figure 2 (no stylesheet).

Figure 1 Figure 2
Demo Custom Page using MIDAS stylesheet Demo Custom Page
Mhxcustom03.jpg
Mhxcustom02.jpg





Alias-Buttons and Hyperlinks

Any hyperlink can easily be included on a Custom Page by using the standard HTML anchor <a...> tag, e.g.

<a href="http://ladd00.triumf.ca/~daqweb/doc/midas/html/">Midas Help</a>

Links on a custom page equivalent to alias-buttons can also be made e.g.

<button type="button" onclick="document.location.href='/Alias/alias&';">alias</button>

See the /Alias ODB tree for details.



Page refresh

The following <meta...> tag included in the HTML header code will cause the whole custom page to refresh in 60 seconds :

<meta http-equiv="Refresh" content="60">

It is also possible to periodically update parts of a custom page.




Periodic update of parts of a custom page

The functionality of ODBGet together with the window.setInterval() function can be used to update parts of the web page periodically. For example the Javascript fragment below contains a function which updates the current run number every 10 seconds in the background:

window.setInterval("Refresh()", 10000);
function Refresh() {

document.getElementById("run_number").innerHTML = ODBGet('/Runinfo/Run number');

}

The custom page has to




Display last MIDAS message(s)

The message log (see Message System) can be accessed from a custom page using a call to the JavaScript library function ODBGetMsg (provided the JS library is included).

This allows the inclusion of the "Last Midas message" on a custom page, e.g.

document.write('Last message:'+ODBGetMsg("midas",0,1))

More messages may be displayed by increasing the third parameter to ODBGetMsg.

Note
Parameters were changed August 2015. See ODBGetMsg for older versions.
Coming soon - a mjsonrpc function




Generate a message log entry

A custom page can generate a message to be sent to the MIDAS message log (see Message System). A call to mjsonrpc_cm_msg() will generate a message if using the mjsonrpc functions. Otherwise, use the AJAX function ODBGenerateMsg. To use these functions, the JS library must be included in the html code.




Checkboxes

NOTE
New (since 2018) custom pages using the Custom Page#modb* Javascript scheme should use modbcheckbox to create a checkbox.



The function ODBSet (provided the JS library is included) can be used when one clicks on a checkbox for example:

<input name="box0" type="checkbox" onClick="ODBSet(my_path, this.checked?'1':'0')">

If used as above, the state of the checkbox must be initialized when the page is loaded. This can be done with some JavaScript code called on initialization, e.g.

document.form1.box0.checked= ODBGet(my_path)); // initialize to the correct value




Replace Status Page by a Custom page

Click to enlarge thumbnail

Figure 3: ODB /Custom/Status custom-link to a custom status page

If a custom-link with the reserved key name Status (not "Status&" or "Status!") is created in the /Custom ODB tree (as shown in Figure 3), then that custom page will replace the default Status Page.

Clicking on the Status button on any of the sub-pages (e.g. ODB Page, Programs Page etc.) will now return to the Custom Status Page. If there are buttons on the Custom Status page, you must include a #Redirect statement of the form

<input type=hidden name="redir" value="../">

or you will see the message

Invalid custom page:NULL path

If the Custom Status page includes #Resource files served on a regular custom page with a statement such as

<script type="text/javascript" src="cs_functions!">

to serve them in a Custom Status page, the statement would be

<script type="text/javascript" src="/CS/cs_functions!">

In fact, this statement can be used in a regular custom page, as the "/CS/" is ignored in that case.

To return to the default Status Page, delete the /Custom/Status key.




Start, Stop and Check if a program is running

There are mjsonrpc functions that implemented all three program management functions - start program, stop program and "is running?" as JSON-RPC methods.




Send an Ajax request

By sending an Ajax request from a custom page, you can make a button perform a specific function.

All functions in midas are controlled through special URLs. So the URL

http://<host:port>/?cmd=Start&value=10

will start run #10.

Although it is easier to use an HTML input statement to #Access to the MIDAS Menu buttons, to send an Ajax request, you can use the function XMLHttpRequestGeneric which is in the MIDAS Javascript library mhttpd.js. Then the HTML code would be


<input type="button" onclick="start()">

and in your JavaScript code add a function start():

function start() {

var request = XMLHttpRequestGeneric();
url = '?cmd=Start&value=10';
request.open('GET', url, true); // asynchronous request
request.send(null);

}

See also #Access to the MIDAS Menu buttons. Another example with optional callback can be found in #Customscript button without a page reload.

This mechanism can be used for starting a particular program, see for example (see [4]). However, this functionality is now provided by mjsonrpc functions - see #Start, Stop and Check if a program is running.




Image insertion

An image can be loaded from the web using an HTML <img...>, e.g.

"TRIUMF logo" <img src="https://lixenon.triumf.ca/InternalDocuments/Alice/figures/TRIUMF-logo.jpg/image_preview">

or a MIDAS History image can be inserted into a custom page using an HTML <img...> tag of the following form:

blah<img src="http://hostname.domain:port/HS/Meterdis.gif&scale=12h&width=300">

If the image file is on the local disk, it can be loaded as a resource file. The image can be of format .pdf, .jpg, .gif, .png. See loading #Resource files.

If you wish to superimpose features such as labels and fills, the image file cannot be served as a resource file. Instead, the image file must be in gif format, and must be included in the /Custom/images subtree (Figure 4). Image insertion into a Custom page will be illustrated using the Demo custom page shown in Figure 2. All the files required for this demo can be found in the MIDAS package at $MIDASSYS/examples/custom. If you do not wish to create the keys yourself, proceed to #Superimposing Labels, Bars and Fills onto a gif image.

Make a custom-link to the Demo custom page file myexpt.html , i.e.

[local:js:S]/>ls /custom
   myexpt&                  /home/test/packages/midas/examples/custom/myexpt.html

To make the image myexpt.gif visible on the custom page, the path and filename of the image file must be defined in the /Custom/images subtree. To do this, create the subtrees /Custom/images/myexpt.gif where the subtree name "myexpt.gif" is named for the image file you are going to use. Multiple images can be used, by creating multiple imagefile subtrees.

In the imagefile subtree myexpt.gif, create the STRING key Background, and set it to contain the path and name of the image file. The tree structure should then look similar to Figure 4, minus the labels/bars/fill subtrees which will be added to the ODB later.

The image must also be referenced in the custom HTML file myexpt.html in the "src" field of an HTML <img...> tag, e.g.

<img src="myexpt.gif">

Click to enlarge thumbnail

Figure 4: /Custom/Images ODB Tree


Once the image is visible, enable #HTML mapping, optionally #Display mouse position and proceed to #Superimposing Labels, Bars and Fills onto a gif image.




HTML mapping

Note that if additional features such as active clickable areas and labels, bars and fills superimposed on the image are also required, HTML mapping must also be activated with the HTML <map...> tag and the "usemap" attribute of the HTML <img> tag

<map name="myexpt.map">
<img src="myexpt.gif" usemap="#myexpt.map">
...
</map>"




Display mouse position

Figure 5: MEG Gas System Custom Page showing cursor position

When writing custom pages with large background images and labels and fills placed on that image, it is hard to figure out X and Y coordinates of the labels. This can now be simplified by using the function getMouseXY() in the development JavaScript built-in library develop.js. This function supplies the X,Y position of the cursor if an element of ID "refimg" is present. This JS library must be included in the custom page in order to use it:

Then, set the "id" attribute of the background HTML <img...> tag to "refimg", e.g.

<img id="refimg" src="ebit_pc.gif" usemap="#Custom1">
<map name="Custom1">
.....
</map>

If the "refimg" tag is present, the cursor changes into a crosshair, and its absolute and relative locations in respect to the reference image are shown in the status bar (Figure 5).




Superimposing Labels, Bars and Fills onto a gif image

You can enhance your custom page by superimposing multiple features based on ODB variables onto an image (e.g. Figure 5), such as

  • labels: "live" ODB values positioned in a particular location of the page
  • bars : "bar level" showing graphically ODB values such as levels or rate etc.
  • fills : "color level" where colour is used as the level indicator.

Each entry (label/bar/fill) will have an ODB tree associated to it defining the ODB variable path, X/Y position, colour, etc. Each time the page is updated, the latest ODB value/level/rate will be shown based on the ODB parameter to which the label, bar or fill is linked - hence the term "live". The overlay of the requested features is done onto the selected image file.

This powerful new extension brings the mhttpd capability closer to other experimental web controllers similar to EPICS.

Note
Be sure to enable the feature to #Display mouse position in order to facilitate finding the X,Y positions of the various features.
#HTML mapping must be activated for labels/bars/fills to work

A Demo custom page showing labels, bars and fills superimposed on an image is shown in Figure 2. All the files for this demo can be found in $MIDASSYS/examples/custom/. The file xcustom.odb contains the ODB keys required, including those to insert the image and superimpose the various labels, fills etc. This file can be loaded into the ODB with the odbedit command load.



Adding Labels

Figure 6: /Custom/Images/Labels ODB subtree

In order to include a readout of ODB values (i.e. labels), on the image, a further ODB subdirectory /Custom/images/<imagefile.gif/Labels must be created. Creating a subdirectory for a particular label i.e. <label name> in the Labels subtree will, at the next custom web page refresh, cause the complete structure for that label to be created and filled with default values. Once the <label name> subtree is created, the user fills the various keys as desired. See /Custom ODB tree#Labels subtree for details of the various fields. This procedure is repeated for all the labels required, using a unique <label name> subdirectory for each label. An example of a <label name> subtree is shown in Figure 6.




Adding Bars

Figure 7: /Custom/Images/Fills ODB subtree

In a similar way, Bars can be superimposed on the image. Create a new ODB subdirectory /Custom/images/<imagefile.gif/Bars. Create a subdirectory for a particular Bar ( <bar name>) in the Bars subdirectory. Refresh the web page and fill the various keys as desired. See /Custom ODB tree#Bars subtree for details of the various fields. Examples of a <bar-name> subtree is shown in Figure 7.




Adding Fills

Figure 8: /Custom/Images/Bars ODB subtree

In a similar way, Fills can be superimposed on the image. Create new ODB subdirectory /Custom/images/<imagefile.gif/Fills. Create a subdirectory for a particular Fill ( <fill name>) in the Fills subdirectory. Refresh the web page and fill the various keys as desired. See /Custom ODB tree#Fills subtree for details of the various fields. Examples of a ( <fill name> subtree is shown in Figure 8.




Mapping active areas onto the image

Provided #HTML mapping is activated, "clickable" areas can be created on the image.

This can be done now with a new function like this:

<area shape="rect" coords="40,200,100,300" alt="Main Valve" href="Custom1?cmd=Toggle&odb=/Equipment/Environment/Variables/Output[2]">

This defines a clickable map on top of the custom image. The area(s) should match with some area(s) on the image, e.g. the box of a valve. Determining the co-ordinates of this area is simplified by using the Display mouse position feature.

By clicking on this area, the supplied path to the ODB is used (in this case /Equipment/Environment/Variables/Output[2]) and its value is toggled. If the valve value is then used in the image via a Fill statement to change the color of the valve, it can turn green or red depending on its state. This is illustrated in Figure 5.


Clicking an active area can also be made to open a new custom page, for example:

<area shape=rect coords="687,530, 890,648" alt="Pump detail" href = "Pump!" title="Click for Details">
<area shape=rect coords="560,574,775,662" alt="Buffer Tank detail" href = "BufferTank!" title="Click for Details">

where Pump! and BufferTank! are defined as links to custom pages in the /Custom ODB tree.




Edit boxes floating on top of a graphic

An edit box can be placed on top of a graphic in a particular position by means of an HTML <div> tag. Using the ODBEdit function from the Midas JS library Mhttpd.js, the custom page code would look like this:

<div style="position:absolute; top:100px; left:50px;">    
<script type="text/javascript"> 
document.write('Run number: ')
path='/runinfo/run number'
rn = ODBGet(path)
document.write('<a href="#" onclick="ODBEdit(path)" >')  
document.write(rn)
document.write('</a>');
</script>
</div>
<img src="custom.gif">

The same thing could be done with the HTML-style <odb> tag :

<div style="position:absolute; top:100px; left:50px;">
Run number:  <odb src="/Runinfo/run number" edit=1>
</div>
<img src="custom.gif">




Examples

For more examples of accessing the ODB with the Javascript library mhttpd.js look at the example experiment in the MIDAS package $MIDASSYS/examples/javascript1/example.html.

Example 1 : Asynchronous calls using mjsonrpc functions

See mjsonrpc#examples

Example 2 : Asynchronous calls using Javascript and AJAX

Example 2 shows html code illustrating the use of ODBMCopy(), where innerHTML is used to display the data. On a page with images or a lot of data, innerHTML allows you to update variables without having to reload the whole page. In the example, a timer causes the page to update every 10s (reread the data). Often the ODB data for the whole page can be read by one asynchronous ODBMCopy() call, rather than scattering synchronous ODBGet() calls throughout the page.

Access to the ODB is provided by the MIDAS Javascript Library, included with the line <script src='mhttpd.js'></script>.

<html>
<head>
<title>MyTitle</title>
<script src='mhttpd.js'></script>

<script>

var updatePeriod = 10000; // in msec
var updateTimerId = 0;
var counter=0;
function update() {

clearTimeout(updateTimerId);
load();
if (updatePeriod > 0)
updateTimerId = setTimeout('update()', updatePeriod);

}
function load() {

document.getElementById('LastUpdated').innerHTML = "Updating..." + new Date;
var paths = [ "/Runinfo", "/Experiment"];
var data_odb=ODBMCopy(paths, mcopy_callback, "json")
counter++;
document.getElementById('counter').innerHTML = 'Counter: '+ counter

}
function mcopy_callback(data) {

var obj= JSON.parse(data);
var runinfo=obj[0];
document.getElementById('rn').innerHTML = 'Run Number ='+ parseInt(runinfo["Run number"]);
document.getElementById('state').innerHTML ='Run State= '+ runinfo.State;
var experiment=obj[1];
document.getElementById('name').innerHTML='Experiment name = '+ experiment.Name
}

</script>
</head>
<body>
<b>Javascript code using ODBMCopy with callback</b>
The data on the page is updated every 10 sec using a timer
<p id="LastUpdated" > Last updated: never</p>
<p id="rn"> Run Number : unknown </p>
<p id="state"> State : unknown</p>
<p id="name"> Experiment name : unknown </p>
<p id="counter">Counter: zero </p>

<script type="text/javascript">
if (updatePeriod > 0)
update();

</script>

</body> </html>




Example 3 : Synchronous Calls using Javascript and AJAX

In the following example, JS functions ODBGet and ODBEdit from the MIDAS Javascript Library are used to access the ODB.

NOTE
  1. Synchronous calls are now deprecated (see above).
  2. The Javascript library must be included in the HTML code.


<script>
document.write ('Experiment Name: '+ ODBGet("/Experiment/Name"))
var alarm_path="/alarms/Alarm system active";
var alarm_active=ODBGet(alarm_path);
document.write('<a href="#" onclick="ODBEdit(alarm_path)" >'+alarm_active+'</a>')
</script>