<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JavaScript &#8211; Undocumented Matlab</title>
	<atom:link href="https://undocumentedmatlab.com/articles/tag/javascript/feed" rel="self" type="application/rss+xml" />
	<link>https://undocumentedmatlab.com</link>
	<description>Professional Matlab consulting, development and training</description>
	<lastBuildDate>Wed, 15 Aug 2018 15:00:10 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.3</generator>
	<item>
		<title>Matlab callbacks for uifigure JavaScript events</title>
		<link>https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=matlab-callbacks-for-uifigure-javascript-events</link>
					<comments>https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events#comments</comments>
		
		<dc:creator><![CDATA[Yair Altman]]></dc:creator>
		<pubDate>Wed, 15 Aug 2018 15:00:10 +0000</pubDate>
				<category><![CDATA[Figure window]]></category>
		<category><![CDATA[Guest bloggers]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[High risk of breaking in future versions]]></category>
		<category><![CDATA[Undocumented feature]]></category>
		<category><![CDATA[Iliya Romm]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[uifigure]]></category>
		<guid isPermaLink="false">http://undocumentedmatlab.com/?p=7913</guid>

					<description><![CDATA[<p>Matlab callback code can be attached to JavaScript events in web-based uifigures. </p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events">Matlab callbacks for uifigure JavaScript events</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events" rel="bookmark" title="Matlab callbacks for Java events">Matlab callbacks for Java events </a> <small>Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events-in-r2014a" rel="bookmark" title="Matlab callbacks for Java events in R2014a">Matlab callbacks for Java events in R2014a </a> <small>R2014a changed the way in which Java objects expose events as Matlab callbacks. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/detecting-window-focus-events" rel="bookmark" title="Detecting window focus events">Detecting window focus events </a> <small>Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan" rel="bookmark" title="Enabling user callbacks during zoom/pan">Enabling user callbacks during zoom/pan </a> <small>Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...</small></li>
</ol>
</div>
]]></description>
										<content:encoded><![CDATA[<p><i>I would like to welcome back guest blogger Iliya Romm of Israel&#8217;s Technion <a href="http://bcukurel.net.technion.ac.il" rel="nofollow" target="_blank">Turbomachinery and Heat Transfer Laboratory</a>. Today Iliya will discuss how to assign Matlab callbacks to JavaScript events in the new web-based uifigures. Other posts on customizations of web-based Matlab GUI can be <a href="https://undocumentedmatlab.com/articles/tag/uifigure" target="_blank">found here</a>.</i><br />
On several occasions (including <a href="https://undocumentedmatlab.com/articles/customizing-web-gui-uipanel" target="_blank">the previous post</a> by Khris Griffis) I came across people who were really missing the ability to have Matlab respond to various JavaScript (JS) events. While MathWorks are working on their plans to incorporate something similar to this in future releases, we&#8217;ll explore the internal tools already available, in the hopes of finding a suitable intermediate solution.<br />
Today I&#8217;d like to share a technique I&#8217;ve been experimenting with, allowing Matlab to respond to pretty much any JS event to which we can attach a listener. This is an overview of how it works:</p>
<ol>
<li>create a UIFigure with the desired contents, and add to it (at least) one more dummy control, which has an associated Matlab callback.</li>
<li>execute a JS snippet that programmatically interacts with the dummy control, whenever some event-of-interest happens, causing the Matlab callback to fire.</li>
<li>query the <code>webWindow</code>, from within the Matlab callback, to retrieve any additional information (“payload”) that the JS passed.</li>
</ol>
<p>This approach allows, for example, to easily respond to mouse events:<br />
<center><img decoding="async" src="https://undocumentedmatlab.com/images/XHDcA.gif" alt="Attaching Matlab callback to a uifigure JavaScript event" title="Attaching Matlab callback to a uifigure JavaScript event" width="80%" style="max-width:1135px;"/></center><br />
<span id="more-7913"></span><br />
Consider the code below, which demonstrates different ways of responding to JS events. To run it, save the <i>.m</i> file function below (<a href="/files/jsEventDemo.m" rel="nofollow" target="_blank">direct download link</a>) and the four accompanying <i>.js</i> <a href="#JS">files</a> in the same folder, then run <code>jsEventDemo(demoNum)</code>, where <code>demoNum</code> is 1..4. Note: this code was developed on R2018a, unfortunately I cannot guarantee it works on other releases.</p>
<pre lang="matlab">
function varargout = jsEventDemo(demoNum)
   % Handle inputs and outputs
   if ~nargin
      demoNum = 4;
   end
   if ~nargout
      varargout = {};
   end
   % Create a simple figure:
   hFig = uifigure('Position',[680,680,330,240],'Resize','off');
   hTA = uitextarea(hFig, 'Value', 'Psst... Come here...!','Editable','off');
   [hWin,idTA] = mlapptools.getWebElements(hTA);
   % Open in browser (DEBUG):
   % mlapptools.waitForFigureReady(hFig); mlapptools.unlockUIFig(hFig); pause(1);
   % web(hWin.URL,'-browser')
   % Prepare the JS command corresponding to the requested demo (1-4)
   switch demoNum
      % Demo #1: Respond to mouse events, inside JS, using "onSomething" bindings:
      case 1
         % Example from: https://dojotoolkit.org/documentation/tutorials/1.10/events/#dom-events
         jsCommand = sprintf(fileread('jsDemo1.js'), idTA.ID_val);
      % Demo #2: Respond to mouse click events, inside JS, using pub/sub:
      case 2
         % Example from: https://dojotoolkit.org/documentation/tutorials/1.10/events/#publish-subscribe
         hTA.Value = 'Click here and see what happens';
         jsCommand = sprintf(fileread('jsDemo2.js'), idTA.ID_val);
      % Demo #3: Trigger Matlab callbacks programmatically from JS by "pressing" a fake button:
      case 3
         hB = uibutton(hFig, 'Visible', 'off', 'Position', [0 0 0 0], ...
                       'ButtonPushedFcn', @fakeButtonCallback);
         [~,idB] = mlapptools.getWebElements(hB);
         jsCommand = sprintf(fileread('jsDemo3.js'), idTA.ID_val, idB.ID_val);
      % Demo 4: Trigger Matlab callbacks and include a "payload" (i.e. eventData) JSON:
      case 4
         hB = uibutton(hFig, 'Visible', 'off', 'Position', [0 0 0 0],...
                      'ButtonPushedFcn', @(varargin)smartFakeCallback(varargin{:}, hWin));
         [~,idB] = mlapptools.getWebElements(hB);
         jsCommand = sprintf(fileread('jsDemo4.js'), idTA.ID_val, idB.ID_val);
   end % switch
   % Execute the JS command
   hWin.executeJS(jsCommand);
end
% Matlab callback function used by Demo #3
function fakeButtonCallback(obj, eventData) %#ok<inusd>
   disp('Callback activated!');
   pause(2);
end
% Matlab callback function used by Demo #4
function smartFakeCallback(obj, eventData, hWin)
   % Retrieve and decode payload JSON:
   payload = jsondecode(hWin.executeJS('payload'));
   % Print payload summary to the command window:
   disp(['Responding to the fake ' eventData.EventName ...
         ' event with the payload: ' jsonencode(payload) '.']);
   % Update the TextArea
   switch char(payload.action)
      case 'enter',  act_txt = 'entered';
      case 'leave',  act_txt = 'left';
   end
   str = ["Mouse " + act_txt + ' from: '; ...
          "(" + payload.coord(1) + ',' + payload.coord(2) + ')'];
   obj.Parent.Children(2).Value = str;
end
</pre>
<p>Several thoughts:</p>
<ul>
<li>The attached <i>.js</i> files will not work by themselves, rather, they require <i><b>sprintf</b></i> to replace the <code>%s</code> with valid widget IDs. Of course, these could be made into proper JS functions.</li>
<li>Instead of loading the JS files using <i><b>fileread</b></i>, we could place the JS code directly in the <code>jsCommand</code> variable, as a Matlab string (char array)</li>
<li>I tried getting it to work with a <a href="https://www.w3schools.com/tags/tag_textarea.asp" rel="nofollow" target="_blank"><code>textarea</code> control</a>, so that we would get the payload right in the callback&#8217;s <code>eventData</code> object in Matlab, Unfortunately, I couldn&#8217;t get it to fire programmatically (solutions <a href="https://stackoverflow.com/a/36648958/3372061" rel="nofollow" target="_blank">like this</a> didn&#8217;t work). So instead, I store the payload as JSON, and retrieve it with <code>jsondecode(hWin.executeJS('payload'))</code> in the <code>smartFakeCallback</code> function.</li>
</ul>
<h3 id="JS">JavaScript files</h3>
<ol>
<li id="jsDemo1"><b>jsDemo1.js</b> (<a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7/raw/872d3d7d00a7b2e18e87257e0ff7c2b6efaa4e45/jsDemo1.js" rel="nofollow" target="_blank">direct download link</a>):
<pre lang="javascript">
require(["dojo/on", "dojo/dom", "dojo/dom-style", "dojo/mouse"],
	function(on, dom, domStyle, mouse) {
		var myDiv = dom.byId("%s");
		on(myDiv, mouse.enter, function(evt){
			domStyle.set(myDiv, "backgroundColor", "red");
		});
		on(myDiv, mouse.leave, function(evt){
			domStyle.set(myDiv, "backgroundColor", "");
		});
	});
</pre>
</li>
<li id="jsDemo2"><b>jsDemo2.js</b> (<a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7/raw/872d3d7d00a7b2e18e87257e0ff7c2b6efaa4e45/jsDemo2.js" rel="nofollow" target="_blank">direct download link</a>):
<pre lang="javascript">
require(["dojo/on", "dojo/topic", "dojo/dom"],
	function(on, topic, dom) {
		var myDiv = dom.byId("%s");
		on(myDiv, "click", function() {
			topic.publish("alertUser", "Your click was converted into an alert!");
		});
		topic.subscribe("alertUser", function(text){
			alert(text);
		});
	});
</pre>
</li>
<li id="jsDemo3"><b>jsDemo3.js</b> (<a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7/raw/872d3d7d00a7b2e18e87257e0ff7c2b6efaa4e45/jsDemo3.js" rel="nofollow" target="_blank">direct download link</a>):
<pre lang="javascript">
require(["dojo/on", "dojo/dom", "dojo/dom-style", "dojo/mouse"],
	function(on, dom, domStyle, mouse) {
		var myDiv = dom.byId("%s");
		var fakeButton = dom.byId("%s");
		on(myDiv, mouse.enter, function(evt){
			fakeButton.click();
		});
	});
</pre>
</li>
<li id="jsDemo4"><b>jsDemo4.js</b> (<a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7/raw/872d3d7d00a7b2e18e87257e0ff7c2b6efaa4e45/jsDemo4.js" rel="nofollow" target="_blank">direct download link</a>):
<pre lang="javascript">
var payload = [];
require(["dojo/on", "dojo/dom", "dojo/topic", "dojo/mouse"],
	function(on, dom, topic, mouse) {
		var myDiv = dom.byId("%s");
		var fakeButton = dom.byId("%s");
		topic.subscribe("sendToMatlab", function(data){
			payload = data;
			fakeButton.click();
		});
		on(myDiv, mouse.enter, function(evt){
			data = {action: "enter",
				coord: [evt.clientX, evt.clientY]};
			topic.publish("sendToMatlab", data);
		});
		on(myDiv, mouse.leave, function(evt){
			data = {action: "leave",
				coord: [evt.clientX, evt.clientY]};
			topic.publish("sendToMatlab", data);
		});
	});
</pre>
</li>
</ol>
<h3 id="Conclusions">Conclusions</h3>
<p>As you can see, this opens some interesting possibilities, and I encourage you to experiment with them yourself! This feature will likely be added to the <a href="https://github.com/StackOverflowMATLABchat/mlapptools" rel="nofollow" target="_blank"><code>mlapptools</code> toolbox</a> as soon as an intuitive API is conceived.<br />
If you have any comments or questions about the code above, or just want to tell me how you harnessed this mechanism to upgrade your uifigure (I would love to hear about it!), feel free to leave a message below <a href="https://gist.github.com/Dev-iL/7bd222efb01b3bf9fc0ed5d5645d53e7" rel="nofollow" target="_blank">the gist</a> on which this post is based (this way I get notifications!).</p>
<p>The post <a rel="nofollow" href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events">Matlab callbacks for uifigure JavaScript events</a> appeared first on <a rel="nofollow" href="https://undocumentedmatlab.com">Undocumented Matlab</a>.</p>
<div class='yarpp-related-rss'>
<h3>Related posts:</h3><ol>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events" rel="bookmark" title="Matlab callbacks for Java events">Matlab callbacks for Java events </a> <small>Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/matlab-callbacks-for-java-events-in-r2014a" rel="bookmark" title="Matlab callbacks for Java events in R2014a">Matlab callbacks for Java events in R2014a </a> <small>R2014a changed the way in which Java objects expose events as Matlab callbacks. ...</small></li>
<li><a href="https://undocumentedmatlab.com/articles/detecting-window-focus-events" rel="bookmark" title="Detecting window focus events">Detecting window focus events </a> <small>Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....</small></li>
<li><a href="https://undocumentedmatlab.com/articles/enabling-user-callbacks-during-zoom-pan" rel="bookmark" title="Enabling user callbacks during zoom/pan">Enabling user callbacks during zoom/pan </a> <small>Matlab zoom, pan and rotate3d modes hijack the user's figure callbacks, but this can be overridden. ...</small></li>
</ol>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://undocumentedmatlab.com/articles/matlab-callbacks-for-uifigure-javascript-events/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
