<?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>Web Development &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/webdevelopment/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Tue, 31 Mar 2026 15:21:49 +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>Scan Barcodes, Pick Colors, Toggle: Xojo Web in 2026r1</title>
		<link>https://blog.xojo.com/2026/03/31/scan-barcodes-pick-colors-toggle-xojo-web-in-2026r1/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 31 Mar 2026 13:22:00 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2026r1]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<category><![CDATA[Xojo Web]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15969</guid>

					<description><![CDATA[If you build web apps with Xojo, 2026r1 is worth a close look. There&#8217;s a good mix of new controls and under-the-hood improvements to explore.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>If you build web apps with Xojo, 2026r1 is worth a close look. There&#8217;s a good mix of new controls and under-the-hood improvements to explore. Exciting times!</p>



<h2 class="wp-block-heading">New Controls</h2>



<p>Three new controls have been added to the Web framework in this release, aiming to close the difference gap between Web and the other project types.</p>



<p><code>WebSwitch</code>&nbsp;is a toggle control that mobile developers will already be familiar with. It&#8217;s been available on iOS and Android for a while. It&#8217;s now available for web projects too, so if you&#8217;ve been approximating a toggle switch using a styled checkbox, you can finally retire that workaround.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="690" src="https://blog.xojo.com/wp-content/uploads/2026/03/switch-vs-checkbox-1024x690.png" alt="" class="wp-image-15992" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/switch-vs-checkbox-1024x690.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/switch-vs-checkbox-300x202.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/switch-vs-checkbox-768x517.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/switch-vs-checkbox-1536x1035.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/03/switch-vs-checkbox-2048x1380.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p><code>WebColorPicker</code> brings color selection to web apps in the same way <code>DesktopColorPicker</code> does for desktop. Drop it in from the Library, wire up the event and you have a color picker the Xojo way.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="731" src="https://blog.xojo.com/wp-content/uploads/2026/03/colorpicker-ide-1024x731.png" alt="" class="wp-image-15994" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/colorpicker-ide-1024x731.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/colorpicker-ide-300x214.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/colorpicker-ide-768x548.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/colorpicker-ide-1536x1096.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/03/colorpicker-ide-2048x1461.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>This is how <code>WebColorPicker</code> looks like in your browser:</p>



<figure class="wp-block-video"><video height="1274" style="aspect-ratio: 1488 / 1274;" width="1488" controls src="https://blog.xojo.com/wp-content/uploads/2026/03/colorpicker-browser.mp4"></video></figure>



<p>The third new control adds barcode reading support. Your web app can now read barcodes directly from the user&#8217;s camera, from desktop or mobile browsers. This opens up a lot of practical use cases: Inventory systems, ticketing, product lookups, that previously would have pushed you toward a native mobile app.</p>



<p>Again, drop the Barcode control into your project and implement the events:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="747" src="https://blog.xojo.com/wp-content/uploads/2026/03/barcode-reader-ide-1024x747.png" alt="" class="wp-image-15995" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/barcode-reader-ide-1024x747.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/barcode-reader-ide-300x219.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/barcode-reader-ide-768x560.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/barcode-reader-ide-1536x1120.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/03/barcode-reader-ide-2048x1494.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>That&#8217;s it! Your web apps can scan a great variety of barcodes now. Including QR, Data Matrix, Aztec, PDF 417 and much more!</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="471" height="1024" src="https://blog.xojo.com/wp-content/uploads/2026/03/aztec-barcode-1-471x1024.png" alt="" class="wp-image-16007" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/aztec-barcode-1-471x1024.png 471w, https://blog.xojo.com/wp-content/uploads/2026/03/aztec-barcode-1-138x300.png 138w, https://blog.xojo.com/wp-content/uploads/2026/03/aztec-barcode-1.png 555w" sizes="auto, (max-width: 471px) 100vw, 471px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="471" height="1024" src="https://blog.xojo.com/wp-content/uploads/2026/03/datamatrix-barcode-1-471x1024.png" alt="" class="wp-image-16008" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/datamatrix-barcode-1-471x1024.png 471w, https://blog.xojo.com/wp-content/uploads/2026/03/datamatrix-barcode-1-138x300.png 138w, https://blog.xojo.com/wp-content/uploads/2026/03/datamatrix-barcode-1.png 555w" sizes="auto, (max-width: 471px) 100vw, 471px" /></figure>
</div>
</div>



<h2 class="wp-block-heading">Icons on WebButtons</h2>



<p><code>WebButton</code>&nbsp;now has an&nbsp;<code>Icon</code>&nbsp;property. You can assign any&nbsp;<code>WebPicture</code>&nbsp;to it, or use one of the Bootstrap icons that are already bundled with the framework. It&#8217;s a small addition, but it makes a noticeable difference when building action-heavy interfaces where a label alone doesn&#8217;t communicate enough at a glance.</p>



<p>Add a button into your project:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="690" src="https://blog.xojo.com/wp-content/uploads/2026/03/button-icon-ide-2-1024x690.png" alt="" class="wp-image-16001" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/button-icon-ide-2-1024x690.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/button-icon-ide-2-300x202.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/button-icon-ide-2-768x517.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/button-icon-ide-2-1536x1035.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/03/button-icon-ide-2-2048x1380.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Configure its Icon property in the <code>Opening</code> event:</p>



<pre class="wp-block-code"><code>Me.Icon = WebPicture.BootstrapIcon("key-fill")</code></pre>



<p>If you don&#8217;t specify a color in BootstrapIcon, it will inherit the button caption color in this case. This is the easiest way to support Dark Mode with the new <code>WebButton.Icon</code> property, without doing any special tricks.</p>



<p>Here is how it looks like at runtime:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="889" src="https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-light-1024x889.png" alt="" class="wp-image-15999" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-light-1024x889.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-light-300x261.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-light-768x667.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-light-1536x1334.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-light.png 1612w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Dark Mode:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="889" src="https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-dark-1024x889.png" alt="" class="wp-image-16000" srcset="https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-dark-1024x889.png 1024w, https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-dark-300x261.png 300w, https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-dark-768x667.png 768w, https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-dark-1536x1334.png 1536w, https://blog.xojo.com/wp-content/uploads/2026/03/button-browser-dark.png 1612w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">WebLabel: Semantic HTML and Proper Element Types</h2>



<p>Two related changes landed for&nbsp;<code>WebLabel</code>&nbsp;in this release. The first is a correctness fix: the control was previously rendered using the HTML&nbsp;<code>&lt;label&gt;</code>&nbsp;element, which is semantically meant to label form inputs, not to display general text. That has been corrected.</p>



<p>The more interesting addition is that you can now choose which HTML element&nbsp;<code>WebLabel</code>&nbsp;renders as. If you want a label to be an&nbsp;<code>&lt;h1&gt;</code>&nbsp;or an&nbsp;<code>&lt;h2&gt;</code>, you can set that directly in the Inspector. This is useful not just for visual styling, but for accessibility tools and search engines that rely on page structure to understand content hierarchy.</p>



<p>Improving both, accessibility and making search engines happier, are some of our goals for 2026. You will continue seeing improvements in this sense.</p>



<h2 class="wp-block-heading">WebTextArea Gets AddText</h2>



<p><code>WebTextArea</code>&nbsp;now has an&nbsp;<code>AddText</code>&nbsp;method, consistent with how the control works on Desktop and Mobile. If you&#8217;re writing code that targets multiple platforms, this kind of parity saves you from having to check which target you&#8217;re on, before appending text.</p>



<h2 class="wp-block-heading">Scale Indicator on WebMapViewer</h2>



<p><code>WebMapViewer</code>&nbsp;now has a&nbsp;<code>HasScaleIndicator</code>&nbsp;property. When enabled, a small visual scale appears on the map showing real-world distance. It makes a difference in apps where users need spatial context. Field work, logistics or anything where &#8220;how far is that?&#8221; is a question users might actually ask.</p>



<h2 class="wp-block-heading">Performance and Modernization Under the Hood</h2>



<p>A few changes in this release won&#8217;t be immediately visible, but they improve things for everyone.</p>



<p>Bootstrap has been updated to v5.3.8 which fixes some issues introduced in v5.3.7 impacting Xojo. The TypeScript compiler has been updated to v5.9.3, and the compilation target has been bumped from ES6 to ES2020. Unused code in the Web Framework has been cleaned up to reduce the compiled bundle size.</p>



<p>Xojo has also removed its own internal usage of Modernizr. The library is still present for now so existing apps that rely on it won&#8217;t break, but it&#8217;s no longer used by the framework itself and will be removed in a future release.</p>



<p>If you&#8217;ve been meaning to audit your web app for performance, this is a good moment to look at&nbsp;<code>SendEventsInBatches</code>&nbsp;and&nbsp;<code>LazyLoadDependencies</code>&nbsp;on&nbsp;<code>WebSession</code>&nbsp;as well. Both now default to&nbsp;<code>True</code>&nbsp;on new projects, so if your existing app has them disabled, it&#8217;s worth trying them out. These properties have been around for a while already but were turned off by default.</p>



<h2 class="wp-block-heading">API Consistency Cleanups</h2>



<p>A few methods have been deprecated in favour of names that are consistent with the rest of the framework:</p>



<ul class="wp-block-list">
<li><code>WebApplication.AutoQuit</code>&nbsp;→&nbsp;<code>AllowAutoQuit</code></li>



<li><code>WebListBox.ReloadData</code>&nbsp;→&nbsp;<code>ReloadFromDataSource</code></li>



<li><code>WebRadioGroup.RemoveAllRows</code>&nbsp;→&nbsp;<code>RemoveAll</code>, and&nbsp;<code>RemoveRowAt</code>&nbsp;→&nbsp;<code>RemoveAt</code></li>
</ul>



<p>Your existing code will still compile, but it&#8217;s worth updating these when you get a chance.</p>



<h2 class="wp-block-heading">Wrapping Up</h2>



<p>Between new controls, better HTML semantics, and a leaner runtime, 2026r1 is a worthwhile update for anyone building web apps with Xojo. Check out the&nbsp;<a href="https://documentation.xojo.com/resources/release_notes/2026r1.html">full release notes</a>&nbsp;for the complete list of changes.</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2026/03/colorpicker-browser.mp4" length="707463" type="video/mp4" />

			</item>
		<item>
		<title>How To Share Your Local Xojo Web App to the Internet Using ngrok</title>
		<link>https://blog.xojo.com/2025/08/07/how-to-share-your-local-xojo-web-app-to-the-internet-using-ngrok/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Thu, 07 Aug 2025 14:52:22 +0000</pubDate>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Developer Tools]]></category>
		<category><![CDATA[Remote Testing]]></category>
		<category><![CDATA[Web App Testing]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Webhook Development]]></category>
		<category><![CDATA[Xojo Web]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15075</guid>

					<description><![CDATA[Have you ever built an amazing Xojo web application locally on your machine and wished you could instantly share it with a client, test it&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Have you ever built an amazing Xojo web application locally on your machine and wished you could instantly share it with a client, test it on a real mobile device outside your local network, or integrate it with a webhook service like Stripe or Twilio? If so, you know the pain of needing a publicly accessible URL for your locally running app.</p>



<p>This is where&nbsp;ngrok&nbsp;comes in: a fantastic tool that creates secure tunnels to your localhost, making your locally running Xojo web app accessible from anywhere in the world. It&#8217;s a game-changer for testing, demonstrations, and rapid development.</p>



<h2 class="wp-block-heading">What is ngrok and Why Xojo Developers Need It?</h2>



<p>At its core, ngrok is a command-line tool that creates a secure, public URL for a service running on your local machine. Think of it as a temporary bridge from the internet directly to your computer, bypassing firewalls and NAT configurations.</p>



<p>For Xojo Web developers, this offers a wealth of benefits:</p>



<ul class="wp-block-list">
<li><strong>Real-device Testing:</strong>&nbsp;Test your Xojo web app&#8217;s responsiveness and functionality on actual mobile phones, tablets, or other computers, even if they&#8217;re not on your local Wi-Fi network.</li>



<li><strong>Instant Demonstrations:</strong>&nbsp;Share your work-in-progress with clients, colleagues, or friends without the need of deploying to a remote server. They just need the ngrok-provided URL!</li>



<li><strong>Webhook Development:</strong>&nbsp;Many third-party services (payment gateways, messaging platforms, etc.) use webhooks to notify your application of events. These webhooks require a public URL to send data to. ngrok provides this, making local webhook development a breeze.</li>



<li><strong>Debugging Public-Facing Issues:</strong>&nbsp;Sometimes, an issue only appears when your app is publicly accessible. ngrok allows you to debug such scenarios without a full deployment cycle.</li>
</ul>



<p>It&#8217;s truly a must-have tool in your Xojo Web development toolkit!</p>



<h2 class="wp-block-heading">Getting Started with ngrok</h2>



<p>Before we connect our Xojo app, we need to get ngrok set up.</p>



<h3 class="wp-block-heading">Step 1: Download ngrok</h3>



<p>Head over to the official ngrok website:&nbsp;<a href="https://ngrok.com/download" target="_blank" rel="noreferrer noopener">https://ngrok.com/download</a>.</p>



<p>Download the version appropriate for your operating system (Windows, macOS, Linux).</p>



<h3 class="wp-block-heading">Step 2: Unzip and Place</h3>



<p>Once downloaded, you&#8217;ll get a single executable file (e.g.,&nbsp;<code>ngrok.exe</code>&nbsp;on Windows,&nbsp;<code>ngrok</code>&nbsp;on macOS/Linux). Unzip it and place it in a convenient location. I recommend creating a dedicated folder for it, or placing it somewhere easily accessible from your terminal or command prompt.</p>



<h2 class="wp-block-heading">Preparing Your Xojo Web App</h2>



<p>Xojo Web applications are self-contained web servers. When you run a Xojo Web app in debug mode or build it for deployment, it listens for incoming connections on a specific port. By default, Xojo Web apps usually listen on&nbsp;port 8080.</p>



<p>Let&#8217;s quickly ensure your Xojo Web app is ready:</p>



<ol class="wp-block-list">
<li><strong>Open your Xojo Web Project:</strong>&nbsp;Open any existing Xojo Web project, or create a new one for testing.</li>



<li><strong>Run in Debug Mode:</strong>&nbsp;Click the &#8220;Run&#8221; button in the Xojo IDE. Your web app will launch in your default browser, at&nbsp;<code>http://localhost:8080</code>.</li>
</ol>



<h2 class="wp-block-heading">Tunneling Your Xojo App with ngrok</h2>



<p>Now for the magic! With your Xojo Web app running locally, we&#8217;ll open a tunnel to it using ngrok.</p>



<h3 class="wp-block-heading">Step 1: Open Terminal/Command Prompt</h3>



<p>Open your system&#8217;s terminal (macOS/Linux) or Command Prompt/PowerShell (Windows).</p>



<h3 class="wp-block-heading">Step 2: Navigate to ngrok Directory (if needed)</h3>



<p>If you didn&#8217;t place the&nbsp;<code>ngrok</code>&nbsp;executable in a system PATH location, navigate to the directory where you unzipped&nbsp;<code>ngrok</code>&nbsp;using the&nbsp;<code>cd</code>&nbsp;command. For example:</p>



<pre class="wp-block-code"><code>cd /path/to/your/ngrok/folder</code></pre>



<h3 class="wp-block-heading">Step 3: Run the ngrok Command</h3>



<p>Now, execute the&nbsp;<code>ngrok</code>&nbsp;command to create the tunnel. Since Xojo Web apps typically run on port 8080, the command will be:</p>



<pre class="wp-block-code"><code>ngrok http 8080</code></pre>



<ul class="wp-block-list">
<li><code>http</code>: Specifies that we&#8217;re tunneling an HTTP service.</li>



<li><code>8080</code>: This is the port your Xojo Web app is listening on. If you&#8217;ve configured your Xojo app to use a different port (e.g., in the Build Settings), make sure to use that port number instead.</li>
</ul>



<p>After running the command, ngrok will output information about the tunnel it has created. You&#8217;ll see output similar to this:</p>



<pre class="wp-block-code"><code>ngrok                                                                            (Ctrl+C to quit)

Session Status                online
Account                       Account Name (Free)
Version                       3.x.x
Region                        United States (us)
Forwarding                    https://a52b-20-40-100-120.ngrok-free.app -&gt; http://localhost:8080

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00
</code></pre>



<p>The most important lines here are the&nbsp;<code>Forwarding</code>&nbsp;lines. These provide you with the public URLs that point to your Xojo web app.</p>



<h2 class="wp-block-heading">Testing Your Public Xojo App</h2>



<p>With the ngrok tunnel active, your Xojo web app is now live to the world!</p>



<ol class="wp-block-list">
<li><strong>Copy the HTTPS URL:</strong>&nbsp;Copy the&nbsp;<code>https://</code>&nbsp;URL provided by ngrok.</li>



<li><strong>Test It:</strong>
<ul class="wp-block-list">
<li>Paste this URL into any web browser, on any device, anywhere with an internet connection.</li>



<li>Send the URL to a friend or client to get their feedback.</li>



<li>Test it on your mobile phone&#8217;s browser using its cellular data connection (not your local Wi-Fi) to simulate a truly external connection.</li>
</ul>
</li>
</ol>



<p>You&#8217;ll see your Xojo web app load as if it were hosted on a remote server!</p>



<p>To stop the ngrok tunnel, press Ctrl+C in the console.</p>



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



<p>ngrok can be an indispensable tool for any Xojo Web developer. It transforms the challenging task of exposing a local web app into a simple, one-line command. Whether you&#8217;re testing on diverse devices, showcasing your progress to clients, or integrating with external webhook services, ngrok streamlines your workflow and lets you focus on what you do best: building amazing applications with Xojo.</p>



<p>Give ngrok a try on your next Xojo Web project, and prepare to be amazed by the convenience it offers!</p>



<p>What if we create a Build Step script to automatically run ngrok when needed? Share your experiences and tips in the <a href="https://forum.xojo.com/" target="_blank" rel="noreferrer noopener">Xojo forums</a>!</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Deploy Xojo Web Apps with Caddy Reverse Proxy</title>
		<link>https://blog.xojo.com/2025/08/04/deploy-xojo-web-apps-with-caddy-reverse-proxy/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Mon, 04 Aug 2025 18:45:28 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Xojo Web]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15201</guid>

					<description><![CDATA[Deploying Xojo web applications offers developers flexible pathways to production. For devs prioritizing minimal infrastructure management,&#160;Xojo Cloud&#160;provides a fully-managed solution with automatic scaling, SSL, and&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Deploying Xojo web applications offers developers flexible pathways to production. For devs prioritizing minimal infrastructure management,&nbsp;<a href="https://www.xojo.com/cloud/" target="_blank" rel="noreferrer noopener">Xojo Cloud</a>&nbsp;provides a fully-managed solution with automatic scaling, SSL, and zero-server-maintenance. However, for developers requiring granular control over their deployment environment, implementing a reverse proxy like <a href="https://caddyserver.com/" data-type="link" data-id="https://caddyserver.com/" target="_blank" rel="noreferrer noopener">Caddy</a> delivers enterprise-grade performance while simplifying critical operations.</p>



<p>This guide focuses on production-ready Caddy configurations that streamline deployments for self-managed Xojo applications, delivering:</p>



<ul class="wp-block-list">
<li>Automated TLS certificate management</li>



<li>Native load balancing between instances</li>



<li>Simplified configuration compared to traditional proxies</li>



<li>Header optimizations specifically tuned for Xojo’s framework</li>
</ul>



<p>You’ll learn configuration strategies that <em>in some benchmarks, can have resource savings as high as 40%</em> over conventional proxies while maintaining Xojo’s signature performance characteristics.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Core Configuration Strategies</h3>



<p><strong>Basic Reverse Proxy Setup</strong></p>



<pre class="wp-block-code"><code>yourdomain.com {
    # Connect to Xojo application
    reverse_proxy localhost:8080 {
        # Preserve client information
        header_up X-Forwarded-For {http.request.remote.host}
        header_up Host {http.request.host}
    }
    
    # Automate HTTPS
    tls admin@yourdomain.com
}</code></pre>



<p><em>Note: The&nbsp;<code>header_up</code>&nbsp;directives ensure Xojo correctly logs client IPs in web events</em></p>



<p><strong>Load Balancing Across Instances</strong></p>



<pre class="wp-block-code"><code>app.yourdomain.com {
    reverse_proxy localhost:8080 localhost:8081 localhost:8082 {
        load_balancer {
            policy round_robin
            health_interval 10s
            health_uri /health
        }
        # Timeouts for heavy processing
        lb_try_duration 30s
    }
}</code></pre>



<p><strong>Security Hardening Measures</strong></p>



<pre class="wp-block-code"><code>yourdomain.com { 
	# Critical protection headers 
	header { 
		X-Content-Type-Options "nosniff" 
		X-Frame-Options "DENY" 
		Content-Security-Policy "default-src 'self'" 
	} 

	# Rate limiting for API endpoints 
	route /api/* { 
		rate_limit { 
			zone api 
			burst 100 
			period 10s 
		} 
	} 
}</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Production-Ready Deployment Scripts</h3>



<p><strong>Linux Systemd Service</strong><br><code>/etc/systemd/system/xojo-caddy.service</code>:</p>



<pre class="wp-block-code"><code>&#91;Unit]
Description=Xojo Caddy Reverse Proxy
After=network.target

&#91;Service]
Type=simple
User=caddy
ExecStart=/usr/bin/caddy run --config /etc/caddy/Caddyfile
Restart=on-failure
RestartSec=5

&#91;Install]
WantedBy=multi-user.target</code></pre>



<p>For a broader, step-by-step guide on preparing your server, please see our foundational tutorial:&nbsp;<a href="https://blog.xojo.com/2021/05/28/tutorial-deploying-web-apps-on-linux/" target="_blank" rel="noreferrer noopener">Tutorial: Deploying Web Apps on Linux</a>. The&nbsp;<code>systemd</code>&nbsp;service above integrates perfectly into that workflow.</p>



<p><strong>Windows Deployment Package</strong><br><code>Xojo-Caddy.bat</code>:</p>



<pre class="wp-block-code"><code>@echo off
REM Start Xojo application instances
start "Xojo Instance 1" /MIN XojoWebApp.exe --port=8080
start "Xojo Instance 2" /MIN XojoWebApp.exe --port=8081

REM Launch Caddy reverse proxy
start "Caddy Proxy" /MIN caddy.exe run --config C:\caddy\Caddyfile</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><strong>Optimized Xojo-Caddy Template</strong><br>Save as&nbsp;<code>Caddyfile</code>&nbsp;in your deployment root:</p>



<pre class="wp-block-code"><code># Production-Grade Xojo Proxy Template
yourdomain.com, www.yourdomain.com {
    # Automated HTTPS
    tls contact@yourdomain.com
    
    # Primary app routing
    reverse_proxy localhost:8080 localhost:8081 {
        header_up X-Forwarded-Proto https
        header_up X-Real-IP {http.request.remote}
    }
    
    # Static content handling
    handle /static/* {
        root * /var/www/static
        file_server
    }
    
    # Security headers
    header {
        Strict-Transport-Security "max-age=31536000"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
}</code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



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



<p>Caddy eliminates proxy complexity while delivering enterprise capabilities:</p>



<ol class="wp-block-list">
<li><strong>Simplified Operations</strong>: Single configuration file replaces complex proxy setups</li>



<li><strong>Automatic Security</strong>: Continuous HTTPS protection without maintenance</li>



<li><strong>Effortless Scaling</strong>: Built-in load balancing grows with your user base</li>



<li><strong>Reduced Overhead</strong>: 40% fewer resources than traditional proxies in benchmarks</li>
</ol>



<p>Implement the provided Xojo-Caddy template to achieve production-grade deployment in under 15 minutes. Monitor performance via Caddy’s built-in&nbsp;<code>/metrics</code>&nbsp;endpoint and scale horizontally as traffic increases.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Web Framework Updates in 2025r2</title>
		<link>https://blog.xojo.com/2025/07/08/web-framework-updates-in-2025r2/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 08 Jul 2025 18:01:00 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2025r2]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[WebMapViewer]]></category>
		<category><![CDATA[WebStyles]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14977</guid>

					<description><![CDATA[Featuring WebStyle state support for creating more polished user interfaces, enhanced event handling capabilities, and a collection of bug fixes and utility improvements, 2025r2 continues&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Featuring WebStyle state support for creating more polished user interfaces, enhanced event handling capabilities, and a collection of bug fixes and utility improvements, 2025r2 continues improvements to your Web Application development experience with Xojo.</p>



<h2 class="wp-block-heading"><strong>Added Support for WebStyle States</strong></h2>



<p>Working on Desktop projects is all fun and jokes. You can just change how the whole application looks every time your application users move their mouse one pixel to the left. Latency? Who cares!</p>



<p>In order to achieve the same results, WebStyle has been improved to support states. Hover, Pressed and Visited.</p>



<ul class="wp-block-list">
<li><strong>WebStyle.Hover</strong><br>This is the style that will be applied when the mouse is over the element</li>



<li><strong>WebStyle.Pressed</strong><br>This is the style that will be applied when the user is pressing a mouse button in the element</li>



<li><strong>WebStyle.Visited</strong><br>This style can be used with WebLink instances. Used to let the user know the browser has visited that link in the past</li>
</ul>



<p>Consider the following WebContainer:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="686" src="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.31.08-1024x686.png" alt="" class="wp-image-14978" srcset="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.31.08-1024x686.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.31.08-300x201.png 300w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.31.08-768x514.png 768w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.31.08-1536x1029.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.31.08-2048x1371.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>In this case, it&#8217;s just a container with a WebLabel inside.</p>



<p>The Opening event contains the following code:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="686" src="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.34.34-1024x686.png" alt="" class="wp-image-14979" srcset="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.34.34-1024x686.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.34.34-300x201.png 300w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.34.34-768x514.png 768w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.34.34-1536x1029.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.34.34-2048x1371.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>Please note I&#8217;m using named colors. You can read more about named colors in <a href="https://blog.xojo.com/2024/10/01/introducing-named-color-and-css-classes-in-xojo-web/" data-type="link" data-id="https://blog.xojo.com/2024/10/01/introducing-named-color-and-css-classes-in-xojo-web/">Introducing Named Color and CSS Classes in Xojo Web</a>. If you try using another Bootstrap theme, the same code will use the new color palette without modifications.</p>



<p>Here is the result:</p>



<figure class="wp-block-video aligncenter"><video height="1044" style="aspect-ratio: 1392 / 1044;" width="1392" controls src="https://blog.xojo.com/wp-content/uploads/2025/06/Grabacion-de-pantalla-2025-06-17-a-las-10.32.14.mp4.mp4"></video></figure>



<p>Combined with <code>WebStyle.AddTransition</code>, it opens the gates for more interesting GUIs. Let&#8217;s add some transitions to our code:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="686" src="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.41.12-1024x686.png" alt="" class="wp-image-14981" srcset="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.41.12-1024x686.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.41.12-300x201.png 300w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.41.12-768x514.png 768w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.41.12-1536x1029.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.41.12-2048x1371.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Let&#8217;s try the project again:</p>



<figure class="wp-block-video"><video height="1044" style="aspect-ratio: 1392 / 1044;" width="1392" controls src="https://blog.xojo.com/wp-content/uploads/2025/06/Grabacion-de-pantalla-2025-06-17-a-las-10.41.58.mp4.mp4"></video></figure>



<p>Neat! Let&#8217;s go crazy for a second with more complex effects:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="686" src="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.57.15-1024x686.png" alt="" class="wp-image-14983" srcset="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.57.15-1024x686.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.57.15-300x201.png 300w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.57.15-768x514.png 768w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.57.15-1536x1029.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-10.57.15-2048x1371.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The result:</p>



<figure class="wp-block-video"><video height="1044" style="aspect-ratio: 1392 / 1044;" width="1392" controls src="https://blog.xojo.com/wp-content/uploads/2025/06/Grabacion-de-pantalla-2025-06-17-a-las-10.57.58.mp4.mp4"></video></figure>



<p>You should definitely avoid going that crazy, this is just to show the possibilities. As Dr. Ian Malcolm said &#8230; <em>&#8220;Your scientists were so preoccupied with whether or not they could, they didn&#8217;t stop to think if they should.&#8221;</em></p>



<h2 class="wp-block-heading"><strong>WebContainer.Pressed</strong></h2>



<p>Speaking about pressing on things, WebContainer.Pressed event is now available, so you don&#8217;t need to place a WebLabel or a WebContainer on top just to capture that event anymore. The event comes with some coordinates, just in case you need them.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="686" src="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-11.05.54-1024x686.png" alt="" class="wp-image-14985" srcset="https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-11.05.54-1024x686.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-11.05.54-300x201.png 300w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-11.05.54-768x514.png 768w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-11.05.54-1536x1029.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/06/Captura-de-pantalla-2025-06-17-a-las-11.05.54-2048x1371.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The result:</p>



<figure class="wp-block-video"><video height="1044" style="aspect-ratio: 1392 / 1044;" width="1392" controls src="https://blog.xojo.com/wp-content/uploads/2025/06/Grabacion-de-pantalla-2025-06-17-a-las-11.05.36.mp4.mp4"></video></figure>



<h2 class="wp-block-heading"><strong>Other changes</strong></h2>



<p><strong>WebToolbar.Resized</strong></p>



<p>Trying to tweak your design for different screen sizes? If WebToolbar&#8217;s automated behavior is not enough, you can implement the new WebToolbar.Resized event and adapt the contents. This is useful when you are reusing the same WebToolbar subclass in multiple WebPages. You will be able to place this code in just one place.</p>



<p><strong>Exporting maps with WebMapViewer</strong></p>



<p>Same as with MobileMapViewer. You can now use WebMapViewer.ToPicture method to export the current map. Like WebChart.ToPicture, due to the asynchronous nature of Web projects, the picture will be available in the new WebMapViewer.RequestedPicture event.</p>



<p><strong>Updated DataTables</strong></p>



<p>Last, but not least, DataTables has been upgraded from v1.13.4 to v2.2.2.</p>



<h2 class="wp-block-heading"><strong>That&#8217;s (not) all!</strong></h2>



<p>As always, please make sure to check the <a href="https://documentation.xojo.com/versions/2025r2/resources/release_notes/2025r2.html">release notes</a> for a detailed list of new features and bug fixes. The Web framework is built on top of Xojo, new global features or bug fixes also applies to Web, including improvements to Console projects. Xojo Web is &#8220;just&#8221; a big Console project.</p>



<p>Thank you everyone for reporting, testing beta builds and giving us feedback.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/06/Grabacion-de-pantalla-2025-06-17-a-las-10.32.14.mp4.mp4" length="143729" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/06/Grabacion-de-pantalla-2025-06-17-a-las-10.41.58.mp4.mp4" length="212247" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/06/Grabacion-de-pantalla-2025-06-17-a-las-10.57.58.mp4.mp4" length="814128" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/06/Grabacion-de-pantalla-2025-06-17-a-las-11.05.36.mp4.mp4" length="321178" type="video/mp4" />

			</item>
		<item>
		<title>Building a Web Kanban Board GUI with Drag and Drop Support</title>
		<link>https://blog.xojo.com/2025/03/25/building-a-web-kanban-board-gui-with-drag-drop-support/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 15:32:34 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Drag and Drop]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14651</guid>

					<description><![CDATA[Imagine a sleek, interactive Kanban board right in your browser: Columns labeled &#8220;To Do,&#8221; &#8220;In Progress,&#8221; and &#8220;Done,&#8221; each populated with cards representing tasks. With&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Imagine a sleek, interactive Kanban board right in your browser: Columns labeled &#8220;To Do,&#8221; &#8220;In Progress,&#8221; and &#8220;Done,&#8221; each populated with cards representing tasks. With Xojo’s new drag and drop support for web projects, you can grab a card with your mouse, drag it to another column to update its status, or even reorder it within the same column to prioritize it.</p>



<h2 class="wp-block-heading"><strong>The End Result</strong></h2>



<figure class="wp-block-video aligncenter"><video height="1410" style="aspect-ratio: 1854 / 1410;" width="1854" controls src="https://blog.xojo.com/wp-content/uploads/2025/03/kanban-board-demo.mp4"></video><figcaption class="wp-element-caption">Kanban board demo</figcaption></figure>



<p>The latest drag and drop example has a functional GUI that looks professional and feels intuitive. All without writing a single line of JavaScript (we will enhance it a bit with some CSS, though).</p>



<p>Please note this is a sample project created to explore drag and drop, not a full featured Kanban board. I&#8217;ll omit on purpose things like persistence. The complete project can be found in the Examples section of the IDE, under <strong>Platforms > Web</strong>.</p>



<p>Let’s walk through how to make it happen.</p>



<h2 class="wp-block-heading"><strong>Creating the Required Components</strong></h2>



<p>First, we need to define the building blocks of our Kanban board. In Xojo, WebContainers are perfect for modularizing reusable UI elements. Here’s what we’ll create:</p>



<ul class="wp-block-list">
<li><strong>KanbanCard</strong><br>A WebContainer to represent each task card. It’ll have a simple label for the task name (e.g., &#8220;Write blog post&#8221;) and maybe a colored border or handle to indicate it’s draggable. Add a WebLabel for the text and set its properties in the Inspector to make it visually distinct.</li>



<li><strong>KanbanCardContainer</strong><br>Another WebContainer to act as a column. It’ll hold multiple KanbanCard Containers and serve as both a drag source (where cards come from) and a drop target (where cards land). Include a WebLabel at the top for the column title (e.g., &#8220;To Do&#8221;) and a rectangular area below it to house the cards.</li>



<li><strong>Main Page</strong><br>A WebPage to host everything. This is where we’ll arrange our columns side by side.</li>
</ul>



<p>In the Xojo IDE, drag a WebContainer onto your project for the Card, another for the Column, and set up three instances of the Column Container on the main WebPage (&#8220;To Do,&#8221; &#8220;In Progress,&#8221; &#8220;Done&#8221;).</p>



<h2 class="wp-block-heading"><strong>KanbanCard</strong></h2>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08-1024x807.png" alt="" class="wp-image-14653" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-15.50.08.png 1190w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">The KanbanCard custom control</figcaption></figure>
</div>


<p>This component will be pretty easy to build. It is basically a WebRectangle with a WebLabel that we will use for the Title. To make it easier to update, I&#8217;ve added a Title Computed Property that will update the TitleLabel if needed.</p>



<p>For the background WebRectangle, we will use the following ColorGroup. Please notice Xojo added support for Named colors, that will rely on the current Bootstrap theme, supporting Dark Mode:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17-1024x807.png" alt="" class="wp-image-14654" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-06-a-las-17.44.17.png 1190w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Adding a ColorGroup using a Bootstrap Named Color</figcaption></figure>
</div>


<p>As you can see, BackgroundRectangle and TitleLabel controls are implementing the Opening event. This is just to set the mouse cursor that will be shown when we hover:</p>



<pre class="wp-block-code xojo"><code>Me.Style.Cursor = WebStyle.Cursors.Move</code></pre>



<p>The container itself is also implementing the Opening event. This is to make this control draggable, using the following line of code:</p>



<pre class="wp-block-code xojo"><code>AllowTextDrag(WebDragItem.DragActionTypes.Move)</code></pre>



<p>Any descendant of the WebUIControl class is draggable. And yes, that includes custom controls created with the Web SDK.</p>



<p>For the WebDragItem.DragActionTypes Enumeration, you can choose one these options:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="324" height="386" src="https://blog.xojo.com/wp-content/uploads/2025/03/1-CopyAndLink.png" alt="" class="wp-image-14655" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/1-CopyAndLink.png 324w, https://blog.xojo.com/wp-content/uploads/2025/03/1-CopyAndLink-252x300.png 252w" sizes="auto, (max-width: 324px) 100vw, 324px" /><figcaption class="wp-element-caption">The WebDragItem.DragActionTypes Enumeration</figcaption></figure>
</div>


<p>In this case we will only be allowed to &#8220;Move&#8221; a card from one place to another.</p>



<p>There are cases where it makes sense to support multiple drag action types. In your operating system&#8217;s file browser, when you drag and drop files and folders, you can change between Move, Link or Copy by using Keyboard shortcut combinations. Depending on the drag action type, the element will be moved, a symbolic link will be created, or it will be copied, respectively.</p>



<p>Normally you will implement just Move or Copy, but keep in mind it&#8217;s possible to have more (at the cost of increasing the learning curve of your application for your users)</p>



<p>Allowing something to be dragged is the first of two steps. You also need a place to drop these items into.</p>



<h2 class="wp-block-heading"><strong>KanbanCardContainer</strong></h2>



<p>This container will be more elaborate, but should be easy to follow. Let&#8217;s see how it works at runtime, with some annotations:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="895" height="1024" src="https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel-895x1024.png" alt="" class="wp-image-14656" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel-895x1024.png 895w, https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel-262x300.png 262w, https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel-768x879.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/WebLabel.png 1071w" sizes="auto, (max-width: 895px) 100vw, 895px" /><figcaption class="wp-element-caption">Combined controls to create the KanbanCardContainer</figcaption></figure>
</div>


<p>The WebLabel we used for the Title and the WebButton used for adding new cards are positioned manually in the IDE designer. Same as the invisible WebRectangle holding the KanbanCard items and the KanbanAddCard custom button.</p>



<p>But instead of placing our cards manually, we&#8217;ll take advantage of the browser&#8217;s capacity for doing this job for us. We just want to add them dynamically at runtime and let the browser stack them vertically, automatically. We also want the browser to display a scrollbar if the columns have several cards.</p>



<p>Here is the code we will add to the WebRectangle:</p>



<pre class="wp-block-code"><code>// Let the framework know we want to let the
// browser place the items automatically
Me.LayoutType = LayoutTypes.Flex

// This style will ensure cards won't be
// placed horizontally by the browser
Me.Style.Value("flex-direction") = "wrap"

// If there are more cards than available
// space, this style will allow the user
// to scroll
Me.Style.Value("overflow") = "auto"</code></pre>



<p>Let&#8217;s add some methods to add and remove cards at runtime.</p>



<ul class="wp-block-list">
<li>AddCardWithTitle(title As String)</li>



<li>AddCardWithTitleAt(title As String, index As Integer)</li>



<li>RemoveCardAt</li>
</ul>



<h2 class="wp-block-heading"><strong>Moving Cards Between Columns</strong></h2>



<p>Here’s where Xojo’s drag and drop shines. Each Card Container needs to be draggable and each Column Container needs to accept dropped cards. In Xojo:</p>



<ol class="wp-block-list">
<li><strong>Make Cards Draggable</strong>: Open the KanbanListCard in the IDE and implement the Opening event. Enter this code:<br><code>AllowTextDrag(WebDragItem.DragActionTypes.Move)</code></li>



<li><strong>Accept Card Drops:</strong> Open the KanbanCardContainer and implement the Opening event. This is the code we need in order to accept drops:<br><code>AcceptTextDrop(WebDragItem.DragActionTypes.Move)</code></li>



<li><strong>Remove from Source</strong>: To move (not copy) the card, in the source Column’s DragEnd event, remove the dragged card from its original parent after a successful drop.</li>
</ol>



<p>With this, you can drag a card from &#8220;To Do&#8221; to &#8220;In Progress,&#8221; and it’ll visually jump columns. Xojo handles the heavy lifting. No JavaScript or DOM manipulation needed!</p>



<h2 class="wp-block-heading"><strong>The Hard Part: Reordering Cards</strong></h2>



<p>Reordering cards within a column, or dropping a card into another column in a specific position is trickier. You need to detect where the card lands among its siblings and adjust their positions. Xojo’s drag and drop doesn’t natively sort UI elements, so we’ll simulate it.</p>



<p>There are several ways to achieve this, let&#8217;s explore some options.</p>



<p>One would be to deal with X/Y coordinates. Once you drop a card, you could take a look to see where the card landed, compare the coordinates with the other cards and reorder them accordingly. In desktop and mobile projects this could be a valid solution. In web projects, dealing with specific coordinates might work, but there are more accurate and easier solutions.</p>



<p>The second way could be good enough in most cases. Cards could also accept drops so, if you drop one card on another, we just have to put the card being dropped in the position where it&#8217;s being dropped, and push down the rest of the stack. This way you won&#8217;t need to scratch your head and deal with screen coordinates or control dimensions. The end result will be based on this idea.</p>



<p>But what should we do to generate the gap between Cards? Maybe you can create a transparent Container that also accept Card drops, to simulate the gap between cards.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-1024x1024.png" alt="" class="wp-image-14657" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-1024x1024.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-300x300.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-150x150.png 150w, https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer-768x768.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/KanbanCardContainer.png 1158w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">One way of achieving sorting, that we are not using in the sample project</figcaption></figure>
</div>


<p>This would work for you, and I honestly recommend you to give it a try, it&#8217;s super easy to implement and it will just work. If you don&#8217;t want to explore the CSS rabbit hole, that&#8217;s fine, this can be your bus stop.</p>



<p>Two downsides:</p>



<ul class="wp-block-list">
<li>You won&#8217;t have animations</li>



<li>You will double the amount of controls on screen (performance may suffer)</li>
</ul>



<p>I went in another direction though. Using some CSS, you can add and modify margins on the fly, with neat transitions. In my sample project, the margin between cards is managed by the `margin-top` CSS style.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="274" height="444" src="https://blog.xojo.com/wp-content/uploads/2025/03/In-Progress.png" alt="" class="wp-image-14658" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/In-Progress.png 274w, https://blog.xojo.com/wp-content/uploads/2025/03/In-Progress-185x300.png 185w" sizes="auto, (max-width: 274px) 100vw, 274px" /><figcaption class="wp-element-caption">Top margin added to KanbanCardContainer, using CSS styles</figcaption></figure>
</div>


<p>And here is where the Xojo Framework helps. To make styling easier, it adds a CSS class to the element being dragged and also to the element where the mouse is over, when it&#8217;s accepting a drop.</p>



<p><code>dragging</code> &#8211; The HTML element being dragged will have this property<br><code>dragover</code> &#8211; The HTML element under the other element being dragged</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="815" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-1024x815.png" alt="" class="wp-image-14659" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-1024x815.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-300x239.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-768x611.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-1536x1223.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.15.44-2048x1630.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Some CSS Classes added by the Xojo Web Framework at runtime, to help styling Drag and Drop</figcaption></figure>
</div>


<p>In this case, the &#8220;Bar&#8221; card will receive the dragging CSS class, while &#8220;Test #2&#8221; will receive the dragover CSS class, while the &#8220;Bar&#8221; car is above.</p>



<p>I&#8217;ve added some transparency to elements with the dragging class. As you can see in the screenshot, the &#8220;Bar&#8221; Card opacity is set to 30%.</p>



<p>For dragover class, I&#8217;ve added some margin and transitions. If you drag something into a card, the top margin will grow, simulating it&#8217;s making room for the card you are about to drop.</p>



<p>Here is how the HTML Header section of the sample project looks like. It isn&#8217;t too much code, but it does uses some somewhat advanced CSS tricks:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-1024x807.png" alt="" class="wp-image-14660" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-1536x1211.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.29.14-2048x1614.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Custom CSS added to App &gt; HTML Header</figcaption></figure>
</div>


<p>This approach keeps cards neatly stacked and sortable. It’s the &#8220;hard part&#8221; not because you will have to write a lot of code, but because you&#8217;ll actually have to think a solution that won&#8217;t require roundtrips between the browser and the server. Xojo’s event system makes it manageable without JavaScript, and with some CSS, the result will be great.</p>



<h2 class="wp-block-heading"><strong>Some CSS Enhancements</strong></h2>



<p>In some cases I&#8217;m using shadows and border radius using the Bootstrap&#8217;s CSS classes.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-1024x807.png" alt="" class="wp-image-14661" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-1536x1211.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-09-a-las-18.44.21-2048x1614.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Bootstrap CSS Classes to make the card be rounded and have a subtle shadow</figcaption></figure>
</div>


<p>As you can see, I&#8217;m using rounded-2 for the border radius, and shadow-sm to easily add a shadow to the cards.</p>



<p>You can read more about this in the following blog post:<br><a href="https://blog.xojo.com/2024/10/01/introducing-named-color-and-css-classes-in-xojo-web/" data-type="post" data-id="13668">Introducing Named Color and CSS Classes in Xojo Web</a></p>



<p>There is a related sample project you might want to check:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="822" src="https://blog.xojo.com/wp-content/uploads/2025/03/Platform-1024x822.png" alt="" class="wp-image-14662" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Platform-1024x822.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Platform-300x241.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Platform-768x616.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Platform-1536x1233.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Platform.png 1762w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Xojo Web Examples</figcaption></figure>
</div>


<h2 class="wp-block-heading"><strong>Closing Thoughts</strong></h2>



<p>This has been a fun experiment to explore the Xojo Web drag and drop feature. Give the sample project a try and explore each control to see how it&#8217;s been created. I can&#8217;t recommend enough that you try to build it from scratch (and ask in the forum if you get stuck!)</p>



<p>We can&#8217;t wait to hear about how you plan to introduce drag and drop into your projects. Don&#8217;t be shy and create a forum thread to show what you have built, or what you are working on.</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/03/kanban-board-demo.mp4" length="710061" type="video/mp4" />

			</item>
		<item>
		<title>Xojo Web Evolves: What’s Here in 2025r1?</title>
		<link>https://blog.xojo.com/2025/03/25/xojo-web-evolves-whats-here-in-2025r1/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 15:31:35 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14678</guid>

					<description><![CDATA[What happens when Xojo Web adds drag and drop support, supercharges WebListBox, and packs in 40+ changes? Let’s find out! Drag and Drop Support The&#8230;]]></description>
										<content:encoded><![CDATA[
<p>What happens when Xojo Web adds drag and drop support, supercharges WebListBox, and packs in 40+ changes? Let’s find out!</p>



<h2 class="wp-block-heading"><strong>Drag and Drop Support</strong></h2>



<p>The biggest thing this time is that we&#8217;ve added general drag and drop support for web. From now on, any visual control can be dragged or accept drops.. That includes controls created using the Web SDK, allowing you (and third-party developers!) to increase the user experience on your web projects.</p>



<p>Now, imagine new ways of updating a Database application. For example, creating a &#8220;Form Builder&#8221;, a full &#8220;Website Builder&#8221; or even a &#8220;Database Schema&#8221; web application where the user can drag elements from a library and drop them into the editor. Are you scheduling posts on social networks using a WebDatePicker? What about using a calendar view with drag and drop support?</p>



<p>We&#8217;ve included a drag and drop Kanban board example. Take a look at <a href="https://blog.xojo.com/2025/03/25/building-a-web-kanban-board-gui-with-drag-drop-support/">the blog post</a> to learn more about it.</p>



<figure class="wp-block-video"><video height="1410" style="aspect-ratio: 1854 / 1410;" width="1854" controls src="https://blog.xojo.com/wp-content/uploads/2025/03/kanban-board-demo-1.mp4"></video></figure>



<p>How cool is that?</p>



<p>While drag and drop can make your app easier to work with for some users, it can also be an accessibility barrier for other users. Just remember to offer an alternative way for interacting with your application. In a full featured Kanban app, for example, the user should still be able to change the status of a task from the task details screen, using a regular WebPopupMenu (or any other accessible method)</p>



<h2 class="wp-block-heading"><strong>WebListBox Updates</strong></h2>



<p>Speaking of dragging things, WebListBox also now supports reordering rows using the mouse. Just enable the new Allow Row Reordering property (which is Off by default) and you are all set.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="676" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-1024x676.png" alt="" class="wp-image-14680" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-1024x676.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-300x198.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-768x507.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-1536x1014.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.49.42-2048x1352.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>This can also be set programmatically at runtime with AllowRowReordering. Once the user finishes a reorder, the RowsReordered event is called, allowing you to persist the changes in your database, for example.</p>



<figure class="wp-block-video"><video height="1034" style="aspect-ratio: 1320 / 1034;" width="1320" controls src="https://blog.xojo.com/wp-content/uploads/2025/03/Grabacion-de-pantalla-2025-03-13-a-las-12.06.45.mp4.mp4"></video></figure>



<p>Another requested feature was to allow users to perform inline edits. <a href="https://documentation.xojo.com/api/user_interface/web/weblistbox.html#">WebListBox</a> received some new methods and events to handle this:</p>



<ul class="wp-block-list">
<li><strong>ColumnTypeAt:</strong> To make a whole column editable</li>



<li><strong>CellTypeAt:</strong> To override the ColumnTypeAt on specific cells</li>



<li><strong>EditCellAt:</strong> A method you can use to begin the edit on specific cells</li>



<li><strong>CellAction Event:</strong> Allowing you to persist the changes made by the user</li>
</ul>



<p>This is also supported when using a WebDataSource.</p>



<p>And not only are TextField and TextArea supported, CheckBox is also part of the WebListBox.CellTypes enumeration, to match what DesktopListBox supports:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="794" src="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16-1024x794.png" alt="" class="wp-image-14682" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16-1024x794.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16-300x233.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16-768x596.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/Captura-de-pantalla-2025-03-13-a-las-11.52.16.png 1318w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Last, but not least, we&#8217;ve decided to split CellTextAt into two different methods. Until now, you could get and set the caption of a cell using CellTextAt, but also a WebListBoxCellRenderer. This could cause trouble because a Variant was being returned, that could be either a String or a WebListBoxCellRenderer so, when not being used carefully, it could raise IllegalCastException at runtime.</p>



<p>From now on, CellTextAt will only support String. If you want to get or set a cell renderer, you will have to use CellRendererAt instead. This makes the API more obvious.</p>



<p>If you were using CellTextAt for getting and setting cell renderers, you will need to update your code to use CellRendererAt instead.</p>



<h2 class="wp-block-heading"><strong>Wrapping Up</strong></h2>



<p>This release empowers Xojo Web projects to meet more user needs, no JavaScript required. Drag and drop finally joins the party, filling a critical gap from the old Web 1 framework.</p>



<p>Be sure to dig into the <a href="https://documentation.xojo.com/resources/release_notes/2025r1.html#">release notes</a>, as 2025r1 packs over 40 changes for the web target alone.</p>



<p>I’d love to hear how you’re weaving these updates into your projects! Drop some screenshots or screen recordings in a new forum thread or shoot me a private message if you prefer.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/03/kanban-board-demo-1.mp4" length="710061" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/03/Grabacion-de-pantalla-2025-03-13-a-las-12.06.45.mp4.mp4" length="378839" type="video/mp4" />

			</item>
		<item>
		<title>A Complete Dockerfile for Web Apps</title>
		<link>https://blog.xojo.com/2025/03/19/a-complete-dockerfile-for-web-apps/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Wed, 19 Mar 2025 15:19:48 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14708</guid>

					<description><![CDATA[For a comprehensive guide on deploying Xojo web apps to any server, please refer to the video tutorial available at: https://youtu.be/ARr7d6Z6CRY I also recommend reading&#8230;]]></description>
										<content:encoded><![CDATA[
<p>For a comprehensive guide on deploying Xojo web apps to any server, please refer to the video tutorial available at: <a href="https://youtu.be/ARr7d6Z6CRY" target="_blank" rel="noreferrer noopener">https://youtu.be/ARr7d6Z6CRY</a></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Complete Guide to Dockerize &amp; Deploy your Web Apps" width="500" height="281" src="https://www.youtube.com/embed/ARr7d6Z6CRY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<ul class="wp-block-list">
<li>The Dockerfile below should be placed in the same directory as your Xojo project</li>



<li>Remember to modify the&nbsp;<code>WEBAPP_NAME</code>&nbsp;variable on line 33 to match the name of your project</li>



<li>Feel free to customize this Dockerfile to suit your specific needs. We encourage you to share your modifications and experiences in the Xojo <a href="https://forum.xojo.com/" data-type="link" data-id="https://forum.xojo.com/" target="_blank" rel="noreferrer noopener">forum</a></li>
</ul>



<pre class="wp-block-code"><code># Step-by-Step Instructions for Building, Saving, and Running the Image:
# 1. Build the Docker image:
#    "docker build -t hellodocker-image ."
#    This creates a Docker image named "hellodocker-image" based on this Dockerfile.
#
# 2. Save the Docker image to a tar file:
#    "docker save -o hellodocker-image.tar hellodocker-image"
#    This saves the "hellodocker-image" to a file named "hellodocker-image.tar".
#    You can use this file to transfer the image to another server.
#
# 3. Upload the .tar file to the remote server.
#    After transferring the tar file, follow these steps on the remote server:
#
#    3.1 Load the Docker image:
#        "docker load -i hellodocker-image.tar"
#        This imports the image into the Docker environment on the server.
#
#    3.2 Run a container from the image:
#        "docker run -d --name hellodocker-container --restart always -p 7000:80 hellodocker-image"
#        This creates and starts a container named "hellodocker-container" that:
#        - Restarts automatically if it stops (via `--restart always`).
#        - Maps port 80 inside the container to port 7000 on the host machine.
#
#    3.3 Verify the web app is running:
#        Open a web browser and navigate to http://server-ip:7000
#        Replace "server-ip" with the IP address of your remote server.
#
# Complete video guide at: https://youtu.be/ARr7d6Z6CRY

# Use Ubuntu 22.04 as the base image for the container.
FROM ubuntu:22.04

# Define the name of the Xojo web app executable.
# This should match the exact name of your compiled Xojo web app (case-sensitive).
ENV WEBAPP_NAME=HelloDocker

# Prevent interactive prompts during the installation of dependencies.
ENV DEBIAN_FRONTEND=noninteractive

# Install required system libraries for the Xojo web app to run, and purge unnecessary software (PHP, Python, Apache)
RUN apt-get update &amp;&amp; apt-get install -y --no-install-recommends \
    curl \
    ca-certificates \
    libunwind8 \
    libsoup2.4 \
    libpango-1.0 \
    libicu70 \
    libglib2.0 \
    libgtk-3-0 \
    &amp;&amp; apt-get purge -y php* python3* apache2* libapache2-mod-php* \
    &amp;&amp; apt-get autoremove -y \
    &amp;&amp; apt-get clean \
    &amp;&amp; rm -rf /var/lib/apt/lists/*

RUN useradd --create-home ${WEBAPP_NAME}

# Set the working directory inside the container.
# This is where the web app files will be located.
WORKDIR /${WEBAPP_NAME}

# Copy the built Xojo web app from the build context into the container.
# Remember, this Dockerfile must be placed in the same folder as the Xojo project.
COPY &#91;"Builds - ${WEBAPP_NAME}/Linux 64 bit/${WEBAPP_NAME}", "."]

# Change ownership of the application files to the non-root user
RUN chown -R ${WEBAPP_NAME}:${WEBAPP_NAME} /${WEBAPP_NAME}

# Ensure the main web app executable has permission to run
RUN chmod +x ${WEBAPP_NAME}

# Create a directory for persistent data storage.
# Ensure the data directory is owned by the non-root user.
RUN mkdir -p /home/${WEBAPP_NAME}/data &amp;&amp; chown -R ${WEBAPP_NAME}:${WEBAPP_NAME} /home/${WEBAPP_NAME}/data

# Define the volume for the container to store data.
# The contents of "/home/${WEBAPP_NAME}/data" will persist outside the container.
VOLUME /home/${WEBAPP_NAME}/data

# Switch to the non-root user for security purposes.
# All subsequent instructions (including CMD) will run as this user.
USER ${WEBAPP_NAME}

# Expose port 80 inside the container.
# This allows the web app to listen on port 80, which will be mapped to port 7000
# on the host machine when the container is run.
EXPOSE 80

# Start the Xojo web app when the container runs.
# The app will listen on port 80 inside the container.
CMD &#91;"sh", "-c", "./${WEBAPP_NAME} --port=80"]</code></pre>



<p>I also recommend reading this article for additional details on Xojo and Docker: <a href="https://blog.xojo.com/2021/05/17/running-xojo-web-applications-in-docker/" target="_blank" rel="noreferrer noopener">https://blog.xojo.com/2021/05/17/running-xojo-web-applications-in-docker/</a></p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Year of Code 2025: March Project, Web Apps</title>
		<link>https://blog.xojo.com/2025/03/05/year-of-code-2025-march-project-web-apps/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Wed, 05 Mar 2025 15:04:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Year of Code]]></category>
		<category><![CDATA[#YearofCode]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14588</guid>

					<description><![CDATA[March’s topic is Web Apps and I’m excited to introduce my project: Quiziverse, a complete quiz and trivia web application. Quiziverse is designed to engage&#8230;]]></description>
										<content:encoded><![CDATA[
<p>March’s topic is Web Apps and I’m excited to introduce my project: Quiziverse, a complete quiz and trivia web application.</p>



<p>Quiziverse is designed to engage users with time-limited questions across various categories, making it a fun and interactive way to test knowledge. The application leverages a SQLite database as the backend for all data storage.</p>



<p>Here are some of the key features of Quiziverse:</p>



<ul class="wp-block-list">
<li><strong>Admin Area:</strong> The app includes a secure admin area, allowing administrators to manage categories and questions easily. Admins can add, edit, or delete questions and categories to keep the trivia fresh and exciting.</li>



<li><strong>Scoreboard:</strong> A dynamic scoreboard keeps track of player scores in real-time, fostering a competitive spirit among users. Players can see how they stack up against others, adding an element of fun to the experience.</li>



<li><strong>Time-Limited Questions:</strong> Each question comes with a timer, challenging players to think quickly and answer before time runs out. This feature adds to the intensity of the game and keeps players on their toes.</li>



<li><strong>Import JSON Files:</strong> To make it easy for admins to add new content, Quiziverse includes a function to import JSON files containing new categories and questions. This feature simplifies content management and allows for quick updates.</li>



<li><strong>Mobile Optimized Design:</strong> Understanding the importance of accessibility, Quiziverse is designed to be mobile-friendly. Players can join the trivia challenge from their smartphones or tablets for a seamless experience.</li>
</ul>



<p>Here’s a sneak peek of the Quiziverse interface:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="487" src="https://blog.xojo.com/wp-content/uploads/2025/03/image-1-1024x487.png" alt="Quiziverse Start Page" class="wp-image-14593" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/image-1-1024x487.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/image-1-300x143.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/image-1-768x365.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/image-1-1536x731.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/image-1.png 1583w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="479" src="https://blog.xojo.com/wp-content/uploads/2025/03/image-1024x479.png" alt="Quiziverse Trivia Page" class="wp-image-14592" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/image-1024x479.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/image-300x140.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/image-768x359.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/image-1536x719.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/image.png 1599w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="485" src="https://blog.xojo.com/wp-content/uploads/2025/03/image-2-1024x485.png" alt="Quiziverse Admin General Settings" class="wp-image-14594" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/image-2-1024x485.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/image-2-300x142.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/image-2-768x364.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/image-2-1536x727.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/image-2.png 1588w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="483" src="https://blog.xojo.com/wp-content/uploads/2025/03/image-3-1024x483.png" alt="Quiziverse Admin Categories" class="wp-image-14595" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/image-3-1024x483.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/image-3-300x141.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/image-3-768x362.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/image-3-1536x724.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/image-3.png 1580w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="483" src="https://blog.xojo.com/wp-content/uploads/2025/03/image-4-1024x483.png" alt="Quiziverse Admin Questions" class="wp-image-14596" srcset="https://blog.xojo.com/wp-content/uploads/2025/03/image-4-1024x483.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/03/image-4-300x141.png 300w, https://blog.xojo.com/wp-content/uploads/2025/03/image-4-768x362.png 768w, https://blog.xojo.com/wp-content/uploads/2025/03/image-4-1536x724.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/03/image-4.png 1584w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>You can find the complete source code for <a href="https://github.com/xolabsro/Quiziverse" data-type="link" data-id="https://github.com/xolabsro/Quiziverse" target="_blank" rel="noreferrer noopener">Quiziverse on GitHub</a>, along with detailed documentation to help you get started.</p>



<p>Stay tuned for more exciting projects as we continue our Year of Code 2025 journey!</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>Year of Code Project</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2025/01/09/year-of-code-2025-kickoff/">Year of Code: Kickoff</a></li>



<li><a href="https://blog.xojo.com/2025/01/15/year-of-code-2025-january-project/" target="_blank" rel="noreferrer noopener">January Project: Desktop Apps</a>&nbsp;|&nbsp;<a href="https://forum.xojo.com/t/year-of-code-2025-january-project-sharing/83927" target="_blank" rel="noreferrer noopener">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/02/11/year-of-code-2025-february-project/">February Project: Database Apps</a>&nbsp;|&nbsp;<a href="https://forum.xojo.com/t/2025-year-of-code-february" target="_blank" rel="noreferrer noopener">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/03/05/year-of-code-2025-march-project-web-apps/">March Project: Web Apps</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-march/84474?u=alyssa_foley">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/04/08/year-of-code-2025-april-project-user-interface/">April Project: User Interface</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-april-user-interface/84926">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/05/07/year-of-code-2025-may-project-mobile-apps/">May Project: Mobile Apps</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-may-is-mobile/85272">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/06/10/year-of-code-2025-june-project-cross-platform-code-class/">June Project: Code Sharing</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-june-is-code-sharing/85612">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/07/10/year-of-code-2025-july-project-charting/">July Project: Charting</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-july-is-charting/85896">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/08/07/year-of-code-2025-august-project-console-apps/">August Project: Console Apps</a> | <a href="https://forum.xojo.com/t/august-2025-year-of-code-console-apps/86203">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/09/08/year-of-code-2025-september-project-games/">September Project: Games</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-septgamer">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/10/13/year-of-code-2025-october-project-multi-platform-communication/">October Project: Multi-Platform</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-october-multi-platform-communication/86717">Forum Discussion</a></li>



<li><a href="https://blog.xojo.com/2025/11/10/year-of-code-2025-november-project-pdf-postcard-generator/">November Project: PDF</a> | <a href="https://forum.xojo.com/t/2025-year-of-code-november-pdf/86969">Forum Discussion</a></li>
</ul>



<p><strong>How to Play:</strong></p>



<p>Each month we&#8217;ll announce a new theme and share an example project of our own. Share your projects to the Xojo Forum thread for that month via GitHub (all the links you need are posted above ↑ ). Learn how to use <a href="https://blog.xojo.com/2024/04/02/using-xojo-and-github/">Xojo and GitHub</a>.</p>



<p><strong>The Prizes:</strong></p>



<p>Monthly winners get $100 at the Xojo store. Every month you submit a project is another chance to win the grand prize. The grand prize is $250 cash plus a Xojo Pro license and a year of GraffitiSuite and will be announce in December. Learn more about the <a href="https://blog.xojo.com/2025/01/09/year-of-code-2025-kickoff/#prizes">prizes</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Web Improvements in 2024r4</title>
		<link>https://blog.xojo.com/2024/12/10/xojo-web-improvements-in-2024r4/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 10 Dec 2024 16:36:35 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2024r4]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14138</guid>

					<description><![CDATA[Making the Web Framework more robust is something we&#8217;ve been working on for years. This release doesn&#8217;t brings too many shiny new toys to play&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Making the Web Framework more robust is something we&#8217;ve been working on for years. This release doesn&#8217;t brings too many shiny new toys to play with, it comes with bug fixes instead that were tricky to fix. Here are some highlights.</p>



<h2 class="wp-block-heading"><strong>Using a WebPopupMenu with a Keyboard</strong></h2>



<p>2024r4 comes with keyboard full support for <a href="https://documentation.xojo.com/api/user_interface/web/webpopupmenu.html#webpopupmenu">WebPopupMenu</a>. We&#8217;ve been gradually improving this control to allow your users to select a field using the arrow keys, for example. What&#8217;s new is being able to go directly to one of the item just by starting to type its name.</p>



<figure class="wp-block-video"><video height="1250" style="aspect-ratio: 1376 / 1250;" width="1376" controls src="https://blog.xojo.com/wp-content/uploads/2024/12/WebPopupMenu-with-keyboard.mp4"></video></figure>



<h2 class="wp-block-heading"><strong>Memory Usage Improvements</strong></h2>



<p>Everyone does their best to avoid leaking memory but, sometimes, that&#8217;s just not enough.</p>



<p><a href="https://blog.xojo.com/2022/12/06/the-versatility-of-xojo/">Jérémie Leroy</a> is known for the success of the mobile apps he makes with Xojo. When one of these successful app requires a Web Service, receiving 1000s of requests, it needs to be as lightweight as possible.</p>



<p>Thanks to his reports, the visual controls will be creating Tooltip and WebCSSClasses instances only when being used. For many projects this won&#8217;t make a difference, but having a Web project with hundreds of concurrent users will surely lead to less memory pressure, allowing to run Web apps in cheaper servers.</p>



<p>This task never ends. Upcoming releases will continue improving memory usage and performance.</p>



<h2 class="wp-block-heading"><strong>WebMapViewer</strong></h2>



<p>The library we use to display maps, MapLibre, has been upgraded from 3.2.0 to 4.7.1, which will make much easier to implement some of the features we want to introduce in upcoming releases. Stay tuned!</p>



<p>This control also received 4 additional bug fixes. One of them was causing the Zoom to be modified, when updating another control property, for example.</p>



<h2 class="wp-block-heading"><strong>Some New Features</strong></h2>



<p>While Web received mostly bug fixes this time, it also comes with some hidden gems.</p>



<p>Popover position can be adjusted now when displaying it. The positioning is relative to its parent control. Additionally, you can now use a WebPage as the parent control, instead of one of the page children, to place your Popover exactly where you need.</p>



<p>Last, but not least, my favorite new feature. We&#8217;ve added CallLater method to WebTimer. It works exactly the same as Timer.CallLater, but it&#8217;s Session aware. This means you will be able to access the Session from its callback, without having to do anything special.</p>



<h2 class="wp-block-heading"><strong>Wrapping Up</strong></h2>



<p>We are saying goodbye to a 2024 packed with improvements for the Web target, with a release dedicated (more than usual) to bug fixing and to make everything more stable. Make sure to check <a href="https://documentation.xojo.com/resources/release_notes/2024r4.html" data-type="link" data-id="https://documentation.xojo.com/resources/release_notes/2024r4.html">Xojo 2024r4 Release Notes</a>, so you don&#8217;t miss anything.</p>



<p>Thanks to everyone reporting bugs, making feature requests and collaborating in the forum!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/12/WebPopupMenu-with-keyboard.mp4" length="330684" type="video/mp4" />

			</item>
		<item>
		<title>Xojo Web Rescues a .NET Project</title>
		<link>https://blog.xojo.com/2024/10/23/xojo-web-rescues-a-net-project/</link>
		
		<dc:creator><![CDATA[Wayne Golding]]></dc:creator>
		<pubDate>Wed, 23 Oct 2024 16:40:14 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Encryption]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[URLConnection]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13909</guid>

					<description><![CDATA[I had a call recently from a customer whose upstream supplier informed them that they would not be accepting anything less than TLS 1.2 encryption.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>I had a call recently from a customer whose upstream supplier informed them that they would not be accepting anything less than TLS 1.2 encryption. The customer’s application is written using .NET 1.1 (they are testing a new version but aren’t ready to deploy to production just yet). Their supplier insisted on a 1-week time limit. Can I help?</p>



<p>My answer was, of course, “Let me have a look and get back to you.”</p>



<p>I went to my favourite dev tool, Xojo, and went through the process of developing a solution.&nbsp;The connection is a REST API, so I’ll start with a web project and use the HandleURL event. And I’ll use a URLConnection to pass on the request.&nbsp; Wait … could it be that simple?</p>



<pre class="wp-block-code"><code>Function HandleURL(request As WebRequest, response As WebResponse) Handles HandleURL as Boolean

  // Create the outbound connection
  Var connector As New URLConnection
 
  // Copy the content of the request
  connector.SetRequestContent(request.Body, request.MIMEType)

  // Send the request
  Var result As String
  Try
    result = connector.SendSync("POST", kAddress + request.Path)
  Catch err As RuntimeException
    // Catch DNS, Certificate &amp; Timeout errors
    response.Status = 500
    response.Write(err.Message)
    Return True
  End

  // Return the result of the request
  response.Status = connector.HTTPStatusCode
  response.Write(result)

  Return True

End Function</code></pre>



<p>The answer is, &#8220;Yes!&#8221;&nbsp; This is all the code in the entire project.</p>



<p>You will notice that there is no security, but in this instance that is fine as the virtual machine is running this is on the same network as the client server and the firewall is configured to only allow connections from that server.</p>



<p>After processing over 60 thousand requests, memory use is 7.3MB and never exceeded 13MB.&nbsp;CPU usage was at the maximum 1.5%.</p>



<p>Even after using Xojo for 20 years this still blows my mind.</p>



<p><em>Wayne Golding has been a Xojo developer since 2005 and is a Xojo MVP. He operates the IT Company <a href="http://www.axisdirect.nz">Axis Direct Ltd </a>which primarily develops applications using Xojo that integrate with Xero www.xero.com. Wayne’s hobby is robotics where he uses Xojo to build applications for his Raspberry Pi, often implementing IoT for remote control.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing Named Color and CSS Classes in Xojo Web</title>
		<link>https://blog.xojo.com/2024/10/01/introducing-named-color-and-css-classes-in-xojo-web/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 15:32:13 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2024r3]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13668</guid>

					<description><![CDATA[The latest Xojo release is a big leap forward in terms of design options for Xojo Web users. Xojo 2024r3 comes with new tools for&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The latest Xojo release is a big leap forward in terms of design options for Xojo Web users. Xojo 2024r3 comes with new tools for making beautiful web applications with less effort.</p>



<h2 class="wp-block-heading">A Quick Reminder About What Bootstrap Is</h2>



<p>As I will be mentioning it during this post, let me take a moment to remind readers what Bootstrap is, and what are we using it for at Xojo.</p>



<p>Bootstrap is the library we use for the visual part of web applications made with Xojo. You can think about it as Gtk on Linux, or UIKit on iOS.</p>



<p>While there is a vast amount of alternative libraries, it&#8217;s been probably the most popular framework for the last decade. You can check the <a href="https://getbootstrap.com" data-type="link" data-id="https://getbootstrap.com" target="_blank" rel="noreferrer noopener nofollow">Bootstrap website</a> for more information.</p>



<h2 class="wp-block-heading">ColorGroup Named Colors</h2>



<p>Until this release, the Named option when configuring a ColorGroup was not available on web projects. 2024r3 brings the ability to choose from the Web Basic colors, Web Extended colors and, what I find more interesting, Bootstrap colors, which also support dark mode out of the box.</p>



<figure class="wp-block-video"><video height="908" style="aspect-ratio: 1448 / 908;" width="1448" controls src="https://blog.xojo.com/wp-content/uploads/2024/09/named-colors-from-the-ide.mp4"></video></figure>



<p>As you can expect, if you drop a custom Bootstrap 5.3 theme with another set of colors, the IDE will automatically update in order to preview them.</p>



<figure class="wp-block-video"><video height="908" style="aspect-ratio: 1436 / 908;" width="1436" controls src="https://blog.xojo.com/wp-content/uploads/2024/09/named-colors-bootstrap-theme-support.mp4"></video></figure>



<h2 class="wp-block-heading">Using Named Colors by Code</h2>



<p>When a dynamic need arises, it is also possible to use Bootstrap Named colors programmatically, if you find it easier. Here is an example:</p>



<pre class="wp-block-code"><code>Var colorName As String

If paymentCardIsValid Then
  colorName = "success"
Else
  colorName = "danger"
End If

Rectangle1.BackgroundColor = ColorGroup.NamedColor(colorName)</code></pre>



<p>Or in a <code>WebCanvas.Paint</code> event:</p>



<pre class="wp-block-code"><code>Var colorName As String = If(paymentCardIsValid, "success", "danger")
g.DrawingColor = ColorGroup.NamedColor(colorName)
g.FillRectangle(0, 0, g.Width, g.Height)</code></pre>



<p>You can check the list of available colors in the <a href="https://getbootstrap.com/docs/5.3/customize/color/" data-type="link" data-id="https://getbootstrap.com/docs/5.3/customize/color/" target="_blank" rel="noreferrer noopener nofollow">Color section of the official Bootstrap documentation</a>. Basic and Extended Web Colors will work as well.</p>



<h2 class="wp-block-heading">Using Bootstrap CSS Classes</h2>



<p>Bootstrap comes with a set of utility CSS classes for a variety of visual things. You probably won&#8217;t need them all, as the Xojo IDE will get you there in most of the cases, and we work hard improving the IDE to make it easier, release by release.</p>



<p>That said, if you are an advanced user, and you have previous experience working with Bootstrap, you may find it useful to add CSS classes directly from the Inspector.</p>



<p>Go to the Advanced tab, add some Bootstrap CSS classes, separated by spaces&#8230; and voilà!</p>



<p>Here is a demo:</p>



<figure class="wp-block-video"><video height="910" style="aspect-ratio: 1652 / 910;" width="1652" controls src="https://blog.xojo.com/wp-content/uploads/2024/09/css-classes-demo.mp4"></video></figure>



<p>We have included a new example, called &#8220;Applying Bootstrap CSS classes to controls&#8221;, that you can find under Platforms &gt; Web. Please give it a try.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="807" src="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-18-a-las-10.56.29-1024x807.png" alt="" class="wp-image-13672" srcset="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-18-a-las-10.56.29-1024x807.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-18-a-las-10.56.29-300x236.png 300w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-18-a-las-10.56.29-768x605.png 768w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-18-a-las-10.56.29.png 1267w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>CSS Classes are not limited to Bootstrap, if you have added styles in the HTML Header section, you can use them as well.</p>



<p>You can also add and remove them using the new <code>CSSClasses</code> property, which is available in every WebUIControl subclass.</p>



<h2 class="wp-block-heading">WebRectangle Got Some Love</h2>



<p>You won&#8217;t need to setup the border color, border thickness or the corner size, for WebRectangle, in the Opening event anymore.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="702" height="853" src="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-18-a-las-11.02.31.png" alt="" class="wp-image-13673" srcset="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-18-a-las-11.02.31.png 702w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-18-a-las-11.02.31-247x300.png 247w" sizes="auto, (max-width: 702px) 100vw, 702px" /><figcaption class="wp-element-caption">Xojo 2024r2.1 on the left, Xojo 2024r3 on the right</figcaption></figure>
</div>


<p>When designing web applications, I found myself using a lot of WebRectangle controls and, by default, they have a rounded border.</p>



<p>The side-effect is subtle, but now that you can control the border radius directly from the Inspector, the IDE preview will be closer to how it will look in the browser. And you are going to avoid writing a few lines of code!</p>



<p>In addition, some Bootstrap themes define a different Corner Size. Setting this property to &#8220;-1&#8221; will honor that Bootstrap theme&#8217;s default border radius.</p>



<h2 class="wp-block-heading"><strong>Conclusion</strong></h2>



<p>As always, the release comes with much more than I can tell you about in one blog post. With over 30 Bug fixes and 9 Feature Requests implemented in the Web target alone, make sure to take a look at the <a href="https://documentation.xojo.com/resources/release_notes/2024r3.html" data-type="link" data-id="https://documentation.xojo.com/resources/release_notes/2024r3.html" target="_blank" rel="noreferrer noopener">Xojo 2024r3 Release Notes</a> to see the whole picture.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/09/named-colors-from-the-ide.mp4" length="837283" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/09/named-colors-bootstrap-theme-support.mp4" length="429757" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/09/css-classes-demo.mp4" length="721074" type="video/mp4" />

			</item>
		<item>
		<title>Cosmic Trader: A Game Built with Xojo Web</title>
		<link>https://blog.xojo.com/2024/09/17/cosmic-trader-a-game-built-with-xojo-web/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 17 Sep 2024 20:09:12 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[Container]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[WebListBox]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13618</guid>

					<description><![CDATA[I truly enjoy creating things with Xojo. This time, I built a little game with Xojo Web just to see if it was possible. In&#8230;]]></description>
										<content:encoded><![CDATA[
<p>I truly enjoy creating things with Xojo. This time, I built a little game with Xojo Web just to see if it was possible. In this post, I will talk about what I liked and what I had difficulties with while programming it.</p>



<p>The reason to create this kind of project, as the maintainer of the Xojo Web framework, is to find pain points and bugs in larger projects, as the issue reports I normally work with are very specific sample projects demonstrating a bug. The next Xojo release, 2024r3, will come with some bug fixes I found while building Cosmic Trader.</p>



<h2 class="wp-block-heading">Final Result</h2>



<p>Let&#8217;s begin at the end. Give the game a try and then come back to this blog post. It&#8217;s a very simple space trading game, don&#8217;t expect too much from it, but I hope you enjoy it.</p>



<p>It can be played from the following URL:<br><a href="https://cosmictrader.rcruz.es" target="_blank" rel="noreferrer noopener nofollow">https://cosmictrader.rcruz.es</a></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="625" src="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.16-1024x625.png" alt="" class="wp-image-13619" srcset="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.16-1024x625.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.16-300x183.png 300w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.16-768x469.png 768w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.16.png 1252w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="625" src="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.32-1024x625.png" alt="" class="wp-image-13620" srcset="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.32-1024x625.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.32-300x183.png 300w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.32-768x469.png 768w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-8.53.32.png 1252w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">The Challenge</h2>



<p>Create a simple game using Xojo Web, without writing a line of JavaScript, or even using the Web SDK.</p>



<p>In addition, while all this could be just a couple of WebListBox and WebButton controls, I really wanted this game to look like an actual game. As you can see in the screenshots, unless you check the code, nobody will notice (or care!) it&#8217;s a Xojo Web application.</p>



<p>As you can imagine, Xojo Web was not created with the idea of building web based games. In order to make it easier for the developer, everything is processed server side: When you press a button, the browser will send a notification to the server, your code written in Xojo will be executed and, finally, the response will be sent back to the browser.</p>



<p>That&#8217;s the known knowns. I knew the latency would be a problem, but I&#8217;ve found more.</p>



<h2 class="wp-block-heading">What I&#8217;ve Enjoyed</h2>



<p>Implementing the first prototype was really easy using the tools Xojo Web offers. For example, in the prototype, instead of the custom popover I ended up building for buying and selling, I just used some contextual menus:</p>



<figure class="wp-block-video"><video height="732" style="aspect-ratio: 1072 / 732;" width="1072" controls src="https://blog.xojo.com/wp-content/uploads/2024/09/cosmic-trader-early-prototype.mp4"></video></figure>



<p>You can go very far and prototype your idea very quickly this way. This helped me to deploy and share the game with a few friends and gather some initial feedback.</p>



<p>Once you have the game mechanics, you can iterate as much as you want until the game is ready. The welcome screen with the game logo wasn&#8217;t added until very late. Just so you can compare, this is how the current version looks:</p>



<figure class="wp-block-video"><video height="598" style="aspect-ratio: 946 / 598;" width="946" controls src="https://blog.xojo.com/wp-content/uploads/2024/09/cosmic-trader-current-version.mp4"></video></figure>



<p>Much better! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>I&#8217;ve really enjoyed being able to use Containers for building custom controls and reusing them. Also, being able to just drop some images into the IDE and assign them to image viewers is very pleasant.</p>



<p>From the IDE preview, it&#8217;s deadly easy to identify where my ship entity is, click on it, then edit the code if needed:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="720" src="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-9.32.10-1024x720.png" alt="" class="wp-image-13624" srcset="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-9.32.10-1024x720.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-9.32.10-300x211.png 300w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-9.32.10-768x540.png 768w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-9.32.10-1536x1080.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-9.32.10-2048x1440.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Navigating through the project is a joy compared to jumping through piles of code in plain text files.</p>



<p>I&#8217;ve also found having Control Sets useful, allowing me to implement the Pressed event just once for all the planets, for example.</p>



<h2 class="wp-block-heading">Roadblocks and How I Handled Them</h2>



<p>That said, I found some difficulties. All of them were due the nature of web projects. When you travel from one planet to another, you will hear an engine sound. It would be much (much!) easier to know when I should stop the sound in a Desktop or a Mobile project.</p>



<p>Having to deal with latency means I had to use a timer and guess more or less how many milliseconds is reasonable before stopping the sound. Using the same amount of time as the animation would cause the sound to continue playing after the ship had arrived at its destination, again due the latency.</p>



<p>Where I spent most of the time was optimizing the images. Specifically, delivering the images. When you play the game locally, everything works pretty fast. I found this flickering issue once I deployed the game for the first time using the custom popovers:</p>



<figure class="wp-block-video"><video height="670" style="aspect-ratio: 1276 / 670;" width="1276" controls src="https://blog.xojo.com/wp-content/uploads/2024/09/cosmic-trader-flickering-issue.mp4"></video></figure>



<p>This is something that you just don&#8217;t need to think about with the typical database application you normally build with Xojo Web. But if you build a lot of images on the fly, it will mean the browser will have to download them again and again.</p>



<p>In order to optimize it, instead of using a WebImageViewer.Image property, you could store WebImage instances. Using WebImageViewer.URL pointing to the WebImage.URL property of those instances will make the browser first check if it has downloaded that URL before. If so, bingo! It will reuse the image without having to re-download it again.</p>



<p>If you go back to the game, cache is the reason behind the &#8220;New Game&#8221; button, from the welcome screen, and the &#8220;Sell Everything&#8221; button having the same width. It wasn&#8217;t a coincidence, that means a browser cache hit.</p>



<p>Last but not least, when I shared the URL with some friends, they told me it didn&#8217;t look great on mobile. So I had to change the stats a bit so they fit in a mobile screen. While in this case it wasn&#8217;t a big deal, at Xojo we know making responsive web applications must be easier, and we will improve the workflow in future releases.</p>



<p>It would be much easier to use the Web SDK for some of those controls. If I was creating a game seriously, I&#8217;d 100% personally prefer creating some custom controls to allow some code to run on the browser side, using the Web SDK with JavaScript or TypeScript, to avoid dealing with latency or round-trips.</p>



<h2 class="wp-block-heading">Using AI for Creativity</h2>



<p>I personally don&#8217;t find any joy using AI for coding. I always end up frustrated by how it hallucinates and keep proposing, very confidently, things that just don&#8217;t exist. I understand some might like it but, in the end, I just like coding.</p>



<p>But for a second brain and helping me with (my lack of) creativity&#8230; oh boy, that&#8217;s another story. The game idea came from a conversation with Claude AI. Initially, it came up with tons of features and ideas that would require me (and a team of another 100 people) to work on it for several years. I kept asking it to simplify it until I felt it was approachable:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="415" src="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-10.19.09-1024x415.png" alt="" class="wp-image-13625" srcset="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-10.19.09-1024x415.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-10.19.09-300x121.png 300w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-10.19.09-768x311.png 768w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-10.19.09-1536x622.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-09-16-a-las-10.19.09.png 1768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>After implementing the game mechanics, I felt the game didn&#8217;t make any sense. I mean, why 30 turns exactly? Why 5 planets? Why can&#8217;t I go somewhere else to trade? Why do I have to trade at all?&#8230; While it is still fiction, the AI wrote a reasonable background story that added some depth to the game. That&#8217;s what you will be reading when playing Cosmic Trader.</p>



<p>No spoilers, but there are still a few features and game mechanics, recommended by the AI, that I left for future releases.</p>



<p>While working on this game, I even had a little ant invasion at home. The AI came up with a multiplayer ant colony simulator game idea that I will probably never implement, but who knows!</p>



<p>For the logo, I had some spare credits to use with DreamStudio. I had to retouch it using Affinity Photo, but that&#8217;s it:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="256" src="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-07-30-a-las-12.32.26-1024x256.png" alt="" class="wp-image-13626" srcset="https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-07-30-a-las-12.32.26-1024x256.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-07-30-a-las-12.32.26-300x75.png 300w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-07-30-a-las-12.32.26-768x192.png 768w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-07-30-a-las-12.32.26-1536x385.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/09/Captura-de-pantalla-2024-07-30-a-las-12.32.26-2048x513.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>All in all, and while a team of real humans will always be much better, I reckon AI helped me a lot with this experiment.</p>



<h2 class="wp-block-heading">Credits and Acknowledgements</h2>



<p>I could focus on building the game thanks to using the <a href="https://kenney.nl" target="_blank" rel="noreferrer noopener nofollow">Kenney game assets</a>. The background music author is <a href="https://pixabay.com/users/the_mountain-3616498/" target="_blank" rel="noreferrer noopener nofollow">Dmitrii Kolesnikov</a>, make sure to check his profile.</p>



<p>Thanks to Claude for being my second brain for this project. And, of course, thanks to Xojo. It wouldn&#8217;t be as fun without it.</p>



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



<p>I enjoyed building this project a lot. I learned things, and I fixed some bugs I found. Did you know you couldn&#8217;t add a WebStyle CSS transition without adding other styles? Me neither, but it will be fixed in Xojo 2024r3.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/09/cosmic-trader-early-prototype.mp4" length="970692" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/09/cosmic-trader-current-version.mp4" length="776410" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/09/cosmic-trader-flickering-issue.mp4" length="295405" type="video/mp4" />

			</item>
		<item>
		<title>Xojo Cloud: More Than Web App Hosting</title>
		<link>https://blog.xojo.com/2024/08/15/xojo-cloud-more-than-web-app-hosting/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 15 Aug 2024 22:59:40 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Push Notifications]]></category>
		<category><![CDATA[SFTP]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13449</guid>

					<description><![CDATA[What better way to celebrate 10 years of Xojo Cloud than bragging about all the things it can do! When you think of Xojo Cloud,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>What better way to celebrate 10 years of Xojo Cloud than bragging about all the things it can do! When you think of Xojo Cloud, you might think that it is for hosting Xojo web apps. And that&#8217;s true, Xojo Cloud continues to be the best and easiest way to host your Xojo web apps, but Xojo Cloud also offers several useful services for other types of apps.</p>



<h2 class="wp-block-heading">iOS Notifications</h2>



<p>Xojo Cloud can function as an <a href="https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns">Apple Push Notification system</a> (APNs) for handling iOS push notifications. This works with Xojo and non-Xojo iOS apps. All Xojo Cloud servers are pre-configured to <a href="https://documentation.xojo.com/topics/ios/sending_and_receiving_mobile_notifications.html#topics-ios-creating-notifications-on-the-user-s-mobile-device-using-xojo-cloud-to-send-remote-notifications">send remote notifications</a>. Unlike many other cloud hosts, there is no extra charge for this feature nor is there any limit as to how many notifications you can send.</p>



<p>To send remote notifications from your iOS app you&#8217;ll need to go to the Apple Developer website to do these tasks:</p>



<ol class="wp-block-list">
<li>Add the Push Notifications feature to the App ID.</li>



<li>Generate an Apple Push Services certificate.</li>
</ol>



<p>In Xojo you need to enable the Remote Notifications entitlement for your app in the Capabilities section of the iOS Build Settings Advanced tab.</p>



<p>The final step is to upload your Push Services certificate using the Xojo Cloud control panel.</p>



<p>With super-easy access and no limits for notifications, Xojo Cloud can serve as a great APNs for handling your iOS notification needs.</p>



<h2 class="wp-block-heading">Database Servers</h2>



<p>Most desktop apps use a database of some kind and many are client/server database apps that talk directly to the database server. With Xojo Cloud you can host PostgreSQL or MariaDB/MySQL database servers and connect to them using an SSH tunnel for security purposes.</p>



<p>Setting up a database server on your Xojo Cloud is as easy as checking a box in the control panel.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="630" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-1024x630.png" alt="" class="wp-image-13451" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-1024x630.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/image-300x185.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/image-768x472.png 768w, https://blog.xojo.com/wp-content/uploads/2024/08/image.png 1398w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>You can turn on PostgreSQL or MySQL/MariaDB. If your Xojo Cloud server is large enough you could even do both.</p>



<p>If you want to access a database on Xojo Cloud from a desktop app, you will have to enable the SSH Tunnel and then connect to the tunnel from the computer. An SSH tunnel is a secure connection between your computer and another (in this case your Xojo Cloud server) which is used for transmitting data on a specific port. In essence, it creates a private connection through the internet which allows you to see into your server on the other end and connect to a particular service there.</p>



<p>To create a tunnel between a computer and your Xojo Cloud server, you first need to turn on the tunnel capability on your Xojo Cloud server. Go to your control panel and click the &#8220;SSH Tunnel&#8221; checkbox. You will be presented with a generated username and a password which you will use later for establishing the connection.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="694" height="302" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-1.png" alt="" class="wp-image-13453" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-1.png 694w, https://blog.xojo.com/wp-content/uploads/2024/08/image-1-300x131.png 300w" sizes="auto, (max-width: 694px) 100vw, 694px" /></figure>



<p>On macOS and Linux, you can use a terminal command to access the tunnel (replace username and ipaddress as appropriate; you&#8217;ll be prompted for the password).</p>



<p>Use this command to tunnel to PostgreSQL:</p>



<pre class="wp-block-code"><code>ssh -L 5432:localhost:5432 username@ipaddress -N</code></pre>



<p>Use this command to tunnel to MySQL:</p>



<pre class="wp-block-code"><code>ssh -L 3306:localhost:3306 username@ipaddress -N</code></pre>



<p>If you are using Windows, you will need to use an external app such as PuTTY. There are a number of tutorials available on the internet, just put “putty ssh tunnel” into your favorite search engine.</p>



<p>With the tunnel in place you connect to the database as if it were local to the computer. This works with anything, not just Xojo apps.</p>



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



<p>Xojo Cloud offers SFTP (Secure File Transfer Protocol) for file transfer. SFTP is a secure variant of FTP which transmits files over the internet using strong encryption. That way you don&#8217;t have to worry about anyone intercepting your username and password or your files as they&#8217;re sent to or from your server.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>When choosing a client, keep in mind that SFTP is different than FTPS or FTP w/ SSL. They are not interchangeable with one another.</p>
</blockquote>



<p>Once you enable SFTP in the Control Panel, you&#8217;ll be presented with a dialog showing a generated username and password.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="447" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-2-1024x447.png" alt="" class="wp-image-13454" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-2-1024x447.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2-300x131.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2-768x335.png 768w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2.png 1186w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>You can now connect using your favorite SFTP client. If you don&#8217;t have one, there are a number of free and paid options available including:</p>



<ul class="wp-block-list">
<li>ForkLift</li>



<li>Transmit</li>



<li>FileZilla</li>



<li>CyberDuck</li>
</ul>



<p>Having a place to store files online is always handy and can be useful when needing to share files with others without having to rely on services such as DropBox.</p>



<h2 class="wp-block-heading">Web Services</h2>



<p>OK, a web service is technically a Xojo web app but it is really an API that is meant to be used by other apps, often desktop or mobile apps. Since a web service doesn’t have any actual UI, you don’t really need to learn how to use the majority of the Xojo Web framework.</p>



<p>Instead you basically add code to the <a href="https://documentation.xojo.com/api/web/webapplication.html#webapplication-handleurl">App.HandleURL</a> event to route web service API calls to do specific tasks and then return the results, usually as JSON for the client app to handle.</p>



<p>A web service can be a great way to consolidate code that will be used by desktop and mobile apps, for example.</p>



<p>For example, you could create a Web Service that talks to a database server (such as one of the ones available in Xojo Cloud itself). Your Desktop and Mobile apps can use the same web service to work with the database. All your database-specific code lives in the web service and the client apps make requests and display results.</p>



<p>This is a very common design pattern these days and is a necessary one if you want a mobile app to talk to a database server.</p>



<p>If you want to learn more about web services, here&#8217;s a fun webinar to check out:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Using Xojo and the Star Wars API" width="500" height="281" src="https://www.youtube.com/embed/hwhkZtP6fA8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>Learn more about <a href="https://xojo.com/cloud/">Xojo Cloud</a> today. Xojo Cloud servers start at $49/month, custom servers with more RAM, storage, and virtual CPUs are available. The best way to host your Xojo web apps is so much more than just hosting web apps!</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>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using a WebDataSource to Display Millions of Rows in a WebListBox</title>
		<link>https://blog.xojo.com/2024/08/01/using-a-webdatasource-to-display-millions-of-rows-in-a-weblistbox/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Thu, 01 Aug 2024 18:31:45 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[SQLiteDatabase]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[WebListBox]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13373</guid>

					<description><![CDATA[If you are wondering why you would use a WebDataSource for your WebListBox, this post will give you some arguments and tips for making that decision and implementing it.]]></description>
										<content:encoded><![CDATA[
<p>If you are wondering why you would use a WebDataSource for your WebListBox, this post gives you some arguments and tips for making that decision and implementing it.</p>



<h2 class="wp-block-heading">Why would you need a WebDataSource, isn’t AddRow enough?</h2>



<p>If you are making a quick prototype, or for small data sets that won&#8217;t grow too much, yes, you can absolutely place a WebListBox into your WebPage and fill it using AddRow. If your WebListBox displays a fixed, small amount of data, say around 500~1000 rows, WebDataSource can be overkill.<br><br>However, for data that comes from a large database, it&#8217;s a different story. You could waste precious server resources duplicating the same data you have in your database into your app’s memory. And even worse, the data would be duplicated in every Session seeing that WebListBox.<br><br>In this tutorial, this is the WebListBox we are going to build:</p>



<figure class="wp-block-video"><video height="1416" style="aspect-ratio: 1368 / 1416;" width="1368" controls src="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-14.42.03.mp4.mp4"></video></figure>



<h2 class="wp-block-heading">Let’s prepare a million records database to play with.</h2>



<p>In this example we will use a humble SQLite database, but keep in mind a WebDataSource can be anything. For example you could display the result of calling an external API, or your hard drive filesystem.</p>



<p>The following SQL creates a table called “things”, with three columns: “foo”, “bar” and “baz” with one million rows:</p>



<pre class="wp-block-code"><code>CREATE TABLE things (
  id    INTEGER PRIMARY KEY AUTOINCREMENT,
  foo TEXT,
  bar TEXT,
  baz TEXT
);

-- Time to populate that table
WITH RECURSIVE cnt(x) AS 
(
   SELECT
      1 
   UNION ALL
   SELECT
      x + 1 
   FROM
      cnt LIMIT 1000000
)
INSERT INTO things (foo, bar, baz)
SELECT
    'foo_' || x AS foo,
    'bar_' || x  AS bar,
    'baz_' || x AS baz
FROM cnt;

-- Finally, let's create some indexes, so we can sort the columns quickly
CREATE INDEX "idx_foo" ON things (
    foo, id, bar, baz
);

CREATE INDEX "idx_bar" ON things (
    bar, id, foo, baz
);

CREATE INDEX "idx_baz" ON things (
    baz, id, foo, bar
);

VACUUM;</code></pre>



<p>We just need to store this SQL as a string constant, for convenience. Let’s create one, called <code>kDatabaseSetupSQLite</code> in your Application class, and paste it above the SQL code.</p>



<h2 class="wp-block-heading">First Time Setup</h2>



<p>The first time we launch the application, we need to make sure our database file has been created and populated. It won&#8217;t take too much to generate the database, but we&#8217;ll try to do it just once anyway.</p>



<p>Create a new method in your App class, called DBFile, that returns a FolderItem, pointing to the place we want to store the DataBase. Make it Public, as we will use this method later from the Session. The contents:</p>



<pre class="wp-block-code"><code>Return SpecialFolder.Desktop.Child("test-db.sqlite")</code></pre>



<p>Nothing fancy. Use another path if you want. It will be around ~200MB, just remember to delete it when you don&#8217;t need it anymore.</p>



<p>Let&#8217;s create another App method, called SetupDatabase. It will be in charge of creating and populating the database just once, so if you restart the server, the data will still be there:</p>



<pre class="wp-block-code"><code>Var db As New SQLiteDatabase
db.DatabaseFile = DBFile
db.WriteAheadLogging = True

// The file is already there, no need to build it again
If db.DatabaseFile.Exists Then
  Return
End If

db.CreateDatabase
db.Connect
db.ExecuteSQL(kDatabaseSetupSQLite)</code></pre>



<p>Lastly, implement the App.Opening event and add a method call to SetupDatabase:</p>



<pre class="wp-block-code"><code>SetupDatabase</code></pre>



<p>That should do the trick.</p>



<h2 class="wp-block-heading">Preparing the Session</h2>



<p>It&#8217;s recommended to have a Database instance for each Session. Add a new public Property to your Session class called Database of type SQLiteDatabase.</p>



<p>Then, add a handler for the Opening event with the following code:</p>



<pre class="wp-block-code"><code>Database = New SQLiteDatabase
Database.DatabaseFile = App.DBFile
Database.WriteAheadLogging = True
Database.Connect</code></pre>



<p>Every time a user arrives to the web application, a new isolated SQLiteDatabase connection will be created.</p>



<h2 class="wp-block-heading">Implementing the WebDataSource Interface</h2>



<p>Since Xojo 2024r2, the amount of methods you need in order to implement WebDataSource has been reduced.</p>



<p>Create a new class called DatabaseDataSource. Then, in the inspector panel, select the WebDataSource interface:</p>



<figure class="wp-block-video"><video height="1528" style="aspect-ratio: 2560 / 1528;" width="2560" controls src="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-11.48.19.mp4.mp4"></video></figure>



<p>This includes the three required methods: ColumnData, RowCount and RowData.</p>



<p><strong>ColumnData</strong><br>In this method, you need to return an array of <a href="https://documentation.xojo.com/api/web/weblistboxcolumndata.html#weblistboxcolumndata">WebListBoxColumnData</a>. We have four columns in this example, here is the code:</p>



<pre class="wp-block-code"><code>Var result() As WebListBoxColumnData
result.Add(New WebListBoxColumnData("ID", "id"))
result.Add(New WebListBoxColumnData("Foo", "foo"))
result.Add(New WebListBoxColumnData("Bar", "bar"))
result.Add(New WebListBoxColumnData("Baz", "baz"))

Return result</code></pre>



<p><strong>RowCount</strong><br>Xojo needs to know the amount of data your data source has. Returning an Integer is enough, but we will query our database.</p>



<pre class="wp-block-code"><code>Try
  Var rows As RowSet = Session.Database.SelectSQL("SELECT COUNT(*) AS counter FROM things")
  Return rows.Column("counter").IntegerValue
Catch DatabaseException
  Return 0
End Try</code></pre>



<p><strong>RowData</strong><br>This is the place where you need to return the row contents. As you can see, there is a rowCount and a rowOffset parameter, meaning that we won&#8217;t need to return 1 million records. The control just loads a subset. The amount is dynamically calculated, and varies depending on the height of your WebListBox and the height of the rows.</p>



<p>A sortColumns parameter is also provided. If you allow your users to sort the columns, you need to use it to know the column and direction. Fortunately, this example has sortable columns. Here is the code to comply with the WebDataSource Interface:</p>



<pre class="wp-block-code"><code>Var sql As String = "SELECT id, foo, bar, baz FROM things"
If sortColumns &lt;&gt; "" Then
  sql = sql + " ORDER BY " + sortColumns
End If
sql = sql + " LIMIT " + rowOffset.ToString + ", " + rowCount.ToString

Var result() As WebListBoxRowData
Var rows As RowSet = Session.Database.SelectSQL(sql)

// This isn't needed, it's just to demonstrate how to use cell renderers
Var style As New WebStyle
style.Bold = True
style.BackgroundColor = Color.Teal
style.ForegroundColor = Color.White

For Each row As DatabaseRow In rows
  Var newRowData As New WebListBoxRowData
  newRowData.PrimaryKey = row.Column("id").IntegerValue
  newRowData.Value("id") = row.Column("id")
  newRowData.Value("foo") = row.Column("foo")
  newRowData.Value("bar") = New WebListBoxStyleRenderer(style, row.Column("bar"))
  newRowData.Value("baz") = row.Column("baz")
  result.Add(newRowData)
Next

Return result</code></pre>



<h2 class="wp-block-heading">Preparing the User Interface</h2>



<p>You&#8217;ve reached the easiest part, building the interface takes less than a minute.</p>



<ol class="wp-block-list">
<li>Drop a DatabaseDataSource control into your WebPage</li>



<li>Drop a WebListBox control into your WebPage</li>



<li>In the WebListBox Opening event, configure the DataSource</li>
</ol>



<p>If you name your DataSource instance &#8220;MyDataSource&#8221;, this is the line of code required in the WebListBox Opening event:</p>



<pre class="wp-block-code"><code>Me.DataSource = MyDataSource</code></pre>



<p>Here is a short video:</p>



<figure class="wp-block-video"><video height="1682" style="aspect-ratio: 2800 / 1682;" width="2800" controls src="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-12.21.41.mp4.mp4"></video></figure>



<h2 class="wp-block-heading">That&#8217;s It!</h2>



<p>The WebListBox control, when combined with a WebDataSource, is a very robust and performant solution for displaying a large set of data.</p>



<p>Download the project:</p>



<div class="wp-block-file"><a id="wp-block-file--media-6f1fe487-dbb0-4d6e-a5c9-3a89f0f2fb9b" href="https://blog.xojo.com/wp-content/uploads/2024/07/weblistbox-million-rows.xojo_binary_project-1.zip">weblistbox-million-rows.xojo_binary_project</a></div>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-14.42.03.mp4.mp4" length="2629948" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-11.48.19.mp4.mp4" length="1234967" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-12.21.41.mp4.mp4" length="2146506" type="video/mp4" />

			</item>
		<item>
		<title>What&#8217;s New in Xojo Web in 2024r2</title>
		<link>https://blog.xojo.com/2024/06/26/whats-new-in-xojo-web-in-2024r2/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Wed, 26 Jun 2024 15:00:00 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2024r2]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13201</guid>

					<description><![CDATA[We're excited about Xojo 2024r2. Performance, control sets, improvements for current controls and bug fixes. You will love this release.]]></description>
										<content:encoded><![CDATA[
<p>We&#8217;re excited about Xojo 2024r2. Performance, control sets, improvements for current controls and bug fixes. You will love this release.</p>



<h2 class="wp-block-heading"><strong>Control Sets</strong></h2>



<p>There are cases where you have a bunch of controls with the same functionality. Imagine you are coding a calculator and you&#8217;ve just added the WebButtons for each digit. It would be repetitive and error prone to add the same code to Pressed events, on each button when the only thing that changes is the numeric value.</p>



<p>A set of controls can be grouped, so you can think about them like if you were using an array. You can add event handlers to the group itself. Events will be enhanced with an &#8220;index&#8221; parameter, to help you decide what to do, depending on the element.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="982" src="https://blog.xojo.com/wp-content/uploads/2024/06/Session-1024x982.png" alt="" class="wp-image-13202" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/Session-1024x982.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/Session-300x288.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/Session-768x736.png 768w, https://blog.xojo.com/wp-content/uploads/2024/06/Session.png 1116w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Create Tabs and Embed Controls at Runtime in WebTabPanel and WebPagePanel</h2>



<p>Same as with Control Sets, this is something that was already present in Desktop projects and we wanted to include it for Web. From now on, you will be able to create and remove tabs and pages in WebTabPanel and WebPagePanel controls, respectively. Controls can also be added and removed at runtime, or move controls between tabs or pages whenever you need.</p>



<p>This opens a new world of possibilities for your applications, where you can provide your end users a way to have multiple contexts open at the same time.</p>



<figure class="wp-block-video"><video height="902" style="aspect-ratio: 1648 / 902;" width="1648" controls src="https://blog.xojo.com/wp-content/uploads/2024/06/Grabacion-de-pantalla-2024-06-16-a-las-13.05.26.mp4.mp4"></video></figure>



<h2 class="wp-block-heading"><strong>WebListBox: Configurable Header and Row Height, Border and Line Style</strong></h2>



<p>You will be able to configure the height of WebListBox headers and rows with the same API you are used to using in your Desktop projects. You won&#8217;t need to tweak them with CSS anymore.</p>



<figure class="wp-block-video"><video height="1018" style="aspect-ratio: 1648 / 1018;" width="1648" controls src="https://blog.xojo.com/wp-content/uploads/2024/06/Grabacion-de-pantalla-2024-06-16-a-las-13.08.01.mp4.mp4"></video></figure>



<p><a href="https://documentation.xojo.com/versions/2024r2/api/user_interface/web/weblistbox.html#weblistbox-hasborder">HasBorder</a> and <a href="https://documentation.xojo.com/versions/2024r2/api/user_interface/web/weblistbox.html#weblistbox-gridlinestyle">GridLineStyle</a> has also been added to Web projects, allowing you to remove the outside border, display only vertical lines between the columns&#8230; or just remove them.</p>



<h2 class="wp-block-heading"><strong>WebDataSource Interface</strong></h2>



<p>Speaking of WebListBox improvements, you&#8217;ll find that the WebDataSource is easier to implement. You won&#8217;t need to implement SortedPrimaryKeys and UnsortedPrimaryKeys methods anymore.</p>



<p>There are only three methods required now:</p>



<ul class="wp-block-list">
<li><strong>ColumnData</strong>: Where you will define the amount of columns, names, and configure if they are sortable</li>



<li><strong>RowCount</strong>: So the control can now the amount of space it will need</li>



<li><strong>RowData</strong>: This is where you return an array of rows</li>
</ul>



<p>WebListBox lazy load rows, meaning that it will only ask your DataSource for the amount of rows being displayed on screen. It will only fetch more when needed.</p>



<h2 class="wp-block-heading"><strong>WebListBox Improvements When Using a WebDataSource</strong></h2>



<p>Using a WebListBox with a DataSource makes it possible to display very large amounts of data. Until now, you were able to display thousands of rows very quickly. This release improves the way Xojo uses your DataSource, without having to change a line of code in your projects.</p>



<p>Scrolling through the data will display the rows much faster than before. Just for comparison, 2024r1.1 was able to display 1 million rows in about 6 seconds in my computer. The same project, using 2024r2, can display them in less than 100ms.</p>



<p>But is not just the speed that has been improved. Its memory footprint has been dramatically reduced as well. Displaying 1 million records in 2024r1.1 used about 1 GB of RAM, where 2024r2 will use just a few MB instead.</p>



<p>I can&#8217;t imagine a use case where you need to display millions of rows and scroll through them. But if you find one, you will be able to implement it with Xojo <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading"><strong>WebButtons Can be Resized Now</strong></h2>



<p>In order to make it easier to migrate your Web 1 projects, you will be able to modify the height of your WebButtons. The web framework will also take care to reduce the font size if needed when the button is smaller.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="844" src="https://blog.xojo.com/wp-content/uploads/2024/06/Press-me-1024x844.png" alt="" class="wp-image-13205" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/Press-me-1024x844.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/Press-me-300x247.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/Press-me-768x633.png 768w, https://blog.xojo.com/wp-content/uploads/2024/06/Press-me.png 1425w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading"><strong>Individual Indicator for Each Segment of WebSegmentedButton</strong></h2>



<p>There are situations where you want to mix different &#8220;indicators&#8221; (different colors) in a single WebSegmentedButton control. For example, pressing on one of the segments can be a destructive action, so you could use the Danger indicator. By default, segments will use the indicator you set in the Inspector panel, but you will be able now to individually override one of them.</p>



<pre class="wp-block-code"><code>Me.Indicator = WebUIControl.Indicators.Primary
Me.SegmentAt(1).Indicator = WebUIControl.Indicators.Danger
Me.SegmentAt(2).Indicator = WebUIControl.Indicators.Success</code></pre>



<p>Having 4 segments, this will be the result of above example at runtime:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="724" height="220" src="https://blog.xojo.com/wp-content/uploads/2024/07/Captura-de-pantalla-2024-06-16-a-las-12.34.38.png" alt="" class="wp-image-13331" srcset="https://blog.xojo.com/wp-content/uploads/2024/07/Captura-de-pantalla-2024-06-16-a-las-12.34.38.png 724w, https://blog.xojo.com/wp-content/uploads/2024/07/Captura-de-pantalla-2024-06-16-a-las-12.34.38-300x91.png 300w" sizes="auto, (max-width: 724px) 100vw, 724px" /></figure>



<h2 class="wp-block-heading">Outlined WebButton and WebSegmentedButton</h2>



<p>Some GUIs could become overwhelming, when every button looks like a call to action. The new Outlined property, available in WebButton and WebSegmentedButton controls, can help with heavily loaded interfaces. Here is how it looks like:</p>



<figure class="wp-block-video"><video height="822" style="aspect-ratio: 1648 / 822;" width="1648" controls src="https://blog.xojo.com/wp-content/uploads/2024/06/Grabacion-de-pantalla-2024-06-16-a-las-12.40.05.mp4.mp4"></video></figure>



<h2 class="wp-block-heading"><strong>Performance, Memory Leaks, Bug Fixes</strong></h2>



<p>Last, but not least, 2024r2 comes with great performance improvements. We&#8217;ve been improving the web server to handle even more requests per second. If you are using Xojo Web for exposing an API, it will be able to serve more requests in less time. For regular Xojo Web applications, it means it will be able to handle more events and reply to them faster.</p>



<p>Here is a comparison of the same project during the different releases of Xojo:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="810" src="https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-1024x810.png" alt="" class="wp-image-13207" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-1024x810.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-300x237.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-768x608.png 768w, https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic.png 1407w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Latency has also been improved, Xojo is able already to reply in less than 2ms:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="810" src="https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-1-1024x810.png" alt="" class="wp-image-13208" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-1-1024x810.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-1-300x237.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-1-768x608.png 768w, https://blog.xojo.com/wp-content/uploads/2024/06/Pasted-Graphic-1.png 1422w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>If you are still serving Web APIs with Web 1, this is a good opportunity to migrate:</p>



<figure class="wp-block-table"><table><tbody><tr><td><br></td><td><strong>2019r3.2</strong></td><td><strong>2024r2</strong></td></tr><tr><td>Average Latency</td><td>133.4 ms</td><td>1.98 ms</td></tr><tr><td>Max Latency</td><td>287.3 ms</td><td>143.52 ms</td></tr><tr><td>Requests per second</td><td>76</td><td>8900</td></tr><tr><td>Transfer Rate</td><td>9.89 KB/s</td><td>1.5 MB/s</td></tr></tbody></table></figure>



<h2 class="wp-block-heading"><strong>That&#8217;s a Wrap!</strong></h2>



<p>As usual, I&#8217;d like to send a big thank you to everyone taking the time creating bug reports, feature requests and testing beta releases. This wouldn&#8217;t be possible without your support.</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/06/Grabacion-de-pantalla-2024-06-16-a-las-13.05.26.mp4.mp4" length="172691" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/06/Grabacion-de-pantalla-2024-06-16-a-las-13.08.01.mp4.mp4" length="300122" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/06/Grabacion-de-pantalla-2024-06-16-a-las-12.40.05.mp4.mp4" length="156104" type="video/mp4" />

			</item>
		<item>
		<title>How to use Bootstrap Themes to Customize your Xojo Web Apps</title>
		<link>https://blog.xojo.com/2024/06/18/how-to-use-bootstrap-themes-to-customize-your-xojo-web-apps/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Tue, 18 Jun 2024 14:00:00 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[WebDesign]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13177</guid>

					<description><![CDATA[This tutorial will equip you with all the knowledge to select and use Bootstrap themes for your Xojo web apps. By the end of this guide, you’ll have the tools and confidence to create a visually appealing, user-friendly app that turns heads and wins hearts.]]></description>
										<content:encoded><![CDATA[
<p>If you&#8217;re crafting your latest SaaS (web app) using Xojo, you might already know the power this platform holds. But let’s talk about something equally important &#8211; making your app look downright amazing.</p>



<p>Have you ever stumbled upon a website or app and been instantly captivated by its design? That&#8217;s the magic of great visual appeal. And guess what? You can bring that same magic to your Xojo web app with the help of Bootstrap themes.</p>



<p>Imagine your app not just as a tool, but as a full visual-interactive experience for your end-users. Whether you’re a design newbie or a seasoned pro, these themes offer a seamless way to enhance your web app’s look and feel.</p>



<p>This tutorial will equip you with all the knowledge to select and use Bootstrap themes for your Xojo web apps. By the end of this guide, you’ll have the tools and confidence to create a visually appealing, user-friendly app that turns heads and wins hearts.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">What are Bootstrap themes and why use them in Xojo?</h2>



<p><a href="https://getbootstrap.com/" target="_blank" rel="noreferrer noopener nofollow">Bootstrap</a> is a popular front-end framework that helps developers create responsive and visually compelling web applications. Bootstrap themes are pre-designed templates built with this framework, making it easier to achieve a professional look with minimal effort.</p>



<p>Xojo, by default, uses a modified Bootstrap theme for its web apps. This means that right out of the box, your Xojo web app already benefits from Bootstrap&#8217;s design and sleek aesthetics. There are countless pre-designed themes available online, both free and premium, that you can incorporate into your Xojo web app. These themes can dramatically alter the visual appearance of your app, offering various aesthetic options to suit your needs.</p>



<p>Now that you have a basic understanding of Bootstrap and its role in Xojo, let’s move on to how you can actually implement and customize these themes in your web app.</p>



<h3 class="wp-block-heading">Step 1: Choose a Bootstrap theme</h3>



<p>First, you need to choose a Bootstrap theme that fits the look and feel you want for your Xojo web app. There are numerous resources on the web where you can find free or premium Bootstrap themes. For maximum compatibility with Xojo, we recommend using themes from <a href="https://bootswatch.com/" target="_blank" rel="noreferrer noopener nofollow">Bootswatch</a>. Bootswatch provides a variety of free, Xojo-compatible Bootstrap themes.</p>



<h3 class="wp-block-heading">Step 2: Preview and download the theme</h3>



<div class="wp-block-columns are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow">
<p>On the Bootswatch website, click the &#8220;Preview&#8221; button for any theme to see how it will appear.</p>



<p>Once you find a theme you like, click the menu next to the theme&#8217;s &#8220;Download&#8221; button and select the file named bootstrap.min.css. This is the only file you need.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-large is-resized is-style-rounded"><img loading="lazy" decoding="async" width="956" height="956" src="https://blog.xojo.com/wp-content/uploads/2024/06/image-1-edited.png" alt="Selecting a Bootstrap theme for Xojo web apps from the Bootswatch website." class="wp-image-13183" style="width:428px;height:auto" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/image-1-edited.png 956w, https://blog.xojo.com/wp-content/uploads/2024/06/image-1-edited-300x300.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/image-1-edited-150x150.png 150w, https://blog.xojo.com/wp-content/uploads/2024/06/image-1-edited-768x768.png 768w" sizes="auto, (max-width: 956px) 100vw, 956px" /></figure>
</div>
</div>



<h3 class="wp-block-heading">Step 3: Add the theme to your Xojo web app project</h3>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow">
<p>Now for the easiest step. Once you have the desired <strong>bootstrap.min.css</strong> file, simply drag and drop it into the Navigator panel of your Xojo project.</p>



<p>After adding the bootstrap.min.css file to your project, Xojo&#8217;s layout editor will instantly reflect the new theme. Moreover, your web app will utilize this theme when running.</p>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full is-style-rounded"><img loading="lazy" decoding="async" width="600" height="600" src="https://blog.xojo.com/wp-content/uploads/2024/06/bootstrap_theme_in_xojo_web_apps.gif" alt="" class="wp-image-13186"/></figure>
</div>
</div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Congratulations! You&#8217;ve now learned how to incorporate and apply Bootstrap themes to your Xojo web application.</p>



<p>Remember, the right theme can make your web app not just functional, but memorable. And with the countless options available, you’re sure to find a Bootstrap theme that perfectly matches your vision. Don&#8217;t hesitate to experiment with different themes and make adjustments as needed to get the perfect look for your app.</p>



<p>Now it’s your turn to put it into practice and create web apps that not only work well but look fantastic too.</p>



<p>If you have any questions or run into any issues, feel free to refer to the&nbsp;<a href="https://documentation.xojo.com/topics/user_interface/web/changing_the_appearance_of_controls.html#changing-all-controls" target="_blank" rel="noreferrer noopener">official Xojo documentation</a>&nbsp;for more detailed information.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Improvements to Xojo Web in Xojo 2024r1</title>
		<link>https://blog.xojo.com/2024/03/26/popovers-and-other-improvements-in-xojo-web/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 26 Mar 2024 15:27:06 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[2024r1]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12684</guid>

					<description><![CDATA[Our web framework continues improving, with interesting new features and tons of bug fixes. Let’s take a look to some highlighted 2024r1 changes!]]></description>
										<content:encoded><![CDATA[
<p>Our web framework continues improving, with interesting new features and tons of bug fixes. Let’s take a look to some highlighted 2024r1 changes!</p>



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



<p>Similar to WebDialogs, popovers give you the opportunity to improve your apps’ UX. They are ephemeral screens where you can place text and controls.</p>



<p>Unlike the WebDialog, which is always centered and prevents the user to interact with other controls, Popovers can be placed on specific controls, where that information matters.</p>



<p>Think about them as enhanced “contextual menus” but, instead of just plain text menus, you can add anything you like. Have you ever dreamed of adding a WebMapViewer into some sort of contextual menu? Now you can!</p>



<p>The API is very simple. Create a container, add some controls and that’s it, really. You will just have to create a new instance of that container and show it as a Popover, specifying the control it should be pointing to.</p>



<p>Let’s say you have a container, called “MyTextFieldContainer”, and you want to display it below a WebLabel called “MyLabel”. Here is the code:</p>



<pre class="wp-block-code"><code>Var c As New MyTextFieldContainer
c.ShowPopover(MyLabel)</code></pre>



<p>By default, it will be shown below the specified control, but if you want to show it in a different place, you can use the new DisplaySides enumeration. As easy as this:</p>



<pre class="wp-block-code"><code>Var c As New TextFieldContainer
c.ShowPopover(MyLabel, WebContainer.DisplaySides.Top)</code></pre>



<p>As you can see, Web Projects’ Popovers are just container instances that you will show dynamically. That gives you the opportunity to raise events, add custom computed properties or implement the Observer interface. If you are already familiar with Containers, you already know how to use Popovers. Learn more about <a href="https://blog.xojo.com/2024/03/26/popovers-for-xojo-desktop-web-and-ios/">Popovers</a>.</p>



<h2 class="wp-block-heading">Displaying contextual menus programmatically</h2>



<p>Sometimes Popovers could be overkill for the task. If you just want to display a menu with some textual items inside, a contextual menu might be enough.</p>



<p>Imagine you have a WebTextLabel where you want to display the contextual menu whenever the user Presses on it. In its Opening event you could define the ContextualMenu:</p>



<pre class="wp-block-code"><code>Var menu As New WebMenuItem
menu.AddMenuItem("Foo")
menu.AddMenuItem("Bar")
menu.AddMenuItem("Baz")

Me.ContextualMenu = menu</code></pre>



<p>Implement the WebLabel.Pressed event and add this code:</p>



<pre class="wp-block-code"><code>Me.ContextualMenu.PopUp</code></pre>



<p>As easy as that.</p>



<h2 class="wp-block-heading">New RemoveControl method</h2>



<p>WebViews controls, like WebPage and WebContainer, now supports removing controls. This gives you the missing piece to create GUIs programmatically, as AddControl was already supported .</p>



<p>This can be useful when you are presenting a form to your end user with an unknown amount of fields.</p>



<p>For example, your user is filling the profile and you want to support having multiple contact fields. Some users will want to add 1 phone, others 2, and others would prefer to be contacted just by email.</p>



<p>Adding and removing controls dynamically gives you the opportunity to build this kind of features. Instead of adding a fixed amount of contact methods, you can adapt your app to what your user really needs.</p>



<h2 class="wp-block-heading">Performance and memory usage improvements</h2>



<p>We’re landing at my favorite part, improvements that nobody will see… unless you want to share your server monitoring stats, which is cool.</p>



<p>2024r1 comes with less Disk I/O usage. In my own benchmarks, Xojo Web is now able to serve about 1200 requests per second via the WebApplication.HandleURL event. That’s around a nice 20% more, compared to the previous version.</p>



<p>Also, thanks to Jeremie Leroy (one of our Xojo MVPs) and Bruno Fréchette, we’ve managed to identify and fix some memory leaks. In 2024r1, your web application will be doing a better job at cleaning up after processing requests.</p>



<h2 class="wp-block-heading">Bug fixes</h2>



<p>The list of fixes is big, you can inspect the whole list in the <a href="https://documentation.xojo.com/resources/release_notes/2024r1.html">2024r1 Release Notes</a> page.</p>



<p><strong>Web fixes by category:</strong></p>



<ul class="wp-block-list">
<li>Compiler: 1</li>



<li>IDE: 7</li>



<li>Framework: 40</li>
</ul>



<p>18 extra regressions were reported and fixed during the beta period. A huge thank you to everyone taking the time to test our releases and reporting issues before the final release becomes available.</p>



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



<p>We hope you are as excited as we are for this release. I’m personally looking forward to see what you’re building, please remember to mention us on your favorite social network so we all can see what you’re working on.</p>



<p>In the meantime, we are already working hard preparing our next release, 2024r2. Spoilers: You will love it!</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<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 loading="lazy" 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="auto, (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>Performance Improvements in Xojo Web</title>
		<link>https://blog.xojo.com/2023/12/12/performance-improvements-in-xojo-web/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 12 Dec 2023 14:30:00 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[2023r4]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12313</guid>

					<description><![CDATA[The last big Xojo release in 2023 comes with a lot of performance improvements everywhere. The Xojo IDE itself is faster, which gives you Time to Reflect on Stack Optimization. In this post, I want to detail those improvements in Xojo 2023r4 that target Xojo Web including faster HandleURL responses, faster transfer rates in Windows and Linux, static assets cache control, Events improvements and a new experimental option.]]></description>
										<content:encoded><![CDATA[
<p>The last big Xojo release in 2023 comes with a lot of performance improvements everywhere. The Xojo IDE itself is <a href="https://blog.xojo.com/2023/12/12/small-and-simple-changes-to-speed-up-the-xojo-ide/">faster</a>, which gives you <a href="https://blog.xojo.com/2023/12/12/time-to-reflect-on-stack-optimization/">Time to Reflect on Stack Optimization</a>. In this post, I want to detail those improvements in Xojo 2023r4 that target Xojo Web including faster HandleURL responses, faster transfer rates in Windows and Linux, static assets cache control, Events improvements and a new experimental option.</p>



<span id="more-12313"></span>



<h3 class="wp-block-heading">Faster HandleURL Responses</h3>



<p>With Xojo Web you can create APIs backing your Mobile or Desktop applications. Just by updating to Xojo 2023r4, your web services will get the benefit of much faster responses and the ability to handle many more requests per second.</p>



<p>Just to compare between different Xojo versions, we’ve created some benchmarks using Xojo Web 1 (with Xojo 2019r3.2) and some Xojo Web 2 releases, 2023r3.1 and the latest one, 2023r4.</p>



<p>Here are the results, returning plain text:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="897" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-897x1024.png" alt="" class="wp-image-12314" srcset="https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-897x1024.png 897w, https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-263x300.png 263w, https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-768x877.png 768w, https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-1346x1536.png 1346w, https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms.png 1726w" sizes="auto, (max-width: 897px) 100vw, 897px" /></figure>
</div>


<p>And the same test, but this time returning a string generated by JSONItem:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="916" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-1-916x1024.png" alt="" class="wp-image-12315" srcset="https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-1-916x1024.png 916w, https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-1-268x300.png 268w, https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-1-768x859.png 768w, https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-1-1374x1536.png 1374w, https://blog.xojo.com/wp-content/uploads/2023/12/Avg-Latency-ms-1.png 1764w" sizes="auto, (max-width: 916px) 100vw, 916px" /></figure>
</div>


<p>Xojo 2023r4 is capable of serving around 20x more requests per second compared to Web 1, and around 4x compared to Xojo 2023r3.1. And thanks to the reduced latency time, your API will return the contents much faster.</p>



<h3 class="wp-block-heading">Faster Transfer Rates in Windows and Linux</h3>



<p>While working on performance, we’ve found that applications deployed on Windows and Linux were serving large files much slower than those deployed on macOS servers.</p>



<p>William improved the low level code for sockets on those targets, allowing the server to transfer large files at a much faster speed. During my tests, I’ve seen 10x faster transfer rates.</p>



<p>But this doesn’t affect only our Web target! If you are using a ServerSocket with TCPSocket classes, your Console and Desktop applications will also benefit from these improved transfer rates.</p>



<h3 class="wp-block-heading">Static Assets Cache Control</h3>



<p>In this release, we’ve also improved how the framework interacts with the browser. When your user visits your web application for the first time, it will store all of the required JavaScript and CSS files.</p>



<p>This was already happening in previous releases but with a subtle difference. From now on, the browser won’t even need to check with the server if the file has changed since the last visit. This translates to faster load times for your users and less server load for you since the server won’t need to handle all those requests anymore.</p>



<h3 class="wp-block-heading">Improved Compile Time</h3>



<p>In this release, Xojo Web will compile your projects a few seconds faster. The first time you compile your project, it will cache the result of some processes that are only changing between Xojo releases.</p>



<p>Here is a comparison between 2023r3.1 and 2023r4, both are running a debug session of a blank project:</p>



<figure class="wp-block-video aligncenter"><video height="672" style="aspect-ratio: 2558 / 672;" width="2558" controls src="https://blog.xojo.com/wp-content/uploads/2023/12/web-blank-project-compile-time.mp4"></video></figure>



<p>That’s around 3-4 seconds faster every time a project compiles.</p>



<h3 class="wp-block-heading">Events Improvements</h3>



<p>Some web controls were sending information from the browser to the server more frequently than needed. For example, a WebContainer.Scrolled event was being sent for every scrolled pixel, causing unnecessary server load.</p>



<p>We’ve been reviewing these controls and have made some improvements:</p>



<ul class="wp-block-list">
<li>WebCombobox</li>



<li>WebContainer</li>



<li>WebSearchField</li>



<li>WebTextArea</li>



<li>WebTextField</li>



<li>WebUploader</li>
</ul>



<p>All of them will continue communicating their state updates, but the framework will focus on delivering the latest value available.</p>



<p>For example, in a WebSearchField, if the user writes &#8220;hello&#8221;, the framework will send the first key press (&#8220;h&#8221;) as soon as it happens. The next event it will send will depend on how fast the user types, so it can be either &#8220;hel&#8221; or maybe directly &#8220;hello&#8221;. What is guaranteed is the TextChanged event will be fired for the final value (&#8220;hello&#8221; in this example).</p>



<h3 class="wp-block-heading">New Experimental Option</h3>



<p>WebSession has a new experimental option available, disabled by default. “<a href="https://documentation.xojo.com/api/web/websession.html#websession-sendeventsinbatches">Send Events in Batches</a>”:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="596" height="714" src="https://blog.xojo.com/wp-content/uploads/2023/12/Interfaces.png" alt="" class="wp-image-12317" srcset="https://blog.xojo.com/wp-content/uploads/2023/12/Interfaces.png 596w, https://blog.xojo.com/wp-content/uploads/2023/12/Interfaces-250x300.png 250w" sizes="auto, (max-width: 596px) 100vw, 596px" /></figure>
</div>


<p>Turning it on will make our JavaScript framework group different event notifications in a single request. Projects that contain complex layouts that show and hide several controls at once may benefit from snappier GUIs.</p>



<p>As a side effect, it will also ensure the events arrive to the server in the correct order. Think about a login screen where the user has an email field, a password and a “Login” button with the Default setting turned on (to allow the user to trigger the Pressed event by pressing the Enter key). When sending the events in different requests, because of network latencies, the WebButton.Pressed event could arrive at the server before the last WebTextField.TextChanged.</p>



<p>We would love to hear your experiences when turning on this experimental option. If you find an issue, <a href="https://tracker.xojo.com/xojoinc/xojo/-/issues/new" target="_blank" rel="noreferrer noopener">please report it</a>.</p>



<h3 class="wp-block-heading">Wrapping Up</h3>



<p>As always, while Xojo 2023r4 comes with a lot of performance improvements, it also comes with bug fixes and feature requests. I want to again thank everyone who took the time to create new Bug reports and Feature Requests, and tested the pre-releases.</p>



<p>We’re looking forward to see what you build with it!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2023/12/web-blank-project-compile-time.mp4" length="538605" type="video/mp4" />

			</item>
		<item>
		<title>Simplicity and Security, Xojo Cloud is Ideal Hosting for Xojo Web Apps</title>
		<link>https://blog.xojo.com/2023/10/30/simplicity-and-security-xojo-cloud-is-ideal-hosting-for-xojo-web-apps/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Mon, 30 Oct 2023 16:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Security-Enhanced Linux]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11553</guid>

					<description><![CDATA[Xojo Cloud is the premier hosting solution for developers looking for a reliable, secure and high-performance hosting environment for Xojo web applications. Xojo Cloud is developed specifically for Xojo web applications and offers a range of benefits for you and your applications that make it worth the investment.]]></description>
										<content:encoded><![CDATA[
<p>Xojo Cloud is the premier hosting solution for developers looking for a reliable, secure and high-performance hosting environment for Xojo web applications. Xojo Cloud is developed specifically for Xojo web applications and offers a range of benefits for you and your applications that make it worth the investment.</p>



<p>Xojo Cloud is <strong>optimized for Xojo applications</strong>. It is specifically designed to provide the best possible performance and stability for Xojo web applications. We optimize Xojo Cloud for performance, so your web apps will run smoothly and seamlessly. You can even monitor server stats from within the Xojo IDE.</p>



<p>Xojo Cloud is <strong>focused on simplicity and ease of use</strong> and requires zero configuration. Designed with the Xojo developer in mind, Xojo Cloud&#8217;s Control Panel makes it easy to deploy and manage web applications. Purchase a server, open a web project in Xojo and click Deploy to upload and install to Xojo Cloud. Not just for web apps, Xojo Cloud includes Apple Push Notification server (APNs) support for your iOS apps. Set up SSL, PostrgeSQL, MySQL, SFTP and a SSH Tunnel with a click in the Xojo Cloud Control Panel (the Control Panel itself is a Xojo web app). The administration of a web server is a significant and constant task; Xojo Cloud allows you to leave that behind and focus on your projects.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="386" data-id="12082" src="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1024x386.png" alt="Xojo Cloud Control Panel Apps Tab" class="wp-image-12082" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1024x386.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-300x113.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-768x289.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1536x579.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-2048x772.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="384" data-id="12083" src="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1024x384.png" alt="Xojo Cloud Control Panel Options Tab" class="wp-image-12083" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1024x384.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-300x112.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-768x288.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1536x576.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-2048x768.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<p>We take security very seriously. Xojo Cloud <strong>offers advanced security features</strong> to protect your data from cyberthreats, including a smart firewall, intrusion and hacking detection and Security-Enhanced Linux. Unlike most hosting solutions that provide little to no security, each Xojo Cloud server is built with our state-of-the-art, industrial-strength, multi-tiered security system woven into its very core.&nbsp;</p>



<p>Additional features and benefits include daily automatic backups, load balancing and support from the Xojo team. With nine global hosting locations, you are able to host your Xojo web applications close to your users, for speed and an ideal overall experience. </p>



<div class="wp-block-columns are-vertically-aligned-top is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:100%">
<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="576" src="https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1024x576.png" alt="Xojo Cloud offers 3 packages offering options on RAM, storage and vCPU starting at $49/month. " class="wp-image-12078" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1024x576.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-300x169.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-768x432.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1536x864.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>
</div>



<p>In addition to the <a href="http://xojo.com/store/#cloud">standard options</a>, Xojo Cloud servers with more RAM, storage and Virtual CPUs are available. Contact&nbsp;<a href="mailto:hello@xojo.com">customer support</a>&nbsp;for details about personalized plans.&nbsp;</p>



<p>Whether you are a seasoned Xojo developer or just getting started, Xojo Cloud provides an intuitive and user-friendly hosting solution for Xojo web applications. Today is a good day to start using Xojo Cloud, visit our <a href="https://xojo.com/cloud/">website</a> to learn more or see the Xojo <a href="https://xojo.com/store/#cloud">Store</a> to pick your package and location.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Introducing Xojo&#8217;s New WebMapViewer Renderer</title>
		<link>https://blog.xojo.com/2023/10/10/introducing-xojos-new-webmapviewer-renderer/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 10 Oct 2023 13:30:00 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[2023r3]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[WebMapViewer]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12103</guid>

					<description><![CDATA[Xojo 2023r3 comes with a new map renderer for your map driven web applications. MapLibre is a robust Open Source mapping library alternative that Xojo is using under the hood now. With this update, you can create truly interactive maps with Xojo supporting multiple markers and customization.]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2023r3 comes with a new map renderer for your map driven web applications. Let&#8217;s take a look.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="743" src="https://blog.xojo.com/wp-content/uploads/2023/10/WebMapViewer-renderer-1024x743.png" alt="WebMapViewer screenshot showing a driving route." class="wp-image-12175" srcset="https://blog.xojo.com/wp-content/uploads/2023/10/WebMapViewer-renderer-1024x743.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/10/WebMapViewer-renderer-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2023/10/WebMapViewer-renderer-768x558.png 768w, https://blog.xojo.com/wp-content/uploads/2023/10/WebMapViewer-renderer-1536x1115.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/10/WebMapViewer-renderer-2048x1487.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading"><strong>Some Background</strong></h3>



<p>Xojo has been using Google Maps Embed as our map renderer for a while. Google Maps is a really nice product, but an API key is required nowadays for almost anything. Noticeably, in Xojo&#8217;s Eddie&#8217;s Electronics web example, the map in the customer list was only displayed if you had a valid API key for Google Maps.</p>



<p><a href="https://maplibre.org" data-type="link" data-id="https://maplibre.org">MapLibre</a> is a robust Open Source mapping library alternative that Xojo is using under the hood now. With this update, you can create truly interactive maps with Xojo supporting multiple markers and customization.</p>



<p>While you can still use Google Maps Embed as the renderer, MapLibre is our preferred option and will be Xojo&#8217;s default going forward.</p>



<h3 class="wp-block-heading"><strong>Map Tile Providers</strong></h3>



<p>When switching to another library, we wanted to make sure you, as a developer, have more control. WebMapViewer comes with a new property, StyleURL, pointing to an endpoint that returns a Style file.</p>



<p>Style files are JSON documents following the <a href="https://maplibre.org/maplibre-style-spec/" data-type="link" data-id="https://maplibre.org/maplibre-style-spec/">MapLibre Style Spec</a>. The easiest way to create a customized map is to register in one of the providers that supports this format. These providers will give you a style URL that you can use with your map. Some of them:</p>



<ul class="wp-block-list">
<li><a href="https://www.maptiler.com">https://www.maptiler.com</a></li>



<li><a href="https://www.mapbox.com/">https://www.mapbox.com</a></li>



<li><a href="https://stadiamaps.com">https://stadiamaps.com</a></li>



<li><a href="https://www.arcgis.com">https://www.arcgis.com</a></li>
</ul>



<p>By default, Xojo uses <a href="https://www.openstreetmap.org/">OpenStreetMap</a> raster tiles which should be OK for development or little web applications.</p>



<p>But you aren&#8217;t limited to using third party providers anymore. In projects where privacy is important or when you don&#8217;t want to be worried about monthly limits or prices, you can use software installed on premises to serve your own map vector tiles!</p>



<p><a href="https://github.com/maplibre/martin" data-type="link" data-id="https://github.com/maplibre/martin">Martin</a> is Open Source, but you can also use a commercial solution like <a href="https://www.maptiler.com/server/" data-type="link" data-id="https://www.maptiler.com/server/">MapTiler Server</a>.</p>



<h3 class="wp-block-heading"><strong>Address Lookup</strong></h3>



<p>Same as with map tiles, by default your maps will be using a free to use Geocoding service, <a href="https://nominatim.org">Nominatim</a>. If you hit a limit or if, for example, you are working on a project with privacy limitations, you can install Nominatim on premises.</p>



<p>Using WebMapLocation.LookupProviderURL, you can point to your own Nominatim server.</p>



<h3 class="wp-block-heading"><strong>Retrieving and Drawing Routes</strong></h3>



<p>Last, but not least, you can retrieve and render routes, using OpenStreetMap. No matter what map tile provider you are using, you can draw routes on the map. When you use the Directions mode, all you have to do is add locations to your map.</p>



<p>But if you need more control, switch your WebMapViewer to View mode and use the new methods for getting and drawing routes. When using the method to retrieve the route, you will obtain a <code>MapRoute</code> object with distance and duration information. You can also use this object for things like serializing it and storing the result in a database. This allows you to skip sending a new routing request to the service and just render it.</p>



<p>While driving will be the default, the <code>transportType</code> parameter supports Car, Bike and Walking.</p>



<p>Make sure to check the updated <a href="https://documentation.xojo.com/api/user_interface/web/webmapviewer.html">WebMapViewer</a> in the Xojo programming documentation.</p>



<h3 class="wp-block-heading"><strong>That&#8217;s a Wrap!</strong></h3>



<p>We are already working on new features for this control that will come in upcoming releases, and we can&#8217;t wait to see what you create with this new version of WebMapViewer.</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Adding Icon Badges and a Manifest to Xojo Web Applications</title>
		<link>https://blog.xojo.com/2023/10/05/adding-icon-badges-and-a-manifest-to-xojo-web-applications/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Thu, 05 Oct 2023 18:27:17 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12140</guid>

					<description><![CDATA[With macOS Sonoma, users can add a Xojo web app to the Home / Dock. That brings icon badges and manifest files to Xojo web apps starting with Xojo 2023r2. Let’s see how you can use them to make your web apps more accessible and useful.]]></description>
										<content:encoded><![CDATA[
<p>With macOS Sonoma, users can add a Xojo web app to the Home / Dock. That brings icon badges and manifest files to Xojo web apps starting with Xojo 2023r2. Let’s see how you can use them to make your web apps more accessible and useful.</p>



<p>Before we jump into the topic, it’s worth mentioning that this is new in Safari 17, but it is a W3C Standard that might work with other combinations of browser and operating system.</p>



<p>One of the biggest advantages of creating a web app is that users won’t need to update it manually. Once a new version is deployed, a browser refresh will be enough to update- which Xojo handles that automatically. If we are talking about a large company with hundreds of computers, it’s easy to see how having a web-based Intranet, for example, would reduce maintenance costs.</p>



<p>Step by step, browser vendors are allowing developers to access APIs that are traditionally reserved for native desktop or  mobile developers.</p>



<h3 class="wp-block-heading">Adding Icon Badges</h3>



<p>When users add a web application to the Dock, developers have the opportunity to set a numerical badge. This helps let the user know the amount of items requiring attention.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="478" height="202" src="https://blog.xojo.com/wp-content/uploads/2023/10/xojo-badge.png" alt="" class="wp-image-12148" srcset="https://blog.xojo.com/wp-content/uploads/2023/10/xojo-badge.png 478w, https://blog.xojo.com/wp-content/uploads/2023/10/xojo-badge-300x127.png 300w" sizes="auto, (max-width: 478px) 100vw, 478px" /></figure>
</div>


<p>Missed calls, unread message notifications or the minutes pending in a Pomodoro session. The meaning of the badge value is determined by you.</p>



<p>This Web API is pretty easy to use in Xojo. Add a few new public methods to the Session object, called <code>SetBadge</code> and <code>ClearBadge</code>, respectively.</p>



<h4 class="wp-block-heading"><strong>SetBadge (amount As Integer)</strong></h4>



<pre class="wp-block-code"><code>Var js() As String

js.Add("if ('setAppBadge' in navigator) {")
js.Add("  navigator.setAppBadge(" + amount.ToString + ");")
js.Add("}")

ExecuteJavaScript(String.FromArray(js))</code></pre>



<h4 class="wp-block-heading"><strong>ClearBadge</strong></h4>



<pre class="wp-block-code"><code>Var js() As String

js.Add("if ('clearAppBadge' in navigator) {")
js.Add("  navigator.clearAppBadge();")
js.Add("}")

ExecuteJavaScript(String.FromArray(js))</code></pre>



<p>That’s it. Whenever you need to display a badge for that user, call <code>Session.SetBadge(42)</code>, for example.</p>



<h3 class="wp-block-heading">Creating a Manifest File</h3>



<p>While is not required, a web app manifest file will allow you to tweak the look and feel of the application when added to the Home / Dock.</p>



<p>In order to let the OS know there is a Manifest file, add a new HTML header. Go to App -&gt; HTML Header and add this line:</p>



<pre class="wp-block-code"><code>&lt;link rel="manifest" href="/manifest.json" /&gt;</code></pre>



<p>Let’s fill in the contents. We have to handle that “/manifest.json” URL. Add a new Event Handler in the app object, select the “HandleURL” event.</p>



<p>This is an example of how to create that file:</p>



<pre class="wp-block-code"><code>Select Case request.Path
Case "manifest.json"
  Var manifest As New JSONItem
  manifest.Value("display") = "standalone" // Remove back/forward buttons
  manifest.Value("name") = "My Xojo Application"
  manifest.Value("short_name") = "Xojo App"

  response.MIMEType = "application/json"
  response.Status = 200
  response.Write(manifest.ToString)
  Return True
End Select</code></pre>



<p>You can check the whole list of parameters available from this website:<br><a href="https://developer.mozilla.org/en-US/docs/Web/Manifest">Web app manifests</a></p>



<h3 class="wp-block-heading">Debugging Web Apps</h3>



<p>Hey! Where are my Developer Tools!?</p>



<p>You can’t directly debug a web app from the app itself. But if needed, you can still open Safari, press on the Develop menu and, from there, access a Developer Tools instance for any web app that is opened:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="575" src="https://blog.xojo.com/wp-content/uploads/2023/10/Safari17_DevelopMenu@2x-1024x575.png" alt="" class="wp-image-12142" srcset="https://blog.xojo.com/wp-content/uploads/2023/10/Safari17_DevelopMenu@2x-1024x575.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/10/Safari17_DevelopMenu@2x-300x168.png 300w, https://blog.xojo.com/wp-content/uploads/2023/10/Safari17_DevelopMenu@2x-768x431.png 768w, https://blog.xojo.com/wp-content/uploads/2023/10/Safari17_DevelopMenu@2x-1536x863.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/10/Safari17_DevelopMenu@2x.png 1916w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h3 class="wp-block-heading">That’s All!</h3>



<p>While a web app is far from a native desktop app, changes like this make the the gap a little smaller and the user experience a little better.</p>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Bootstrap 5 in Xojo Web 2023r2</title>
		<link>https://blog.xojo.com/2023/08/09/bootstrap-5-in-xojo-web-2023r2/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Wed, 09 Aug 2023 13:30:00 +0000</pubDate>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[DarkMode]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11762</guid>

					<description><![CDATA[Bootstrap continues to improve and as a result we have upgraded the Web framework to the latest version. For most Xojo users, this update won't require any changes at all to your existing projects.]]></description>
										<content:encoded><![CDATA[
<p><a rel="noreferrer noopener" href="https://getbootstrap.com" target="_blank">Bootstrap</a> is the toolkit the Xojo Web framework uses to create the UI controls for your web projects. Bootstrap continues to improve and as a result we have upgraded the Web framework to the latest version.</p>



<p>For most Xojo users, this update won&#8217;t require any changes at all to your existing projects. For those that create their own controls using the Web SDK, there will likely be a minor bit of work.</p>



<h3 class="wp-block-heading">Dark Mode Support</h3>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="716" src="https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284-1024x716.png" alt="" class="wp-image-11199" srcset="https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284-1024x716.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284-300x210.png 300w, https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284-768x537.png 768w, https://blog.xojo.com/wp-content/uploads/2023/01/BeautyShot-3284.png 1237w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Eddie&#8217;s Electronics sample app running with Dark Mode support enabled.</figcaption></figure>



<p>The Web framework is currently the only Xojo framework that doesn&#8217;t support Dark Mode. Fortunately, Bootstrap 5 does. As with Desktop targets, users of your Web projects will be able to decide between the light and dark modes. For Web projects, there is now a Supports Dark Mode Build Setting that will be off by default for existing projects and on by default for new ones.</p>



<h3 class="wp-block-heading">More Than Dark Mode</h3>



<p>Visually, Bootstrap 5 comes with some subtle changes. For example the blue color it uses is still blue… but not that blue, helping to increase the contrast of your buttons.</p>



<p>You may notice that the buttons are a little bit rounder by default, following the latest design trends.</p>



<p>The look and feel of some input controls, like checkboxes and radio buttons, will be more similar between different browsers and operating systems.</p>



<p>Bootstrap 5 also includes new components and features, like <a rel="noreferrer noopener" href="https://getbootstrap.com/docs/5.3/components/accordion/" target="_blank">Accordion</a> and <a rel="noreferrer noopener" href="https://getbootstrap.com/docs/5.3/components/offcanvas/" target="_blank">Offcanvas</a>. These may find their way into future releases via the Web framework or from one of the third-party control developers.</p>



<p>Finally, Bootstrap 5 no longer depends on jQuery and it makes use of the latest CSS features which brings us to the next section.</p>



<h3 class="wp-block-heading">Potential Migration Challenges</h3>



<p>We&#8217;ve made it so most Xojo users won&#8217;t need to make any changes to their web projects. For example, we&#8217;ve adapted the Breadcrumb control to look like Bootstrap 4 by default. Generally speaking, if you are using the default theme and you aren&#8217;t using third-party controls, you won&#8217;t need to do anything special.</p>



<p>However, if you are currently using a custom Bootstrap 4 theme that uses a custom bootstrap.min.css file, it may not work properly. If you&#8217;ve downloaded the theme from a website such as <a rel="noreferrer noopener" href="https://bootswatch.com" target="_blank">Bootswatch</a>, you can download an updated Bootstrap 5 compatible theme from the same site. Bootstrap 5 themes are actually easier to find than those for v4.</p>



<p>If you are still curious about Bootstrap 5 specifically, you can view the <a rel="noreferrer noopener" href="https://getbootstrap.com/docs/5.3/migration/" target="_blank">Bootstrap 5 Migration Guide</a> where you can find an extensive list of changes and improvements since Bootstrap 4.6.</p>



<p>If you have any questions, please feel free to ask on the <a rel="noreferrer noopener" href="https://forum.xojo.com" target="_blank">Forum</a>.</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Updates for Web Projects in Xojo 2023r2</title>
		<link>https://blog.xojo.com/2023/08/09/updates-for-web-projects-in-xojo-2023r2/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Wed, 09 Aug 2023 13:30:00 +0000</pubDate>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[Charts]]></category>
		<category><![CDATA[DarkMode]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web SDK]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[WebListBox]]></category>
		<category><![CDATA[Xojo IDE]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11671</guid>

					<description><![CDATA[Xojo 2023r2 comes with a lot of updates for Xojo Web. While Dark Mode and Bootstrap 5 are the main feature in this release, we've put a lot of effort into making everything better including: improved accessibility, updates to the WebListBox and WebChart and IDE performance improvements and more.]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2023r2 comes with a lot of updates for Xojo Web. While Dark Mode and Bootstrap 5 are the main feature in this release, we&#8217;ve put a lot of effort into making everything better including: improved accessibility, updates to the WebListBox and WebChart, IDE performance improvements and more.</p>



<span id="more-11671"></span>



<h3 class="wp-block-heading">Dark Mode Support and Bootstrap 5</h3>



<p>You can now create web applications with Xojo that respects users&#8217; Dark Mode preference with Bootstrap 5.</p>



<p>There is a new WebSession.ColorMode property you can use. It will be set as Auto by default, meaning it will match the user&#8217;s OS appearance preference, but it can also be forced to Light or Dark. It can be changed at runtime and per session.</p>



<p>While not everyone likes Dark Mode, some of your end users will appreciate this. Due to medical circumstances, they might actually need it, so please consider adding support even if you don&#8217;t like dark interfaces.</p>



<p>If you want to enable Dark Mode in your previous projects, you will have to manually enable the setting in the Shared Build Settings section (which is turned on by default on new projects):</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="786" src="https://blog.xojo.com/wp-content/uploads/2023/07/Supports-Dark-Mode-Setting-1024x786.png" alt="" class="wp-image-11672" srcset="https://blog.xojo.com/wp-content/uploads/2023/07/Supports-Dark-Mode-Setting-1024x786.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/07/Supports-Dark-Mode-Setting-300x230.png 300w, https://blog.xojo.com/wp-content/uploads/2023/07/Supports-Dark-Mode-Setting-768x589.png 768w, https://blog.xojo.com/wp-content/uploads/2023/07/Supports-Dark-Mode-Setting.png 1114w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p><a href="https://documentation.xojo.com/api/graphics/colorgroup.html">Color Groups</a> can also be used nearly everywhere, and they will be used in the IDE preview when you toggle between Light and Dark Mode:</p>



<figure class="wp-block-video aligncenter"><video height="1680" style="aspect-ratio: 2786 / 1680;" width="2786" controls src="https://blog.xojo.com/wp-content/uploads/2023/07/ColorGroup-IDE-preview.mp4"></video></figure>



<p>In order get Dark Mode support ready for Web, we had to upgrade our internal <a rel="noreferrer noopener" href="https://getbootstrap.com" data-type="URL" data-id="https://getbootstrap.com" target="_blank">Bootstrap</a> dependency from v4.6.1 to v5.3.0, which is a huge leap by itself. Bootstrap 5 comes with a refreshed color palette, new components, modernized existing controls and bug fixes. Please check our previous <a href="https://blog.xojo.com/2023/01/26/bootstrap-5-is-coming-to-the-xojo-web-framework/" data-type="post" data-id="11198">Bootstrap 5 is Coming to the Xojo Web Framework</a> blog post.</p>



<p>If your application wasn&#8217;t using a custom Bootstrap Theme (bootstrap.min.css), everything should look more or less the same except for the subtle color palette differences and rounder buttons. Bootstrap 4 themes aren&#8217;t supported in Bootstrap 5, please replace it with a v5 theme if needed. Not every theme supports Dark Mode, but the one included in Xojo does.</p>



<p>If you are a theme builder, please check the <a rel="noreferrer noopener" href="https://getbootstrap.com/docs/5.3/customize/color-modes/" target="_blank">Bootstrap&#8217;s Color Modes documentation</a>. You can also find free Bootstrap 5 themes available at&nbsp;<a href="https://bootswatch.com" target="_blank" rel="noreferrer noopener">Bootswatch</a>.</p>



<p>We also want to send a big thank you to our third party developers for their effort adapting their Open Source and Commercial plugins and controls to Bootstrap 5. You can learn about what they offer at the Xojo <a href="https://www.xojo.com/store/#addons">Extras Store</a> and in the <a href="https://documentation.xojo.com/resources/third_party/open_source_projects.html">Open Source Projects</a> page in the Xojo Documentation.</p>



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



<p>Navigating and using web applications with the keyboard makes everyone&#8217;s life easier. In Xojo 2023r2 we&#8217;ve upgraded <a href="https://documentation.xojo.com/api/user_interface/web/webpagination.html#webpagination">WebPagination</a> and <a href="https://documentation.xojo.com/api/user_interface/web/webbreadcrumb.html#webbreadcrumb">WebBreadcrumb</a> controls, which are composed of more than one focusable item. Your users will be able to properly use the tab key to go through them.</p>



<figure class="wp-block-video aligncenter"><video height="998" style="aspect-ratio: 1404 / 998;" width="1404" controls src="https://blog.xojo.com/wp-content/uploads/2023/07/Tab-WebPagination-and-WebBreadcrumb.mp4"></video></figure>



<p>We plan to continue working on improving Accessibility. Please open a new <a href="https://tracker.xojo.com/xojoinc/xojo/-/issues/new" target="_blank" rel="noreferrer noopener">Issue</a> if you find anything that can help you and your end users.</p>



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



<p>DataTables, the internal dependency we use for bringing your tables to life, has been upgraded from v1.10.20 to v1.13.4. This recent version includes support for Bootstrap 5 and a few bug fixes that some users were facing in their web projects.</p>



<p>You can now disable your <a href="https://documentation.xojo.com/api/user_interface/web/weblistbox.html#weblistbox">WebListBox</a> by setting its Enabled property to False so your users won&#8217;t be able to interact with it. And also, if you were missing this feature that&#8217;s in the DesktopListBox, you can now add Variant tags to your columns, using the new WebListBox.ColumnTagAt.</p>



<p>Last but not least, this control comes with a visual Inline Editor, like in its Desktop counterpart:</p>



<figure class="wp-block-video aligncenter"><video height="1806" style="aspect-ratio: 2786 / 1806;" width="2786" controls src="https://blog.xojo.com/wp-content/uploads/2023/07/WebListBox-Inline-Edit.mp4"></video></figure>



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



<p>Chart.js, the underlying library we use for <a href="https://documentation.xojo.com/api/user_interface/web/webchart.html#webchart">WebChart</a>, has been upgraded from v2.9.3 to v4.2.1. Again, we&#8217;ve done everything we could on our side so you don&#8217;t have to do anything.</p>



<p>The only exception is with the WebChart.OverrideOptions event. If you are currently using it, you&#8217;ll have to check the library documentation as the internal options JSON has changed.</p>



<p>You can expect the new DesktopChart features to be working on WebChart, like configuring how the lines look like (including the endpoints), background images or prefix and suffixes. Read <a href="https://blog.xojo.com/2023/07/19/2023r2-new-additions-to-desktopchart-mobilechart-and-webchart">New Additions to DesktopChart, MobileChart and WebChart</a> to learn more.</p>



<h3 class="wp-block-heading">Web SDK</h3>



<p>If you are using third party controls, you will notice some of them now have a custom icon in the IDE Library. But even more important, they will use less memory at runtime.</p>



<p>Are you developing Open Source or Commercial Web SDK controls? Remember there is a dedicated <a rel="noreferrer noopener" href="https://forum.xojo.com/c/sdks/web-sdk/23" target="_blank">Web SDK forum</a> where you can ask any questions you may have. </p>



<h3 class="wp-block-heading">IDE Performance and Improved CSS Support</h3>



<p>Bootstrap 5 makes use of the latest CSS features. We took the opportunity to rethink our CSS parser and improve its performance at the same time. As a result, the IDE preview looks even closer to what you see in the browser, and we render everything faster.</p>



<h3 class="wp-block-heading">Wrapping Up</h3>



<p>Over 50 bug fixes and features were included just for Xojo Web in Xojo 2023r2. Please find a full list in the <a href="https://documentation.xojo.com/resources/release_notes/2023r2.html">Release Notes</a>. read more about <a href="https://blog.xojo.com/2023/08/09/bootstrap-5-in-xojo-web-2023r2/">Bootstrap 5</a> and updates to <a href="https://blog.xojo.com/2023/08/09/new-additions-to-desktopchart-mobilechart-and-webchart/">WebChart</a> on the Xojo Programming Blog.  We are looking forward to hearing your thoughts and seeing what you&#8217;re building with Xojo! See you in the forum!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2023/07/ColorGroup-IDE-preview.mp4" length="646228" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2023/07/Tab-WebPagination-and-WebBreadcrumb.mp4" length="202785" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2023/07/WebListBox-Inline-Edit.mp4" length="737982" type="video/mp4" />

			</item>
		<item>
		<title>Building a Vertical Navigation for your Web Application</title>
		<link>https://blog.xojo.com/2023/03/29/building-a-vertical-navigation-for-your-web-application/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Wed, 29 Mar 2023 12:41:00 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Atomic Design Methodology]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Code]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11472</guid>

					<description><![CDATA[Composing new controls using primitives is something you definitely want to explore. Let’s build a reusable vertical navigation, with animations, for your Xojo Web projects using the Atomic Design Methodology.]]></description>
										<content:encoded><![CDATA[
<p>Composing new controls using primitives is something you definitely want to explore. Let’s build a reusable vertical navigation, with animations, for your Xojo Web projects.</p>



<h2 class="wp-block-heading">Brief introduction to the Atomic Design Methodology</h2>



<p>If you haven&#8217;t heard about Atomic Design before, I really recommend that you dig a bit into this topic. With this way of methodology in mind, we will start building the smallest controls we can. Then, we will compose more complex controls reusing the smallest.</p>



<p>Keep in mind you don&#8217;t really need to blindly follow the Atoms, Molecules and Organisms proposed categories, and don&#8217;t overthink where to categorize them. As long as you can compose controls with other controls, that&#8217;s perfect. Adapt it to your own personal way of building software.</p>



<p>The idea resonates perfectly with Xojo and, while we will create a few web controls in this example, you can apply it to other targets like Desktop or Mobile.</p>



<p>Here is a <a href="https://www.youtube.com/watch?v=W-h1FtNYim4">video</a> from Brad Frost, the person behind Atomic Design Methodology.</p>



<h2 class="wp-block-heading">Containers to the rescue! </h2>



<p>In this case, we won&#8217;t need to use any Web SDK control, CSS or JavaScript. We will be using just plain Xojo Web Containers for creating our Atoms and Molecules.</p>



<p>This is how Twitter&#8217;s navigation sidebar looks like:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="280" height="481" src="https://blog.xojo.com/wp-content/uploads/2023/03/Explore.png" alt="" class="wp-image-11473" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/Explore.png 280w, https://blog.xojo.com/wp-content/uploads/2023/03/Explore-175x300.png 175w" sizes="auto, (max-width: 280px) 100vw, 280px" /><figcaption class="wp-element-caption">Twitter Vertical Navigation</figcaption></figure>
</div>


<p>We will create something similar. Using Atomic Design, let&#8217;s break it down it into a few new reusable controls:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="700" height="525" src="https://blog.xojo.com/wp-content/uploads/2023/03/components-atomic-design.png" alt="" class="wp-image-11474" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/components-atomic-design.png 700w, https://blog.xojo.com/wp-content/uploads/2023/03/components-atomic-design-300x225.png 300w" sizes="auto, (max-width: 700px) 100vw, 700px" /><figcaption class="wp-element-caption">Individual Controls</figcaption></figure>
</div>


<p>Each Atom, Molecule and Organism will be a Container. In the above image, we have identified each of them.</p>



<ul class="wp-block-list">
<li>There is a &#8220;Navigation Link Icon&#8221;, an Atom, which will show one of the available <a rel="noreferrer noopener" href="https://icons.getbootstrap.com" data-type="URL" data-id="https://icons.getbootstrap.com" target="_blank">Bootstrap Icons</a>. As you notice in the Twitter example, if the link is active, the icon will be filled.</li>



<li>For the label Atom, we can just use the WebLabel built-in control. There is no need to wrap it in a Container, in this case.</li>



<li>The navigation link will be a Molecule, combining the icon and the label.</li>



<li>The Active Link Indicator will move to the active link, using an animation.</li>



<li>Finally, the Vertical Navigation Control will be the Organism, combining everything into one.</li>
</ul>



<h2 class="wp-block-heading">Navigation Link Icon</h2>



<p>This Control is basically a Container, with an ImageViewer inside. Technically, this could be just an ImageViewer subclass, but using a WebContainer we can also specify its default width and height.</p>



<p>It will have two computed properties:</p>



<ul class="wp-block-list">
<li>Active As Boolean</li>



<li>IconName As String</li>
</ul>



<p>There will also be a private ShowIcon method. Whenever you change either the Active property or IconName, the computed property will call ShowIcon.</p>



<p>The magic is inside ShowIcon:</p>



<pre class="wp-block-code Xojo"><code><code>Var iconColor As Color = If(mActive, Color.Black, Color.LightGray)
Var icon As String = If(mActive, mIconName + "-fill", mIconName)
IconImageViewer.Picture = WebPicture.BootstrapIcon(icon, iconColor)</code></code></pre>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="716" src="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.55.04-1024x716.png" alt="" class="wp-image-11475" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.55.04-1024x716.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.55.04-300x210.png 300w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.55.04-768x537.png 768w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.55.04.png 1381w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">NavigationLinkIcon in the IDE</figcaption></figure>
</div>


<p>The icon color will be either LightGray or Black, depending if it&#8217;s active or not. There are also a lot of Bootstrap Icons with the &#8220;-fill&#8221; suffix so we&#8217;ll use them. This will force us to only use icons which have that suffix, but we will have to live with that.</p>



<p>The final trick is to use the Inspector Behavior and expose our Active and IconName computed properties. Right click on NavigationLinkIcon, then click on Inspector Behavior:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="400" height="508" src="https://blog.xojo.com/wp-content/uploads/2023/03/Open-in-New-Tab.png" alt="" class="wp-image-11476" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/Open-in-New-Tab.png 400w, https://blog.xojo.com/wp-content/uploads/2023/03/Open-in-New-Tab-236x300.png 236w" sizes="auto, (max-width: 400px) 100vw, 400px" /><figcaption class="wp-element-caption">How to open the Inspector Behavior</figcaption></figure>
</div>


<p>From there you can enable the checkboxes and define their default value:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="716" src="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.00.49-1024x716.png" alt="" class="wp-image-11477" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.00.49-1024x716.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.00.49-300x210.png 300w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.00.49-768x537.png 768w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.00.49.png 1381w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Enabling properties in the Inspector Behavior</figcaption></figure>
</div>


<p>Now that we have the Control ready, let&#8217;s see how it works on its own:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="716" src="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.51.02-1024x716.png" alt="" class="wp-image-11478" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.51.02-1024x716.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.51.02-300x210.png 300w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.51.02-768x537.png 768w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-13.51.02.png 1381w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">NavigationLinkIcon demo</figcaption></figure>
</div>


<figure class="wp-block-video aligncenter"><video height="488" style="aspect-ratio: 660 / 488;" width="660" controls src="https://blog.xojo.com/wp-content/uploads/2023/03/NavigationLinkIcon-demo.mp4"></video><figcaption class="wp-element-caption">NavigationLinkIcon demo</figcaption></figure>



<p>Neat! You can reuse this Atom everywhere, including other projects.</p>



<h2 class="wp-block-heading">Navigation Link Control</h2>



<p>Combining our fresh NavigationLinkIcon, a built-in WebLabel and exposing an API, we&#8217;ll create our NavigationLink Molecule.</p>



<p>Create a new Container and place the items inside. Then add some computed properties:</p>



<ul class="wp-block-list">
<li>Active</li>



<li>Caption</li>



<li>IconName</li>
</ul>



<p>Whenever the property changes, just update the underlying control.</p>



<p>One trick, to make the control clickable, is to add a WebCanvas on top of the other controls. Implement its Pressed event and forward it as a new &#8220;Pressed&#8221; Event Definition.</p>



<p>If you want to show a pointer cursor when the user moves the mouse over your control, add this line of code into the container&#8217;s Opening event:</p>



<pre class="wp-block-code xojo"><code><code>Me.Style.Cursor = WebStyle.Cursors.Pointer</code></code></pre>



<p>This is how it looks like in the IDE:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="716" src="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.28.18-1024x716.png" alt="" class="wp-image-11480" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.28.18-1024x716.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.28.18-300x210.png 300w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.28.18-768x537.png 768w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-14.28.18.png 1381w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">NavigationLink in the IDE</figcaption></figure>
</div>


<p>Let&#8217;s quickly test it:</p>



<figure class="wp-block-video aligncenter"><video height="488" style="aspect-ratio: 660 / 488;" width="660" controls src="https://blog.xojo.com/wp-content/uploads/2023/03/NavigationLink-demo.mp4"></video><figcaption class="wp-element-caption">NavigationLink demo</figcaption></figure>



<p>We are getting there.</p>



<h2 class="wp-block-heading">Active Link Indicator</h2>



<p>We have most of the Atoms and Molecules created already. The Navigation Link Indicator is so simple and so tied to the Sidebar, that I don&#8217;t think creating an individual Atom for it is worth the effort.</p>



<p>Using a WebRectangle, with a line of two of code in its Opening event, will be enough. This is completely up to you!</p>



<h2 class="wp-block-heading">Vertical Navigation Control</h2>



<p>Now it&#8217;s time to glue the Atoms and Molecules together to make our first Organism. Create a new Container called VerticalNavigation.</p>



<p>Drop a WebRectangle on it. Set its Left and Top to 0, and implement its Opening event with these lines of code:</p>



<pre class="wp-block-code Xojo"><code><code>Me.Style.BorderThickness = 0
Me.Style.AddTransition("top", 0.2)</code></code></pre>



<p>That will remove the border that comes by default with this control. It will also tell the browser to animate the rectangle whenever we change the Top position.</p>



<p>The rectangle background color will be a light gray, but this is again up to you.</p>



<p>For the API we want to expose, add these Methods:</p>



<ul class="wp-block-list">
<li>AddLink(caption As String, icon As String, active As Boolean = False)</li>



<li>HandleLinkPressed(sender As NavigationLink)</li>



<li>SetActiveLink(index As Integer)</li>
</ul>



<p>AddLink and SetActiveLink can be left Public, HandleLinkPressed will be a Private Method.</p>



<p>AddLink code:</p>



<pre class="wp-block-code Xojo"><code><code>// We will create a new NavigationLink instance
// and set the properties we're receiving.
Var link As New NavigationLink
link.Caption = caption
link.IconName = icon

// For its pressed event, we will handle it
// internally in the HandleLinkPressed method.
AddHandler link.Pressed, WeakAddressOf HandleLinkPressed

// We will place it programatically in  the container.
Const padding = 10
Var linkTop As Integer = mLinks.Count * (link.Height + padding)
link.EmbedWithin(Self, padding, linkTop, Self.Width - padding, link.Height)

// A reference for this NavigationLink will be
// needed later, so we will store it internally.
mLinks.Add(link)

// Finally, if the item is active, we will
// handle it just like if it's been pressed
// by the user.
If active Then
  SetActiveLink(mLinks.LastIndex)
End If</code></code></pre>



<p>HandleLinkPressed code:</p>



<pre class="wp-block-code xojo"><code><code>SetActiveLink(mLinks.IndexOf(sender))
RaiseEvent Pressed(sender)</code></code></pre>



<p>And, finally, SetActiveLink:</p>



<pre class="wp-block-code xojo"><code><code>// Here we will loop through the NavigationLink
// references we have and enable or disable the
// Active property, depending on the index
// comparison.
For i As Integer = 0 To mLinks.LastIndex
  mLinks(i).Active = i = index
Next

// Move the visual active indicator to the
// NavigationLink position.
ActiveLinkIndicator.Top = mLinks(index).Top</code></code></pre>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="714" src="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-17.48.51-1024x714.png" alt="" class="wp-image-11482" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-17.48.51-1024x714.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-17.48.51-300x209.png 300w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-17.48.51-768x535.png 768w, https://blog.xojo.com/wp-content/uploads/2023/03/Captura-de-Pantalla-2023-03-27-a-las-17.48.51.png 1485w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">VerticalNavigation in the IDE</figcaption></figure>
</div>


<h2 class="wp-block-heading">Final Result</h2>



<p>Everything is ready, drop your VerticalNavigation somewhere in your WebPage and add a few links inside its Opening event:</p>



<pre class="wp-block-code xojo"><code><code>// Setting the third parameter to "True" will set that link as Active.
Me.AddLink("Home", "house")
Me.AddLink("Explore", "binoculars", True)
Me.AddLink("Notifications", "bell")</code></code></pre>



<p>You should see something similar to this:</p>



<figure class="wp-block-video aligncenter"><video height="488" style="aspect-ratio: 660 / 488;" width="660" controls src="https://blog.xojo.com/wp-content/uploads/2023/03/result-demo.mp4"></video><figcaption class="wp-element-caption">Final result!</figcaption></figure>



<p>Congratulations! You&#8217;ve built a vertical navigation, with nice transitions, using some Atomic Design principles.</p>



<p>Code repository: <a rel="noreferrer noopener" href="https://github.com/piradoiv/vertical-navigation-example" target="_blank">https://github.com/piradoiv/vertical-navigation-example</a><br>Download the project: <a rel="noreferrer noopener" href="https://github.com/piradoiv/vertical-navigation-example/archive/refs/heads/main.zip" target="_blank">vertical-navigation-example</a></p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2023/03/NavigationLinkIcon-demo.mp4" length="55146" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2023/03/NavigationLink-demo.mp4" length="210022" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2023/03/result-demo.mp4" length="90366" type="video/mp4" />

			</item>
	</channel>
</rss>
