<?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; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 18 Aug 2025 20:39:57 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Building for Xojo Web from the Ground Up</title>
		<link>https://blog.xojo.com/2024/02/22/building-for-xojo-web-from-the-ground-up/</link>
		
		<dc:creator><![CDATA[Anthony Cyphers]]></dc:creator>
		<pubDate>Thu, 22 Feb 2024 17:00:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[GraffitiSuite]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12541</guid>

					<description><![CDATA[Building custom components for Xojo Web can be incredibly easy, or equally as difficult. If you want to build something unique so that you’re not at the mercy of a third-party library in the future, it really is “hard mode”.]]></description>
										<content:encoded><![CDATA[
<p>Building custom components for Xojo Web can be incredibly easy, or equally as difficult. If you want to build something unique so that you’re not at the mercy of a third-party library in the future, it really is “hard mode”.</p>



<p>Lately I’ve been pushing more toward building my own components from the ground up in JavaScript + Xojo rather than just wrapping libraries already available. It’s not an easy proposition. You don’t take advantage of the years of work that may have been put in to those libraries, but you’re also less at the mercy of those developers when you want to build new things on top or customize existing code. I thought I’d take the opportunity to document the hours I spent on a new component that will be coming to GraffitiSuite for Xojo Web in the next release.</p>



<h2 class="wp-block-heading">Planning</h2>



<p>Arguably the hardest part. Like any development project, a good foundation is the best place to start. Each time I decide to begin work on a new component, the first thing I do is outline, generally, what I want it to look like and how I want it to behave. This process is usually fairly quick as we’re just talking about a rough outline that’s typed or written out quickly. In all, I spend about an hour on the rough draft, then work on other things for a little while my brain works the problem. When I’m not focusing on something is when I have my best ideas, so I let my subconscious take the wheel. Over time, I’ll update that rough draft any new ideas I have. It’s important to quickly jot down anything good so you don’t forget. Then, when I’m ready to complete the planning phase, I gather all of my notes and start filling in the blanks.</p>



<p>At this point, I begin working on the API. What functions will this component need in JavaScript? In Xojo? What properties will it need? What types are those properties? Some things, of course, are a question mark until I actually start implementing. This usually takes a couple of hours not including any time I may spend talking to customers/clients about what their needs from the component might be.</p>



<p><em>Time: 4 hours</em></p>



<h2 class="wp-block-heading">Building</h2>



<h3 class="wp-block-heading"><br>HTML</h3>



<p>I start by building the sketched UI in HTML. I want to see how all of the pieces fit together, then I can translate that to JavaScript code later. This isn’t a big process as I don’t implement things like tooltips, animation, etc. I just need a starting point.</p>



<p><em>Time: 3 hours</em></p>



<h3 class="wp-block-heading">JavaScript</h3>



<p>I’ve been working with vanilla JavaScript lately, as I don’t want my components to rely on jQuery (which the whole world is trying to get away from). Since I need as much of my code as possible to be client-side, and I want to be OOP, everything is built in JavaScript classes complete with getters and setters for properties — which is a lot of repetitious code that doesn’t seem like it would take long, but it does. I also don’t build my JavaScript directly on the Xojo WebSDK anymore because I need it to be more portable and useful in more places than just Xojo.</p>



<p>The first step here is implementing my default values that I determined were needed in the planning phase as properties of the class. This is also where those getters and setters come in to play. I want a basic new instance of the class to be as feature complete as possible then allow customization by altering those properties at runtime. To accomplish this I create a defaults object that contains all those values, which also serves as a quick reference in code when I’m implementing everything later.</p>



<p>Next I start building the UI. Each of my classes has a render() method that is responsible for creating the HTMLElements and adding them to the document where they’re supposed to be. This has gotten a lot easier with vanilla JS in recent years, but it can still be pretty time-consuming. There’s a lot of back and forth testing during this phase to ensure that the appearance is correct, the defaults are honored, etc.</p>



<p>Once the UI is completed, I go back and implement all of those setters to make the necessary changes to the HTMLElements when their value has changed. This can take a bit of time depending on what that property accomplishes.</p>



<p>Finally, the meat of the component. Any logic gets built at this point such as showing/hiding elements based on events or properties, implementing event callers, filtering data, etc. This is usually the longest part and requires a lot of testing. If the logic of the component fails right out of the gate, the rest of the component can fail too.</p>



<p>Throughout this phase I test against a static HTML page, and correcting anything obvious as I go, try new things, fail at trying new things, and more.</p>



<p><em>Time: 51 hours</em></p>



<h3 class="wp-block-heading">Xojo</h3>



<p>Building the Xojo wrapper on my JavaScript class can be painful because it’s just so tedious sometimes. Creating Xojo classes (of which there are typically more than one) with all of their properties, methods, and event definitions to match the JavaScript API can be very mind-numbing, but it’s usually pretty quick, by comparison, if you resist the urge to just walk away for days on end. I also have to make sure that if there are child classes, they have a method to communicate with the parent class and that it functions properly as all of the changes sent to the JavaScript class will happen in the parent.</p>



<p><em>Time: 15 hours</em></p>



<h2 class="wp-block-heading">Testing</h2>



<p>Testing should, and does, take a very long time. At this point I recognize and correct not only bugs, but inconsistencies in the API. It’s at this point that all of the polish is added. Making the Xojo class(es) communicate effectively with the JavaScript class(es), ensuring that data types are being honored between the two, testing every feature as in-depth as I can. As many of us know, this is where we really see how well our planning phase went.</p>



<p><em>Time: 26 hours</em></p>



<h2 class="wp-block-heading">Implementation</h2>



<p>Depending on the control, this can be very fast or take quite a long time. Some components are just so complex that they’d take ages to build in the GraffitiSuite Demo, so I have to pick and choose what I want to draw the user’s attention to. Likewise, sometimes they’re so simple that there really isn’t much to the demo beyond a couple of buttons and labels. For this component, it’s one that’s so complex that showing off as much as I can is the route to take, but with limited ability for users to change what’s happening on the screen during the demo, so it was pretty quick to build.</p>



<p><em>Time: 2 hours</em></p>



<h2 class="wp-block-heading">TLDR</h2>



<p>Just one of the new components coming to GraffitiSuite for Xojo Web Edition in the next release took a total of 101 hours to complete from planning its feature set to creating the demo page in Xojo. I’m feeling even more exhausted just reading that number, but I know that I have a solid foundation for my product going forward. One that I wrote and will be able to easily maintain for use with Xojo or anywhere else I may have a need.</p>



<figure class="wp-block-image size-large is-style-default"><img fetchpriority="high" decoding="async" width="1024" height="640" src="https://blog.xojo.com/wp-content/uploads/2024/02/time-chart-1024x640.png" alt="" class="wp-image-12543" srcset="https://blog.xojo.com/wp-content/uploads/2024/02/time-chart-1024x640.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/02/time-chart-300x188.png 300w, https://blog.xojo.com/wp-content/uploads/2024/02/time-chart-768x480.png 768w, https://blog.xojo.com/wp-content/uploads/2024/02/time-chart.png 1328w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="has-text-align-left"><em>Anthony G. Cyphers is the Lead Developer and Sole Proprietor of </em><a href="https://graffitisuite.com/" target="_blank" rel="noreferrer noopener"><em>GraffitiSuite Solutions</em></a><em> and a Xojo MVP. He has been providing custom Xojo components and contract development since 2003. </em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Android Improvements in Xojo 2023r3</title>
		<link>https://blog.xojo.com/2023/10/10/android-improvements-in-xojo-2023r3/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 10 Oct 2023 13:30:44 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2023r3]]></category>
		<category><![CDATA[Declares]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12123</guid>

					<description><![CDATA[Android remains in Beta, but there have been many fixes and improvements in Xojo 2023r3 and I'd like to highlight a few including: more support for dark mode, additions to MobileTextField, a Destination property, a HasBackButton property, MobilePopupMenu, enhancements to MobileHTMLViewer, support for running JavaScript, the new Kotlin Declare and more detailed in this post.]]></description>
										<content:encoded><![CDATA[
<p>Android remains in Beta, but there have been many fixes and improvements in Xojo 2023r3 and I&#8217;d like to highlight a few including: more support for dark mode, additions to MobileTextField, a Destination property, a HasBackButton property, MobilePopupMenu, enhancements to MobileHTMLViewer, support for running JavaScript, the new Kotlin Declare and more.</p>



<p>Although Xojo for Android does not yet have full dark mode support, things continue to head in that direction. Previously your app would adjust its UI for light/dark if the Support Dark Mode property was turned on in the Android Build Settings. Starting in Xojo 2023r3, Color.TextColor and Color.FillColor also adjust their values when run in light mode or dark mode, making it easier for your custom drawing to also adapt.</p>



<p>MobileTextField gets a couple new additions. The ReturnPressed event is now called when, as the name suggests, return is pressed. The AllowSpellChecking property is now also available for MobileTextField and MobileTextArea.</p>



<p>In the Shared Build Settings Inspector there is now a Destination property as there is with other platforms.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="377" height="434" src="https://blog.xojo.com/wp-content/uploads/2023/10/image.png" alt="" class="wp-image-12124" srcset="https://blog.xojo.com/wp-content/uploads/2023/10/image.png 377w, https://blog.xojo.com/wp-content/uploads/2023/10/image-261x300.png 261w" sizes="(max-width: 377px) 100vw, 377px" /></figure>



<p>Many Android devices have physical back buttons and all let you turn on global software controls that have a back button, but sometimes you want to have the back button clearly shown on the navigation toolbar. With Xojo 2023r3, the new HasBackButton property of MobileScreen can show a back button on the navigation toolbar.</p>



<p>To make it easier to write code that is applicable to both iOS and Android, but not other platforms, there is a new <a href="https://documentation.xojo.com/api/compiler_directives/targetmobile.html">TargetMobile</a> constant available for conditional compilation.</p>



<p><a href="https://documentation.xojo.com/api/user_interface/mobile/mobilepopupmenu.html">MobilePopupMenu</a> is an all-new control for Android that makes it possible to simplify some of your user interfaces. It works similarly to a PopupMenu on Desktop or Web: when the user taps this control a list of items appears and they can choose one.</p>



<p>On the Advanced tab of the Android Build Settings there is a new Manifest section with a Permissions property. Here you can specify the names of <a href="https://developer.android.com/reference/android/Manifest.permission">Android permission constants</a> that are needed by Declares or libraries. They are added to the AndroidManifest.xml file when the app is run/built.</p>



<p>MobileHTMLViewer got several enhancements. It now has various processing events, including: DocumentBegin, DocumentComplete, CancelLoad, Error, NewWindow, DocumentProgressChanged and TitleChanged.</p>



<p>And there is now support for running JavaScript using the ExecuteJavaScript method along with the JavaScriptResult and JavaScriptRequest events. ExecuteJavaScript is asynchronous and results appear in the JavaScriptResult event. To call the JavaScriptRequest event, use xojo.execute() in the JavaScript code. A method name and up to 5 parameters can be passed back to Xojo. <a href="https://documentation.xojo.com/api/user_interface/mobile/mobilehtmlviewer.html#mobilehtmlviewer-javascriptrequest">Learn more</a> in the Xojo Programming Documentation.</p>



<p>The last thing I want to highlight is the new Kotlin <a href="https://documentation.xojo.com/api/language/declare.html">Declare</a>. For advanced users, this adds the ability to create Android declares that can pass untouched calls via Alias (with the exception of required type/object handling) to the Kotlin compilation step. This is done by specifying Lib &#8220;Kotlin&#8221; or adding &#8220;:Kotlin&#8221; to the end of Lib. Here are a couple examples of what this can look like:</p>



<pre class="wp-block-code"><code>Declare Function AndroidVersion Lib "Kotlin" Alias "android.os.Build.VERSION.RELEASE" As CString</code></pre>



<pre class="wp-block-code"><code>Declare Sub findAllAsync Lib "Object:ctrl:MobileHTMLViewer:Kotlin" Alias "findAllAsync(myfind.toString())" (myFind As CString)</code></pre>



<p>Of course there were many bug fixes as well. Be sure to check out the <a href="https://documentation.xojo.com/versions/2023r3/resources/release_notes/2023r3.html">full release notes</a> for all the details.</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A Deep Dive into Custom Cell Renderers, Part II</title>
		<link>https://blog.xojo.com/2021/09/20/a-deep-dive-into-custom-cell-renderers-part-ii/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Mon, 20 Sep 2021 13:51:43 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9226</guid>

					<description><![CDATA[There is something that is even better than using Cell Renderers from third parties- building them yourself. In this second part, you will learn how&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There is something that is even better than using Cell Renderers from third parties- building them yourself. In this second part, you will learn how to create your very own controls using Xojo&#8217;s WebSDK.</p>



<p>In case you missed it,&nbsp;<a rel="noreferrer noopener" href="https://blog.xojo.com/2021/09/09/a-deep-dive-into-custom-cell-renderers-part-i/" target="_blank">the previous article</a>&nbsp;explains in detail what Cell Renderers are and how to use them. Anything you can imagine can be done inside your WebListView control cells. In order to do so, be prepared to write some JavaScript code. Today we will create a very basic example, a Custom Cell Renderer capable of showing&nbsp;<a rel="noreferrer noopener" href="https://getbootstrap.com/docs/4.4/components/badge/#pill-badges" target="_blank">Bootstrap Badges</a>.</p>



<p>If we think about it, in a nutshell, what we want to achieve is to inject this HTML (coming directly from Bootstrap&#8217;s docs) into our cells:</p>



<pre class="wp-block-preformatted">&lt;span class="badge badge-pill badge-primary"&gt;Primary&lt;/span&gt;</pre>



<p>The first step is to create a new class in our Xojo project. Let&#8217;s call it BadgeColumn, for example. It will be a child of&nbsp;<a rel="noreferrer noopener" href="https://documentation.xojo.com/api/user_interface/web/weblistbox.htmlCellRenderer" target="_blank">WebListboxCellRenderer</a>&nbsp;Superclass. </p>



<figure class="wp-block-image size-full is-resized is-style-default"><img decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.10.01.png" alt="" class="wp-image-9294" width="468" height="256" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.10.01.png 314w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.10.01-300x164.png 300w" sizes="(max-width: 468px) 100vw, 468px" /></figure>



<p>Extending WebListBoxCellRenderer will allow our class to listen to some events that Xojo will emit, used to render our badges inside the table. There are three: Deserialize, JavascriptClassCode and Serialize. </p>



<figure class="wp-block-image size-full is-resized is-style-default"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.22.21.png" alt="" class="wp-image-9295" width="468" height="140" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.22.21.png 341w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.22.21-300x90.png 300w" sizes="auto, (max-width: 468px) 100vw, 468px" /></figure>



<p>We will ignore all of them for the moment, except JavascriptClassCode. But it is important to know that Serialize must return an instance of a&nbsp;<a rel="noreferrer noopener" href="https://documentation.xojo.com/api/text/json/jsonitem.html" target="_blank">JSONItem</a>&nbsp;class, or you will get a NilObjectException, as soon as you add a new row using this renderer. </p>



<p>Let&#8217;s add this code to the Serialize event, we will come back to this event later:</p>



<pre class="wp-block-preformatted">Return New JSONItem</pre>



<p>JavascriptClassCode event will be executed only once, no matter the amount of instances of our renderers we have. It must return a String containing a JavaScript class that extends XojoWeb.ListboxCellRenderer, containing a render() method inside (remember that JavaScript is case-sensitive). </p>



<p>In render(), we will simply replace the contents of the cell DOM element with the badge HTML code snippet provided by the Bootstrap docs that we just saw.</p>



<p>In order to keep it as readable as possible, what I prefer to do is to create a String Constant called &#8220;kJavascriptClass&#8221; (the name is arbitrary, use anything you want), with the JavaScript code inside:</p>



<pre class="wp-block-preformatted">class BadgeColumn extends XojoWeb.ListboxCellRenderer {
&nbsp; &nbsp; render(controlID, row, data, rowIndex, columnIndex, cell) {
&nbsp; &nbsp; &nbsp; &nbsp; cell.innerHTML = '&lt;span class="badge badge-pill badge-primary"&gt;Primary&lt;/span&gt;';
&nbsp; &nbsp; }
}</pre>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="674" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59-1024x674.png" alt="" class="wp-image-9296" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59-1024x674.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59-300x197.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59-768x505.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.37.59.png 1369w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Having our raw JavaScript as a String constant, our JavascriptClassCode event can just return it:</p>



<pre class="wp-block-preformatted">Return kJavascriptClass</pre>



<p>Congratulations! That&#8217;s your first Cell Renderer. It won&#8217;t do a lot of things, but that&#8217;s the basic plumbing needed to start creating lots of them. With this new class, following the steps you&#8217;ve learned on the first part of this tutorial, you will be able to use it in your tables. Drop a WebListView into your WebPage and add a handler for the Opening event. Then add this code:</p>



<pre class="wp-block-preformatted">Me.AddRow("Hello, World!")
Me.CellValueAt(0, 0) = New BadgeColumn</pre>



<p>It will add a row to the control, and then it will make use of our new Cell Renderer to replace the first cell of the first row. If you run your project, you will see a website that looks like the following screenshot:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01-1024x743.png" alt="" class="wp-image-9297" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-18.46.01.png 1027w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>While promising, you will notice the badge says &#8220;Primary&#8221; instead of the &#8220;Hello, World!&#8221; message we want. Looking at the render() method, within our Javascript, you will find &#8220;data&#8221; as one of the parameters it receives. It is a JSON object that comes from (I&#8217;m sure you&#8217;ve guessed it already) the Serialize event we saw a few paragraphs ago. </p>



<p>Edit the Serialize event handler. This time, instead of returning an empty JSONItem, we will fill it with some data.</p>



<pre class="wp-block-preformatted">Var json As New JSONItem
json.Value("content") = "Test"
json.Value("appearance") = "success"
Return json</pre>



<p>Next, update your kJavascriptClass constant with the following snippet of code. Notice we are making use of the values we have in the data parameter, coming as a Javascript object:</p>



<pre class="wp-block-preformatted">class BadgeColumn extends XojoWeb.ListboxCellRenderer {
&nbsp; &nbsp; render(controlID, row, data, rowIndex, columnIndex, cell) {
&nbsp; &nbsp; &nbsp; &nbsp; cell.innerHTML = '&lt;span class="badge badge-pill badge-' + data.appearance + '"&gt;' + data.content + '&lt;/span&gt;';
&nbsp; &nbsp; }
}</pre>



<p>Running the web application again will make you smile a bit:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34-1024x743.png" alt="" class="wp-image-9298" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.05.34.png 1027w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Nearly there! Now that we know how to communicate between Xojo and the cell that is running in our browser, we just need to find a way to create instances of these BadgeColumn classes, using real content. </p>



<p>My preference is to create a Constructor with the parameters I want, and some class properties. This is completely up to you.</p>



<p>Create a few properties for our BadgeColumn class:</p>



<ul class="wp-block-list"><li>Content As String</li><li>Appearance As String</li></ul>



<p>Then a Constructor with the following parameters:</p>



<ul class="wp-block-list"><li>content As String</li><li>appearance As String</li></ul>



<figure class="wp-block-image size-full is-resized is-style-default"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-20.50.43.png" alt="" class="wp-image-9299" width="541" height="343" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-20.50.43.png 375w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-20.50.43-300x190.png 300w" sizes="auto, (max-width: 541px) 100vw, 541px" /></figure>



<p>Inside our new Constructor, you will need to call its Superclass Constructor, wiring the internal properties of the instance with the parameters, as following:</p>



<pre class="wp-block-preformatted">Super.Constructor
Self.Content = content
Self.Appearance = appearance</pre>



<p>The Serialize event handler can be updated now to make use of our new properties, instead hardcoded data:</p>



<pre class="wp-block-preformatted">Var json As New JSONItem
json.Value("content") = Content
json.Value("appearance") = Appearance
Return json</pre>



<p>Finally, we need to update the Opening event we used in our ListBox. Just remember thtat BadgeColumn now needs to be instantiated with some parameters:</p>



<pre class="wp-block-preformatted">Me.AddRow("")
Me.CellValueAt(0, 0) = New BadgeColumn("Hello, World!", "warning")</pre>



<p>Run the application again and see what happens:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55-1024x743.png" alt="" class="wp-image-9300" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.22.55.png 1027w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Whoops! That doesn&#8217;t looks right, does it? We are missing one important step. </p>



<p>The communication between Xojo and the control that lives inside JavaScript is bidirectional. This way, &#8220;Data&#8221; can be modified while running in your browser, and it will be sent back to Xojo. In order to fix our issue, we just have to take care of the Deserialize event handler we&#8217;ve completely ignored until now, with the following code:</p>



<pre class="wp-block-preformatted">Content = js.Value("content")
Appearance = js.Value("appearance")</pre>



<p>This will recreate our instance using fresh data coming from JavaScript. Run the project again and voilà!, your table looks perfect now:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15-1024x743.png" alt="" class="wp-image-9301" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15-768x557.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/Captura-de-pantalla-2021-09-11-a-las-19.34.15.png 1027w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>This is not the end, but the beginning of your journey. With this little recipe you already have a lot of knowledge and hours of fun ahead, building your Cell Renderers. Once you feel comfortable, the next step I recommend is to learn how to emit custom cell actions from your JavaScript that you can handle from the CustomCellAction event of your WebListBox controls.  In order to see how this works, check some of the examples coming with Xojo, under Web &gt; WebSDK &gt; WebListBox Cell Renderers. The open source repository we saw in the previous article,&nbsp;<a rel="noreferrer noopener" href="https://github.com/piradoiv/xojo-web-cell-renderers" target="_blank">xojo-web-cell-renderers</a>, also makes use of this event in some of the included Cell Renderers.</p>



<h3 class="wp-block-heading">Conclusion</h3>



<p>While we had to get our hands dirty with JavaScript, it&#8217;s really fun to create Cell Renderers for our Xojo projects. They are super easy to share and reuse, and will make your tables look so much better. The source code for this example project can be downloaded <a href="https://blog.xojo.com/wp-content/uploads/2021/09/Custom-Cell-Renderers.xojo_binary_project.zip">here</a>.</p>



<p>I hope you find this tutorial useful, if you have any question, please feel free to ask them in&nbsp;<a rel="noreferrer noopener" href="https://forum.xojo.com/" target="_blank">the forum</a>.</p>



<p><em><a href="https://en.rcruz.es">Ricardo Cruz</a> helps companies with large websites to optimise and secure them, making them reliable and ensuring they are always online. He uses Xojo for building internal tools, but he is starting to explore the desktop software market, with apps like <a href="https://today.rcruz.es">Today</a> and <a href="https://beautyshot.rcruz.es">Beauty Shot</a>. As a hobby, during his free time, Ricardo has been teaching Scuba Diving for more than 10 years.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo and JavaScript &#8211; A Perfect Combination</title>
		<link>https://blog.xojo.com/2020/02/03/xojo-and-javascript-a-perfect-combination/</link>
		
		<dc:creator><![CDATA[Stefanie Juchmes]]></dc:creator>
		<pubDate>Mon, 03 Feb 2020 10:00:00 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Monkeybread Software]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=6565</guid>

					<description><![CDATA[In the newest version of the MBS Xojo Plugin 10.0 we offer functions for the use of JavaScript in your Xojo solutions. If you have a problem that you want to solve, you don't have to reinvent the wheel again and again. ]]></description>
										<content:encoded><![CDATA[
<p>In the newest version of the MBS Xojo Plugin 10.0 we offer functions for the use of JavaScript in your Xojo solutions. If you have a problem that you want to solve, you don&#8217;t have to reinvent the wheel again and again. Perhaps someone has already found a solution to this problem and shared the solution on the Internet. So start a search engine and try your luck. Special thanks to <a href="https://www.andrerinas.de">André Rinas</a> whose site supplies very useful JavaScript snippets. This example is based on one of his JavaScript codes. Because you can use JavaScript code in your Xojo projects, you not need to convert an existing JavaScript function to Xojo syntax to use it directly in your projects.</p>



<p>In this example, I&#8217;ll show you a JavaScript that calculates the difference between two geo coordinates given by longitude and latitude. We will design a GUI with 4 Textfields. Two fields contains the longitude and latitude of the first coordinate, two other fields store the longitude and latitude of the second coordinate. Furthermore we need a label that shows the result of the calculation and a button to start it. Then we look at the JavaScript code.</p>



<p>For the calculation we need the longitude and latitude in the unit radiance. Because that we need a function that converts between angle and radiance since we have the coordinates in the unit angle. The formula for the calculation is y = x * Pi / 180.&nbsp;</p>



<p>A JavaScript function for that looks like this:</p>



<pre class="wp-block-preformatted">function DegToRad( deg ) {         
        return deg * Math.PI / 180; 
}</pre>



<p>The keyword “function” starts a function definition, followed by the function name. The parameters are written with brackets, just like in Xojo, but without data type. The calculation for the function body is surrounded by curly brackets. Math.Pi is a built-in constant that defines Pi, so we use it here to do the math.&nbsp;</p>



<p>Then we can write the function for the distance calculation:</p>



<pre class="wp-block-preformatted">function distance( lat1, lon1, lat2, lon2 ) {                </pre>



<pre class="wp-block-preformatted">       var R = 6371; // The earth's radius in km

       lat1 = DegToRad(lat1);
       lat2 = DegToRad(lat2);
       lon1 = DegToRad(lon1);
       lon2 = DegToRad(lon2);
 &nbsp;
       var x = (lon2 - lon1) * Math.cos((lat1+lat2) / 2);
       var y = (lat2 - lat1);
       var d = Math.sqrt(x*x + y*y) * R;
       return d;
 
}
 </pre>



<p>We have a function with four input parameters. That are the latitudes and longitudes of the coordinates. For each of these values we call the converting function and save the returned value in the variable again. Because these variables are defined as parameters of the function, we don’t need to declare them again. Moreover JavaScript has dynamic data types and internally uses doubles for all numbers. Because of this we don’t need to define them. All other variables (R, x, y and d) are explicitly declared with the keyword “var”. When using variables, we must pay attention to the fact that JavaScript is a case-sensitive language. A and a would be two different variables!</p>



<p>This JavaScript function is perfect for our use. Now we want to look at the possibilities to embedded it to our program.&nbsp; At first we want to evaluate the JavaScript. Because that we create a new instance of the JavaScriptEngineMBS class and evaluate the JavaScript with the “Evaluate function”. In the parameter of the function we set our JavaScript as a string. Additionally, we append the call of the function in JavaScript syntax.&nbsp;</p>



<pre class="wp-block-preformatted">	Dim js As New JavaScriptEngineMBS</pre>



<pre class="wp-block-preformatted">	Dim r as Variant = js.Evaluate("function DegToRad( deg )&nbsp; { return deg * Math.PI / 180 ; } function 	distance( lat1, lon1, lat2, lon2 ) { var R = 6371 ; lat1 = DegToRad(lat1); lat2 = DegToRad(lat2); lon1 = DegToRad(lon1); lon2 = DegToRad(lon2); var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2); var y = (lat2 - lat1); var d = Math.sqrt(x * x + y * y) * R ; return d ; } distance( 50.73743, 7.0982068, 50.61, 7.2025);")</pre>



<p>Then we have the result of the variable. The result is of type variant with an embedded double value. If we want the result as a string, we call the “EvaluateToString” function in place of the “Evaluate” function with the same parameters and the plugin performs toString operation in JavaScript if needed.&nbsp;</p>



<p>It would be very annoying if we have to change the string of the JavaScript for each query by hand. Furthermore we want to calculate the difference between the coordinates that are set in the text fields and not between fix coordinates. One possibility to do this is to set global properties in JavaScript environment with the MBS Plugin functions.</p>



<p>Before we call one of the evaluation functions we set the variables like that:&nbsp;</p>



<pre class="wp-block-preformatted">js.GlobalProperty("lat1") = LatitudeA.Text
js.GlobalProperty("lat2") = LatitudeB.Text
js.GlobalProperty("lon1") = LongitudeA.Text
js.GlobalProperty("lon2") = LongitudeB.Text</pre>



<p>Then we replace the constant values in the function call, with our variables :&nbsp;</p>



<pre class="wp-block-preformatted">distance( lat1, lon1, lat2, lon2 )</pre>



<p>If we want to avoid setting this huge part of script in every evaluation function, we can add the DagToRad function and the distance function to the environment of the JavaScript. Then we only need to call the distance function with the right parameters. That is easier for debugging, too. Here the final example code:</p>



<pre class="wp-block-preformatted">Dim lat1 As String = LatitudeA.Text
Dim lat2 As String = LatitudeB.Text
Dim lon1 As String = LongitudeA.Text
Dim lon2 As String = LongitudeB.Text
Dim r As Variant&nbsp;
 
Dim js As New JavaScriptEngineMBS</pre>



<pre class="wp-block-preformatted">js.AddFunction "DegToRad", "function( deg ) { return deg * Math.PI / 180 ;}"  js.AddFunction "distance", "function( lat1, lon1, lat2, lon2 ) { lat1 = DegToRad(lat1); lat2 = DegToRad(lat2); lon1 = DegToRad(lon1); lon2 = DegToRad(lon2); var R = 6371; var x = (lon2-lon1) * Math.cos((lat1+lat2)/2); var y = (lat2-lat1); var d = Math.sqrt(x*x + y*y) * R; return d; }"
 r = js.CallFunction("distance", lat1, lon1, lat2, lon2)
 Result.Text = str(r, “####.##") </pre>



<p>Once the JavaScriptEngineMBS object is initialized, you can store it in a window property and reuse it several times to do more calculations. A great use for this JavaScript is to do calculations in your applications to match the hash/signature algorithm used by a web service to authenticate. If you get a JavaScript snippet, you can just run it, if required dependencies are provided. And you may find it useful to perform JavaScript server side for your Xojo web apps.</p>



<p>I hope that you like our new JavaScript functions. I wish you lots of fun with them. If you have any questions, please do not hesitate to contact us.&nbsp;</p>



<p>Stefanie Juchmes studies Computer Science at the University of Bonn. She came in touch with Xojo due to the work of her brother-in-law and got a junior developer position in early 2019 at<a rel="noreferrer noopener" href="https://www.monkeybreadsoftware.de/xojo/" target="_blank">&nbsp;Monkeybread Software.</a>&nbsp;You may have also read her articles in<a rel="noreferrer noopener" href="http://www.xdevmag.com/" target="_blank">&nbsp;Xojo Developer Magazine</a>.&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tutorial: Saving WebCanvas Images to Disk</title>
		<link>https://blog.xojo.com/2018/10/11/tutorial-saving-webcanvas-images-to-disk/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 11 Oct 2018 10:00:34 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[AprendeXojo]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WebCanvas]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5024</guid>

					<description><![CDATA[The WebCanvas control is used for drawing graphics in web apps. It takes advantage of the HTML5 Canvas making it fast and powerful. Sometimes is can be useful to be able to save the graphics drawn in the WebCanvas to an image file, but unfortunately there is no built-in Xojo method to do this. However, by using a little JavaScript you can easily add this capability to Xojo.]]></description>
										<content:encoded><![CDATA[<p>The <strong>WebCanvas</strong> control is used for drawing graphics in web apps. It takes advantage of the HTML5 Canvas making it fast and powerful. Sometimes is can be useful to be able to save the graphics drawn in the WebCanvas to an image file, but unfortunately there is no built-in Xojo method to do this.</p>
<p>However, by using a little JavaScript you can easily add this capability to Xojo.</p>
<p><span id="more-5024"></span></p>
<p>In order to follow this tutorial, create a new <b>Web</b> project and add a new <a href="http://developer.xojo.com/webcanvas"><b>WebCanvas</b></a> control from the Library to the default Web Page added to the project: <code>WebPage1</code>. With the WebCanvas selected in the Navigator, change its name to <code>cCanvas</code> using the Inspector and add the <code>Paint</code> Event Handler to it using the <code>Insert &gt; Event Handler</code> option from the menu. Use the following code to draw a black colored rectangle:</p>
<pre>g.FillRect 0, 0, g.Width, g.Height</pre>
<p>Obviously, you can draw anything you want in the WebCanvas or even <em>paint</em> a picture on it. The achieved result will be the same. For example, we can draw a picture added to our project (with the filename &#8220;landscape&#8221;), using this line of code in the Paint event of our <code>cCanvas</code> instance:</p>
<pre>g.DrawPicture landscape, 0, 0, g.Width, g.Height</pre>
<h2>Retrieving the WebCanvas image data</h2>
<p>The first interesting step is retrieving the underlying image represented by the WebCanvas and that is something we can get using a fragment of <b>JavaScript</b> code executed from the Xojo side. This is the process we will execute from the <code>Action</code> Event Handler of a <b>WebButton</b> added to the <code>WebPage1</code> from the Library. In fact, this will be the button in charge of calling the process to save the image as a picture file on the user disk.</p>
<p>Once the WebButton has been added to the WebPage from the Library, put the following code in its <code>Action</code> Event Handler:</p>
<pre>Dim js() As String
js.Append "var canvas = document.getElementById('" + cCanvas.ControlID + "_canvas');" // We get the item reference based on its ID
js.Append "var img = canvas.toDataURL(""image/png;base64;"");" // We access to the image data, encoded as a base64 string
js.Append "document.location.hash=img" // We assign that data to the document Hash property, so we can retrieve it from the Xojo side

Dim execute As String = Join(js,"")

ExecuteJavaScript execute // Finally, we execute the JavaScript code</pre>
<p>As you can see, the first line of the JavaScript code is in charge of retrieving the <code>cCanvas</code> reference from the DOM (document object model) of the Web Page. For that, we use the <code>ControlID</code> property on our WebCanvas instance, adding the &#8220;canvas&#8221; appended by Xojo to all these kind of objects when generating the source code for the page.</p>
<p>Once we get the reference to our Canvas instance, the following line of code retrieves the picture content itself and assigns it to the <code>img</code> variable. The <em>trick</em> here is that we retrieve that information in its URL format and, thus, encoded as <b>Base64</b> data that we can assign to other document properties without losing its original meaning.</p>
<p>Then, we assign the data to the document <b>Hash</b> property. This is the property that allows us to jump to other page sections previously tagged. However, we will use this property as a temporary storage container for passing the data between the HTML/JavaScript side of the web page and the Xojo side of our code. Why we do this? Well, because we can add the <b>HashTagChanged</b> Event Handler to the <b>Session</b> object so it will fire every time we change the value of the <code>Hash</code> property and we will be able to retrieve the data from that property.</p>
<h2>Retrieving the image, from the Xojo side</h2>
<p>So, the next step is adding the <code>HashTagChanged</code> event to the <b>Session</b> object of our example project, writing the following snippet of code in the associated Code Editor:</p>
<pre>Dim data As String = DecodeBase64(Hashtag.NthField(",",2) ) // We retrieve the information saved in the Hash, but just the relevant data for the image and not the URL part.
wp = New WebPicture(data,"My_Picture.png") // We create a new WebPicture instance using the previously retrieved image data in the constructor, and giving a default file name for the image
wp.ForceDownload = True // We want to force the file download instead of showing it
ShowURL wp.URL // and finally we start the file download process.

Hashtag = "" // Let's empty the hash property, just to make sure that the event will fire even if the WebCanvas doesn't change its contents</pre>
<p>As you can see, in the first line of code we retrieve the image data. We do that using the <code>NthField</code> command because we are only interested in the image data and not in the URL information that precedes it. In addition, we decode the previously encoded data as Base64, so we really get the bytes of the image in PNG format.</p>
<p>Once we get the picture data, we can use any of the available constructors for the <a href="http://developer.xojo.com/webpicture"><b>WebPicture</b></a> class; in this case the one that lets us create a new image from the passed data. In addition, we use this class because it is a subclass of <b>WebFile</b>, and that means that it is simpler to force the download as an image file instead of showing its contents in a new web page.</p>
<p>In fact, this is what we achieve setting the <code>ForceDownload</code> property to <code>True</code>, so when in the following line we use <code>ShowURL</code> we will be forcing the download of the file instead of displaying the image as a new page in the browser. Goal achieved!</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-5027 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/10/WebCanvasToFile.png" alt="" width="500" height="279" /></p>
<h2>Download persistence</h2>
<p>You probably noted that the <code>wp</code> variable is not declared in the previous fragment of code. This is because we need to make sure that the object it points to is in scope during the file downloading process and won&#8217;t get destroyed once we exit the Event Handler (we would want a message error from the web browser in that case). The solution is pretty easy &#8211; we only need to add a new property to our <b>Session</b> object, using the following values:</p>
<ul>
<li><b>Name</b>: wp</li>
<li><b>Type</b>: WebPicture</li>
<li><b>Scope</b>: Private</li>
</ul>
<p>Now, every time you run the app web and click the button, you&#8217;ll see how the web browser downloads the WebCanvas image as a PNG file to disk.</p>
<p>To summarize, in this tutorial we have seen a way to &#8220;communicate&#8221; between the data generated executing JavaScript code in our web app so we can retrieve and use it from the Xojo side of our Web App; in this case applied to the retrieval and saving of the underlying picture represented by a WebCanvas object.</p>
<p>*Watch a <a href="https://www.youtube.com/watch?time_continue=29&amp;v=RTBuub8Atjw">video of this Tutorial in Spanish</a></p>
<p>*<a href="https://www.aprendexojo.com/2016/06/crear-servicio-web-con-xojo/">Read this Tutorial in Spanish</a></p>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others</em></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
